[Cerowrt-devel] BCP38 implementation

Dave Taht dave.taht at gmail.com
Wed Mar 19 17:44:06 EDT 2014


wow, thx. I was just about to give up and declare cero "baked enough".

the core problem remaining is ensuring dhcp request and renew work even
with double-nat and that state is retained across a network and firewall reload.

jow is mr firewall at openwrt, cc'd for comments.

On Wed, Mar 19, 2014 at 1:59 PM, Toke Høiland-Jørgensen <toke at toke.dk> wrote:
>
> 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.

For example, configuring cablemodems commonly relies on 192.168.100.1
being the accessible external-through-nat ip.

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

If it fails without hurting connectivity I can live with that.

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

My hope was to identify the upstream host and subnet and allow
that by hooking into the dhcp request.

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

Theoretically the option to add to the reject statement in the fw3 rules
stanze would be:

        option extra ' --reject-with addr-unreach'

the full list of --reject-with options can be seen with:

iptables -j REJECT --help

it is not obvious what icmp message to send on a reject

--reject-with icmp-net-prohibited # or host-prohibited

seems logical. I am all in favor of being chatty inside the fw, and not
outside.


>
>
> Anyway, comments welcome. :)
>
> -Toke
>
> _______________________________________________
> Cerowrt-devel mailing list
> Cerowrt-devel at lists.bufferbloat.net
> https://lists.bufferbloat.net/listinfo/cerowrt-devel
>



-- 
Dave Täht

Fixing bufferbloat with cerowrt: http://www.teklibre.com/cerowrt/subscribe.html



More information about the Cerowrt-devel mailing list