summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/vpn/egress.nix90
-rw-r--r--modules/vpn/ingress.nix16
2 files changed, 69 insertions, 37 deletions
diff --git a/modules/vpn/egress.nix b/modules/vpn/egress.nix
index fe39880..7858751 100644
--- a/modules/vpn/egress.nix
+++ b/modules/vpn/egress.nix
@@ -20,6 +20,9 @@ let
# other protocols, if roskomnadzor learns to sniff out vless fully.
protocol = "vless";
+ inboundTag = "vless-in";
+ outboundTag = "direct-out";
+
definition = import ./definition.nix;
inherit (definition) paths mask;
@@ -27,48 +30,63 @@ let
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;
+ xrayConfig = {
+ inbounds = [
+ {
+ inherit port protocol;
+ tag = inboundTag;
+
+ settings = {
+ clients = [
+ {
+ id = path.info.uuid;
+ flow = "xtls-rprx-vision";
+ }
+ ];
+ decryption = "none";
+ };
- settings = {
- clients = [
- {
- id = path.info.uuid;
- flow = "xtls-rprx-vision";
- }
+ streamSettings = {
+ network = "tcp";
+ security = "reality";
+ realitySettings = {
+ show = false;
+ dest = "www.${mask}:443";
+ serverNames = [
+ "www.${mask}"
+ mask
];
- decryption = "none";
+ privateKey = "@PRIVATE_KEY@";
+ shortIds = [ path.info.short ];
};
+ };
+ }
+ ];
- 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 = outboundTag;
+ }
+ ];
- # and we're out!
- outbounds = [
+ routing = {
+ rules = [
{
- protocol = "freedom";
- tag = "direct";
+ type = "field";
+ inboundTag = [ inboundTag ];
+ inherit outboundTag;
}
];
- }
- );
+ };
+
+ log = {
+ loglevel = "debug";
+ };
+ };
+
+ config-file = pkgs.writeText "xray.json" (builtins.toJSON xrayConfig);
in
{
networking.firewall.allowedTCPPorts = [ port ];
@@ -92,7 +110,7 @@ in
};
script = ''
mkdir -p /run/xray-configuration
- cp ${xrayConfig} /run/xray-configuration/xray.json
+ cp ${config-file} /run/xray-configuration/xray.json
egress_key=$(cat ${config.age.secrets.egress-key.path})
@@ -104,7 +122,7 @@ in
xray = {
requires = [ "generate-xray-config.service" ];
after = [ "generate-xray-config.service" ];
- restartTriggers = [ xrayConfig ];
+ restartTriggers = [ config-file ];
};
};
diff --git a/modules/vpn/ingress.nix b/modules/vpn/ingress.nix
index 2a6a582..2cf1ae5 100644
--- a/modules/vpn/ingress.nix
+++ b/modules/vpn/ingress.nix
@@ -25,7 +25,8 @@ let
ingressName = index: "vpn-ingress${toString index}";
egressName = "vpn-egress0";
- egressAddress = "10.123.255.1/30";
+ egressAddress = "10.123.255.1/16"; # /16 encompasses all possible subnet addresses
+ egressMTU = 1400;
egressHost = name: "${name}.rnrd.eu";
in
@@ -36,6 +37,8 @@ in
networking.firewall = {
allowedUDPPorts = map (x: x.port) paths;
+ allowedTCPPorts = map (x: x.port) paths;
+ checkReversePath = "loose";
};
age.secrets.ingress-key = {
@@ -83,9 +86,13 @@ in
"20-${egressName}" = {
name = egressName;
address = [ egressAddress ];
+ networkConfig = {
+ IPv4ReversePathFilter = "loose";
+ };
linkConfig = {
ActivationPolicy = "up";
RequiredForOnline = "no"; # does not count as online
+ MTUBytes = toString egressMTU;
};
routes = [
{
@@ -137,6 +144,7 @@ in
tag = inboundName;
interface_name = egressName;
address = [ egressAddress ];
+ mtu = egressMTU;
auto_route = false; # we route manually
strict_route = false;
endpoint_independent_nat = true;
@@ -146,6 +154,7 @@ in
outbounds = map (path: {
type = "vless";
flow = "xtls-rprx-vision";
+ packet_encoding = "xudp";
server = egressHost path.egress;
server_port = 443;
@@ -179,6 +188,11 @@ in
auto_detect_interface = true;
};
+
+ log = {
+ level = "debug";
+ timestamp = true;
+ };
};
};
}