├── 99-ipv6.conf ├── LICENSE ├── README.md ├── dhclient6-pd.conf ├── dhclient6-pd.service └── docker-ipv6 /99-ipv6.conf: -------------------------------------------------------------------------------- 1 | net.ipv6.conf.all.forwarding=1 2 | net.ipv6.conf.ens3.accept_ra=2 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Wido den Hollander 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker IPv6 2 | This respository contains various scripts and tools to enable [Docker](https://www.docker.com/) to 3 | use a IPv6 prefix obtained through DHCPv6 Prefix Delegation. 4 | 5 | This allows containers to use native IPv6 without any need for proxies. 6 | 7 | The scripts and tooling in this repository were tested on Ubuntu 14.04 (upstart) 8 | and 16.04 (systemd). 9 | 10 | # Prefix Delegation 11 | [Prefix Delegation](https://tools.ietf.org/html/rfc37690) (PD) is a mechanism which allows a client to request a 12 | IPv6 prefix to be routed towards that host. 13 | 14 | Usually a client will obtain a prefix larger than a /64 to allow splitting 15 | up this prefix in multiple smaller prefixes. 16 | 17 | # Docker and IPv6 18 | Docker can use IPv6 for it's containers if you start the docker daemon with 19 | the --ipv6 flag. 20 | 21 | For example: 22 | 23 | ```docker daemon --ipv6 --fixed-cidr-v6=2001:db8:100::/80``` 24 | 25 | IPv6 addresses of Docker containers are based on the MAC address. A /80 subnet 26 | combined with the 48-bits of a MAC address sums op to 128-bits for a full IPv6 27 | address. 28 | 29 | More information about Docker and IPv6 can be found in Docker's [documentation](https://docs.docker.com/engine/userguide/networking/default_network/ipv6/). 30 | 31 | ## sysctl 32 | A few sysctl settings have to be applied for IPv6 to work properly. 33 | 34 | 35 | To do so create */etc/sysctl.d/99-ipv6.conf* and add: 36 | 37 |
net.ipv6.conf.all.forwarding=1
 38 | net.ipv6.conf.eth0.accept_ra=2
39 | 40 | **NOTE:** Replace eth0 by your primary interface. This might be *ens3* on newer kernels. 41 | 42 | You can now apply these settings: 43 | 44 |
sysctl -p /etc/sysctl.d/99-ipv6.conf
45 | 46 | A reboot of the system is suggested to make sure the settings are applied. 47 | 48 | # dhclient 49 | dhclient is part of ISC DHCP and can request a IPv6 Prefix through DHCPv6. 50 | 51 | In order to do so, dhclient should be run with these flags: 52 | 53 | ```dhclient -6 -P eth0``` 54 | 55 | It will request a prefix through DHCPv6. 56 | 57 | You can find the DHCPv6 information in */var/lib/dhcp/dhclient6.leases* 58 | 59 | ## Ubuntu 14.04: Upstart 60 | Under Ubuntu 14.04 you can run dhclient using upstart to 61 | request the prefix and renew then needed. 62 | 63 | See the upstart file in the repository to do so. 64 | 65 | You should place this file in */etc/init/dhclient6-pd.conf* 66 | 67 | Afterwards you can start and stop with: 68 | 69 | ``sudo start dhclient6-pd`` 70 | 71 | ``sudo stop dhclient6-pd`` 72 | 73 | ## Ubuntu 16.04: systemd 74 | Ubuntu 16.04 using systemd and to run dhclient for Prefix Delegation to have to install *dhclient6-pd.service* in */etc/systemd/system/* 75 | 76 | Now reload systemd and start dhclient: 77 | 78 |
systemctl daemon-reload
79 | 80 |
systemctl start dhclient6-pd
81 | 82 |
systemctl status dhclient6-pd
83 | 84 | ### Interface 85 | By default it uses eth0 as the configured interface. Change this in the service file if this differs on your system. 86 | 87 | With newer kernels this might be *ens3* for example. 88 | 89 | ### ifupdown / interfaces file 90 | The ifupdown package on Ubuntu is responsible for configuring network interfaces under Debian and Ubuntu. 91 | 92 | I wrote a [patch](https://anonscm.debian.org/cgit/collab-maint/ifupdown.git/commit/?id=9af9a607274bec491ca165f9b8af6af26bbdf585) for ifupdown so that 93 | you can configure the network stack to perform the Prefix Delegation request for you. 94 | 95 | When Ubuntu and Debian apply this patch you can use it in your interfaces file: 96 | 97 |
iface eth0 inet6 auto
 98 |   dhcp 1
 99 |   request_prefix 1
100 | 101 | Hopefully this makes it into Ubuntu 16.04. 102 | 103 | ## Docker IPv6 hook 104 | The *docker-ipv6* dhclient hook in this repository should be placed in 105 | **/etc/dhcp/dhclient-enter-hooks.d/** where it will be executed after dhclient 106 | obtains a prefix. 107 | 108 | The hook will get the first **/80** subnet out of the delegated prefix and 109 | write it to */etc/docker/ipv6.prefix* 110 | 111 | The Docker daemon is then restarted so it will use the new subnet as the fixed 112 | IPv6 cidr. 113 | 114 | Depending on your Ubuntu version (14.04 or 16.04) configuration has to be done differently due to the Upstart vs systemd changes. The end result is the same. 115 | 116 | Afterwards you can print the processlist and see docker running with these arguments: 117 | 118 | ``/usr/bin/docker daemon --ipv6 --fixed-cidr-v6=2001:00db8:100:0000:0000:0000:0000:0000/80`` 119 | 120 | ### Ubuntu 14.04 121 | In order for this to work the *DOCKER_OPTS* in /etc/default/docker should be set to: 122 | 123 | ```DOCKER_OPTS="--ipv6 --fixed-cidr-v6=`cat /etc/docker/ipv6.prefix`"``` 124 | 125 | ### Ubuntu 16.04 126 | First we copy the systemd service file for docker to /etc: 127 | 128 |
cp /lib/systemd/system/docker.service /etc/systemd/system
129 | 130 | Now modify the *ExecStatrt* line so that it contains: 131 | 132 |
ExecStart=/bin/bash -c "/usr/bin/docker daemon --ipv6 --fixed-cidr-v6=`cat /etc/docker/ipv6.prefix` -H fd://"
133 | 134 | Now reload systemd and stop/start Docker: 135 | 136 |
systemctl daemon-reload
137 | 138 |
systemctl stop docker
139 | 140 |
systemctl start docker
141 | 142 | -------------------------------------------------------------------------------- /dhclient6-pd.conf: -------------------------------------------------------------------------------- 1 | description "DHCPv6 Prefix Delegation client" 2 | 3 | start on runlevel [2345] 4 | stop on runlevel [!2345] 5 | 6 | respawn 7 | respawn limit 30 3 8 | umask 022 9 | 10 | console log 11 | 12 | exec dhclient -6 -P -d eth0 13 | -------------------------------------------------------------------------------- /dhclient6-pd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=DHCPv6 Prefix Delegation client 3 | Wants=network.target network-online.target 4 | After=network.target network-online.target 5 | 6 | [Service] 7 | Type=simple 8 | Environment=NETWORK_INTERFACE=eth0 9 | ExecStart=/sbin/dhclient -6 -P -d ${NETWORK_INTERFACE} 10 | Restart=always 11 | RestartSec=10s 12 | 13 | [Install] 14 | WantedBy=multi-user.target 15 | -------------------------------------------------------------------------------- /docker-ipv6: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # DHCPv6 hook for Docker 4 | # 5 | # This hook will configure Docker to use the first /80 IPv6 subnet 6 | # from the Prefix we got through DHCPv6 Prefix Delegation 7 | # 8 | # A /80 subnet is large enough for Docker. 80 + 48 bits (MAC) equals 128-bits. 9 | # 10 | # dhclient will run this hook after it obtains the lease 11 | # 12 | # Make sure you can dhclient in a way that it requests a prefix, eg: 13 | # 14 | # dhclient -6 -P -d eth0 15 | # 16 | # With the new prefix we can reconfigure Docker and restart it 17 | # 18 | # Make sure /etc/default/docker contains: 19 | # 20 | # DOCKER_OPTS="--ipv6 --fixed-cidr-v6=`cat /etc/docker/ipv6.prefix`" 21 | # 22 | # This script requires sipcalc to function 23 | command -v sipcalc >/dev/null 2>&1 || exit 0 24 | 25 | SUBNET_SIZE=80 26 | DOCKER_ETC_DIR="/etc/docker" 27 | DOCKER_PREFIX_FILE="${DOCKER_ETC_DIR}/ipv6.prefix" 28 | 29 | if [ ! -z "$new_ip6_prefix" ]; then 30 | SUBNET=$(sipcalc -S $SUBNET_SIZE $new_ip6_prefix|grep Network|head -n 1|awk '{print $3}') 31 | echo "${SUBNET}/${SUBNET_SIZE}" > $DOCKER_PREFIX_FILE 32 | 33 | if [ "$old_ip6_prefix" != "$new_ip6_prefix" ]; then 34 | service docker restart 35 | fi 36 | fi 37 | --------------------------------------------------------------------------------