{ pkgs, lib, config, ... }: let netns = "calyx"; inherit (config.services) openvpn; apiUrl = "https://api.calyx.net:4430/3/cert"; ca = pkgs.fetchurl { url = "https://calyx.net/ca.crt"; hash = "sha256-zLs7TRXrHlPjqdaBN1cmbB062XhKs4cv5ajmrkg4O8s="; curlOptsList = [ "-k" ]; } + ""; key-cert = "/run/openvpn-${netns}/key+cert.pem"; in { services.openvpn.servers.${netns} = { inherit netns; settings = { remote = # new-york (vpn2.calyx.net) [ "162.247.72.193" ] ++ [ ]; remote-random = true; port = "443"; proto = "tcp"; inherit ca; key = key-cert; cert = key-cert; auth = "SHA1"; client = true; dev = "ov-${netns}"; dev-type = "tun"; keepalive = "10 30"; nobind = true; persist-key = true; persist-tun = true; remote-cert-tls = "server"; reneg-sec = 0; script-security = 2; tls-cipher = "TLS-DHE-RSA-WITH-AES-128-CBC-SHA"; tls-client = true; tun-ipv6 = true; up-restart = true; verb = 3; }; }; systemd.services."openvpn-${netns}" = { after = [ "network-online.target" ]; preStart = '' ( set -ex ${pkgs.curl}/bin/curl -X POST --cacert ${ca} -o ${key-cert} -vLs ${apiUrl} chmod 700 ${key-cert} ) ''; serviceConfig = { RuntimeDirectory = [ "openvpn-${netns}" ]; RuntimeDirectoryMode = "0700"; }; }; networking.nftables.ruleset = '' table inet filter { chain output-net { skuid root tcp dport https counter accept comment "OpenVPN Calyx" skuid root tcp dport 4430 counter accept comment "OpenVPN Calyx (API)" } } ''; services.netns.namespaces.${netns} = { nftables = lib.mkBefore '' include "${../networking/nftables.txt}" table inet filter { chain output-lan { meta l4proto { udp, tcp } th dport domain counter accept comment "DNS" log prefix "calyx: output-lan: " counter drop } chain output-net { tcp dport { http, https } counter accept comment "HTTP" } chain output { ip daddr 10.0.0.0/8 counter goto output-lan ip daddr 172.16.0.0/12 counter goto output-lan ip daddr 192.168.0.0/16 counter goto output-lan ip daddr 224.0.0.0/3 counter goto output-lan jump output-net log prefix "calyx: output-net: " counter drop } } ''; }; }