In my quest to make SMB browsing work with the default firewall rules, thus fixing: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=133478 https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=113918 I have now written a kernel conntrack module (attached) that marks replies to netbios name requests as RELATED to the original connection. This means the default firewall rules will work when this module is loaded. I'm not actually an expert in netbios or firewall stuff, so I'd love if someone who knew this better took a look at it and made sure it looks ok. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Alexander Larsson Red Hat, Inc alexl@xxxxxxxxxx alla@xxxxxxxxxxxxxx He's an impetuous crooked stage actor on a mission from God. She's a warm-hearted foul-mouthed opera singer from a different time and place. They fight crime!
#include <linux/module.h> #include <linux/ip.h> #include <linux/udp.h> #include <linux/netfilter.h> #include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ip_conntrack_helper.h> MODULE_AUTHOR("Alexander Larsson <alexl@xxxxxxxxxx>"); MODULE_DESCRIPTION("netbios ns conntrack helper"); MODULE_LICENSE("GPL"); #define NETBIOS_NS_PORT 137 #define NETBIOS_NS_REPLY_TIMEOUT 20 #if 0 #define DEBUGP(format, args...) printk(KERN_ERR "%s:" format, \ __FUNCTION__ , ## args) #else #define DEBUGP(format, args...) #endif static int netbios_ns_help(struct sk_buff *skb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) { struct ip_conntrack_expect *exp; exp = ip_conntrack_expect_alloc(); if (exp == NULL) return NF_ACCEPT; exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; exp->mask.src.ip = 0; exp->mask.dst.ip = 0xffffffff; exp->mask.dst.u.udp.port = 0xffff; exp->mask.dst.protonum = 0xffff; exp->expectfn = NULL; ip_conntrack_expect_related(exp, ct); return NF_ACCEPT; } static struct ip_conntrack_helper netbios_ns; static int __init init(void) { memset(&netbios_ns, 0, sizeof(struct ip_conntrack_helper)); netbios_ns.name = "netbios-ns"; netbios_ns.max_expected = 0; /* No maximum */ netbios_ns.timeout = NETBIOS_NS_REPLY_TIMEOUT; netbios_ns.flags = IP_CT_HELPER_F_REUSE_EXPECT; netbios_ns.me = THIS_MODULE; netbios_ns.help = netbios_ns_help; netbios_ns.tuple.dst.protonum = IPPROTO_UDP; netbios_ns.mask.dst.protonum = 0xFFFF; netbios_ns.tuple.src.u.udp.port = htons(NETBIOS_NS_PORT); netbios_ns.mask.src.u.udp.port = 0xFFFF; return ip_conntrack_helper_register(&netbios_ns); } static void fini(void) { ip_conntrack_helper_unregister(&netbios_ns); } PROVIDES_CONNTRACK(netbios_ns); module_init(init); module_exit(fini);