[Cerowrt-devel] BCP38 implementation

Toke Høiland-Jørgensen toke at toke.dk
Wed Mar 19 16:59:18 EDT 2014

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
-- 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

	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'

Anyway, comments welcome. :)

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: <https://lists.bufferbloat.net/pipermail/cerowrt-devel/attachments/20140319/7a8b4905/attachment.sig>

More information about the Cerowrt-devel mailing list