aboutsummaryrefslogtreecommitdiff
path: root/src/dns
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-09-27 22:25:05 +0000
committerChristian Grothoff <christian@grothoff.org>2016-09-27 22:25:05 +0000
commit64732cdb0d95320d9274b26fcac6e617d6473248 (patch)
treea21c273a37f4f210dd577a30e746d6269db75ccf /src/dns
parent94adb0e8c48d47e13e7319bb0fe228263b15abbf (diff)
downloadgnunet-64732cdb0d95320d9274b26fcac6e617d6473248.tar.gz
gnunet-64732cdb0d95320d9274b26fcac6e617d6473248.zip
fixes relating to intercepting DNS queries over IPv6
Diffstat (limited to 'src/dns')
-rw-r--r--src/dns/Makefile.am1
-rw-r--r--src/dns/dnsstub.c10
-rw-r--r--src/dns/gnunet-helper-dns.c95
-rw-r--r--src/dns/gnunet-service-dns.c8
-rwxr-xr-xsrc/dns/test_gnunet_dns.sh6
5 files changed, 108 insertions, 12 deletions
diff --git a/src/dns/Makefile.am b/src/dns/Makefile.am
index 45b86c71b..f5fcf3782 100644
--- a/src/dns/Makefile.am
+++ b/src/dns/Makefile.am
@@ -89,6 +89,7 @@ libgnunetdnsparser_la_LDFLAGS = \
89libgnunetdnsstub_la_SOURCES = \ 89libgnunetdnsstub_la_SOURCES = \
90 dnsstub.c 90 dnsstub.c
91libgnunetdnsstub_la_LIBADD = \ 91libgnunetdnsstub_la_LIBADD = \
92 $(top_builddir)/src/tun/libgnunettun.la \
92 $(top_builddir)/src/util/libgnunetutil.la $(XLIB) 93 $(top_builddir)/src/util/libgnunetutil.la $(XLIB)
93libgnunetdnsstub_la_LDFLAGS = \ 94libgnunetdnsstub_la_LDFLAGS = \
94 $(GN_LIB_LDFLAGS) \ 95 $(GN_LIB_LDFLAGS) \
diff --git a/src/dns/dnsstub.c b/src/dns/dnsstub.c
index b3cd2817e..68cd55275 100644
--- a/src/dns/dnsstub.c
+++ b/src/dns/dnsstub.c
@@ -24,6 +24,7 @@
24 */ 24 */
25#include "platform.h" 25#include "platform.h"
26#include "gnunet_util_lib.h" 26#include "gnunet_util_lib.h"
27#include "gnunet_tun_lib.h"
27#include "gnunet_dnsstub_lib.h" 28#include "gnunet_dnsstub_lib.h"
28 29
29/** 30/**
@@ -381,9 +382,7 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx,
381 _("Failed to send DNS request to %s\n"), 382 _("Failed to send DNS request to %s\n"),
382 GNUNET_a2s (sa, salen)); 383 GNUNET_a2s (sa, salen));
383 rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT); 384 rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT);
384
385 return rs; 385 return rs;
386
387} 386}
388 387
389 388
@@ -441,9 +440,10 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs,
441 } 440 }
442 dns = (struct GNUNET_TUN_DnsHeader *) buf; 441 dns = (struct GNUNET_TUN_DnsHeader *) buf;
443 if ( (addrlen != rs->addrlen) || 442 if ( (addrlen != rs->addrlen) ||
444 (0 != memcmp (&rs->addr, 443 (GNUNET_YES !=
445 &addr, 444 GNUNET_TUN_sockaddr_cmp ((struct sockaddr *) &rs->addr,
446 addrlen)) || 445 (struct sockaddr *) &addr,
446 GNUNET_YES)) ||
447 (0 == GNUNET_TIME_absolute_get_remaining (rs->timeout).rel_value_us) ) 447 (0 == GNUNET_TIME_absolute_get_remaining (rs->timeout).rel_value_us) )
448 { 448 {
449 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 449 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
diff --git a/src/dns/gnunet-helper-dns.c b/src/dns/gnunet-helper-dns.c
index 2f723d09d..1d411379f 100644
--- a/src/dns/gnunet-helper-dns.c
+++ b/src/dns/gnunet-helper-dns.c
@@ -101,6 +101,11 @@ struct in6_ifreq
101static const char *sbin_iptables; 101static const char *sbin_iptables;
102 102
103/** 103/**
104 * Name and full path of IPTABLES binary.
105 */
106static const char *sbin_ip6tables;
107
108/**
104 * Name and full path of sysctl binary 109 * Name and full path of sysctl binary
105 */ 110 */
106static const char *sbin_sysctl; 111static const char *sbin_sysctl;
@@ -757,7 +762,7 @@ main (int argc, char *const*argv)
757 return 254; 762 return 254;
758 } 763 }
759#endif 764#endif
760 if (0 == strncmp(argv[6], "1", 2)) 765 if (0 == strncmp (argv[6], "1", 2))
761 nortsetup = 1; 766 nortsetup = 1;
762 767
763 if (0 == nortsetup) 768 if (0 == nortsetup)
@@ -774,6 +779,17 @@ main (int argc, char *const*argv)
774 strerror (errno)); 779 strerror (errno));
775 return 3; 780 return 3;
776 } 781 }
782 if (0 == access ("/sbin/ip6tables", X_OK))
783 sbin_ip6tables = "/sbin/ip6tables";
784 else if (0 == access ("/usr/sbin/ip6tables", X_OK))
785 sbin_ip6tables = "/usr/sbin/ip6tables";
786 else
787 {
788 fprintf (stderr,
789 "Fatal: executable ip6tables not found in approved directories: %s\n",
790 strerror (errno));
791 return 3;
792 }
777 if (0 == access ("/sbin/ip", X_OK)) 793 if (0 == access ("/sbin/ip", X_OK))
778 sbin_ip = "/sbin/ip"; 794 sbin_ip = "/sbin/ip";
779 else if (0 == access ("/usr/sbin/ip", X_OK)) 795 else if (0 == access ("/usr/sbin/ip", X_OK))
@@ -942,6 +958,16 @@ main (int argc, char *const*argv)
942 if (0 != fork_and_exec (sbin_iptables, mangle_args)) 958 if (0 != fork_and_exec (sbin_iptables, mangle_args))
943 goto cleanup_rest; 959 goto cleanup_rest;
944 } 960 }
961 {
962 char *const mangle_args[] =
963 {
964 "ip6tables", "-m", "owner", "-t", "mangle", "-I", "OUTPUT", "1", "-p",
965 "udp", "--gid-owner", mygid, "--dport", DNS_PORT, "-j",
966 "ACCEPT", NULL
967 };
968 if (0 != fork_and_exec (sbin_ip6tables, mangle_args))
969 goto cleanup_rest;
970 }
945 /* Mark all of the other DNS traffic using our mark DNS_MARK */ 971 /* Mark all of the other DNS traffic using our mark DNS_MARK */
946 { 972 {
947 char *const mark_args[] = 973 char *const mark_args[] =
@@ -953,6 +979,16 @@ main (int argc, char *const*argv)
953 if (0 != fork_and_exec (sbin_iptables, mark_args)) 979 if (0 != fork_and_exec (sbin_iptables, mark_args))
954 goto cleanup_mangle_1; 980 goto cleanup_mangle_1;
955 } 981 }
982 {
983 char *const mark_args[] =
984 {
985 "ip6tables", "-t", "mangle", "-I", "OUTPUT", "2", "-p",
986 "udp", "--dport", DNS_PORT, "-j", "MARK", "--set-mark", DNS_MARK,
987 NULL
988 };
989 if (0 != fork_and_exec (sbin_ip6tables, mark_args))
990 goto cleanup_mangle_1;
991 }
956 /* Forward all marked DNS traffic to our DNS_TABLE */ 992 /* Forward all marked DNS traffic to our DNS_TABLE */
957 { 993 {
958 char *const forward_args[] = 994 char *const forward_args[] =
@@ -962,6 +998,14 @@ main (int argc, char *const*argv)
962 if (0 != fork_and_exec (sbin_ip, forward_args)) 998 if (0 != fork_and_exec (sbin_ip, forward_args))
963 goto cleanup_mark_2; 999 goto cleanup_mark_2;
964 } 1000 }
1001 {
1002 char *const forward_args[] =
1003 {
1004 "ip", "-6", "rule", "add", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL
1005 };
1006 if (0 != fork_and_exec (sbin_ip, forward_args))
1007 goto cleanup_mark_2;
1008 }
965 /* Finally, add rule in our forwarding table to pass to our virtual interface */ 1009 /* Finally, add rule in our forwarding table to pass to our virtual interface */
966 { 1010 {
967 char *const route_args[] = 1011 char *const route_args[] =
@@ -972,6 +1016,15 @@ main (int argc, char *const*argv)
972 if (0 != fork_and_exec (sbin_ip, route_args)) 1016 if (0 != fork_and_exec (sbin_ip, route_args))
973 goto cleanup_forward_3; 1017 goto cleanup_forward_3;
974 } 1018 }
1019 {
1020 char *const route_args[] =
1021 {
1022 "ip", "-6", "route", "add", "default", "dev", dev,
1023 "table", DNS_TABLE, NULL
1024 };
1025 if (0 != fork_and_exec (sbin_ip, route_args))
1026 goto cleanup_forward_3;
1027 }
975 } 1028 }
976 1029
977 /* drop privs *except* for the saved UID; this is not perfect, but better 1030 /* drop privs *except* for the saved UID; this is not perfect, but better
@@ -1028,6 +1081,16 @@ main (int argc, char *const*argv)
1028 if (0 != fork_and_exec (sbin_ip, route_clean_args)) 1081 if (0 != fork_and_exec (sbin_ip, route_clean_args))
1029 r += 1; 1082 r += 1;
1030 } 1083 }
1084 if (0 == nortsetup)
1085 {
1086 char *const route_clean_args[] =
1087 {
1088 "ip", "-6", "route", "del", "default", "dev", dev,
1089 "table", DNS_TABLE, NULL
1090 };
1091 if (0 != fork_and_exec (sbin_ip, route_clean_args))
1092 r += 1;
1093 }
1031 cleanup_forward_3: 1094 cleanup_forward_3:
1032 if (0 == nortsetup) 1095 if (0 == nortsetup)
1033 { 1096 {
@@ -1038,6 +1101,15 @@ main (int argc, char *const*argv)
1038 if (0 != fork_and_exec (sbin_ip, forward_clean_args)) 1101 if (0 != fork_and_exec (sbin_ip, forward_clean_args))
1039 r += 2; 1102 r += 2;
1040 } 1103 }
1104 if (0 == nortsetup)
1105 {
1106 char *const forward_clean_args[] =
1107 {
1108 "ip", "-6", "rule", "del", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL
1109 };
1110 if (0 != fork_and_exec (sbin_ip, forward_clean_args))
1111 r += 2;
1112 }
1041 cleanup_mark_2: 1113 cleanup_mark_2:
1042 if (0 == nortsetup) 1114 if (0 == nortsetup)
1043 { 1115 {
@@ -1049,6 +1121,16 @@ main (int argc, char *const*argv)
1049 if (0 != fork_and_exec (sbin_iptables, mark_clean_args)) 1121 if (0 != fork_and_exec (sbin_iptables, mark_clean_args))
1050 r += 4; 1122 r += 4;
1051 } 1123 }
1124 if (0 == nortsetup)
1125 {
1126 char *const mark_clean_args[] =
1127 {
1128 "ip6tables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp",
1129 "--dport", DNS_PORT, "-j", "MARK", "--set-mark", DNS_MARK, NULL
1130 };
1131 if (0 != fork_and_exec (sbin_ip6tables, mark_clean_args))
1132 r += 4;
1133 }
1052 cleanup_mangle_1: 1134 cleanup_mangle_1:
1053 if (0 == nortsetup) 1135 if (0 == nortsetup)
1054 { 1136 {
@@ -1061,6 +1143,17 @@ main (int argc, char *const*argv)
1061 if (0 != fork_and_exec (sbin_iptables, mangle_clean_args)) 1143 if (0 != fork_and_exec (sbin_iptables, mangle_clean_args))
1062 r += 8; 1144 r += 8;
1063 } 1145 }
1146 if (0 == nortsetup)
1147 {
1148 char *const mangle_clean_args[] =
1149 {
1150 "ip6tables", "-m", "owner", "-t", "mangle", "-D", "OUTPUT", "-p", "udp",
1151 "--gid-owner", mygid, "--dport", DNS_PORT, "-j", "ACCEPT",
1152 NULL
1153 };
1154 if (0 != fork_and_exec (sbin_ip6tables, mangle_clean_args))
1155 r += 8;
1156 }
1064 1157
1065 cleanup_rest: 1158 cleanup_rest:
1066 /* close virtual interface */ 1159 /* close virtual interface */
diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c
index 50aa730e7..52f924cdf 100644
--- a/src/dns/gnunet-service-dns.c
+++ b/src/dns/gnunet-service-dns.c
@@ -410,7 +410,7 @@ request_done (struct RequestRecord *rr)
410 destination_port = src->sin6_port; 410 destination_port = src->sin6_port;
411 GNUNET_TUN_initialize_ipv6_header (&ip6, 411 GNUNET_TUN_initialize_ipv6_header (&ip6,
412 IPPROTO_UDP, 412 IPPROTO_UDP,
413 reply_len - sizeof (struct GNUNET_TUN_IPv6Header), 413 reply_len - off - sizeof (struct GNUNET_TUN_IPv6Header),
414 &dst->sin6_addr, 414 &dst->sin6_addr,
415 &src->sin6_addr); 415 &src->sin6_addr);
416 GNUNET_memcpy (&buf[off], &ip6, sizeof (ip6)); 416 GNUNET_memcpy (&buf[off], &ip6, sizeof (ip6));
@@ -916,7 +916,7 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client,
916 ip6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1]; 916 ip6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1];
917 if ( (msize < sizeof (struct GNUNET_TUN_IPv6Header)) || 917 if ( (msize < sizeof (struct GNUNET_TUN_IPv6Header)) ||
918 (ip6->version != 6) || 918 (ip6->version != 6) ||
919 (ntohs (ip6->payload_length) != msize) || 919 (ntohs (ip6->payload_length) != msize - sizeof (struct GNUNET_TUN_IPv6Header)) ||
920 (ip6->next_header != IPPROTO_UDP) ) 920 (ip6->next_header != IPPROTO_UDP) )
921 { 921 {
922 /* non-IP/UDP packet received on TUN (or with extensions) */ 922 /* non-IP/UDP packet received on TUN (or with extensions) */
@@ -924,7 +924,7 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client,
924 _("Received malformed IPv6-UDP packet on TUN interface.\n")); 924 _("Received malformed IPv6-UDP packet on TUN interface.\n"));
925 return GNUNET_OK; 925 return GNUNET_OK;
926 } 926 }
927 udp = (const struct GNUNET_TUN_UdpHeader*) &ip6[1]; 927 udp = (const struct GNUNET_TUN_UdpHeader *) &ip6[1];
928 msize -= sizeof (struct GNUNET_TUN_IPv6Header); 928 msize -= sizeof (struct GNUNET_TUN_IPv6Header);
929 break; 929 break;
930 default: 930 default:
@@ -939,6 +939,8 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client,
939 (DNS_PORT != ntohs (udp->destination_port)) ) 939 (DNS_PORT != ntohs (udp->destination_port)) )
940 { 940 {
941 /* non-DNS packet received on TUN, ignore */ 941 /* non-DNS packet received on TUN, ignore */
942 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
943 _("DNS interceptor got non-DNS packet (dropped)\n"));
942 GNUNET_STATISTICS_update (stats, 944 GNUNET_STATISTICS_update (stats,
943 gettext_noop ("# Non-DNS UDP packet received via TUN interface"), 945 gettext_noop ("# Non-DNS UDP packet received via TUN interface"),
944 1, GNUNET_NO); 946 1, GNUNET_NO);
diff --git a/src/dns/test_gnunet_dns.sh b/src/dns/test_gnunet_dns.sh
index ab8cca4b1..84a57f87e 100755
--- a/src/dns/test_gnunet_dns.sh
+++ b/src/dns/test_gnunet_dns.sh
@@ -6,7 +6,7 @@ then
6 echo "This test only works if run as root. Skipping." 6 echo "This test only works if run as root. Skipping."
7 exit 77 7 exit 77
8fi 8fi
9if ! which sudo > /dev/null 9if ! which sudo > /dev/null
10then 10then
11 echo "This test requires sudo. Skipping." 11 echo "This test requires sudo. Skipping."
12 exit 77 12 exit 77
@@ -17,7 +17,7 @@ then
17 exit 77 17 exit 77
18fi 18fi
19if ! which nslookup > /dev/null 19if ! which nslookup > /dev/null
20then 20then
21 echo "This test requires nslookup. Skipping." 21 echo "This test requires nslookup. Skipping."
22 exit 77 22 exit 77
23fi 23fi
@@ -38,7 +38,7 @@ gnunet-dns-redirector -c dns.conf -4 127.0.0.1 &
38sleep 1 38sleep 1
39# need to run 'nslookup' as 'nobody', as gnunet-service-dns runs as root 39# need to run 'nslookup' as 'nobody', as gnunet-service-dns runs as root
40# and thus 'root' is excepted from DNS interception! 40# and thus 'root' is excepted from DNS interception!
41LO=`sudo -u nobody nslookup gnunet.org | grep Address | tail -n1` 41LO=`sudo -u nobody nslookup -type=A gnunet.org | grep Address | tail -n1`
42if [ "$LO" != "Address: 127.0.0.1" ] 42if [ "$LO" != "Address: 127.0.0.1" ]
43then 43then
44 echo "Fail: got address $LO, wanted 127.0.0.1" 44 echo "Fail: got address $LO, wanted 127.0.0.1"