From d35cb151534861162478079877818e71e6838ac1 Mon Sep 17 00:00:00 2001 From: Henri Menke Date: Wed, 24 Jun 2020 10:36:36 +1200 Subject: [PATCH 1/3] nixos/shadowsocks: support plugins --- .../services/networking/shadowsocks.nix | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/nixos/modules/services/networking/shadowsocks.nix b/nixos/modules/services/networking/shadowsocks.nix index af12db590f0..4fd988297f6 100644 --- a/nixos/modules/services/networking/shadowsocks.nix +++ b/nixos/modules/services/networking/shadowsocks.nix @@ -11,8 +11,13 @@ let method = cfg.encryptionMethod; mode = cfg.mode; user = "nobody"; - fast_open = true; - } // optionalAttrs (cfg.password != null) { password = cfg.password; }; + fast_open = cfg.fastOpen; + } // optionalAttrs (cfg.plugin != null) { + plugin = cfg.plugin; + plugin_opts = cfg.pluginOpts; + } // optionalAttrs (cfg.password != null) { + password = cfg.password; + }; configFile = pkgs.writeText "shadowsocks.json" (builtins.toJSON opts); @@ -74,6 +79,14 @@ in ''; }; + fastOpen = mkOption { + type = types.bool; + default = true; + description = '' + use TCP fast-open + ''; + }; + encryptionMethod = mkOption { type = types.str; default = "chacha20-ietf-poly1305"; @@ -82,6 +95,23 @@ in ''; }; + plugin = mkOption { + type = types.nullOr types.str; + default = null; + example = "\${pkgs.shadowsocks-v2ray-plugin}/bin/v2ray-plugin"; + description = '' + SIP003 plugin for shadowsocks + ''; + }; + + pluginOpts = mkOption { + type = types.str; + default = ""; + example = "server;host=example.com"; + description = '' + Options to pass to the plugin if one was specified + ''; + }; }; }; @@ -99,7 +129,7 @@ in description = "shadowsocks-libev Daemon"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.shadowsocks-libev ] ++ optional (cfg.passwordFile != null) pkgs.jq; + path = [ pkgs.shadowsocks-libev cfg.plugin ] ++ optional (cfg.passwordFile != null) pkgs.jq; serviceConfig.PrivateTmp = true; script = '' ${optionalString (cfg.passwordFile != null) '' From ef6c9fbd6b18dbea1ea6548ac8cb1aa625420563 Mon Sep 17 00:00:00 2001 From: Henri Menke Date: Wed, 26 Aug 2020 13:38:16 +1200 Subject: [PATCH 2/3] maintainers: add hmenke --- maintainers/maintainer-list.nix | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index fe06e428ff0..c6d59b621d0 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -9468,4 +9468,14 @@ github = "yevhenshymotiuk"; githubId = 44244245; }; + hmenke = { + name = "Henri Menke"; + email = "henri@henrimenke.de"; + github = "hmenke"; + githubId = 1903556; + keys = [{ + longkeyid = "rsa4096/0xD65C9AFB4C224DA3"; + fingerprint = "F1C5 760E 45B9 9A44 72E9 6BFB D65C 9AFB 4C22 4DA3"; + }]; + }; } From 27f281bc50a81302a2c9dc8885fafa1ecd87f0e9 Mon Sep 17 00:00:00 2001 From: Henri Menke Date: Wed, 26 Aug 2020 13:39:43 +1200 Subject: [PATCH 3/3] nixos/shadowsocks: add test --- nixos/tests/all-tests.nix | 1 + nixos/tests/shadowsocks.nix | 80 +++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 nixos/tests/shadowsocks.nix diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 7b8e1b2b56d..fe9b83fbe10 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -307,6 +307,7 @@ in sanoid = handleTest ./sanoid.nix {}; sddm = handleTest ./sddm.nix {}; service-runner = handleTest ./service-runner.nix {}; + shadowsocks = handleTest ./shadowsocks.nix {}; shattered-pixel-dungeon = handleTest ./shattered-pixel-dungeon.nix {}; shiori = handleTest ./shiori.nix {}; signal-desktop = handleTest ./signal-desktop.nix {}; diff --git a/nixos/tests/shadowsocks.nix b/nixos/tests/shadowsocks.nix new file mode 100644 index 00000000000..6cb288f7611 --- /dev/null +++ b/nixos/tests/shadowsocks.nix @@ -0,0 +1,80 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: { + name = "shadowsocks"; + meta = { + maintainers = with lib.maintainers; [ hmenke ]; + }; + + nodes = { + server = { + boot.kernel.sysctl."net.ipv4.ip_forward" = "1"; + networking.useDHCP = false; + networking.interfaces.eth1.ipv4.addresses = [ + { address = "192.168.0.1"; prefixLength = 24; } + ]; + networking.firewall.rejectPackets = true; + networking.firewall.allowedTCPPorts = [ 8488 ]; + networking.firewall.allowedUDPPorts = [ 8488 ]; + services.shadowsocks = { + enable = true; + encryptionMethod = "chacha20-ietf-poly1305"; + password = "pa$$w0rd"; + localAddress = [ "0.0.0.0" ]; + port = 8488; + fastOpen = false; + mode = "tcp_and_udp"; + plugin = "${pkgs.shadowsocks-v2ray-plugin}/bin/v2ray-plugin"; + pluginOpts = "server;host=nixos.org"; + }; + services.nginx = { + enable = true; + virtualHosts.server = { + locations."/".root = pkgs.writeTextDir "index.html" "It works!"; + }; + }; + }; + + client = { + networking.useDHCP = false; + networking.interfaces.eth1.ipv4.addresses = [ + { address = "192.168.0.2"; prefixLength = 24; } + ]; + systemd.services.shadowsocks-client = { + description = "connect to shadowsocks"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = with pkgs; [ + shadowsocks-libev + shadowsocks-v2ray-plugin + ]; + script = '' + exec ss-local \ + -s 192.168.0.1 \ + -p 8488 \ + -l 1080 \ + -k 'pa$$w0rd' \ + -m chacha20-ietf-poly1305 \ + -a nobody \ + --plugin "${pkgs.shadowsocks-v2ray-plugin}/bin/v2ray-plugin" \ + --plugin-opts "host=nixos.org" + ''; + }; + }; + }; + + testScript = '' + start_all() + + server.wait_for_unit("shadowsocks-libev.service") + client.wait_for_unit("shadowsocks-client.service") + + client.fail( + "${pkgs.curl}/bin/curl 192.168.0.1:80" + ) + + msg = client.succeed( + "${pkgs.curl}/bin/curl --socks5 localhost:1080 192.168.0.1:80" + ) + assert msg == "It works!", "Could not connect through shadowsocks" + ''; + } +)