* [Cerowrt-devel] BCP38 implementation
@ 2014-03-19 20:59 Toke Høiland-Jørgensen
2014-03-19 21:44 ` Dave Taht
0 siblings, 1 reply; 9+ messages in thread
From: Toke Høiland-Jørgensen @ 2014-03-19 20:59 UTC (permalink / raw)
To: cerowrt-devel
[-- Attachment #1: Type: text/plain, Size: 4176 bytes --]
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
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 489 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Cerowrt-devel] BCP38 implementation
2014-03-19 20:59 [Cerowrt-devel] BCP38 implementation Toke Høiland-Jørgensen
@ 2014-03-19 21:44 ` Dave Taht
2014-03-19 22:31 ` Toke Høiland-Jørgensen
[not found] ` <532AB801.6050702@openwrt.org>
0 siblings, 2 replies; 9+ messages in thread
From: Dave Taht @ 2014-03-19 21:44 UTC (permalink / raw)
To: Toke Høiland-Jørgensen, jow; +Cc: cerowrt-devel
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@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@lists.bufferbloat.net
> https://lists.bufferbloat.net/listinfo/cerowrt-devel
>
--
Dave Täht
Fixing bufferbloat with cerowrt: http://www.teklibre.com/cerowrt/subscribe.html
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Cerowrt-devel] BCP38 implementation
2014-03-19 21:44 ` Dave Taht
@ 2014-03-19 22:31 ` Toke Høiland-Jørgensen
2014-03-20 9:29 ` Toke Høiland-Jørgensen
[not found] ` <532AB801.6050702@openwrt.org>
1 sibling, 1 reply; 9+ messages in thread
From: Toke Høiland-Jørgensen @ 2014-03-19 22:31 UTC (permalink / raw)
To: Dave Taht, jow; +Cc: cerowrt-devel
On 19 March 2014 22:44:06 CET, Dave Taht <dave.taht@gmail.com> wrote:
> wow, thx. I was just about to give up and declare cero "baked enough".
Haha, well, felt like hacking on something new, and thought this might be appropriate :)
> 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.
Right. Well an easy fix could be to just omit the OUTPUT rule, so packets sent from the router itself are not blocked at all... But for double-nat, the actual traffic also needs to be allowed, I suppose.
Otherwise the documentation mentions hotplug scripts when an interface joins a firewall zone. That might be a suitable place to pick up addressing information? Storing it in the config shouldn't be a problem, but there probably needs to be some way for the user to override wrong auto-detection.
What source and dest ip does dhcp use?
-Toke
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Cerowrt-devel] BCP38 implementation
2014-03-19 22:31 ` Toke Høiland-Jørgensen
@ 2014-03-20 9:29 ` Toke Høiland-Jørgensen
2014-03-20 13:07 ` Toke Høiland-Jørgensen
0 siblings, 1 reply; 9+ messages in thread
From: Toke Høiland-Jørgensen @ 2014-03-20 9:29 UTC (permalink / raw)
To: Dave Taht; +Cc: jow, cerowrt-devel
[-- Attachment #1: Type: text/plain, Size: 835 bytes --]
Did an updated version that now has it's own configuration tab under
the firewall settings, so no need to patch the firewall .lua file. Also,
it is now possible to configure the subnets that are blocked and
whitelisted.
To try the new version, install these packages:
http://archive.tohojo.dk/cerowrt/wndr/3.10.32-9-tohojo/packages/bcp38_3-1_ar71xx.ipk
http://archive.tohojo.dk/cerowrt/wndr/3.10.32-9-tohojo/packages/luci-app-bcp38_1-1_all.ipk
and add the firewall rules as per the previous email.
Still a couple of issues:
- Manual firewall rules are still required. I think it would probably be
better to insert the iptables rules from the script directly so they
don't have to be specified in the firewall config file.
- Still need to have a hotplug script auto-detect blocked upstream
networks and exclude them.
-Toke
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 489 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Cerowrt-devel] BCP38 implementation
[not found] ` <532AB801.6050702@openwrt.org>
@ 2014-03-20 10:28 ` Toke Høiland-Jørgensen
0 siblings, 0 replies; 9+ messages in thread
From: Toke Høiland-Jørgensen @ 2014-03-20 10:28 UTC (permalink / raw)
To: jow; +Cc: cerowrt-devel
[-- Attachment #1: Type: text/plain, Size: 489 bytes --]
jow@openwrt.org writes:
> You can trim down the ipset uci declaration a bit, it is possible to
> specify the direction of the set directly in the "option ipset" param,
> therfore you can get rid of the 2nd -ingress declaration.
Ah, neat. Is there an easy way to programmatically insert these rules
when the bcp38 logic is activated? Or is the easiest way to create the
iptables rules manually from the external script (which is run by an
include statement in the firewall rules)?
-Toke
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 489 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Cerowrt-devel] BCP38 implementation
2014-03-20 9:29 ` Toke Høiland-Jørgensen
@ 2014-03-20 13:07 ` Toke Høiland-Jørgensen
2014-03-20 17:38 ` Dave Taht
0 siblings, 1 reply; 9+ messages in thread
From: Toke Høiland-Jørgensen @ 2014-03-20 13:07 UTC (permalink / raw)
To: cerowrt-devel
[-- Attachment #1: Type: text/plain, Size: 1479 bytes --]
So, another new version that should now be relatively feature-complete.
It should be possible to just install these two packages:
http://archive.tohojo.dk/cerowrt/wndr/3.10.32-9-tohojo/packages/bcp38_4-1_ar71xx.ipk
http://archive.tohojo.dk/cerowrt/wndr/3.10.32-9-tohojo/packages/luci-app-bcp38_2-1_all.ipk
and have everything enabled and working. This version does away with the
firewall rules in the config (so no need to add them; if they exist it
shouldn't hurt, I think, but might as well just remove them) in favour
of inserting a whole separate iptables chain to do the matching on.
There's now also an auto-detection feature for the upstream network,
which should automatically whitelist it when the rules are set up. It
does this by looking at the routing table for the upstream interface,
and testing all 'scope link' routes against the configured ipset, adding
exceptions if they match. There's a config toggle to turn off this
behaviour, and manual exceptions can be added instead of (or in addition
to) the auto-detection.
Since this detection is done at every run time, it should also include
hotplugging; the firewall is reloaded every time an interface is
hotplugged, which also reloads the bcp38 configuration and re-does the
auto-detection.
Testing is very much appreciated; until some of you tell me different, I
believe this version is suitable for inclusion in cerowrt. At least all
the issues on my own previous lists have been fixed AFAIK. :)
-Toke
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 489 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Cerowrt-devel] BCP38 implementation
2014-03-20 13:07 ` Toke Høiland-Jørgensen
@ 2014-03-20 17:38 ` Dave Taht
2014-03-20 18:14 ` Toke Høiland-Jørgensen
2014-03-22 20:04 ` Norman Yarvin
0 siblings, 2 replies; 9+ messages in thread
From: Dave Taht @ 2014-03-20 17:38 UTC (permalink / raw)
To: Toke Høiland-Jørgensen; +Cc: cerowrt-devel
I have tested this, made one small modification, and it will be in
cerowrt-3.10.32-12 and on by default. Nice work!
It doesn't appear to affect the speed of a transfer through the ge00
port at all, and it's really nice to see
d@nuc:~$ ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
From 172.26.4.1 icmp_seq=1 Destination Net Unreachable
One possible problem with pushing this up to openwrt is that arguably
it needs to apply this to the "wan" abstraction in the firewall rules
rather than a specific interface, and hook into that chain instead.
(on the other hand, using an
actual interface is also good)
The ipset facility has great potential for other uses, for example:
1) it allows for creation of a port bitmap to be checked for blocking
ports. Right now what happens is we create an iptables rule per
blocked port which is probably less efficient with lots of ports than
using a single ipset would be.
2) it allows for dynamic addition/subtraction of troublesome (e.g.
DDOSing or infected) hosts. Right now xinetd does half the job of
detecting probes like attempts to telnet to the router and blocks
access to other services controlled by xinetd for a couple hours.
ipset has basically the same functionality and could be made to do it
for the entire box.
An example idea is that I average 2 ssh dictionary attacks/sec on some
of my boxes, and I'd just as soon start dropping connection attempts
after X number of tries.... another is detecting dns relay attempts...
etc.
On Thu, Mar 20, 2014 at 6:07 AM, Toke Høiland-Jørgensen <toke@toke.dk> wrote:
> So, another new version that should now be relatively feature-complete.
> It should be possible to just install these two packages:
>
> http://archive.tohojo.dk/cerowrt/wndr/3.10.32-9-tohojo/packages/bcp38_4-1_ar71xx.ipk
>
> http://archive.tohojo.dk/cerowrt/wndr/3.10.32-9-tohojo/packages/luci-app-bcp38_2-1_all.ipk
>
> and have everything enabled and working. This version does away with the
> firewall rules in the config (so no need to add them; if they exist it
> shouldn't hurt, I think, but might as well just remove them) in favour
> of inserting a whole separate iptables chain to do the matching on.
>
> There's now also an auto-detection feature for the upstream network,
> which should automatically whitelist it when the rules are set up. It
> does this by looking at the routing table for the upstream interface,
> and testing all 'scope link' routes against the configured ipset, adding
> exceptions if they match. There's a config toggle to turn off this
> behaviour, and manual exceptions can be added instead of (or in addition
> to) the auto-detection.
>
> Since this detection is done at every run time, it should also include
> hotplugging; the firewall is reloaded every time an interface is
> hotplugged, which also reloads the bcp38 configuration and re-does the
> auto-detection.
>
>
> Testing is very much appreciated; until some of you tell me different, I
> believe this version is suitable for inclusion in cerowrt. At least all
> the issues on my own previous lists have been fixed AFAIK. :)
>
> -Toke
>
> _______________________________________________
> Cerowrt-devel mailing list
> Cerowrt-devel@lists.bufferbloat.net
> https://lists.bufferbloat.net/listinfo/cerowrt-devel
>
--
Dave Täht
Fixing bufferbloat with cerowrt: http://www.teklibre.com/cerowrt/subscribe.html
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Cerowrt-devel] BCP38 implementation
2014-03-20 17:38 ` Dave Taht
@ 2014-03-20 18:14 ` Toke Høiland-Jørgensen
2014-03-22 20:04 ` Norman Yarvin
1 sibling, 0 replies; 9+ messages in thread
From: Toke Høiland-Jørgensen @ 2014-03-20 18:14 UTC (permalink / raw)
To: Dave Taht; +Cc: cerowrt-devel
On 20 March 2014 18:38:17 CET, Dave Taht <dave.taht@gmail.com> wrote:
> I have tested this, made one small modification, and it will be in
> cerowrt-3.10.32-12 and on by default. Nice work!
Thanks! :)
> One possible problem with pushing this up to openwrt is that arguably
> it needs to apply this to the "wan" abstraction in the firewall rules
> rather than a specific interface, and hook into that chain instead.
> (on the other hand, using an actual interface is also good)
Well, having the configuration option be for a firewall zone rather than an interface shouldn't be that difficult. More of a policy question of how to handle upstream detection etc for potentially multiple interfaces. But then I suppose having the option of adding the filter to multiple interfaces might be useful too...
Either way, I can look into it at some later date if it becomes an issue. :)
> The ipset facility has great potential for other uses, for example:
Yeah, it seems to be pretty cool. How is it related to nftables?
-Toke
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Cerowrt-devel] BCP38 implementation
2014-03-20 17:38 ` Dave Taht
2014-03-20 18:14 ` Toke Høiland-Jørgensen
@ 2014-03-22 20:04 ` Norman Yarvin
1 sibling, 0 replies; 9+ messages in thread
From: Norman Yarvin @ 2014-03-22 20:04 UTC (permalink / raw)
To: Dave Taht; +Cc: cerowrt-devel
On Thu, Mar 20, 2014 at 10:38:17AM -0700, Dave Taht wrote:
>An example idea is that I average 2 ssh dictionary attacks/sec on some
>of my boxes, and I'd just as soon start dropping connection attempts
>after X number of tries....
That's not hard to do, via the "recent" iptables module. Here's my
set of custom rules for it. I set up a "throttle" chain to do the
work:
iptables -N throttle
iptables -A throttle -m recent --update --seconds 1200 --hitcount 4 -j DROP
iptables -A throttle -m recent --set
iptables -A throttle -j ACCEPT
Then after a bit of preliminary filtering I forward incoming ssh and
ftp attempts to the "throttle" chain:
iptables -I INPUT -i ge00 -m conntrack --ctstate NEW -p tcp --dport ssh \
-j throttle
iptables -I INPUT -i ge00 -m conntrack --ctstate NEW -p tcp --dport ftp \
-j throttle
--
Norman Yarvin http://yarchive.net/blog
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2014-03-22 20:04 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-19 20:59 [Cerowrt-devel] BCP38 implementation Toke Høiland-Jørgensen
2014-03-19 21:44 ` Dave Taht
2014-03-19 22:31 ` Toke Høiland-Jørgensen
2014-03-20 9:29 ` Toke Høiland-Jørgensen
2014-03-20 13:07 ` Toke Høiland-Jørgensen
2014-03-20 17:38 ` Dave Taht
2014-03-20 18:14 ` Toke Høiland-Jørgensen
2014-03-22 20:04 ` Norman Yarvin
[not found] ` <532AB801.6050702@openwrt.org>
2014-03-20 10:28 ` Toke Høiland-Jørgensen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox