So I've hacked a bit on a BCP38 implementation for IPv4, and I think I sorta have a working prototype. I ran out of steam trying to package everything up properly, so thought I'd distribute it so that those adventurous enough to do a manual install could give some feedback. Install instructions (for 3.10.32-9 -- dunno if it will work in earlier versions): 1. Get and install the bcp38 package from http://archive.tohojo.dk/cerowrt/wndr/3.10.32-9-tohojo/packages/bcp38_2-1_ar71xx.ipk -- this will get you the script and it should be run from the firewall. 2. Add the following to your /etc/config/firewall, after the last 'forwarding' section: config ipset option name 'bcp38-ipv4' option family 'ipv4' option match 'dest_net' option storage 'hash' config ipset option name 'bcp38-ipv4-ingress' option external 'bcp38-ipv4' option family 'ipv4' option match 'src_net' option storage 'hash' config rule option src 'wan' option ipset 'bcp38-ipv4-ingress' option family 'ipv4' option name 'drop-bcp38-ipv4 input' option target 'DROP' option proto 'all' config rule option src 'wan' option dest '*' option ipset 'bcp38-ipv4-ingress' option family 'ipv4' option name 'drop-bcp38-ipv4' option target 'DROP' option proto 'all' config rule option dest 'wan' option ipset 'bcp38-ipv4' option name 'reject-bcp38-ipv4 output' option family 'ipv4' option target 'REJECT' option proto 'all' config rule option dest 'wan' option src '*' option ipset 'bcp38-ipv4' option name 'reject-bcp38-ipv4' option family 'ipv4' option target 'REJECT' option proto 'all' Those two steps should be enough to enable the basic mechanism. It is controlled by adding a new option to the firewall config file, in the defaults section. The option is called 'enable_bcp38'. So adding a line like: option enable_bcp38 '1' to the end of the 'defaults' at the top of /etc/config/firewall should enable the mechanism on firewall reload. Additionally, an option called bcp38_whitelist can be set to one or more CIDR style net addresses (space separated) which will be excluded from the matching. This can be used to account for double nat'ing, so if your WAN interface gets an address that would be blocked by the bcp38 rules, add it here and it should go through. To get a checkbox and a field in the firewall GUI to control this, apply the following patch to /usr/lib/lua/luci/model/cbi/firewall/zones.lua (with patch -p1; not sure if that is included in cerowrt, otherwise, just paste in the added lines manually): --- a/zones.lua +++ b/zones.lua @@ -32,6 +32,12 @@ o = s:option(Flag, "drop_invalid", translate("Drop invalid packets")) o.default = o.disabled +b = s:option(Flag, "enable_bcp38", translate("Enable BCP38 filtering")) +b.default = b.disabled + +bip = s:option(Value, "bcp38_whitelist", translate("BCP38 whitelist subnet")) +bip:depends("enable_bcp38", "1") + p = { s:option(ListValue, "input", translate("Input")), s:option(ListValue, "output", translate("Output")), As I said, the basic functionality should be there, but there's some outstanding issues. Including, but not necessarily limited to: - Should there be a separate configuration page where the included subnets can be specified? Or is the checkbox on the firewall page sufficient? I think it logically belongs with the firewall, and indeed it is needs the firewall config rules to function, but maybe more configurability is good thing? - Managing the different parts of the configuration can be brittle. I.e. if the mechanism is disabled but the firewall rules are missing, or vice versa, it's not going to work. - Some sort of auto-detection of upstream private subnets would probably be good, unless we risk people having no access before they change the config manually. - Right now blocked outgoing packets get a 'destination port unreachable' -- this seems to be a hard-coded feature of the firewall script setup. Should probably be a 'destination net unreachable' instead. Anyway, comments welcome. :) -Toke