Start working on ipv6

This commit is contained in:
AaronDewes 2022-05-13 21:12:21 +00:00
parent b63e0fa574
commit e58d849609
7 changed files with 130 additions and 13 deletions

View File

@ -8,3 +8,7 @@ networks:
default: default:
name: citadel_main_network name: citadel_main_network
external: true external: true
ipv6:
name: citadel_ip6_network
external: true

View File

@ -7,6 +7,7 @@ def permissions():
"lnd": { "lnd": {
"environment_allow": [ "environment_allow": [
"LND_IP", "LND_IP",
"LND_IP6",
"LND_GRPC_PORT", "LND_GRPC_PORT",
"LND_REST_PORT", "LND_REST_PORT",
"BITCOIN_NETWORK" "BITCOIN_NETWORK"
@ -18,6 +19,7 @@ def permissions():
"bitcoind": { "bitcoind": {
"environment_allow": [ "environment_allow": [
"BITCOIN_IP", "BITCOIN_IP",
"BITCOIN_IP6",
"BITCOIN_NETWORK", "BITCOIN_NETWORK",
"BITCOIN_P2P_PORT", "BITCOIN_P2P_PORT",
"BITCOIN_RPC_PORT", "BITCOIN_RPC_PORT",
@ -36,18 +38,20 @@ def permissions():
"electrum": { "electrum": {
"environment_allow": [ "environment_allow": [
"ELECTRUM_IP", "ELECTRUM_IP",
"ELECTRUM_IP6",
"ELECTRUM_PORT", "ELECTRUM_PORT",
], ],
"volumes": [] "volumes": []
}, },
"c-lightning": { "c-lightning": {
"environment_allow": [ "environment_allow": [
"C_LIGHTNING_IP" "C_LIGHTNING_IP",
"C_LIGHTNING_IP6"
], ],
"volumes": [] "volumes": []
}, },
} }
# Vars which are always allowed without permissions # Vars which are always allowed without permissions
always_allowed_env = ["TOR_PROXY_IP", "TOR_PROXY_PORT", always_allowed_env = ["TOR_PROXY_IP","TOR_PROXY_IP6", "TOR_PROXY_PORT",
"APP_DOMAIN", "APP_HIDDEN_SERVICE", "BITCOIN_NETWORK"] "APP_DOMAIN", "APP_HIDDEN_SERVICE", "BITCOIN_NETWORK"]

View File

@ -9,9 +9,11 @@ import json
from os import path from os import path
import random import random
from lib.composegenerator.v1.utils.networking import getContainerHiddenService, getFreePort, getHiddenService from lib.composegenerator.v1.utils.networking import getContainerHiddenService, getFreePort, getHiddenService
import ipaddress
def assignIp(container: ContainerStage2, appId: str, networkingFile: str, envFile: str) -> ContainerStage2: def assignIp(container: ContainerStage2, appId: str, networkingFile: str, envFile: str) -> ContainerStage2:
ipv6Net = ipaddress.ip_network("fd9e:4a81::/32")
# Strip leading/trailing whitespace from container.name # Strip leading/trailing whitespace from container.name
container.name = container.name.strip() container.name = container.name.strip()
# If the name still contains a newline, throw an error # If the name still contains a newline, throw an error
@ -21,9 +23,16 @@ def assignIp(container: ContainerStage2, appId: str, networkingFile: str, envFil
appId.upper().replace("-", "_"), appId.upper().replace("-", "_"),
container.name.upper().replace("-", "_") container.name.upper().replace("-", "_")
) )
ipv6_env_var = "APP_{}_{}_IP6".format(
appId.upper().replace("-", "_"),
container.name.upper().replace("-", "_")
)
# Write a list of used IPs to the usedIpFile as JSON, and read that file to check if an IP # Write a list of used IPs to the usedIpFile as JSON, and read that file to check if an IP
# can be used # can be used
usedIps = [] usedIps = []
usedIpv6 = []
# The first 100000 addresses are reserved for Citadel
ip6Offset = 100000
networkingData = {} networkingData = {}
if path.isfile(networkingFile): if path.isfile(networkingFile):
with open(networkingFile, 'r') as f: with open(networkingFile, 'r') as f:
@ -33,7 +42,15 @@ def assignIp(container: ContainerStage2, appId: str, networkingFile: str, envFil
usedIps = list(networkingData['ip_addresses'].values()) usedIps = list(networkingData['ip_addresses'].values())
else: else:
networkingData['ip_addresses'] = {} networkingData['ip_addresses'] = {}
# An IP 10.21.21.xx, with x being a random number above 40 is asigned to the container if 'ip6_addresses' in networkingData:
usedIpv6 = list(networkingData['ip6_addresses'].values())
else:
networkingData['i6p_addresses'] = {}
if 'ip6Offset' in networkingData:
ip6Offset = int(networkingData['ip6Offset'])
else:
networkingData['ip6Offset'] = 100000
# An IP 10.21.21.xx, with x being a random number above 40 is assigned to the container
# If the IP is already in use, it will be tried again until it's not in use # If the IP is already in use, it will be tried again until it's not in use
# If it's not in use, it will be added to the usedIps list and written to the usedIpFile # If it's not in use, it will be added to the usedIps list and written to the usedIpFile
# If the usedIpsFile contains all IPs between 10.21.21.20 and 10.21.21.255 (inclusive), # If the usedIpsFile contains all IPs between 10.21.21.20 and 10.21.21.255 (inclusive),
@ -51,18 +68,29 @@ def assignIp(container: ContainerStage2, appId: str, networkingFile: str, envFil
networkingData['ip_addresses']["{}-{}".format( networkingData['ip_addresses']["{}-{}".format(
appId, container.name)] = ip appId, container.name)] = ip
break break
if "{}-{}".format(appId, container.name) in networkingData['ip6_addresses']:
ip6 = networkingData['ip_addresses']["{}-{}".format(
appId, container.name)]
else:
networkingData['ip6Offset'] += 1
ip6 = ipv6Net[networkingData['ip6Offset']]
container.networks = from_dict(data_class=NetworkConfig, data={'default': { container.networks = from_dict(data_class=NetworkConfig, data={'default': {
'ipv4_address': "$" + env_var}}) 'ipv4_address': "$" + env_var}, 'ipv6': {
'ipv6_address': "$" + ipv6_env_var}})
dotEnv = parse_dotenv(envFile) dotEnv = parse_dotenv(envFile)
if env_var in dotEnv and str(dotEnv[env_var]) == str(ip): if not (env_var in dotEnv and str(dotEnv[env_var]) == str(ip)):
return container
# Now append a new line with APP_{app_name}_{container_name}_IP=${IP} to the envFile # Now append a new line with APP_{app_name}_{container_name}_IP=${IP} to the envFile
with open(envFile, 'a') as f: with open(envFile, 'a') as f:
f.write("{}={}\n".format(env_var, ip)) f.write("{}={}\n".format(env_var, ip))
with open(networkingFile, 'w') as f: with open(networkingFile, 'w') as f:
json.dump(networkingData, f) json.dump(networkingData, f)
if not (ipv6_env_var in dotEnv and str(dotEnv[ipv6_env_var]) == str(ipv6_ip)):
# Now append a new line with APP_{app_name}_{container_name}_IP=${IP} to the envFile
with open(envFile, 'a') as f:
f.write("{}={}\n".format(ipv6_env_var, ip6))
with open(networkingFile, 'w') as f:
json.dump(networkingData, f)
return container return container

View File

@ -13,6 +13,8 @@ services:
networks: networks:
default: default:
ipv4_address: $TOR_PROXY_IP ipv4_address: $TOR_PROXY_IP
ipv6:
ipv6_address: $TOR_PROXY_IP6
app-tor: app-tor:
container_name: app-tor container_name: app-tor
image: lncm/tor:0.4.6.8@sha256:c262923ffd0bd224a4a4123cf1c88eea11e2314566b7b7e8a1f77969deeb0208 image: lncm/tor:0.4.6.8@sha256:c262923ffd0bd224a4a4123cf1c88eea11e2314566b7b7e8a1f77969deeb0208
@ -24,6 +26,8 @@ services:
networks: networks:
default: default:
ipv4_address: $APPS_TOR_IP ipv4_address: $APPS_TOR_IP
ipv6:
ipv6_address: $APPS_TOR_IP_IP6
app-2-tor: app-2-tor:
container_name: app-2-tor container_name: app-2-tor
image: lncm/tor:0.4.6.8@sha256:c262923ffd0bd224a4a4123cf1c88eea11e2314566b7b7e8a1f77969deeb0208 image: lncm/tor:0.4.6.8@sha256:c262923ffd0bd224a4a4123cf1c88eea11e2314566b7b7e8a1f77969deeb0208
@ -35,6 +39,8 @@ services:
networks: networks:
default: default:
ipv4_address: $APPS_2_TOR_IP ipv4_address: $APPS_2_TOR_IP
ipv6:
ipv6_address: $APPS_2_TOR_IP6
app-3-tor: app-3-tor:
container_name: app-3-tor container_name: app-3-tor
image: lncm/tor:0.4.6.8@sha256:c262923ffd0bd224a4a4123cf1c88eea11e2314566b7b7e8a1f77969deeb0208 image: lncm/tor:0.4.6.8@sha256:c262923ffd0bd224a4a4123cf1c88eea11e2314566b7b7e8a1f77969deeb0208
@ -46,6 +52,8 @@ services:
networks: networks:
default: default:
ipv4_address: $APPS_3_TOR_IP ipv4_address: $APPS_3_TOR_IP
ipv6:
ipv6_address: $APPS_3_TOR_IP6
nginx: nginx:
container_name: nginx container_name: nginx
image: nginx:1.21.6@sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767 image: nginx:1.21.6@sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767
@ -63,6 +71,8 @@ services:
networks: networks:
default: default:
ipv4_address: $NGINX_IP ipv4_address: $NGINX_IP
ipv6:
ipv6_address: $NGINX_IP6
bitcoin: bitcoin:
container_name: bitcoin container_name: bitcoin
image: nolim1t/bitcoinknots:v22.0.knots20211108@sha256:a475da2b2ecda55fcc65ea23e1a36c58b2c10549f1c3d3bb3c31c7dda1127354 image: nolim1t/bitcoinknots:v22.0.knots20211108@sha256:a475da2b2ecda55fcc65ea23e1a36c58b2c10549f1c3d3bb3c31c7dda1127354
@ -77,6 +87,8 @@ services:
networks: networks:
default: default:
ipv4_address: $BITCOIN_IP ipv4_address: $BITCOIN_IP
ipv6:
ipv6_address: $BITCOIN_IP6
lightning: lightning:
container_name: lightning container_name: lightning
image: lightninglabs/lnd:v0.14.3-beta@sha256:6a2234b0aad4caed3d993736816b198d6228f32c59b27ba2218d5ebf516ae905 image: lightninglabs/lnd:v0.14.3-beta@sha256:6a2234b0aad4caed3d993736816b198d6228f32c59b27ba2218d5ebf516ae905
@ -98,6 +110,8 @@ services:
networks: networks:
default: default:
ipv4_address: $LND_IP ipv4_address: $LND_IP
ipv6:
ipv6_address: $LND_IP6
dashboard: dashboard:
container_name: dashboard container_name: dashboard
image: ghcr.io/runcitadel/dashboard:v0.0.11@sha256:a1aac1c2fe3dc5a9604e5ec1ab9db0cc8f21d6c2b90f12898750bcb2c3b835f3 image: ghcr.io/runcitadel/dashboard:v0.0.11@sha256:a1aac1c2fe3dc5a9604e5ec1ab9db0cc8f21d6c2b90f12898750bcb2c3b835f3
@ -106,6 +120,8 @@ services:
networks: networks:
default: default:
ipv4_address: $DASHBOARD_IP ipv4_address: $DASHBOARD_IP
ipv6:
ipv6_address: $DASHBOARD_IP6
manager: manager:
container_name: manager container_name: manager
image: ghcr.io/runcitadel/manager:v0.0.12@sha256:de97eeb6e8caae5d1a8aeb045213621cf8e6e928177236bb0b3c25e76f6cd041 image: ghcr.io/runcitadel/manager:v0.0.12@sha256:de97eeb6e8caae5d1a8aeb045213621cf8e6e928177236bb0b3c25e76f6cd041
@ -160,6 +176,8 @@ services:
networks: networks:
default: default:
ipv4_address: $MANAGER_IP ipv4_address: $MANAGER_IP
ipv6:
ipv6_address: $MANAGER_IP6
middleware: middleware:
container_name: middleware container_name: middleware
image: ghcr.io/runcitadel/middleware:v0.0.10@sha256:afd6e2b6f5ba27cde32f6f6d630ddc6dd46d1072871f7834d7424d0554d0f53d image: ghcr.io/runcitadel/middleware:v0.0.10@sha256:afd6e2b6f5ba27cde32f6f6d630ddc6dd46d1072871f7834d7424d0554d0f53d
@ -187,6 +205,8 @@ services:
networks: networks:
default: default:
ipv4_address: $MIDDLEWARE_IP ipv4_address: $MIDDLEWARE_IP
ipv6:
ipv6_address: $MIDDLEWARE_IP6
neutrino-switcher: neutrino-switcher:
container_name: neutrino-switcher container_name: neutrino-switcher
image: lncm/neutrino-switcher:1.0.5@sha256:3ddf58c5599ba22db8414f2694bfeeba086455d4a19b4955b26c3ae5e967d42a image: lncm/neutrino-switcher:1.0.5@sha256:3ddf58c5599ba22db8414f2694bfeeba086455d4a19b4955b26c3ae5e967d42a
@ -207,6 +227,8 @@ services:
networks: networks:
default: default:
ipv4_address: $NEUTRINO_SWITCHER_IP ipv4_address: $NEUTRINO_SWITCHER_IP
ipv6:
ipv6_address: $NEUTRINO_SWITCHER_IP6
electrum: electrum:
container_name: electrum container_name: electrum
image: ghcr.io/runcitadel/electrs:v0.9.5@sha256:5fdd76415645de14f31c43844dc143b1477f86872d2f73a041c5005d469ed510 image: ghcr.io/runcitadel/electrs:v0.9.5@sha256:5fdd76415645de14f31c43844dc143b1477f86872d2f73a041c5005d469ed510
@ -221,6 +243,8 @@ services:
networks: networks:
default: default:
ipv4_address: $ELECTRUM_IP ipv4_address: $ELECTRUM_IP
ipv6:
ipv6_address: $ELECTRUM_IP6
redis: redis:
container_name: redis container_name: redis
image: redis:7.0.0-bullseye@sha256:ad0705f2e2344c4b642449e658ef4669753d6eb70228d46267685045bf932303 image: redis:7.0.0-bullseye@sha256:ad0705f2e2344c4b642449e658ef4669753d6eb70228d46267685045bf932303
@ -234,6 +258,8 @@ services:
networks: networks:
default: default:
ipv4_address: $REDIS_IP ipv4_address: $REDIS_IP
ipv6:
ipv6_address: $REDIS_IP6
networks: networks:
default: default:
name: citadel_main_network name: citadel_main_network
@ -241,6 +267,12 @@ networks:
driver: default driver: default
config: config:
- subnet: $NETWORK_IP/24 - subnet: $NETWORK_IP/24
ipv6:
name: citadel_ip6_network
ipam:
config:
- subnet: fd9e:4a81::/32
gateway: fd9e:4a81::1
volumes: volumes:
jwt-public-key: null jwt-public-key: null
jwt-private-key: null jwt-private-key: null

31
scripts/configure vendored
View File

@ -269,6 +269,23 @@ APPS_2_TOR_IP="10.21.21.13"
APPS_3_TOR_IP="10.21.21.14" APPS_3_TOR_IP="10.21.21.14"
REDIS_IP="10.21.21.15" REDIS_IP="10.21.21.15"
IP6_SUBNET="fd9e:4a81::/32"
IP6_GATEWAY="fd9e:4a81::1"
NGINX_IP6="fd9e:4a81::2"
DASHBOARD_IP6="fd9e:4a81::3"
MANAGER_IP6="fd9e:4a81::4"
MIDDLEWARE_IP6="fd9e:4a81::5"
NEUTRINO_SWITCHER_IP6="fd9e:4a81::6"
DASHBOARD_NEW_IP6="fd9e:4a81::7"
BITCOIN_IP6="fd9e:4a81::8"
LND_IP6="fd9e:4a81::9"
ELECTRUM_IP6="fd9e:4a81::10"
TOR_PROXY_IP6="fd9e:4a81::11"
APPS_TOR_IP6="fd9e:4a81::12"
APPS_2_TOR_IP6="fd9e:4a81::13"
APPS_3_TOR_IP6="fd9e:4a81::14"
REDIS_IP6="fd9e:4a81::15"
# Ports # Ports
BITCOIN_RPC_PORT="8332" BITCOIN_RPC_PORT="8332"
BITCOIN_P2P_PORT="8333" BITCOIN_P2P_PORT="8333"
@ -365,6 +382,20 @@ print("Generated configuration files\n")
print("Checking if Docker Compose is installed...") print("Checking if Docker Compose is installed...")
download_docker_compose() download_docker_compose()
dockerIp6Config = json.dumps({
"ipv6": True,
"fixed-cidr-v6": "fd9e:4a81::/32"
})
print("Updating docker config")
if(os.path.isfile("/etc/docker/daemon.json")):
print("Docker config already present, not changing anything")
else:
print("Configuring Docker for IPv6")
with open("/etc/docker/daemon.json", "w") as file:
file.write(dockerIp6Config)
if not reconfiguring: if not reconfiguring:
print("Updating apps...\n") print("Updating apps...\n")
os.system('./scripts/app --invoked-by-configure update') os.system('./scripts/app --invoked-by-configure update')

View File

@ -41,3 +41,21 @@ APPS_2_TOR_IP=<apps-2-tor-ip>
APPS_3_TOR_IP=<apps-3-tor-ip> APPS_3_TOR_IP=<apps-3-tor-ip>
DOCKER_BINARY=<docker-binary> DOCKER_BINARY=<docker-binary>
UPDATE_CHANNEL=<update-channel> UPDATE_CHANNEL=<update-channel>
# IPv6
IP6_SUBNET=<ip6-subnet>
IP6_GATEWAY=<ip6-gateway>
NGINX_IP6=<nginx-ip6>
DASHBOARD_IP6=<dashboard-ip6>
DASHBOARD_NEW_IP6=<dashboard-new-ip6>
MANAGER_IP6=<manager-ip6>
MIDDLEWARE_IP6=<middleware-ip6>
NEUTRINO_SWITCHER_IP6=<neutrino-switcher-ip6>
BITCOIN_IP6=<bitcoin-ip6>
LND_IP6=<lnd-ip6>
ELECTRUM_IP6=<electrum-ip6>
TOR_PROXY_IP6=<tor-proxy-ip6>
APPS_TOR_IP6=<apps-tor-ip6>
APPS_2_TOR_IP6=<apps-2-tor-ip6>
APPS_3_TOR_IP6=<apps-3-tor-ip6>
REDIS_IP6=<redis-ip6>

View File

@ -32,7 +32,7 @@ http {
# dashboard (old) # dashboard (old)
location / { location / {
proxy_pass http://<dashboard-ip>:3004/; proxy_pass http://[<dashboard-ip6>]:3004/;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";