blob: 69688da265357c01fc706ad7003fe23a19348016 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
{
config,
inputs,
lib,
pkgs,
...
}:
with lib; let
cfg = config.nixfiles.modules.shadowsocks;
in {
options.nixfiles.modules.shadowsocks = {
enable = mkEnableOption "Shadowsocks";
port = mkOption {
type = with types; port;
default = 8388;
description = "Port.";
};
};
config = mkIf cfg.enable {
secrets.shadowsocks-json.file = "${inputs.self}/secrets/shadowsocks-json";
services.fail2ban.jails.shadowsocks = {
enabled = true;
settings = {
filter = "shadowsocks";
inherit (cfg) port;
};
};
systemd.services.shadowsocks = {
description = "Shadowsocks";
after = ["network.target"];
wantedBy = ["multi-user.target"];
serviceConfig = {
DynamicUser = true;
RuntimeDirectory = "shadowsocks";
LoadCredential = "secret.json:${config.secrets.shadowsocks-json.path}";
ExecStartPre = let
mergeJson = let
configFile = pkgs.writeText "config.json" (generators.toJSON {} {
server = "::";
server_port = cfg.port;
# Can't really use AEAD-2022[1] just yet because it's not
# supported by some[2] clients.
#
# [1]: https://shadowsocks.org/doc/sip022.html
# [2]: https://github.com/shadowsocks/ShadowsocksX-NG/issues/1480
# [2]: https://github.com/shadowsocks/shadowsocks-windows/issues/3448
# method = "2022-blake3-chacha20-poly1305";
method = "chacha20-ietf-poly1305";
password = null; # Must be set as a secret.
users = null; # Muse be set as a secret.
fast_open = true;
acl = pkgs.writeText "block-internal-access.acl" ''
[outbound_block_list]
0.0.0.0/8
10.0.0.0/8
100.64.0.0/10
127.0.0.0/8
169.254.0.0/16
172.16.0.0/12
192.0.0.0/24
192.0.2.0/24
192.88.99.0/24
192.168.0.0/16
198.18.0.0/15
198.51.100.0/24
203.0.113.0/24
224.0.0.0/4
240.0.0.0/4
255.255.255.255/32
::1/128
::ffff:127.0.0.1/104
fc00::/7
fe80::/10
'';
});
in
pkgs.writeShellScript "meregeJson" ''
${getExe pkgs.jq} \
-s '.[0] * .[1]' \
${configFile} \
$CREDENTIALS_DIRECTORY/secret.json \
>$RUNTIME_DIRECTORY/config.json
'';
in
mergeJson;
ExecStart = "${pkgs.shadowsocks-rust}/bin/ssserver --config \${RUNTIME_DIRECTORY}/config.json";
};
};
environment.etc = mkIf config.nixfiles.modules.fail2ban.enable {
"fail2ban/filter.d/shadowsocks.conf".text = ''
[Definition]
failregex = ^.*tcp handshake failed.*\[::ffff:<ADDR>\].*$
ignoreregex =
journalmatch = _SYSTEMD_UNIT=shadowsocks.service
'';
};
networking.firewall.allowedTCPPorts = [cfg.port];
# https://github.com/shadowsocks/shadowsocks/wiki/Optimizing-Shadowsocks
boot.kernel.sysctl = {
"net.core.rmem_max" = mkOverride 100 (pow 2 26);
"net.core.wmem_max" = mkOverride 100 (pow 2 26);
"net.core.netdev_max_backlog" = pow 2 18;
"net.core.somaxconn" = pow 2 12;
"net.ipv4.tcp_syncookies" = 1;
"net.ipv4.tcp_tw_reuse" = mkOverride 100 1;
"net.ipv4.tcp_tw_recycle" = mkOverride 100 0;
"net.ipv4.tcp_fin_timeout" = mkOverride 100 30;
"net.ipv4.tcp_keepalive_time" = 60 * 20;
"net.ipv4.ip_local_port_range" = "10000 65000";
"net.ipv4.tcp_max_syn_backlog" = pow 2 13;
"net.ipv4.tcp_max_tw_buckets" = pow 2 12;
"net.ipv4.tcp_fastopen" = mkOverride 100 3;
"net.ipv4.tcp_mem" = mkOverride 100 (mkTcpMem 15 16 17);
"net.ipv4.tcp_rmem" = mkOverride 100 (mkTcpMem 12 16 26);
"net.ipv4.tcp_wmem" = mkOverride 100 (mkTcpMem 12 16 26);
"net.ipv4.tcp_mtu_probing" = 1;
"net.ipv4.tcp_congestion_control" = "hybla";
};
};
}
|