116 lines
3.8 KiB
Text
116 lines
3.8 KiB
Text
|
title: Securing network access to IPv6 docker containers
|
||
|
---
|
||
|
pub_date: 2019-12-14
|
||
|
---
|
||
|
author: ungleich virtualisation team
|
||
|
---
|
||
|
twitter_handle: ungleich
|
||
|
---
|
||
|
_hidden: no
|
||
|
---
|
||
|
_discoverable: yes
|
||
|
---
|
||
|
abstract:
|
||
|
Configure your firewall correctly for IPv6 docker containers
|
||
|
---
|
||
|
body:
|
||
|
|
||
|
Like in any situation, we should secure our systems. In the legacy
|
||
|
IPv4 world, things are often not clear due to the use of NAT (network
|
||
|
address translation). Things are
|
||
|
much more transparent and also easier with IPv6.
|
||
|
|
||
|
In this article we give easy to follow instructions on how to secure
|
||
|
your IPv6 based docker containers.
|
||
|
|
||
|
## Docker containers with IPv6
|
||
|
|
||
|
IPv6 was made to restore direct connectivity, like the Internet was
|
||
|
designed to be in the first place. So instead of needing to "expose
|
||
|
ports" or to add "port forwarding", IPv6 addresses are generally
|
||
|
directly reachable.
|
||
|
|
||
|
This is nice and general, but if we run containers that are not fully
|
||
|
secured, this is a security risk.
|
||
|
|
||
|
For this reason we should limit access to our docker containers.
|
||
|
|
||
|
## Network firewall with nftables
|
||
|
|
||
|
You might have seen noticed that in the Linux world we are moving from
|
||
|
iptables to nftables. In case you need a refresher on the differences,
|
||
|
checkout the article about [iptables
|
||
|
vs. nftables](https://ungleich.ch/en-us/cms/blog/2018/08/18/iptables-vs-nftables/).
|
||
|
|
||
|
## What to allow, what to filter?
|
||
|
|
||
|
So what should be the general general rules for accessing our docker
|
||
|
containers? We have made a short list on what we think is a good way
|
||
|
to expose your docker containers:
|
||
|
|
||
|
First, allow ping6 and various helper packets from icmp6. This way our
|
||
|
containers can react on debugging messages from the network and are
|
||
|
working in settings with different MTUs. The rule for this in nftables
|
||
|
looks as follows:
|
||
|
|
||
|
```
|
||
|
icmpv6 type { destination-unreachable, packet-too-big,
|
||
|
time-exceeded, parameter-problem, echo-request,
|
||
|
nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
|
||
|
|
||
|
```
|
||
|
|
||
|
Secondly, allow the tcp ports 22 (ssh), 80 (http) and 443
|
||
|
(https). While http is unencrypted, we need to open it so that
|
||
|
letsencrypt certificate verifications can work. And we want to be
|
||
|
able to get letsencrypt certificates to secure communication with
|
||
|
https. In nftables, this reads as follows:
|
||
|
|
||
|
```
|
||
|
tcp dport { 22, 80, 443 } accept
|
||
|
```
|
||
|
|
||
|
And the rest? We will drop the rest. This is as simple as saying
|
||
|
`drop` in nftables.
|
||
|
|
||
|
## Putting it all together
|
||
|
|
||
|
So how does this look like in a complete picture? You can use the
|
||
|
below configuration directly on your machine, just replace
|
||
|
**2001:db8::/64** with your IPv6 docker network.
|
||
|
|
||
|
```
|
||
|
table ip6 filter {
|
||
|
chain forward {
|
||
|
type filter hook forward priority filter; policy accept;
|
||
|
ct state established,related accept
|
||
|
ip6 daddr 2001:db8::/64 jump to_docker_container
|
||
|
}
|
||
|
|
||
|
chain to_docker_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
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
You can save this snippet as nftables.conf and run `nft -f
|
||
|
nftables.conf` to apply it. Use `nftables list ruleset` to see your
|
||
|
active rules.
|
||
|
|
||
|
## Proxying insecure applications
|
||
|
|
||
|
With the above firewall you can run your insecure applications on any
|
||
|
port that is not 22, 80 or 443. And then you can use a side car or
|
||
|
proxy to expose it securely. If you use above firewall, we recommend
|
||
|
to run your insecure (http) containers on port 8080. This indicates it
|
||
|
is http (alike) and is also automatically blocked from the outside
|
||
|
world.
|
||
|
|
||
|
## Learning more about this
|
||
|
|
||
|
You can give above a direct try with a VM from
|
||
|
[IPv6onlyhosting](https://IPv6onlyhosting.com) or talk to others about
|
||
|
it on the [IPv6.Chat](https://IPv6.chat).
|