mirror of
https://github.com/CHN-beta/nixos.git
synced 2026-01-12 04:39:23 +08:00
Merge branch 'main' into next
This commit is contained in:
19
flake.nix
19
flake.nix
@@ -206,6 +206,8 @@
|
||||
xrayClient =
|
||||
{
|
||||
enable = true;
|
||||
serverAddress = "74.211.99.69";
|
||||
serverName = "vps6.xserver.chn.moe";
|
||||
dns =
|
||||
{
|
||||
extraInterfaces = [ "docker0" ];
|
||||
@@ -237,6 +239,7 @@
|
||||
};
|
||||
};
|
||||
nix-serve.enable = true;
|
||||
smartd.enable = true;
|
||||
};
|
||||
bugs =
|
||||
[
|
||||
@@ -306,7 +309,23 @@
|
||||
snapper = { enable = true; configs.persistent = "/nix/persistent"; };
|
||||
sops = { enable = true; keyPathPrefix = "/nix/persistent"; };
|
||||
sshd.enable = true;
|
||||
xrayServer = { enable = true; serverName = "vps6.xserver.chn.moe"; };
|
||||
frpServer = { enable = true; serverName = "frp.chn.moe"; };
|
||||
nginx =
|
||||
{
|
||||
transparentProxy =
|
||||
{
|
||||
enable = true;
|
||||
externalIp = "74.211.99.69";
|
||||
map =
|
||||
{
|
||||
default = "443";
|
||||
"ng01.mirism.one" = "7411";
|
||||
"beta.mirism.one" = "9114";
|
||||
};
|
||||
proxyPorts = [ 443 7411 9114 ];
|
||||
};
|
||||
};
|
||||
};
|
||||
boot =
|
||||
{
|
||||
|
||||
@@ -41,12 +41,19 @@ inputs:
|
||||
xrayClient =
|
||||
{
|
||||
enable = mkOption { type = types.bool; default = false; };
|
||||
serverAddress = mkOption { type = types.nonEmptyStr; };
|
||||
serverName = mkOption { type = types.nonEmptyStr; };
|
||||
dns = mkOption { type = types.submodule { options =
|
||||
{
|
||||
hosts = mkOption { type = types.attrsOf types.nonEmptyStr; default = {}; };
|
||||
extraInterfaces = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
|
||||
}; }; };
|
||||
};
|
||||
xrayServer =
|
||||
{
|
||||
enable = mkOption { type = types.bool; default = false; };
|
||||
serverName = mkOption { type = types.nonEmptyStr; };
|
||||
};
|
||||
firewall.trustedInterfaces = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
|
||||
acme =
|
||||
{
|
||||
@@ -78,13 +85,24 @@ inputs:
|
||||
serverName = mkOption { type = types.nonEmptyStr; };
|
||||
};
|
||||
nix-serve.enable = mkOption { type = types.bool; default = false; };
|
||||
smartd.enable = mkOption { type = types.bool; default = false; };
|
||||
nginx =
|
||||
{
|
||||
transparentProxy =
|
||||
{
|
||||
enable = mkOption { type = types.bool; default = false; };
|
||||
externalIp = mkOption { type = types.nonEmptyStr; };
|
||||
map = mkOption { type = types.attrsOf types.nonEmptyStr; };
|
||||
proxyPorts = mkOption { type = types.listOf types.ints.unsigned; };
|
||||
};
|
||||
};
|
||||
};
|
||||
config =
|
||||
let
|
||||
inherit (inputs.lib) mkMerge mkIf;
|
||||
inherit (inputs.localLib) stripeTabs attrsToList;
|
||||
inherit (inputs.config.nixos) services;
|
||||
inherit (builtins) map listToAttrs;
|
||||
inherit (builtins) map listToAttrs concatStringsSep toString elemAt genList length;
|
||||
in mkMerge
|
||||
[
|
||||
(
|
||||
@@ -268,6 +286,7 @@ inputs:
|
||||
settings =
|
||||
{
|
||||
no-poll = true;
|
||||
log-queries = true;
|
||||
server = [ "127.0.0.1#10853" ];
|
||||
interface = services.xrayClient.dns.extraInterfaces ++ [ "lo" ];
|
||||
bind-dynamic = true;
|
||||
@@ -292,13 +311,13 @@ inputs:
|
||||
group = "v2ray";
|
||||
content = builtins.toJSON
|
||||
{
|
||||
log.loglevel = "warning";
|
||||
log.loglevel = "info";
|
||||
dns =
|
||||
{
|
||||
servers =
|
||||
[
|
||||
{ address = "223.5.5.5"; domains = [ "geosite:geolocation-cn" ]; port = 53; skipFallback = true; }
|
||||
{ address = "8.8.8.8"; domains = [ "geosite:geolocation-!cn" ]; port = 53; skipFallback = true; }
|
||||
{ address = "8.8.8.8"; domains = [ "geosite:geolocation-!cn" ]; port = 53; skipFallback = true; }
|
||||
{ address = "223.5.5.5"; expectIPs = [ "geoip:cn" ]; }
|
||||
{ address = "8.8.8.8"; }
|
||||
];
|
||||
@@ -319,7 +338,7 @@ inputs:
|
||||
protocol = "dokodemo-door";
|
||||
settings = { network = "tcp,udp"; followRedirect = true; };
|
||||
streamSettings.sockopt.tproxy = "tproxy";
|
||||
sniffing = { enabled = true; destOverride = [ "http" "tls" ]; routeOnly = true; };
|
||||
sniffing = { enabled = true; destOverride = [ "http" "tls" "quic" ]; routeOnly = true; };
|
||||
tag = "common-in";
|
||||
}
|
||||
{
|
||||
@@ -337,7 +356,7 @@ inputs:
|
||||
protocol = "vless";
|
||||
settings.vnext =
|
||||
[{
|
||||
address = inputs.config.sops.placeholder."xray-client/server";
|
||||
address = services.xrayClient.serverAddress;
|
||||
port = 443;
|
||||
users =
|
||||
[{
|
||||
@@ -352,7 +371,7 @@ inputs:
|
||||
security = "tls";
|
||||
tlssettings =
|
||||
{
|
||||
serverName = inputs.config.sops.placeholder."xray-client/serverName";
|
||||
serverName = services.xrayClient.serverName;
|
||||
allowInsecure = false;
|
||||
fingerprint = "firefox";
|
||||
};
|
||||
@@ -369,7 +388,7 @@ inputs:
|
||||
];
|
||||
routing =
|
||||
{
|
||||
domainStrategy = "IPIfNonMatch";
|
||||
domainStrategy = "AsIs";
|
||||
rules = builtins.map (rule: rule // { type = "field"; })
|
||||
[
|
||||
{ inboundTag = [ "dns-in" ]; outboundTag = "dns-out"; }
|
||||
@@ -387,8 +406,7 @@ inputs:
|
||||
};
|
||||
};
|
||||
};
|
||||
secrets = listToAttrs
|
||||
(map (name: { name = "xray-client/${name}"; value = {}; }) [ "server" "serverName" "uuid" ]);
|
||||
secrets."xray-client/uuid" = {};
|
||||
};
|
||||
systemd.services.xray =
|
||||
{
|
||||
@@ -408,6 +426,102 @@ inputs:
|
||||
environment.etc."resolv.conf".text = "nameserver 127.0.0.1";
|
||||
}
|
||||
)
|
||||
(
|
||||
mkIf services.xrayServer.enable
|
||||
{
|
||||
services =
|
||||
{
|
||||
xray = { enable = true; settingsFile = inputs.config.sops.templates."xray-server.json".path; };
|
||||
nginx.virtualHosts.xserver =
|
||||
{
|
||||
serverName = services.xrayServer.serverName;
|
||||
default = true;
|
||||
listen = [{ addr = "127.0.0.1"; port = 7233; }];
|
||||
locations."/".return = "400";
|
||||
};
|
||||
};
|
||||
sops = let userList = genList (n: n) 3; in
|
||||
{
|
||||
templates."xray-server.json" =
|
||||
{
|
||||
mode = "0440";
|
||||
owner = "v2ray";
|
||||
group = "v2ray";
|
||||
content = builtins.toJSON
|
||||
{
|
||||
log.loglevel = "warning";
|
||||
inbounds =
|
||||
[
|
||||
{
|
||||
port = 4726;
|
||||
listen = "127.0.0.1";
|
||||
protocol = "vless";
|
||||
settings =
|
||||
{
|
||||
clients = map
|
||||
(n:
|
||||
{
|
||||
id = inputs.config.sops.placeholder."xray-server/clients/user${toString n}";
|
||||
flow = "xtls-rprx-vision";
|
||||
email = "${toString n}@xray.chn.moe";
|
||||
})
|
||||
userList;
|
||||
decryption = "none";
|
||||
fallbacks = [{ dest = "127.0.0.1:7233"; }];
|
||||
};
|
||||
streamSettings =
|
||||
{
|
||||
network = "tcp";
|
||||
security = "tls";
|
||||
tlsSettings =
|
||||
{
|
||||
alpn = [ "http/1.1" "h2" ];
|
||||
certificates =
|
||||
let
|
||||
cert = inputs.config.security.acme.certs.${services.xrayServer.serverName}.directory;
|
||||
in
|
||||
[{
|
||||
certificateFile = "${cert}/full.pem";
|
||||
keyFile = "${cert}/key.pem";
|
||||
}];
|
||||
};
|
||||
};
|
||||
tag = "in";
|
||||
}
|
||||
];
|
||||
outbounds = [{ protocol = "freedom"; tag = "freedom"; }];
|
||||
};
|
||||
};
|
||||
secrets = listToAttrs (map (n: { name = "xray-server/clients/user${toString n}"; value = {}; }) userList);
|
||||
};
|
||||
systemd.services.xray =
|
||||
{
|
||||
serviceConfig =
|
||||
{
|
||||
DynamicUser = inputs.lib.mkForce false;
|
||||
User = "v2ray";
|
||||
Group = "v2ray";
|
||||
CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
|
||||
AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
|
||||
LimitNPROC = 10000;
|
||||
LimitNOFILE = 1000000;
|
||||
};
|
||||
restartTriggers = [ inputs.config.sops.templates."xray-server.json".file ];
|
||||
};
|
||||
users = { users.v2ray = { isSystemUser = true; group = "v2ray"; }; groups.v2ray = {}; };
|
||||
nixos.services =
|
||||
{
|
||||
acme = { enable = true; certs = [ services.xrayServer.serverName ]; };
|
||||
nginx.transparentProxy =
|
||||
{
|
||||
enable = true;
|
||||
map."${services.xrayServer.serverName}" = "4726";
|
||||
proxyPorts = [ 4726 ];
|
||||
};
|
||||
};
|
||||
security.acme.certs.${services.xrayServer.serverName}.group = "v2ray";
|
||||
}
|
||||
)
|
||||
{ networking.firewall.trustedInterfaces = services.firewall.trustedInterfaces; }
|
||||
(
|
||||
mkIf services.acme.enable
|
||||
@@ -558,5 +672,96 @@ inputs:
|
||||
sops.secrets."store/signingKey" = {};
|
||||
}
|
||||
)
|
||||
(mkIf services.smartd.enable { services.smartd.enable = true; })
|
||||
(
|
||||
mkIf services.nginx.transparentProxy.enable
|
||||
{
|
||||
services.nginx =
|
||||
{
|
||||
enable = true;
|
||||
streamConfig = stripeTabs
|
||||
''
|
||||
map $ssl_preread_server_name $backend
|
||||
{
|
||||
${concatStringsSep "\n" (map
|
||||
(x: '' "${x.name}" 127.0.0.1:${x.value};'')
|
||||
(attrsToList services.nginx.transparentProxy.map))}
|
||||
}
|
||||
server
|
||||
{
|
||||
listen ${services.nginx.transparentProxy.externalIp}:443;
|
||||
ssl_preread on;
|
||||
proxy_bind $remote_addr transparent;
|
||||
proxy_pass $backend;
|
||||
proxy_connect_timeout 1s;
|
||||
proxy_socket_keepalive on;
|
||||
proxy_buffer_size 128k;
|
||||
}
|
||||
'';
|
||||
};
|
||||
systemd.services =
|
||||
{
|
||||
nginx-proxy =
|
||||
let
|
||||
ipset = "${inputs.pkgs.ipset}/bin/ipset";
|
||||
iptables = "${inputs.pkgs.iptables}/bin/iptables";
|
||||
ip = "${inputs.pkgs.iproute}/bin/ip";
|
||||
start = inputs.pkgs.writeShellScript "nginx-proxy.start"
|
||||
(
|
||||
(
|
||||
stripeTabs
|
||||
''
|
||||
${ipset} create nginx_proxy_port bitmap:port range 0-65535
|
||||
${iptables} -t mangle -N nginx_proxy_mark
|
||||
${iptables} -t mangle -A OUTPUT -j nginx_proxy_mark
|
||||
${iptables} -t mangle -A nginx_proxy_mark -s 127.0.0.1 -p tcp \
|
||||
-m set --match-set nginx_proxy_port src -j MARK --set-mark 2/2
|
||||
${iptables} -t mangle -N nginx_proxy
|
||||
${iptables} -t mangle -A PREROUTING -j nginx_proxy
|
||||
${iptables} -t mangle -A nginx_proxy -s 127.0.0.1 -p tcp \
|
||||
-m set --match-set nginx_proxy_port src -j MARK --set-mark 2/2
|
||||
${ip} rule add fwmark 2/2 table 200
|
||||
${ip} route add local 0.0.0.0/0 dev lo table 200
|
||||
''
|
||||
)
|
||||
+ concatStringsSep "\n" (map
|
||||
(port: ''${ipset} add nginx_proxy_port ${toString port}'')
|
||||
services.nginx.transparentProxy.proxyPorts)
|
||||
);
|
||||
stop = inputs.pkgs.writeShellScript "nginx-proxy.stop" (stripeTabs
|
||||
''
|
||||
${iptables} -t mangle -F nginx_proxy_mark
|
||||
${iptables} -t mangle -D OUTPUT -j nginx_proxy_mark
|
||||
${iptables} -t mangle -X nginx_proxy_mark
|
||||
${iptables} -t mangle -F nginx_proxy
|
||||
${iptables} -t mangle -D PREROUTING -j nginx_proxy
|
||||
${iptables} -t mangle -X nginx_proxy
|
||||
${ip} rule del fwmark 2/2 table 200
|
||||
${ip} route del local 0.0.0.0/0 dev lo table 200
|
||||
${ipset} destroy nginx_proxy_port
|
||||
'');
|
||||
in
|
||||
{
|
||||
description = "nginx transparent proxy";
|
||||
after = [ "network.target" ];
|
||||
serviceConfig =
|
||||
{
|
||||
Type = "simple";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = start;
|
||||
ExecStop = stop;
|
||||
};
|
||||
wants = [ "network.target" ];
|
||||
wantedBy= [ "multi-user.target" ];
|
||||
};
|
||||
nginx.serviceConfig =
|
||||
{
|
||||
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
|
||||
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
|
||||
};
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 443 ];
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
xray-client:
|
||||
server: ENC[AES256_GCM,data:VeaWBXupVGmYjDdchQ==,iv:SGw9ramdMIQPzjcQgyBKr44SFEOYWhIpcLrncm/UMIo=,tag:ecdUKPvV39/LzJbFmCtw6Q==,type:str]
|
||||
uuid: ENC[AES256_GCM,data:DlObWxoYN7vzvTdSkoWKf5i6uEkW1U9a6GsO7XHH3f0CEu+p,iv:pGL9GRxM1rAvs1ySZaT32w+rUGXyzO+lWLxc0yUkZYQ=,tag:QMxUopHC2+rdlj8vD/PAvg==,type:str]
|
||||
serverName: ENC[AES256_GCM,data:2kXUR/DWn9Sd97YMqsjH+k6sKT8klw==,iv:6SbPM5cIoKfCqPd4CnFnXSRTPjsozP/Fpd0BgAA0dBk=,tag:tSJf1XED45xkkCxkoq81pw==,type:str]
|
||||
uuid: ENC[AES256_GCM,data:XU7/GZ8cJmDwNsrQfoFHrquZT5QkjvTPZfnghX3BLyvPLlrX,iv:e/BQkZ5ydWD4P/qT9OUloB8/cXImfkG3YZnuIeNLoTc=,tag:EW3ZBzGnyIrUfcMeJqm4aA==,type:str]
|
||||
acme:
|
||||
cloudflare.ini: ENC[AES256_GCM,data:hPNpTclYvRbcbFO6aR9PNyHt3kDUmjeUgg4NPsr+c/yxKPundoiziNYBRfF7/axlw8Hu32jf/cDlcWaEmqCBQJY=,iv:bdGCD/a6AnGQhiFNyZ+fD1f/rILsEcPXC2qRDsAO4n8=,tag:MLZak9uSqsg/0Ldx2Wgb6A==,type:str]
|
||||
frp:
|
||||
@@ -32,8 +30,8 @@ sops:
|
||||
OUlxNjdQaXdXMkZ6bnV1ek4yZ2dpbkEKpKGOAxo5Eef2jtGrg4iSzmGCeg+vTgvu
|
||||
+K8b+O19MIkGMDBm6UbYUPtc/7eqoEZRiTUzNMTmfkLVS4ul5zou9A==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2023-08-07T13:42:57Z"
|
||||
mac: ENC[AES256_GCM,data:r9wDr9ay7bBXJYFE2rsp5yy+M560ZY//RjiRj0vQ8JDZrNk/3kTBDEPXMYwfYhfmO9kqOjcVLUlpJ3orua/FzJUpZsZiopXudRzhbeIanUIoIunsRuxaCEwKAfO12TaQlhEXI7IWC96iXinJfLiM3JvzRC6OF5alokl7fR5npWM=,iv:PP5bG8RgajGkVoJu75Vl5YKfjxjIzDIYVBr7NaghiUw=,tag:JAuyDgD//TDjaf2IZZyobQ==,type:str]
|
||||
lastmodified: "2023-08-10T12:20:11Z"
|
||||
mac: ENC[AES256_GCM,data:wqoImAQTe864KxGtxyhGzJ2iD75NWsdVI4vJMD2G1qAzbLpg6Wh4cmv1F5qdBN3F6dJBKGZYg8k1blqCb6dTl1Q8ZmB6/EUFHNPoq4sc97yGlhar7tEHbgcOq+AXKJqe6bAu65oLOLokiVDRWUI+tAxW4T/wLowvR1CykzfyWCI=,iv:oEMiUd2kFsHxVAIPpqHmFQw4FVTmQC4zBOjt2GuvXNI=,tag:B1cf+QWlhhca+cmrQkAjOQ==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.7.3
|
||||
|
||||
@@ -2,6 +2,11 @@ acme:
|
||||
cloudflare.ini: ENC[AES256_GCM,data:X1v1QuOZemIuxldd1bzIvbUsq+8HMGLh91zUB+fnrxaW40z0OQh9L1rF/0Nj3gmUmgT4KEV7nkHFYYpZBp4/Kyc=,iv:fQmbhx9wV3l+DVPaBrAyJbTCsS3q3s5F9Go1F7pZ2pQ=,tag:P4vuruX460YSOUsx6zGHXQ==,type:str]
|
||||
frp:
|
||||
token: ENC[AES256_GCM,data:T8b1ku4HNCNSJ+33QgIt1GILFA4wTu3Qd0rDqHPVgdqsGo0R90k0u8z+dElSO7q9PapTqUbZ,iv:hwnMu6JxfYLgw4TyhujX5dI2IAytgZh+Bexhgta6ATQ=,tag:lqgwvXlS/jGPxasmk5Vh3w==,type:str]
|
||||
xray-server:
|
||||
clients:
|
||||
user0: ENC[AES256_GCM,data:rJ00sfe/oJSry6Ixn4Bn+p41syqsOrdWv6fRGVCwPvn/unMY,iv:htTvFMvhIRkORA/gIU8J7CgA+tOncYQWh7sUh+F6XDs=,tag:VrSJBD7ti9WtSLHoWjMClw==,type:str]
|
||||
user1: ENC[AES256_GCM,data:S3IHO9FcVHTJOsRxjSohM9MgnrEwLdDpFU+efLkQaXT2jNJG,iv:KOesvPzjDfm1EDLFiegbk0wgjp7di5mUwUuuY2hwvOQ=,tag:ZsYyUyyEhO5S3weCw/gPMw==,type:str]
|
||||
user2: ENC[AES256_GCM,data:e7ITe2ZouKr8dXT7SYATyzbzHaVeu6AKt1OcQKk3U0nsQgoa,iv:UbOOuojy6OAFEH8lGhKe5Hs+2K6FX5MZ8Br9AB007gs=,tag:5XeB4YngzTcHZvCpXe/ZXA==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
@@ -26,8 +31,8 @@ sops:
|
||||
ZXFTU3ZCaW1pTVh0RUJzdDdGdHlPYTgK2mlgcX2kEc8+2UDdBnhUm6IIuh8V6agW
|
||||
ooxH9OEPXUVI/4JcDo4v8ZUhAyU1ehLH0Ef7PJCChOZe2KZmWSNbhA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2023-08-07T13:16:17Z"
|
||||
mac: ENC[AES256_GCM,data:7e8voN3mIeqg7Rhxy1zbkvoLRx3d2t/PBnEGiBJT/xFtqrZBrQyvYOWII5gHuaEAuhQPR5wmFolJjUOm3fXzt/3GCYszLBcchr6m8yZOhO4BMR7977sfwggJ2WdoEV3uDZyAdp1H2vgbQXLhWyjmfrMoHRDPkJ6iQk4p3wKXACU=,iv:1qBcuZQ1Skr3Zw2H8PMj78EMqhxoSS9+1Fi5kzucYGI=,tag:xWPippyUMH2bbhrITQK3xg==,type:str]
|
||||
lastmodified: "2023-08-10T11:31:46Z"
|
||||
mac: ENC[AES256_GCM,data:+NY9DY6NvTfGkfrjglcGpBSTLbLSzYw0A9zMo5/sGwcFtJKgjhGTUmKAgjKeojYsXk+ha8mdBoHnpVoW253EYywdq5uSXnw6KDnNZ+UVNxbD3JP9rnx3x+ZWehG7K6NH9ANW4GQjrKW+WDFPCggoviNWRZ3hANWVvJNV3jwj88E=,iv:04RvCNPh1N3uc1pv9Zxwhppe1s5YtpgMhq4VXd+twCA=,tag:4K2RV++JdCBBPYh7InNyjg==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.7.3
|
||||
|
||||
Reference in New Issue
Block a user