xray: config via sops, private routes spliced into sing-box at runtime
This commit is contained in:
parent
a7ec82579c
commit
8458e0645d
3 changed files with 44 additions and 16 deletions
|
|
@ -1,7 +1,6 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
xrayServer = (import ./private/xray-routes.nix).xrayServer;
|
|
||||||
wifiIf = "wlp194s0";
|
wifiIf = "wlp194s0";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
@ -87,7 +86,8 @@ in
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
ExecStart = pkgs.writeShellScript "killswitch-up" ''
|
ExecStart = pkgs.writeShellScript "killswitch-up" ''
|
||||||
${pkgs.nftables}/bin/nft -f - <<'EOF'
|
XRAY_SERVER=$(cat ${config.sops.secrets."xray-endpoint".path})
|
||||||
|
${pkgs.nftables}/bin/nft -f - <<EOF
|
||||||
table inet killswitch {
|
table inet killswitch {
|
||||||
set captive_portals_v4 {
|
set captive_portals_v4 {
|
||||||
type ipv4_addr; flags interval;
|
type ipv4_addr; flags interval;
|
||||||
|
|
@ -107,7 +107,7 @@ in
|
||||||
ct state established,related accept
|
ct state established,related accept
|
||||||
oif "lo" accept
|
oif "lo" accept
|
||||||
oif { "wg0", "wg2", "tun0" } accept
|
oif { "wg0", "wg2", "tun0" } accept
|
||||||
ip daddr ${xrayServer} accept
|
ip daddr $XRAY_SERVER accept
|
||||||
udp dport 67 accept # DHCP client
|
udp dport 67 accept # DHCP client
|
||||||
udp dport 547 accept # DHCPv6
|
udp dport 547 accept # DHCPv6
|
||||||
udp dport { 53, 5353 } ip daddr 127.0.0.0/8 accept
|
udp dport { 53, 5353 } ip daddr 127.0.0.0/8 accept
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# Stub. Real values kept locally via:
|
|
||||||
# git update-index --skip-worktree modules/private/xray-routes.nix
|
|
||||||
{
|
|
||||||
xrayServer = "0.0.0.0";
|
|
||||||
routeExcludeAddress = [ ];
|
|
||||||
}
|
|
||||||
|
|
@ -2,10 +2,40 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
private = import ./private/xray-routes.nix;
|
# Pin Firefox DevEdition to nixpkgs 2026-07-05: 152.0b8 is cached there,
|
||||||
xrayServer = private.xrayServer;
|
# whereas the current nixpkgs ships the same version uncached with a broken
|
||||||
|
# source build (webrender COUNT identifier error). Drop this pin once a
|
||||||
|
# newer, cached devedition lands upstream.
|
||||||
|
pkgsFirefox = import (builtins.fetchTree {
|
||||||
|
type = "github";
|
||||||
|
owner = "NixOS";
|
||||||
|
repo = "nixpkgs";
|
||||||
|
rev = "d407951447dcd00442e97087bf374aad70c04cea";
|
||||||
|
}) { inherit (pkgs.stdenv.hostPlatform) system; config.allowUnfree = true; };
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
# Config is sops-encrypted; decrypted to /run/secrets at activation and
|
||||||
|
# handed to the DynamicUser service via LoadCredential (stays root-only 0400).
|
||||||
|
sops.secrets."xray-config.json" = {
|
||||||
|
sopsFile = "/etc/nixos/secrets/xray-config.json";
|
||||||
|
format = "json";
|
||||||
|
key = "";
|
||||||
|
restartUnits = [ "xray.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Private endpoints/routes, spliced into the sing-box config at runtime
|
||||||
|
# via _secret (values never enter the nix store or the repo in plaintext).
|
||||||
|
sops.secrets."xray-endpoint" = {
|
||||||
|
sopsFile = "/etc/nixos/secrets/network.yaml";
|
||||||
|
key = "xray-endpoint";
|
||||||
|
restartUnits = [ "sing-box.service" ];
|
||||||
|
};
|
||||||
|
sops.secrets."route-exclude" = {
|
||||||
|
sopsFile = "/etc/nixos/secrets/network.yaml";
|
||||||
|
key = "route-exclude";
|
||||||
|
restartUnits = [ "sing-box.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
# Xray — VLESS+Reality with post-quantum encryption
|
# Xray — VLESS+Reality with post-quantum encryption
|
||||||
systemd.services.xray = {
|
systemd.services.xray = {
|
||||||
description = "Xray Proxy";
|
description = "Xray Proxy";
|
||||||
|
|
@ -13,13 +43,13 @@ in
|
||||||
wants = [ "network-online.target" ];
|
wants = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${pkgs.xray}/bin/xray run -config /etc/xray/config.json";
|
ExecStart = "${pkgs.xray}/bin/xray run -config %d/config.json";
|
||||||
|
LoadCredential = [ "config.json:${config.sops.secrets."xray-config.json".path}" ];
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = 5;
|
RestartSec = 5;
|
||||||
DynamicUser = true;
|
DynamicUser = true;
|
||||||
NoNewPrivileges = true;
|
NoNewPrivileges = true;
|
||||||
ProtectSystem = "strict";
|
ProtectSystem = "strict";
|
||||||
ReadOnlyPaths = [ "/etc/xray" ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -36,7 +66,11 @@ in
|
||||||
address = [ "198.18.0.1/15" "fdfe:dcba:9876::1/126" ];
|
address = [ "198.18.0.1/15" "fdfe:dcba:9876::1/126" ];
|
||||||
auto_route = true;
|
auto_route = true;
|
||||||
strict_route = true;
|
strict_route = true;
|
||||||
route_exclude_address = [ "${xrayServer}/32" ] ++ private.routeExcludeAddress;
|
# File contains a JSON array (xray server + wg endpoints/nets + overlays)
|
||||||
|
route_exclude_address = {
|
||||||
|
_secret = config.sops.secrets."route-exclude".path;
|
||||||
|
quote = false;
|
||||||
|
};
|
||||||
stack = "gvisor";
|
stack = "gvisor";
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
|
@ -83,7 +117,7 @@ in
|
||||||
{
|
{
|
||||||
action = "route";
|
action = "route";
|
||||||
outbound = "direct";
|
outbound = "direct";
|
||||||
ip_cidr = [ "${xrayServer}/32" ];
|
ip_cidr = [ { _secret = config.sops.secrets."xray-endpoint".path; } ];
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
action = "route";
|
action = "route";
|
||||||
|
|
@ -109,7 +143,7 @@ in
|
||||||
# Firefox dev edition
|
# Firefox dev edition
|
||||||
programs.firefox = {
|
programs.firefox = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.firefox-devedition;
|
package = pkgsFirefox.firefox-devedition;
|
||||||
policies = {
|
policies = {
|
||||||
# Estonian ID: load OpenSC PKCS#11 for TLS client-cert auth,
|
# Estonian ID: load OpenSC PKCS#11 for TLS client-cert auth,
|
||||||
# and force-install the Web eID extension (talks to web-eid-app host).
|
# and force-install the Web eID extension (talks to web-eid-app host).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue