diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-09-27 22:25:05 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-09-27 22:25:05 +0000 |
commit | 64732cdb0d95320d9274b26fcac6e617d6473248 (patch) | |
tree | a21c273a37f4f210dd577a30e746d6269db75ccf /src/dns | |
parent | 94adb0e8c48d47e13e7319bb0fe228263b15abbf (diff) | |
download | gnunet-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.am | 1 | ||||
-rw-r--r-- | src/dns/dnsstub.c | 10 | ||||
-rw-r--r-- | src/dns/gnunet-helper-dns.c | 95 | ||||
-rw-r--r-- | src/dns/gnunet-service-dns.c | 8 | ||||
-rwxr-xr-x | src/dns/test_gnunet_dns.sh | 6 |
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 = \ | |||
89 | libgnunetdnsstub_la_SOURCES = \ | 89 | libgnunetdnsstub_la_SOURCES = \ |
90 | dnsstub.c | 90 | dnsstub.c |
91 | libgnunetdnsstub_la_LIBADD = \ | 91 | libgnunetdnsstub_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) |
93 | libgnunetdnsstub_la_LDFLAGS = \ | 94 | libgnunetdnsstub_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 | |||
101 | static const char *sbin_iptables; | 101 | static const char *sbin_iptables; |
102 | 102 | ||
103 | /** | 103 | /** |
104 | * Name and full path of IPTABLES binary. | ||
105 | */ | ||
106 | static const char *sbin_ip6tables; | ||
107 | |||
108 | /** | ||
104 | * Name and full path of sysctl binary | 109 | * Name and full path of sysctl binary |
105 | */ | 110 | */ |
106 | static const char *sbin_sysctl; | 111 | static 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 |
8 | fi | 8 | fi |
9 | if ! which sudo > /dev/null | 9 | if ! which sudo > /dev/null |
10 | then | 10 | then |
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 |
18 | fi | 18 | fi |
19 | if ! which nslookup > /dev/null | 19 | if ! which nslookup > /dev/null |
20 | then | 20 | then |
21 | echo "This test requires nslookup. Skipping." | 21 | echo "This test requires nslookup. Skipping." |
22 | exit 77 | 22 | exit 77 |
23 | fi | 23 | fi |
@@ -38,7 +38,7 @@ gnunet-dns-redirector -c dns.conf -4 127.0.0.1 & | |||
38 | sleep 1 | 38 | sleep 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! |
41 | LO=`sudo -u nobody nslookup gnunet.org | grep Address | tail -n1` | 41 | LO=`sudo -u nobody nslookup -type=A gnunet.org | grep Address | tail -n1` |
42 | if [ "$LO" != "Address: 127.0.0.1" ] | 42 | if [ "$LO" != "Address: 127.0.0.1" ] |
43 | then | 43 | then |
44 | echo "Fail: got address $LO, wanted 127.0.0.1" | 44 | echo "Fail: got address $LO, wanted 127.0.0.1" |