2024-10-11 01:28:03 +03:00
{
2024-10-11 23:27:07 +03:00
lib ,
config ,
pkgs ,
. . .
2024-10-11 01:28:03 +03:00
} :
let
2024-10-11 23:27:07 +03:00
cfg = config . module . zapret ;
2024-08-28 01:31:17 +03:00
2024-10-11 23:27:07 +03:00
whitelist =
if cfg . whitelist != null then
" - - h o s t l i s t ${ pkgs . writeText " z a p r e t - w h i t e l i s t " ( lib . concatStringsSep " \n " cfg . whitelist ) } "
else
" " ;
2024-08-28 01:31:17 +03:00
2024-10-11 23:27:07 +03:00
blacklist =
if cfg . blacklist != null then
" - - h o s t l i s t - e x c l u d e ${ pkgs . writeText " z a p r e t - b l a c k l i s t " ( lib . concatStringsSep " \n " cfg . blacklist ) } "
else
" " ;
2024-09-02 13:03:19 +03:00
2024-10-11 23:27:07 +03:00
ports = if cfg . httpSupport then " 8 0 , 4 4 3 " else " 4 4 3 " ;
2024-10-11 01:28:03 +03:00
in
2024-10-11 23:27:07 +03:00
{
options . module . zapret = {
enable = lib . mkEnableOption " E n a b l e Z a p r e t D P I b y p a s s s e r v i c e . " ;
package = lib . mkPackageOption pkgs " z a p r e t " { } ;
params = lib . mkOption {
default = null ;
type = with lib . types ; listOf str ;
example = ''
[
" - - d p i - d e s y n c = f a k e , d i s o r d e r 2 "
" - - d p i - d e s y n c - t t l = 1 "
" - - d p i - d e s y n c - a u t o t t l = 2 "
] ;
'' ;
description = ''
Specify the bypass parameters for Zapret binary .
There are no universal parameters as they vary between different networks , so you'll have to find them yourself .
2024-10-11 01:28:03 +03:00
2024-10-11 23:27:07 +03:00
This can be done by running the ` blockcheck ` binary from zapret package , i . e . ` nix-shell - p zapret - - command blockcheck ` .
It'll try different params and then tell you which params are working for your network .
'' ;
} ;
whitelist = lib . mkOption {
default = null ;
type = with lib . types ; nullOr ( listOf str ) ;
example = ''
[
" y o u t u b e . c o m "
" g o o g l e v i d e o . c o m "
" y t i m g . c o m "
" y o u t u . b e "
]
'' ;
description = ''
Specify a list of domains to bypass . All other domains will be ignored .
You can specify either whitelist or blacklist , but not both .
If neither are specified , then bypass all domains .
2024-10-11 01:28:03 +03:00
2024-10-11 23:27:07 +03:00
It is recommended to specify the whitelist . This will make sure that other resources won't be affected by this service .
'' ;
} ;
blacklist = lib . mkOption {
default = null ;
type = with lib . types ; nullOr ( listOf str ) ;
example = ''
[
" e x a m p l e . c o m "
]
'' ;
description = ''
Specify a list of domains NOT to bypass . All other domains will be bypassed .
You can specify either whitelist or blacklist , but not both .
If neither are specified , then bypass all domains .
'' ;
} ;
qnum = lib . mkOption {
default = 200 ;
type = lib . types . int ;
description = ''
Routing queue number .
Only change this if you already use the default queue number somewhere else .
'' ;
} ;
configureFirewall = lib . mkOption {
default = true ;
type = lib . types . bool ;
description = ''
Whether to setup firewall routing so that system http ( s ) traffic is forwarded via this service .
Disable if you want to set it up manually .
'' ;
} ;
httpSupport = lib . mkOption {
default = true ;
type = lib . types . bool ;
description = ''
Whether to route http traffic on port 80 .
Http bypass rarely works and you might want to disable it if you don't utilise http connections .
'' ;
} ;
} ;
2024-08-28 01:31:17 +03:00
2024-10-11 23:27:07 +03:00
config = lib . mkIf cfg . enable (
lib . mkMerge [
{
assertions = [
{
assertion = cfg . whitelist == null || cfg . blacklist == null ;
message = " C a n ' t s p e c i f y b o t h w h i t e l i s t a n d b l a c k l i s t . " ;
}
] ;
2024-08-28 01:31:17 +03:00
2024-10-11 23:27:07 +03:00
systemd . services . zapret = {
description = " D P I b y p a s s s e r v i c e . " ;
wantedBy = [ " m u l t i - u s e r . t a r g e t " ] ;
after = [ " n e t w o r k . t a r g e t " ] ;
serviceConfig = {
ExecStart = " ${ cfg . package } / b i n / n f q w s - - p i d f i l e = / r u n / n f q w s . p i d ${ lib . concatStringsSep " " cfg . params } ${ whitelist } ${ blacklist } - - q n u m = ${ toString cfg . qnum } " ;
Type = " s i m p l e " ;
PIDFile = " / r u n / n f q w s . p i d " ;
Restart = " a l w a y s " ;
RuntimeMaxSec = " 1 h " ; # This service loves to crash silently or cause network slowdowns. It also restarts instantly. In my experience restarting it hourly provided the best experience.
2024-08-28 01:31:17 +03:00
2024-10-11 23:27:07 +03:00
# Hardening.
DevicePolicy = " c l o s e d " ;
KeyringMode = " p r i v a t e " ;
PrivateTmp = true ;
PrivateMounts = true ;
ProtectHome = true ;
ProtectHostname = true ;
ProtectKernelModules = true ;
ProtectKernelTunables = true ;
ProtectSystem = " s t r i c t " ;
ProtectProc = " i n v i s i b l e " ;
RemoveIPC = true ;
RestrictNamespaces = true ;
RestrictRealtime = true ;
RestrictSUIDSGID = true ;
SystemCallArchitectures = " n a t i v e " ;
} ;
} ;
}
2024-10-11 01:28:03 +03:00
2024-10-11 23:27:07 +03:00
# Route system traffic via service for specified ports.
( lib . mkIf cfg . configureFirewall {
networking . firewall . extraCommands = ''
iptables - t mangle - I POSTROUTING - p tcp - m multiport - - dports $ { ports } - m connbytes - - connbytes-dir = original - - connbytes-mode = packets - - connbytes 1 : 6 - m mark ! - - mark 0x40000000/0x40000000 - j NFQUEUE - - queue-num $ { toString cfg . qnum } - - queue-bypass
'' ;
} )
]
) ;
2024-10-11 01:28:03 +03:00
2024-10-11 23:27:07 +03:00
meta . maintainers = with lib . maintainers ; [ voronind ] ;
2024-08-28 01:31:17 +03:00
}