170 lines
5.4 KiB
Markdown
170 lines
5.4 KiB
Markdown
[[!meta title="My notebook firewall for the 36c3"]]
|
|
|
|
It's time for the
|
|
[36c3](https://events.ccc.de/congress/2019/wiki/index.php/Main_Page)
|
|
and to verify that some things are in place where they should be.
|
|
|
|
As some of you might know, I am using
|
|
[IPv6 extensively](https://ipv6onlyhosting.com) to provide
|
|
services anywhere on anything, so you will see quite some IPv6 related
|
|
rules in my configuration.
|
|
|
|
This post should serve two purpose:
|
|
|
|
* Inspire others to verify their network settings prior to the
|
|
congress
|
|
* Get feedback from anyone spotting a huge mistake in my config :-)
|
|
|
|
## The firewall rules
|
|
|
|
I am using
|
|
[nftables](https://ungleich.ch/en-us/cms/blog/2018/09/11/introduction-to-nftables/)
|
|
on my notebook and the full ruleset is shown below.
|
|
|
|
|
|
```
|
|
table ip6 filter {
|
|
chain input {
|
|
type filter hook input priority 0;
|
|
policy drop;
|
|
|
|
iif lo accept
|
|
ct state established,related accept
|
|
|
|
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, 80, 443 } accept
|
|
|
|
}
|
|
|
|
chain forward {
|
|
type filter hook forward priority 0;
|
|
policy drop;
|
|
|
|
ct state established,related accept
|
|
|
|
ip6 daddr 2a0a:e5c1:137:b00::/64 jump container
|
|
ip6 daddr 2a0a:e5c1:137:cafe::/64 jump 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, 80, 443 } accept
|
|
drop
|
|
|
|
}
|
|
chain output {
|
|
type filter hook output priority 0;
|
|
policy accept;
|
|
}
|
|
}
|
|
|
|
table ip filter {
|
|
chain input {
|
|
type filter hook input priority 0;
|
|
policy drop;
|
|
|
|
iif lo accept
|
|
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.with.ungleich.ch),
|
|
[twitter](https://twitter.com/NicoSchottelius) or IRC (telmich).
|
|
|
|
## Update 2019-12-24
|
|
|
|
I forgot to allow loopback traffic in the original version, which
|
|
breaks some local networking.
|
|
|
|
[[!tag ccc firewall nftables ipv6]]
|