diff options
Diffstat (limited to 'modules/vpn/egress.nix')
| -rw-r--r-- | modules/vpn/egress.nix | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/modules/vpn/egress.nix b/modules/vpn/egress.nix new file mode 100644 index 0000000..699d107 --- /dev/null +++ b/modules/vpn/egress.nix @@ -0,0 +1,108 @@ +{ + me, + config, + pkgs, + lib, + ... +}: + +let + inherit (lib) findFirst; + + # this is the https port, we use it to try to trick dpi into thinking + # we are just serving normal encrypted web traffic, nothing interesting! :) + # this does mean that our egress servers are unable to support normal www + # services which we put on machines by default, which is okay. + port = 443; + + # supposedly the current gold-standard protocol for circumventing dpi! + # both xray (egress-side) and sing-box (ingress-side) support various + # other protocols, if roskomnadzor learns to sniff out vless fully. + protocol = "vless"; + + definition = import ./definition.nix; + inherit (definition) paths mask; + + path = findFirst ( + p: p.egress == me.name + ) (throw "no egress information found for this server!") paths; + + xrayConfig = pkgs.writeText "xray.json" ( + builtins.toJSON { + inbounds = [ + { + inherit port protocol; + + settings = { + clients = [ + { + id = path.info.uuid; + flow = "xtls-rprx-vision"; + } + ]; + decryption = "none"; + }; + + streamSettings = { + network = "tcp"; + security = "reality"; + realitySettings = { + show = false; + dest = "www.${mask}:443"; + serverNames = [ + "www.${mask}" + mask + ]; + privateKey = "@PRIVATE_KEY@"; + shortIds = [ path.info.short ]; + }; + }; + } + ]; + + # and we're out! + outbounds = [ + { + protocol = "freedom"; + tag = "direct"; + } + ]; + } + ); +in +{ + networking.firewall.allowedTCPPorts = [ port ]; + + age.secrets.egress-key = { + file = path.info.keySecret; + }; + + # we have to make an xray config on the fly because + # xray does not like reading secrets from specific files, + # it wants them in plain-text! + systemd.services.generate-xray-config = { + before = [ "xray.service" ]; + requiredBy = [ "xray.service" ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + mkdir -p /run/xray-configuration + cp ${xrayConfig} /run/xray-configuration/xray.json + + egress_key=$(cat ${config.age.secrets.egress-key.path}) + + # use sd for replacement as a fancy new tool for this + ${pkgs.sd}/bin/sd "@PRIVATE_KEY@" "$egress_key" /run/xray-configuration/xray.json + + chown root:xray /run/xray-configuration/xray.json + chmod 640 /run/xray-configuration/xray.json + ''; + }; + + services.xray = { + enable = true; + settingsFile = "/run/xray-configuration/xray.json"; + }; +} |
