feat: nas add cyberghost

This commit is contained in:
2025-12-11 11:34:57 +01:00
parent 10fb8e88ce
commit d728722274
2 changed files with 54 additions and 36 deletions

View File

@@ -1,6 +1,7 @@
{ config, pkgs, ... }:
let
localNetwork = "10.42.96.0/20";
vpnServer = "87-1-hu.cg-dialup.net";
in
{
# SOPS secrets for CyberGhost credentials
@@ -23,10 +24,16 @@ in
environment.systemPackages = [ pkgs.openvpn ];
# OpenVPN client service
# Enable iproute2 for routing tables
networking.iproute2.enable = true;
networking.iproute2.rttablesExtraConfig = ''
100 vpn
'';
# OpenVPN client service - only establishes tunnel, no routing
services.openvpn.servers.cyberghost = {
autoStart = true;
updateResolvConf = true;
updateResolvConf = false;
config = ''
client
dev tun
@@ -53,51 +60,62 @@ in
# Connection
ping 5
explicit-exit-notify 2
route-delay 5
# Split tunnel: Don't pull routes from server, we'll set our own
# Don't pull any routes - we manage routing ourselves
route-nopull
# Route all traffic through VPN except local network
route 0.0.0.0 128.0.0.0 vpn_gateway
route 128.0.0.0 128.0.0.0 vpn_gateway
# Keep local network route direct
route ${localNetwork} net_gateway
verb 4
'';
};
# Kill switch: Block outgoing traffic if VPN is down
networking.firewall = {
extraCommands = ''
# Allow traffic to local network
iptables -A OUTPUT -d ${localNetwork} -j ACCEPT
# Systemd service to set up VPN routing after tunnel is up
systemd.services.cyberghost-routing = {
description = "CyberGhost VPN routing rules";
after = [ "openvpn-cyberghost.service" ];
requires = [ "openvpn-cyberghost.service" ];
wantedBy = [ "multi-user.target" ];
# Allow traffic through VPN tunnel
iptables -A OUTPUT -o tun+ -j ACCEPT
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = pkgs.writeShellScript "vpn-routing-up" ''
# Wait for tun0 to be available
for i in $(seq 1 30); do
if ${pkgs.iproute2}/bin/ip link show tun0 &>/dev/null; then
break
fi
sleep 1
done
# Allow loopback
iptables -A OUTPUT -o lo -j ACCEPT
# Add default route via VPN tunnel to table vpn
${pkgs.iproute2}/bin/ip route add default dev tun0 table vpn 2>/dev/null || true
# Allow established connections (for responses)
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Policy rules (lower number = higher priority)
# VPN server traffic must use main table to avoid routing loop
# Resolve all IPs (hostname has multiple A records for load balancing)
for VPN_SERVER_IP in $(${pkgs.dig}/bin/dig +short ${vpnServer} A); do
${pkgs.iproute2}/bin/ip rule add to $VPN_SERVER_IP table main priority 50 2>/dev/null || true
done
# Allow OpenVPN to establish connection (UDP 443)
iptables -A OUTPUT -p udp --dport 443 -j ACCEPT
# Local network always uses main routing table
${pkgs.iproute2}/bin/ip rule add to ${localNetwork} table main priority 100 2>/dev/null || true
${pkgs.iproute2}/bin/ip rule add from ${localNetwork} table main priority 100 2>/dev/null || true
# Drop all other outgoing internet traffic (kill switch)
iptables -A OUTPUT ! -d ${localNetwork} -j DROP
'';
# Everything else goes through VPN
${pkgs.iproute2}/bin/ip rule add table vpn priority 200 2>/dev/null || true
'';
ExecStop = pkgs.writeShellScript "vpn-routing-down" ''
${pkgs.iproute2}/bin/ip rule del table vpn priority 200 2>/dev/null || true
${pkgs.iproute2}/bin/ip rule del from ${localNetwork} table main priority 100 2>/dev/null || true
${pkgs.iproute2}/bin/ip rule del to ${localNetwork} table main priority 100 2>/dev/null || true
extraStopCommands = ''
iptables -D OUTPUT -d ${localNetwork} -j ACCEPT 2>/dev/null || true
iptables -D OUTPUT -o tun+ -j ACCEPT 2>/dev/null || true
iptables -D OUTPUT -o lo -j ACCEPT 2>/dev/null || true
iptables -D OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 2>/dev/null || true
iptables -D OUTPUT -p udp --dport 443 -j ACCEPT 2>/dev/null || true
iptables -D OUTPUT ! -d ${localNetwork} -j DROP 2>/dev/null || true
'';
# Clean up all VPN server IP rules
for VPN_SERVER_IP in $(${pkgs.dig}/bin/dig +short ${vpnServer} A); do
${pkgs.iproute2}/bin/ip rule del to $VPN_SERVER_IP table main priority 50 2>/dev/null || true
done
${pkgs.iproute2}/bin/ip route del default table vpn 2>/dev/null || true
'';
};
};
}