Reputation: 38
I need your support. I am building up a business network on a VPS, and I'm using Docker Swarm. In the Swarm environment, there will be a Wireguard VPN service, a DNS server and a bunch of other services that needs to be accessed only through VPN. Here is my file:
version: '3.8'
volumes:
wireguard_data:
gitlab_data:
gitlab_logs:
gitlab_config:
traefik-certificates:
networks:
vpn:
name: vpn
driver: overlay
ipam:
config:
- subnet: 10.0.1.0/24
services:
wg-easy:
environment:
- LANG=it
# ⚠️ Required:
# Change this to your host's public address
- WG_HOST=localhost
# Optional:
- PASSWORD=admin
# - PASSWORD_HASH=$$2y$$10$$hBCoykrB95WSzuV4fafBzOHWKu9sbyVa34GJr8VV5R/pIelfEMYyG (needs double $$, hash of 'foobar123'; see "How_to_generate_an_bcrypt_hash.md" for generate the hash)
# - PORT=51821
# - WG_PORT=51820
# - WG_CONFIG_PORT=92820
- WG_DEFAULT_ADDRESS=10.0.2.x
- WG_DEFAULT_DNS=dns.example.com
# - WG_MTU=1420
- WG_ALLOWED_IPS=10.0.1.0/24
# - WG_PERSISTENT_KEEPALIVE=25
- WG_PRE_UP=iptables -t nat -A POSTROUTING -d 10.0.1.0/24 -j MASQUERADE
- WG_POST_DOWN=iptables -t nat -D POSTROUTING -d 10.0.1.0/24 -j MASQUERADE
- UI_TRAFFIC_STATS=true
- UI_CHART_TYPE=1 # (0 Charts disabled, 1 # Line chart, 2 # Area chart, 3 # Bar chart)
image: ghcr.io/wg-easy/wg-easy
container_name: wg-easy
hostname: 'vpn.example.com'
depends_on:
- dnsmasq
volumes:
- wireguard_data:/etc/wireguard
networks:
- vpn
ports:
- "51820:51820/udp"
- "51821:51821/tcp"
restart: unless-stopped
cap_add:
- NET_ADMIN
- SYS_MODULE
# - NET_RAW # ⚠️ Uncomment if using Podman
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1
deploy:
replicas: 1
labels:
- "traefik.enable=true"
- "traefik.udp.routers.wireguard.entrypoints=wireguard"
- "traefik.udp.services.wireguard.loadbalancer.server.port=51820"
- "traefik.http.routers.wireguard-ui.rule=Host(`vpn.example.com`)"
- "traefik.http.routers.wireguard-ui.entrypoints=web"
- "traefik.http.services.wireguard-ui.loadbalancer.server.port=51821"
dnsmasq:
image: dockurr/dnsmasq
container_name: dnsmasq
hostname: 'dns.example.com'
environment:
DNS1: "1.0.0.1"
DNS2: "1.1.1.1"
networks:
- vpn
volumes:
- ./configs/dnsmasq.conf:/etc/dnsmasq.conf
restart: unless-stopped
cap_add:
- NET_ADMIN
deploy:
replicas: 1
labels:
- "traefik.enable=false"
gitlab:
image: gitlab/gitlab-ee:latest
container_name: gitlab
restart: always
hostname: 'gitlab.example.com'
volumes:
- gitlab_data:/var/opt/gitlab
- gitlab_logs:/var/log/gitlab
- gitlab_config:/etc/gitlab
shm_size: '256m'
#environment:
#GITLAB_OMNIBUS_CONFIG: |
# # Add any other gitlab.rb configuration here, each on its own line
# external_url 'https://gitlab.example.com'
networks:
- vpn
deploy:
replicas: 1
labels:
- "traefik.enable=true"
- "traefik.http.routers.gitlab.rule=Host(`gitlab.example.com`)"
- "traefik.http.routers.gitlab.entrypoints=web"
- "traefik.http.services.gitlab.loadbalancer.server.port=80"
whoami:
image: traefik/whoami
container_name: whoami
restart: always
hostname: 'whoami.example.com'
networks:
- vpn
deploy:
replicas: 1
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
traefik:
image: traefik:latest
command:
- "--providers.docker=true"
- "--api.dashboard=true"
- "--log.level=INFO"
#- "--log.filepath=/var/log/traefik.log
- "--accesslog=true"
#- "--accesslog.filepath=/var/log/traefik-access.log
- "--providers.docker.exposedByDefault=false"
- "--providers.docker.network=vpn"
- "--providers.swarm.endpoint=unix:///var/run/docker.sock"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.dns.address=:53"
- "--entrypoints.wireguard.address=:51820/udp"
- "--certificatesresolvers.myresolver.acme.tlschallenge=false"
- "--certificatesresolvers.myresolver.acme.email=your-email@example.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- traefik-certificates:/letsencrypt
networks:
- vpn
deploy:
#mode: global
labels:
- traefik.enable=true
- "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.services.dummy-svc.loadbalancer.server.port=9999"
As you can see, I'm using DNSMasq to redirect all instances of "example.com" to the Traefik reverse proxy, and I need to configure the DNSMasq instance as default DNS for Wireguard VPN Clients (WG_DEFAULT_DNS variable), but it seems I cannot retrieve IP Addresses of these containers.
The ideal solution would be:
address=/example.com/10.0.1.100
). Swarm assign to DNSMasq container an IP (e.g. 10.0.1.2)Obviously, the order will be managed by depends_on directive, so I'll be sure Wireguard starts once DNSMasq started, and this one starts once Traefik instance started.
With a configuration like that, I'm totally sure that I do not need to reconfigure anything in case of restart/outage/change of IP Addresses.
Is this configuration possible? If I am wrong with some, if not all, of the concepts, please guide me in the right direction to achieve the same objective. I also thought about making DNSMasq as system service on host, instead of Docker Swarm, but I'll still need the Traefik IP to redirect correctly.
Thanks in advance
Upvotes: 0
Views: 152