Nginx in Docker, IPv6 with routed prefix.
I don't want to waste my IPv6 routed prefix.
Some background story first. I applied for an IPv6 tunnel broker and they assigned me a /64 routed prefix (read the post). How to use it? Of course, docker containers. So I grab the nginx image and run containers with IPv6 support, access with public v6 IP or a domain name.
The question remains: Why do we still use IPv4???
HOW-TO
In the docker documentation, it recommends creating new networks instead of using those default ones (bridge/host/none). So I follow the instruction and create a bridge network for my IPv6 routed prefix.
0. IP Forwarding
Note, IP forwading is required, and you can enable it by (with root!)
# echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
1. Create docker network.
2001:db8:1f19:242::/64 is the routed prefix I want to use with docker and I named the network nginxipv6.
$ docker network create -d bridge --ipv6 nginxipv6 \--subnet "2001:db8:1f19:242::/64" \--gateway "2001:db8:1f19:242::1"
Inspect the network we just created. IPv6 and IPv4 subnets and gateways are included, but we can safely ignore the IPv4 portion. BTW, how to get rid of the IPv4 one?
$ docker network inspect nginxipv6...
[{"Name": "nginxipv6","Id": "6c04630ac36e67a55cc5bfe90558f96394cc6d6b559726bf15155457f56ae38c","Created": "2020-12-25T21:06:16.572829837-08:00","Scope": "local","Driver": "bridge","EnableIPv6": true,"IPAM": {"Driver": "default","Options": {},"Config": [{"Subnet": "172.18.0.0/16","Gateway": "172.18.0.1"},{"Subnet": "2001:db8:1f19:242::/64","Gateway": "2001:db8:1f19:242::1"}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {},"Options": {},"Labels": {}}]
We may also find the network interface corresponding to the network newly created.
$ ip addr...23: br-6c04630ac36e: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group defaultlink/ether 02:42:2e:76:3f:20 brd ff:ff:ff:ff:ff:ffinet 172.18.0.1/16 brd 172.18.255.255 scope global br-6c04630ac36evalid_lft forever preferred_lft foreverinet6 2001:db8:1f19:242::1/64 scope globalvalid_lft forever preferred_lft foreverinet6 fe80::42:2eff:fe76:3f20/64 scope linkvalid_lft forever preferred_lft foreverinet6 fe80::1/64 scope linkvalid_lft forever preferred_lft forever
Verify the routing is correct too.
$ ip -6 route | grep br-6c2001:db8:1f19:242::/64 dev br-6c04630ac36e proto kernel metric 256 linkdown pref mediumfe80::/64 dev br-6c04630ac36e proto kernel metric 256 linkdown pref medium
So the network is ready. Let's start containers!
2. Run a docker container.
$ docker run --name nginx1 -d --rm --network nginxipv6 nginx4c3a31b9fd53efb7b01b3d637ad030bbae82b8f319129497587038902d4ebf76
Inspect the container and find the IP.
$ docker inspect nginx1
You may specify IP in the last step, with --ip6. The command will be:
$ docker run --name nginx2 -d --rm \--network nginxipv6 \--ip6 "2001:db8:1f19:242::1000" \nginx
We don't have to specify "-p 80:80" anymore.
3. Access the web.
We can reach it from home or another machine supporting IPv6.
$ curl -6v [2001:db8:1f19:242::1000]* Rebuilt URL to: [2001:db8:1f19:242::1000]/* Trying 2001:db8:1f19:242::1000...* Connected to 2001:db8:1f19:242::1000 (2001:db8:1f19:242::1000) port 80 (#0)> GET / HTTP/1.1> Host: [2001:db8:1f19:242::1000]> User-Agent: curl/7.47.0> Accept: */*>< HTTP/1.1 200 OK< Server: nginx/1.19.6< Date: Sat, 26 Dec 2020 06:21:18 GMT< Content-Type: text/html< Content-Length: 612< Last-Modified: Tue, 15 Dec 2020 13:59:38 GMT< Connection: keep-alive< ETag: "5fd8c14a-264"< Accept-Ranges: bytes<<!DOCTYPE html><html><head>...
Security concern
By setting IPs in IPv6, it allows us to directly access the nginx inside docker and completely 'ignore' the isolation provided by docker. If someone outside tries another port, then they will be able to access it if there is a service listening on that port.
I do this just for fun, not for production environment.
Conclusion
IPv6 is easy and you should start using it if possible. Plan your network for IPv6 as early as possible.
Comments
Post a Comment