Quellcode durchsuchen

feat(network): BREAKING CHANGE internal network refactoring

- make IPv4 internal net prefix configurable
- restructure internal networks into several smaller ones, to restrict
  container visibility

NOTE: This commit changes some of the internal container IPs, even if you
set the new IPv4 prefix variable to its previous implicit  value (172.16).
You need to update the MariaDB grant tables as well  as the IP address in
the dbmaster supermaster table.
Also, if you change the IPv4 internal net prefix variable in the future,
the tables will need to be updated manually as well. See README.
Peter Thomassen vor 8 Jahren
Ursprung
Commit
adf0c1aa17

+ 2 - 1
.env.default

@@ -1,5 +1,6 @@
 # network
-DESECSTACK_IPV6_SUBNET=bade:affe:dead:beef:deec:/80
+DESECSTACK_IPV4_REAR_PREFIX16=172.16
+DESECSTACK_IPV6_SUBNET=bade:affe:dead:beef:deec::/80
 DESECSTACK_IPV6_ADDRESS=bade:affe:dead:beef:deec:0642:ac10:0080
 
 # certificates

+ 9 - 0
.travis.yml

@@ -1,6 +1,8 @@
 sudo: required
 
 env:
+  matrix:
+   - DOCKER_COMPOSE_VERSION: 1.9.0
   global:
    - DESECSTACK_API_ADMIN=john.doe@example.com
    - DESECSTACK_API_ALLOWED_HOSTS=desec.your.hostname.example.com update.dedyn.your.hostname.example.com
@@ -20,6 +22,7 @@ env:
    - DESECSTACK_DB_SUBJECT_ns2replication=9Fn33T5yGukjnrtj
    - DESECSTACK_DEVADMIN_PASSWORDmd5=.
    - DESECSTACK_NSLORD_APIKEY=9Fn33T5yGukjekwjew
+   - DESECSTACK_IPV4_REAR_PREFIX16=172.19
    - DESECSTACK_IPV6_SUBNET=fd80::/8
    - DESECSTACK_IPV6_ADDRESS=fd80::1
    - DESECSTACK_WWW_CERTS=/dev/null
@@ -33,6 +36,12 @@ services:
   - docker
 
 before_install:
+  # Get our own docker-compose
+  - sudo rm /usr/local/bin/docker-compose
+  - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
+  - chmod +x docker-compose
+  - sudo mv docker-compose /usr/local/bin
+  # Get web content
   - rm -f www
   - rm -f static
   - git clone https://github.com/desec-io/desec-www.git www

+ 15 - 10
README.md

@@ -24,6 +24,8 @@ Although most configuration is contained in this repository, some external depen
 
 3.  Set sensitive information and network topology using environment variables or an `.env` file. You need (you can use the `.env.default` file as a template):
     - network
+      - `DESECSTACK_IPV4_REAR_PREFIX16`: IPv4 net, size /16, for assignment of internal container IPv4 addresses. **NOTE:** If you change this in an existing setup, you 
+        need to manually update MySQL grant tables and the `nsmaster` supermaster table to update IP addresses! Better don't do it.
       - `DESECSTACK_IPV6_SUBNET`: IPv6 net, ideally /80 (see below)
       - `DESECSTACK_IPV6_ADDRESS`: IPv6 address of frontend container, ideally 0642:ac10:0080 in within the above subnet (see below)
     - certificates
@@ -89,18 +91,21 @@ This stack is IPv6-capable. Caveats:
 
   - Due to various issues with Docker and docker-compose, IP addresses are current hardcoded (see [`docker-compose.yml`](docker-compose.yml) and the `TODO` flags therein).
 
-  - Docker currently exposes IPv6-capable containers fully, without restriction. Therefore, it is necessary to set up a firewall, like (`ip6tables`)
-
-        -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-        -A FORWARD -d 2a01:4f8:a0:12eb:deec:642:ac10:0/108 -i eth0 -j ACCEPT
-        -A FORWARD -d 2a01:4f8:a0:12eb:deec::/80 -i eth0 -j REJECT --reject-with icmp6-port-unreachable
-
-    Topology: 2a01:4f8:a0:12eb::/64 is the host network, and we reserve 2a01:4f8:a0:12eb:deec::/80 for the deSEC stack. Docker has more or less established that IPv6 
-    addresses be composed of the /80 prefix and the container MAC address. We choose the private 06:42:ac MAC prefix, defining a /104 subnet. For the remaining 24 bits of 
-    the MAC and IPv6 address, we again follow the convention and use the 24 last bits from the assigned IPv4 address, the first 4 of which are constant (since IPv4 
-    addresses reside in 172.16.0.0/12). We thus arrive at the subnet 2a01:4f8:a0:12eb:deec:642:ac10:0/108 for our public IPv6-enabled Docker containers.
+  - Topology: Assuming 2a01:4f8:a0:12eb::/64 is the host network, and we reserve 2a01:4f8:a0:12eb:deec::/80 for the deSEC stack. Docker has more or less established that 
+    IPv6  addresses be composed of the /80 prefix and the container MAC address. We choose the private 06:42:ac MAC prefix, defining a /104 subnet. For the remaining 24 
+    bits of the MAC and IPv6 address, the convention seems to be to use the last 24 bits from the internally assigned IPv4 address. However, the first 8 of these are 
+    configurable through the `DESECSTACK_IPV4_REAR_PREFIX16` variable. Since we don't want public IPv6 addresses to change if the internal IPv4 net prefix changes, we use 
+    `0x10` for bits at position 24--17. We thus arrive at the subnet 2a01:4f8:a0:12eb:deec:642:ac10:0/108 for our public IPv6-enabled Docker containers. The last 16 bits 
+    of the IPv6 address we indeed take from the internally assigned IP address. The same procedure is used to set the MAC address of IPv6 containers (they begin with 
+    `06:42:ac:10:`).
 
     All other traffic in the /80 subnet is unexpected and therefore rejected. This includes traffic for IPv6 addresses that Docker assigns. (If Docker uses the MAC address 
     for this purpose, the prefix is 02:42:ac which is not part of our public network, so we're safe.)
 
     Since the above topology is strictly determined by the /80 prefix and the MAC address, we hope that most of the hardcoding can be removed in the future.
+
+  - Docker currently exposes IPv6-capable containers fully, without restriction. Therefore, it is necessary to set up a firewall, like (`ip6tables`)
+
+        -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
+        -A FORWARD -d 2a01:4f8:a0:12eb:deec:642:ac10:0/108 -i eth0 -j ACCEPT
+        -A FORWARD -d 2a01:4f8:a0:12eb:deec::/80 -i eth0 -j REJECT --reject-with icmp6-port-unreachable

+ 3 - 3
dbapi/initdb.d/00-init.sql.var

@@ -1,7 +1,7 @@
 -- deSEC user and domain database
 CREATE DATABASE desec;
-CREATE USER 'desec'@'172.16.1.%' IDENTIFIED BY '${DESECSTACK_DBAPI_PASSWORD_desec}';
-GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES, INDEX, CREATE, ALTER, DROP ON desec.* TO 'desec'@'172.16.1.%';
+CREATE USER 'desec'@'${DESECSTACK_IPV4_REAR_PREFIX16}.5.%' IDENTIFIED BY '${DESECSTACK_DBAPI_PASSWORD_desec}';
+GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES, INDEX, CREATE, ALTER, DROP ON desec.* TO 'desec'@'${DESECSTACK_IPV4_REAR_PREFIX16}.5.%';
 
 -- privileges for deSEC test database
-GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES, INDEX, CREATE, ALTER, DROP ON test_desec.* TO 'desec'@'172.16.1.%';
+GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES, INDEX, CREATE, ALTER, DROP ON test_desec.* TO 'desec'@'${DESECSTACK_IPV4_REAR_PREFIX16}.5.%';

+ 4 - 4
dblord/initdb.d/00-init.sql.var

@@ -1,8 +1,8 @@
 -- nslord database
 CREATE DATABASE pdns;
-CREATE USER 'pdns'@'172.16.1.%' IDENTIFIED BY '${DESECSTACK_DBLORD_PASSWORD_pdns}';
-GRANT SELECT, INSERT, UPDATE, DELETE ON pdns.* TO 'pdns'@'172.16.1.%';
+CREATE USER 'pdns'@'${DESECSTACK_IPV4_REAR_PREFIX16}.3.%' IDENTIFIED BY '${DESECSTACK_DBLORD_PASSWORD_pdns}';
+GRANT SELECT, INSERT, UPDATE, DELETE ON pdns.* TO 'pdns'@'${DESECSTACK_IPV4_REAR_PREFIX16}.3.%';
 
 -- poweradmin database (for devadmin)
-CREATE USER 'poweradmin'@'172.16.1.%' IDENTIFIED BY '${DESECSTACK_DBLORD_PASSWORD_poweradmin}';
-GRANT SELECT, INSERT, UPDATE, DELETE ON pdns.* TO 'poweradmin'@'172.16.1.%';
+CREATE USER 'poweradmin'@'${DESECSTACK_IPV4_REAR_PREFIX16}.3.%' IDENTIFIED BY '${DESECSTACK_DBLORD_PASSWORD_poweradmin}';
+GRANT SELECT, INSERT, UPDATE, DELETE ON pdns.* TO 'poweradmin'@'${DESECSTACK_IPV4_REAR_PREFIX16}.3.%';

+ 2 - 2
dbmaster/initdb.d/00-init.sql.var

@@ -1,7 +1,7 @@
 -- nsmaster database
 CREATE DATABASE pdns;
-CREATE USER 'pdns'@'172.16.1.%' IDENTIFIED BY '${DESECSTACK_DBMASTER_PASSWORD_pdns}';
-GRANT SELECT, INSERT, UPDATE, DELETE ON pdns.* TO 'pdns'@'172.16.1.%';
+CREATE USER 'pdns'@'${DESECSTACK_IPV4_REAR_PREFIX16}.4.%' IDENTIFIED BY '${DESECSTACK_DBMASTER_PASSWORD_pdns}';
+GRANT SELECT, INSERT, UPDATE, DELETE ON pdns.* TO 'pdns'@'${DESECSTACK_IPV4_REAR_PREFIX16}.4.%';
 
 -- replication
 CREATE USER ns1@'%' IDENTIFIED BY "${DESECSTACK_DBMASTER_PASSWORD_ns1replication}";

+ 2 - 3
dbmaster/initdb.d/11-pdns-master-supermasters.sql

@@ -1,3 +1,2 @@
-USE pdns;
-
-INSERT INTO supermasters SET ip="172.16.1.11", nameserver="ns1.desec.io";
+-- This file is required to exist and will be overriden by 00-init.sh.
+-- If it is created only by 00-init.sh, the entrypoint script will miss it.

+ 3 - 0
dbmaster/initdb.d/11-pdns-master-supermasters.sql.var

@@ -0,0 +1,3 @@
+USE pdns;
+
+INSERT INTO supermasters SET ip="${DESECSTACK_IPV4_REAR_PREFIX16}.1.11", nameserver="ns1.desec.io";

+ 0 - 10
dev

@@ -1,14 +1,4 @@
 #!/usr/bin/env bash
-# The following options should be set by default: -o "com.docker.network.bridge.enable_icc"="true" -o "com.docker.network.bridge.host_binding_ipv4"="0.0.0.0" -o "com.docker.network.driver.mtu"="1500" 
-
-(
-source .env
-docker network inspect desecstack_front &>/dev/null \
-	|| docker network create --subnet=172.16.0.0/24 --gateway=172.16.0.1 \
-		--ipv6 --subnet=${DESECSTACK_IPV6_SUBNET} \
-		-o "com.docker.network.bridge.enable_ip_masquerade"="true" \
-		desecstack_front
-)
 
 docker-compose -f docker-compose.yml -f docker-compose.dev.yml build \
 	&& docker-compose -f docker-compose.yml -f docker-compose.dev.yml up

+ 3 - 2
docker-compose.dev.yml

@@ -1,4 +1,4 @@
-version: '2'
+version: '2.1'
 
 # mostly extending from main .yml
 services:
@@ -52,4 +52,5 @@ services:
     ports:
      - "127.0.0.1:81:80"
     networks:
-    - back1
+    - rearwww
+    - rearlord

+ 1 - 1
docker-compose.test.yml

@@ -1,4 +1,4 @@
-version: '2'
+version: '2.1'
 
 # mostly extending from main .yml
 services:

+ 60 - 22
docker-compose.yml

@@ -1,4 +1,4 @@
-version: '2'
+version: '2.1'
 
 services:
   www:
@@ -16,9 +16,9 @@ services:
     mac_address: 06:42:ac:10:00:80
     networks:
       front:
-        ipv4_address: 172.16.0.128
+        ipv4_address: ${DESECSTACK_IPV4_REAR_PREFIX16}.0.128
         ipv6_address: ${DESECSTACK_IPV6_ADDRESS}
-#      - back2 # TODO add when https://github.com/docker/docker/issues/27101 is fixed
+      rearwww:
     logging:
       driver: "syslog"
       options:
@@ -29,7 +29,7 @@ services:
     build: static
     image: desec/dedyn-static:latest
     networks:
-    - front # TODO change to back2 when https://github.com/docker/docker/issues/27101 is fixed
+    - rearwww
     logging:
       driver: "syslog"
       options:
@@ -42,9 +42,10 @@ services:
     volumes:
     - dbapi_mysql:/var/lib/mysql
     environment:
+    - DESECSTACK_IPV4_REAR_PREFIX16
     - DESECSTACK_DBAPI_PASSWORD_desec
     networks:
-    - back1
+    - rearapi2
     logging:
       driver: "syslog"
       options:
@@ -57,11 +58,12 @@ services:
     volumes:
     - dblord_mysql:/var/lib/mysql
     environment:
+    - DESECSTACK_IPV4_REAR_PREFIX16
     - DESECSTACK_DBLORD_PASSWORD_pdns
     - DESECSTACK_DBLORD_PASSWORD_poweradmin
     - DESECSTACK_DEVADMIN_PASSWORD_poweradmin
     networks:
-    - back1
+    - rearlord
     logging:
       driver: "syslog"
       options:
@@ -77,13 +79,14 @@ services:
     - ${DESECSTACK_DBMASTER_CERTS}:/etc/ssl/private:ro
     - dbmaster_mysql:/var/lib/mysql
     environment:
+    - DESECSTACK_IPV4_REAR_PREFIX16
     - DESECSTACK_DBMASTER_PASSWORD_pdns
     - DESECSTACK_DBMASTER_PASSWORD_ns1replication
     - DESECSTACK_DBMASTER_SUBJECT_ns1replication
     - DESECSTACK_DBMASTER_PASSWORD_ns2replication
     - DESECSTACK_DBMASTER_SUBJECT_ns2replication
     networks:
-    - back1
+    - rearmaster
     logging:
       driver: "syslog"
       options:
@@ -110,8 +113,9 @@ services:
     - DESECSTACK_NORECAPTCHA_SITE_KEY
     - DESECSTACK_NORECAPTCHA_SECRET_KEY
     networks:
-    - back1
-    - front # TODO change to back2 when https://github.com/docker/docker/issues/27101 is fixed
+    - rearapi1
+    - rearapi2
+    - rearwww
     logging:
       driver: "syslog"
       options:
@@ -122,6 +126,7 @@ services:
     build: nslord
     image: desec/dedyn-nslord:latest
     environment:
+    - DESECSTACK_IPV4_REAR_PREFIX16
     - DESECSTACK_DBLORD_PASSWORD_pdns
     - DESECSTACK_NSLORD_APIKEY
     - DESECSTACK_NSLORD_CARBONSERVER
@@ -129,8 +134,9 @@ services:
     depends_on:
     - dblord
     networks:
-      back1:
-        ipv4_address: 172.16.1.11
+      rearapi1:
+        ipv4_address: ${DESECSTACK_IPV4_REAR_PREFIX16}.1.11
+      rearlord:
     logging:
       driver: "syslog"
       options:
@@ -147,8 +153,9 @@ services:
     depends_on:
     - dbmaster
     networks:
-      back1:
-        ipv4_address: 172.16.1.12
+      rearapi1:
+        ipv4_address: ${DESECSTACK_IPV4_REAR_PREFIX16}.1.12
+      rearmaster:
     logging:
       driver: "syslog"
       options:
@@ -161,20 +168,51 @@ volumes:
   dbmaster_mysql:
 
 networks:
-  back1: # TODO can we declare this internal? compose 1.9.0 will allow it: https://github.com/docker/compose/pull/3488 May break apt inside nslord etc.
+  # Note that it is required that the front network ranks lower (in lexical order)
+  # than the other networks. See https://github.com/docker/docker/issues/27101
+  front:
+    enable_ipv6: true
     driver: bridge
     ipam:
       driver: default
       config:
-      - subnet: 172.16.1.0/24
-        gateway: 172.16.1.1
-  back2:
+      - subnet: ${DESECSTACK_IPV4_REAR_PREFIX16}.0.0/24
+        gateway: ${DESECSTACK_IPV4_REAR_PREFIX16}.0.1
+      - subnet: ${DESECSTACK_IPV6_SUBNET}
+  # Make sure these come after the front network (lexical order). This is why we 
+  # call it rear, not back. See https://github.com/docker/docker/issues/27101
+  rearapi1:
     driver: bridge
     ipam:
       driver: default
       config:
-      - subnet: 172.16.2.0/24
-        gateway: 172.16.2.1
-  front:
-    external: # TODO define network here when https://github.com/docker/compose/issues/3988 is fixed
-      name: desecstack_front
+      - subnet: ${DESECSTACK_IPV4_REAR_PREFIX16}.1.0/24
+        gateway: ${DESECSTACK_IPV4_REAR_PREFIX16}.1.1
+  rearapi2:
+    driver: bridge
+    ipam:
+      driver: default
+      config:
+      - subnet: ${DESECSTACK_IPV4_REAR_PREFIX16}.5.0/24
+        gateway: ${DESECSTACK_IPV4_REAR_PREFIX16}.5.1
+  rearwww:
+    driver: bridge
+    ipam:
+      driver: default
+      config:
+      - subnet: ${DESECSTACK_IPV4_REAR_PREFIX16}.2.0/24
+        gateway: ${DESECSTACK_IPV4_REAR_PREFIX16}.2.1
+  rearlord:
+    driver: bridge
+    ipam:
+      driver: default
+      config:
+      - subnet: ${DESECSTACK_IPV4_REAR_PREFIX16}.3.0/24
+        gateway: ${DESECSTACK_IPV4_REAR_PREFIX16}.3.1
+  rearmaster:
+    driver: bridge
+    ipam:
+      driver: default
+      config:
+      - subnet: ${DESECSTACK_IPV4_REAR_PREFIX16}.4.0/24
+        gateway: ${DESECSTACK_IPV4_REAR_PREFIX16}.4.1

+ 3 - 3
nslord/conf/pdns.conf.var

@@ -1,5 +1,5 @@
-allow-axfr-ips=172.16.1.0/24
-also-notify=172.16.1.12
+allow-axfr-ips=${DESECSTACK_IPV4_REAR_PREFIX16}.1.0/24
+also-notify=${DESECSTACK_IPV4_REAR_PREFIX16}.1.12
 api=yes
 api-key=${DESECSTACK_NSLORD_APIKEY}
 default-soa-edit=INCREMENT-WEEKS
@@ -14,7 +14,7 @@ soa-minimum-ttl=60
 version-string=powerdns
 webserver=yes
 webserver-address=0.0.0.0
-webserver-allow-from=172.16.1.0/24
+webserver-allow-from=${DESECSTACK_IPV4_REAR_PREFIX16}.1.0/24
 carbon-server=${DESECSTACK_NSLORD_CARBONSERVER}
 carbon-ourname=${DESECSTACK_NSLORD_CARBONOURNAME}
 

+ 0 - 10
test-api

@@ -1,14 +1,4 @@
 #!/usr/bin/env bash
-# The following options should be set by default: -o "com.docker.network.bridge.enable_icc"="true" -o "com.docker.network.bridge.host_binding_ipv4"="0.0.0.0" -o "com.docker.network.driver.mtu"="1500" 
-
-(
-source .env
-docker network inspect desecstack_front &>/dev/null \
-	|| docker network create --subnet=172.16.0.0/24 --gateway=172.16.0.1 \
-		--ipv6 --subnet=${DESECSTACK_IPV6_SUBNET} \
-		-o "com.docker.network.bridge.enable_ip_masquerade"="true" \
-		desecstack_front
-)
 
 if [ "$1" = "reset" ]
 then