+article: docker / ipv6 networks
This commit is contained in:
		
					parent
					
						
							
								d0fe687c36
							
						
					
				
			
			
				commit
				
					
						904d7276e2
					
				
			
		
					 1 changed files with 115 additions and 0 deletions
				
			
		| 
						 | 
					@ -0,0 +1,115 @@
 | 
				
			||||||
 | 
					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).
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue