nixos-config/modules/nixos/sing-box.nix

87 lines
2.6 KiB
Nix

{
config,
pkgs,
lib,
utils,
...
}:
let
cfg = config.custom.sing-box;
settingsFormat = pkgs.formats.json { };
in
{
options = {
custom.sing-box = {
enable = lib.mkEnableOption "sing-box";
package = lib.mkPackageOption pkgs "sing-box" { };
stateDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/sing-box";
};
configFile = {
urlFile = lib.mkOption { type = lib.types.path; };
name = lib.mkOption {
type = lib.types.str;
default = "config.json";
};
hash = lib.mkOption {
type = lib.types.str;
example = "9a304bcb87d4c3f1e50f6281f25dd78635255ebde06cd4d2555729ecda43aed4";
};
};
overrideSettings = lib.mkOption {
type = lib.types.submodule {
freeformType = settingsFormat.type;
options = {
route = {
geoip.path = lib.mkOption {
type = lib.types.path;
default = "${pkgs.sing-geoip}/share/sing-box/geoip.db";
defaultText = lib.literalExpression "\${pkgs.sing-geoip}/share/sing-box/geoip.db";
description = lib.mdDoc ''
The path to the sing-geoip database.
'';
};
geosite.path = lib.mkOption {
type = lib.types.path;
default = "${pkgs.sing-geosite}/share/sing-box/geosite.db";
defaultText = lib.literalExpression "\${pkgs.sing-geosite}/share/sing-box/geosite.db";
description = lib.mdDoc ''
The path to the sing-geosite database.
'';
};
};
};
};
default = { };
};
};
};
config = lib.mkIf cfg.enable {
networking.firewall.trustedInterfaces = [ "tun0" ];
systemd.packages = [ cfg.package ];
systemd.services.sing-box =
let
configFile = cfg.stateDir + "/${cfg.configFile.name}";
in
{
preStart = ''
umask 0077
mkdir -p /etc/sing-box
if ! [ -e ${configFile} ]; then
${pkgs.curl}/bin/curl "$(${pkgs.coreutils}/bin/cat ${cfg.configFile.urlFile})" > '${configFile}'
test "${cfg.configFile.hash}" $(${pkgs.coreutils}/bin/sha256sum '${configFile}' | ${pkgs.coreutils}/bin/cut -d ' ' -f 1)
fi
${utils.genJqSecretsReplacementSnippet cfg.overrideSettings "/etc/sing-box/config.json"}
${cfg.package}/bin/sing-box merge -c '${configFile}' -c /etc/sing-box/config.json /etc/sing-box/config.json
'';
wantedBy = [ "multi-user.target" ];
};
};
}