{ config, inputs, lib, ... }: with lib; let cfg = config.nixfiles.modules.sing-box; in { options.nixfiles.modules.sing-box = { enable = mkEnableOption ""; }; config = mkIf cfg.enable { assertions = [ { assertion = cfg.enable -> !config.nixfiles.modules.nginx.enable; message = "VLESS requires binding to 443"; } ]; secrets = { sing-box-shadowsocks-password.file = "${inputs.self}/secrets/sing-box-shadowsocks-password"; sing-box-shadowsocks-users.file = "${inputs.self}/secrets/sing-box-shadowsocks-users"; sing-box-vless-tls.file = "${inputs.self}/secrets/sing-box-vless-tls"; sing-box-vless-users.file = "${inputs.self}/secrets/sing-box-vless-users"; }; services.sing-box = { enable = true; settings = { log = { level = "warn"; timestamp = false; }; inbounds = [ { tag = "shadowsocks"; type = "shadowsocks"; listen = "::"; listen_port = 21515; method = "2022-blake3-aes-128-gcm"; password = { _secret = config.secrets.sing-box-shadowsocks-password.path; quote = true; }; users = { _secret = config.secrets.sing-box-shadowsocks-users.path; quote = false; }; multiplex.enabled = true; } { tag = "vless"; type = "vless"; listen = "::"; listen_port = 443; users = { _secret = config.secrets.sing-box-vless-users.path; quote = false; }; tls = { _secret = config.secrets.sing-box-vless-tls.path; quote = false; }; } ]; outbounds = [ { type = "direct"; } ]; }; }; networking.firewall.allowedTCPPorts = map ( a: a.listen_port ) config.services.sing-box.settings.inbounds; }; }