Wireguard und NordVPN kombinieren (WG-Easy)

Wireguard und NordVPN kombinieren (WG-Easy)

Im Gegensatz zur ersten Anleitung https://dr3st.de/wireguard-clients-durch-nordvpn-tunneln/, soll diese einen noch einfacheren Weg beschreiben, einen Wireguard Server einzurichten, dessen Clients über NordVPN geroutet und maskiert werden.
Die komplette Anleitung basiert ausschließlich auf Docker und benötigt keinerlei Änderungen im Host-System.
Der Vorteil bei diesem "optimierten" Setup ist, dass Clients aus dem isolierten Netzwerk des Docker-Containers nicht ausbrechen können und jeglicher Traffic komplett via NordVPN geroutet wird. Es sind keine Zugriffe auf das Host-System vorgesehen. Die genauen Details und Anpassungen beschreibe ich an den jeweiligen Stellen um sie zu verdeutlichen.

Schritte sind als Root auszuführen, oder sudo-Prefix wenn man möchte!

Docker / Compose installieren

# Ubuntu
apt-get install docker.io docker-compose

# Archlinux
pacman -Syu docker docker-compose

Docker-Compose Konfiguration

Diese Konfiguration kann je nach Bedarf angepasst werden, hierbei ist wichtig dass folgende Werte bearbeitet werden,

  • TOKEN des NordVPN mit gültigem API-Token ersetzen, 64 Zeichen, die man bei NordVPN anfragen kann (siehe hier)
  • CUSTOM_GW muss die IP-Adresse des NordVPN Containers enthalten
  • NET_LOCAL und WG_DEFAULT_ADDRESS abgleichen, damit NordVPN das Netz hinter dem Wireguard-Tunnel kennt dieses für die Maskierung berücksichtigt. Das abschließende x ist korrekt und wird von wg-easy ersetzt!
  • PASSWORD setzen
  • CONNECT auf gewünschtes Land (Gruppe) setzen
  • WG_CONTAINER_IP muss der IP des Wireguard Containers entsprechen
  • WG_HOST ein Hostname der auf den Server zeigt, wird in der VPN Config der Clients als Endpunkt zum Verbinden genutzt
  • Ports des Wireguard-Containers nach Wunsch anpassen, entfernen, abhängig von den eigenen Vorstellungen
# file: /srv/docker/wg_easy/docker-compose.yml
version: "3.8"
services:
  nvpn_01:
    container_name: wgeasy_nvpn_01
    image: ghcr.io/bubuntux/nordvpn
    restart: unless-stopped
    environment:
      TOKEN: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      NET_LOCAL: "192.168.33.0/24"
      WG_CONTAINER_IP: "192.168.33.11"
      PRE_CONNECT: "/hooks/pre_connect.sh"
      CONNECT: "Germany"
    volumes:
    - /srv/docker/wg_easy/nvpn_01:/hooks:rw
    cap_add:
    - NET_ADMIN
    - NET_RAW
    networks:
      default:
        ipv4_address: 172.18.18.2
  wg_01:
    container_name: wgeasy_wg_01
    image: weejewel/wg-easy
    ports:
      - "51820:51820/udp"
      - "51821:51821/tcp"
    environment:
      CUSTOM_GW: "172.18.18.2"
      WG_HOST: "my.host.com"
      PASSWORD: "xxxxxxxxxxxxxxxxxxxxx"
      WG_DEFAULT_ADDRESS: "192.168.33.x"
      WG_DEFAULT_DNS: "1.1.1.1,9.9.9.9"
      WG_MTU: "1420"
      WG_PERSISTENT_KEEPALIVE: "30"
      WG_PRE_UP: "/hooks/pre_up.sh"
      # - WG_POST_UP=echo "Post Up" > /etc/wireguard/post-up.txt
      # - WG_PRE_DOWN=echo "Pre Down" > /etc/wireguard/pre-down.txt
      # - WG_POST_DOWN=echo "Post Down" > /etc/wireguard/post-down.txt
      WG_ALLOWED_IPS: "0.0.0.0/5,8.0.0.0/7,11.0.0.0/8,12.0.0.0/6,16.0.0.0/4,32.0.0.0/3,64.0.0.0/2,128.0.0.0/3,160.0.0.0/5,168.0.0.0/6,172.0.0.0/12,172.32.0.0/11,172.64.0.0/10,172.128.0.0/9,173.0.0.0/8,174.0.0.0/7,176.0.0.0/4,192.0.0.0/9,192.128.0.0/11,192.160.0.0/13,192.169.0.0/16,192.170.0.0/15,192.172.0.0/14,192.176.0.0/12,192.192.0.0/10,193.0.0.0/8,194.0.0.0/7,196.0.0.0/6,200.0.0.0/5,208.0.0.0/4,224.0.0.0/3"
    volumes:
      - /srv/docker/wg_easy/wg_01_config:/etc/wireguard
      - /srv/docker/wg_easy/wg_01_hooks:/hooks:rw
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    sysctls:
      - net.ipv4.ip_forward=1
      - net.ipv4.conf.all.src_valid_mark=1
    networks:
      default:
        ipv4_address: 172.18.18.11
		
networks:
  default:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.18.18.0/24
    driver_opts:
      com.docker.network.bridge.name: br_wgeasy

In die Container werden zusätzlich noch Skripte eingehängt, um die Routing-Funktion zu ermöglichen. Normalerweise würde der WG-Easy Conainer selbst maskieren und über sein Gateway (den Host) routen. Somit würde es nicht durch den NordVPN Container laufen.
Die Skripts im Detail:

NordVPN Hook

Das Skript wird vor der Verbindung mit NordVPN ausgeführt und löscht die Route, welches das Startskript des Containers anlegt. Diese würde normalerweise gesondert behandelt werden und muss so angepasst werden, dass sie über den Wireguard-Container geroutet wird.

# File: /srv/docker/wg_easy/nvpn_01/pre_connect.sh

#!/bin/bash
# löschen der existierenden Route von NordPVN
ip route del $NET_LOCAL
# Route um das Wireguard-Netz über wgeasy Container zu routen
ip route add $NET_LOCAL via $WG_CONTAINER_IP


WG-Easy Hook

Wird vorm Start des Wireguard-Servers ausgeführt um die Umgebung abzusichern und das Routing via NordVPN vorzubereiten. Ist NordVPN nicht aktiv, besteht keine Möglichkeit in das Internet zu routen. Dies ist aber ein gewünschter Nebeneffekt.

File: /srv/docker/wg_easy/wg_01_hooks/pre_up.sh

#/bin/bash

set -e

# Netzwerk und Standard-Gateway auslesen
NETWORK=${WG_DEFAULT_ADDRESS/.x/.0/24}
GW=$(/sbin/ip route | awk '/default/ { print $3 }')

# Web-Interface wird vom Host aus erlaubt
iptables -I INPUT -s ${GW} -p tcp --dport 51821 -j ACCEPT
# DNS im Container erlauben
iptables -I INPUT -i lo -s 127.0.0.1 -j ACCEPT
# existierende Verbindungen werden erlaubt
iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# Standard-Regel ist das Verwerfen von Paketen, Accept wird von wg-easy hinterlegt!
iptables -P INPUT DROP
iptables -P FORWARD DROP

# wg-easy legt eine masquerade Regel an, diese hebeln wir aus, damit im Nordvpn Container die Tunnel-IP-Adresse des Clients ersichtlich ist und nicht zwischen den Containern genatted wird
iptables -t nat -I POSTROUTING -j ACCEPT

# alle Pakete aus dem Tunnel Netzwerk erhalten eine eigene Routing-Tabelle
# somit kann der wgeasy Container selbst wie gewohnt ohne VPN in das Internet routen, aber alle VPN-Clients werden gesondert behandelt

# Routen für IP-Pakete von WG-Clients werden in Tabelle 1000 gesucht
ip rule add from ${NETWORK} lookup 1000

# Standard-GW für Tunnel-Clients über den NordVPN Container
ip route add default via ${CUSTOM_GW} table 1000

# alle privaten Netze werden verworfen, diese sollten nicht in das Internet / über NordVPN geroutet werden! Möchte man weitere IP-Adressen blockieren, einfach hinterlegen. Außerdem wird somit zusätzlich sichergestellt, dass WG-Clients sich unereinander nicht erreichen können.
ip route add blackhole 10.0.0.0/8 table 1000
ip route add blackhole 172.16.0.0/12 table 1000
ip route add blackhole 192.168.0.0/16 table 1000

Nachbereitung und Server Start

cd /srv/docker/wg_easy/

# Berechtigung der Skripts erweitern, damit diese ausführbar sind
find . -name "*.sh" -exec chmod +x {} \;

docker-compose up -d

Im Anschluss sollten die beiden Container gestartet werden und das Webinterface erreichbar sein. Je nachdem ob die Ports angepasst wurden muss dies berücksichtigt werden...
Weitere Informationen über die Funktion und die Einrichtung von Zugängen bei WG-Easy findet man im Projekt: https://github.com/WeeJeWel/wg-easy

NordVPN Server finden

Im Nordvpn Container können die Länder, Gruppen / Server aufgelistet werden. Je nach Bedarf kann man somit die CONNECT-Variable anpassen. Wie genau dies funktioniert kann hier nachgelesen werden: https://github.com/bubuntux/nordvpn

Beispiele:

docker exec -ti wgeasy_nvpn_01 bash

root@vpn:/# nordvpn countries
Albania, Argentina, Australia, Austria, Belgium, Bosnia_And_Herzegovina, Brazil, Bulgaria, Canada, Chile, Colombia, Costa_Rica, Croatia, Cyprus, Czech_Republic, Denmark, Estonia, Finland, France, Georgia, Germany, Greece, Hong_Kong, Hungary, Iceland, Indonesia, Ireland, Israel, Italy, Japan, Latvia, Lithuania, Luxembourg, Malaysia, Mexico, Moldova, Netherlands, New_Zealand, North_Macedonia, Norway, Poland, Portugal, Romania, Serbia, Singapore, Slovakia, Slovenia, South_Africa, South_Korea, Spain, Sweden, Switzerland, Taiwan, Thailand, Turkey, Ukraine, United_Kingdom, United_States, Vietnam

root@vpn:/# nordvpn cities Germany
Berlin, Frankfurt