| From dd4b5a1e5e52f2107227b8513fbf87bc4b0df079 Mon Sep 17 00:00:00 2001 |
| From: Kevin Cernekee <cernekee@chromium.org> |
| Date: Sun, 4 Sep 2016 19:39:04 -0700 |
| Subject: [PATCH] conntrackd: cthelper: Add new mdns helper |
| |
| This allows unicast replies to multicast DNS (mDNS / RFC6762) queries. |
| These queries are often used when a full-featured mDNS service (such as |
| avahi-daemon) is not running, or if an mDNS client does not have |
| permission to bind to port 5353. |
| |
| Signed-off-by: Kevin Cernekee <cernekee@chromium.org> |
| Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |
| --- |
| doc/helper/conntrackd.conf | 12 ++++++- |
| src/helpers/Makefile.am | 5 +++ |
| src/helpers/mdns.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++ |
| 3 files changed, 105 insertions(+), 1 deletion(-) |
| create mode 100644 src/helpers/mdns.c |
| |
| diff --git a/doc/helper/conntrackd.conf b/doc/helper/conntrackd.conf |
| index 5c075090c6ad..a827b93461a6 100644 |
| --- a/doc/helper/conntrackd.conf |
| +++ b/doc/helper/conntrackd.conf |
| @@ -25,7 +25,9 @@ Helper { |
| QueueLen 10240 |
| |
| # |
| - # Set the Expectation policy for this helper. |
| + # Set the Expectation policy for this helper. This section |
| + # is optional; if left unspecified, the defaults from the |
| + # ctd_helper struct will be used. |
| # |
| Policy ftp { |
| # |
| @@ -70,6 +72,14 @@ Helper { |
| ExpectTimeout 300 |
| } |
| } |
| + Type mdns inet udp { |
| + QueueNum 6 |
| + QueueLen 10240 |
| + Policy mdns { |
| + ExpectMax 8 |
| + ExpectTimeout 30 |
| + } |
| + } |
| Type ssdp inet udp { |
| QueueNum 5 |
| QueueLen 10240 |
| diff --git a/src/helpers/Makefile.am b/src/helpers/Makefile.am |
| index 78ef7aa71776..51f4887ccced 100644 |
| --- a/src/helpers/Makefile.am |
| +++ b/src/helpers/Makefile.am |
| @@ -3,6 +3,7 @@ include $(top_srcdir)/Make_global.am |
| pkglib_LTLIBRARIES = ct_helper_amanda.la \ |
| ct_helper_dhcpv6.la \ |
| ct_helper_ftp.la \ |
| + ct_helper_mdns.la \ |
| ct_helper_rpc.la \ |
| ct_helper_tftp.la \ |
| ct_helper_tns.la \ |
| @@ -21,6 +22,10 @@ ct_helper_ftp_la_SOURCES = ftp.c |
| ct_helper_ftp_la_LDFLAGS = -avoid-version -module $(LIBNETFILTER_CONNTRACK_LIBS) |
| ct_helper_ftp_la_CFLAGS = $(AM_CFLAGS) $(LIBNETFILTER_CONNTRACK_CFLAGS) |
| |
| +ct_helper_mdns_la_SOURCES = mdns.c |
| +ct_helper_mdns_la_LDFLAGS = -avoid-version -module $(LIBNETFILTER_CONNTRACK_LIBS) |
| +ct_helper_mdns_la_CFLAGS = $(AM_CFLAGS) $(LIBNETFILTER_CONNTRACK_CFLAGS) |
| + |
| ct_helper_rpc_la_SOURCES = rpc.c |
| ct_helper_rpc_la_LDFLAGS = -avoid-version -module $(LIBNETFILTER_CONNTRACK_LIBS) |
| ct_helper_rpc_la_CFLAGS = $(AM_CFLAGS) $(LIBNETFILTER_CONNTRACK_CFLAGS) |
| diff --git a/src/helpers/mdns.c b/src/helpers/mdns.c |
| new file mode 100644 |
| index 000000000000..7605589e606f |
| --- /dev/null |
| +++ b/src/helpers/mdns.c |
| @@ -0,0 +1,89 @@ |
| +/* |
| + * Copyright (C) 2016 Google Inc. |
| + * Author: Kevin Cernekee <cernekee@chromium.org> |
| + * |
| + * This helper pokes a hole in the firewall for unicast mDNS replies |
| + * (RFC6762 section 5.1). It is needed because the destination address of |
| + * the outgoing mDNS query (224.0.0.251) will not match the source address |
| + * of the incoming response (192.168.x.x or similar). The helper is not used |
| + * for standard multicast queries/responses in which the sport and dport are |
| + * both 5353, because those can be handled by a standard filter/INPUT rule. |
| + * |
| + * Usage: |
| + * |
| + * nfct add helper mdns inet udp |
| + * iptables -t raw -A OUTPUT -p udp -d 224.0.0.251 '!' --sport 5353 \ |
| + * --dport 5353 -j CT --helper mdns |
| + * iptables -t filter -A INPUT -p udp -d 224.0.0.251 --dport 5353 -j ACCEPT |
| + * iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED \ |
| + * -j ACCEPT |
| + * |
| + * Requires Linux 3.12 or higher. NAT is unsupported. |
| + * |
| + * This program is free software; you can redistribute it and/or modify |
| + * it under the terms of the GNU General Public License version 2 as |
| + * published by the Free Software Foundation. |
| + */ |
| + |
| +#include "conntrackd.h" |
| +#include "helper.h" |
| +#include "myct.h" |
| +#include "log.h" |
| + |
| +#include <libnetfilter_conntrack/libnetfilter_conntrack.h> |
| +#include <linux/netfilter.h> |
| + |
| +static int mdns_helper_cb(struct pkt_buff *pkt, uint32_t protoff, |
| + struct myct *myct, uint32_t ctinfo) |
| +{ |
| + struct nf_expect *exp; |
| + int dir = CTINFO2DIR(ctinfo); |
| + union nfct_attr_grp_addr saddr; |
| + uint16_t sport, dport; |
| + |
| + exp = nfexp_new(); |
| + if (exp == NULL) { |
| + pr_debug("conntrack_mdns: failed to allocate expectation\n"); |
| + return NF_ACCEPT; |
| + } |
| + |
| + cthelper_get_addr_src(myct->ct, dir, &saddr); |
| + cthelper_get_port_src(myct->ct, dir, &sport); |
| + cthelper_get_port_src(myct->ct, !dir, &dport); |
| + |
| + if (cthelper_expect_init(exp, |
| + myct->ct, |
| + 0 /* class */, |
| + NULL /* saddr */, |
| + &saddr /* daddr */, |
| + IPPROTO_UDP, |
| + &dport /* sport */, |
| + &sport /* dport */, |
| + NF_CT_EXPECT_PERMANENT)) { |
| + pr_debug("conntrack_mdns: failed to init expectation\n"); |
| + nfexp_destroy(exp); |
| + return NF_ACCEPT; |
| + } |
| + |
| + myct->exp = exp; |
| + return NF_ACCEPT; |
| +} |
| + |
| +static struct ctd_helper mdns_helper = { |
| + .name = "mdns", |
| + .l4proto = IPPROTO_UDP, |
| + .priv_data_len = 0, |
| + .cb = mdns_helper_cb, |
| + .policy = { |
| + [0] = { |
| + .name = "mdns", |
| + .expect_max = 8, |
| + .expect_timeout = 30, |
| + }, |
| + }, |
| +}; |
| + |
| +static void __attribute__ ((constructor)) mdns_init(void) |
| +{ |
| + helper_register(&mdns_helper); |
| +} |
| -- |
| 2.8.0.rc3.226.g39d4020 |
| |