diff --git a/blog/my-notebook-firewall-36c3.mdwn b/blog/my-notebook-firewall-36c3.mdwn index 356eb630..37fadf31 100644 --- a/blog/my-notebook-firewall-36c3.mdwn +++ b/blog/my-notebook-firewall-36c3.mdwn @@ -19,27 +19,10 @@ This post should serve two purpose: I am using [nftables](https://ungleich.ch/en-us/cms/blog/2018/09/11/introduction-to-nftables/) -on my notebook and the ruleset is shown below: +on my notebook and the full ruleset is shown below. ``` -table ip filter { - chain input { - type filter hook input priority 0; - policy drop; - - ct state established,related accept - tcp dport { 22 } accept - } - chain forward { - type filter hook forward priority 0; - policy drop; - } - chain output { - type filter hook output priority 0; - policy accept; - } -} table ip6 filter { chain input { type filter hook input priority 0; @@ -50,22 +33,22 @@ table ip6 filter { ct state established,related accept tcp dport { 22, 80, 443 } accept - log } chain forward { type filter hook forward priority 0; - policy accept; + policy drop; ct state established,related accept - ip6 daddr 2a0a:e5c1:137:b00::/64 jump docker_container + ip6 daddr 2a0a:e5c1:137:b00::/64 jump container + ip6 daddr 2a0a:e5c1:137:cafe::/64 jump container } - chain docker_container { + chain container { icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept - tcp dport { 22, 443 } accept + tcp dport { 22, 80, 443 } accept drop } @@ -74,8 +57,107 @@ table ip6 filter { policy accept; } } + +table ip filter { + chain input { + type filter hook input priority 0; + policy drop; + + ct state established,related accept + tcp dport { 22 } accept + tcp dport { 51820 } accept + } + chain forward { + type filter hook forward priority 0; + policy drop; + } + chain output { + type filter hook output priority 0; + policy accept; + } +} + ``` +## The firewall explained: IPv6 + +Let's have a look at the IPv6 part first. In nftables we can freely +define chains, what is important is is the **hook** that we use in it. + +``` + chain input { + type filter hook input priority 0; + ... +``` + +The policy has the same meaning as in iptables and basically specifies +what to do with unmatched packets. + +IPv6 uses quite some ICMP6 messages to control and also to establish +communication in the first place, so the list for accepting is quite +long. + +``` + icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept +``` + +As we are dealing with traffic that comes to my notebook ("hook +input"), I want to allow any incoming packets that belong to one of +the connections that I initiated: + +``` + ct state established,related accept +``` + +And finally, I allow port 22, to be able to ssh into my notebook, +port 80 to get letsencrypt certificates and port 443 for serving +https. When I am online, my notebook is reachable at +[nico.plays.ipv6.games](https://nico.plays.ipv6.games), so I need the +web ports to be open. + +As I run quite some test on my notebook with docker and lxc, I created +a /64 IPv6 network for each of them. When matching on those specific +networks, I jump into a chain that allows specific configurations for +containers: + +``` + ip6 daddr 2a0a:e5c1:137:b00::/64 jump container + ip6 daddr 2a0a:e5c1:137:cafe::/64 jump container +``` + +The **chain container** consists at the moment of the same rule set as +the input chain, however this changes occasionally when testing +applications in containers. + +And for the output chain, I trust that the traffic my notebook emits +is what I wanted it to emit (but also allows malware to send out data, +if I had some installed). + +## The firewall explained: IPv4 + +In the IPv4 irea ("**table ip filter***) things are quite similar with +some small differences: + +* I don't provides services on IPv4 besides ssh and wireguard (port 22 + and 51820) +* There is nothing to be forwarded for IPv4, all containers use IPv6 +* Same logic for the output as in IPv6 + +## Safe or not safe? + +Whether this ruleset is safe or not depends a bit on your degree of +paranoia. I allow access to port 443 on which an nginx runs which then +again proxies to a self written flask application, which +might-or-might-not be safe. + +Some people argue to limit outgoing traffic and while this is +certainly possible (whitelist ports?), often this does is rendered +useless, as any command and control server can be reached on port 80 +and you probably don't want to block outgoing port 80 traffic. + +If you have any comments about it, I'm interested in hearing your +feedback on [the ungleich chat](http://chat.ungleich.ch), +[twitter](https://twitter.com/NicoSchottelius) or IRC (telmich). [[!tag ccc firewall nftables ipv6]]