summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorTimo Kaufmann <timokau@zoho.com>2020-06-24 22:13:19 +0200
committerGitHub <noreply@github.com>2020-06-24 22:13:19 +0200
commit41ba255e23c09db9abfd99b58aac494621edd1bf (patch)
tree02fae9c944b13e1fde81a6f2cc0133dfcd056cfe /nixos
parentb53777c840a79580e9da73b215bac5327622bf86 (diff)
parent4593482d4e14ae12edae5102747479b738fc2263 (diff)
downloadnixpkgs-41ba255e23c09db9abfd99b58aac494621edd1bf.tar
nixpkgs-41ba255e23c09db9abfd99b58aac494621edd1bf.tar.gz
nixpkgs-41ba255e23c09db9abfd99b58aac494621edd1bf.tar.bz2
nixpkgs-41ba255e23c09db9abfd99b58aac494621edd1bf.tar.lz
nixpkgs-41ba255e23c09db9abfd99b58aac494621edd1bf.tar.xz
nixpkgs-41ba255e23c09db9abfd99b58aac494621edd1bf.tar.zst
nixpkgs-41ba255e23c09db9abfd99b58aac494621edd1bf.zip
Merge pull request #77982 from symphorien/sshl_ipv6
nixos/sslh: make it possible (and the default) to listen on ipv6, plus regression test
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/services/networking/sslh.nix18
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/sslh.nix83
3 files changed, 97 insertions, 5 deletions
diff --git a/nixos/modules/services/networking/sslh.nix b/nixos/modules/services/networking/sslh.nix
index c4fa370a5fe..0921febba66 100644
--- a/nixos/modules/services/networking/sslh.nix
+++ b/nixos/modules/services/networking/sslh.nix
@@ -15,7 +15,11 @@ let
 
     listen:
     (
-      { host: "${cfg.listenAddress}"; port: "${toString cfg.port}"; }
+      ${
+        concatMapStringsSep ",\n"
+        (addr: ''{ host: "${addr}"; port: "${toString cfg.port}"; }'')
+        cfg.listenAddresses
+      }
     );
 
     ${cfg.appendConfig}
@@ -33,6 +37,10 @@ let
   '';
 in
 {
+  imports = [
+    (mkRenamedOptionModule [ "services" "sslh" "listenAddress" ] [ "services" "sslh" "listenAddresses" ])
+  ];
+
   options = {
     services.sslh = {
       enable = mkEnableOption "sslh";
@@ -55,10 +63,10 @@ in
         description = "Will the services behind sslh (Apache, sshd and so on) see the external IP and ports as if the external world connected directly to them";
       };
 
-      listenAddress = mkOption {
-        type = types.str;
-        default = "0.0.0.0";
-        description = "Listening address or hostname.";
+      listenAddresses = mkOption {
+        type = types.coercedTo types.str singleton (types.listOf types.str);
+        default = [ "0.0.0.0" "[::]" ];
+        description = "Listening addresses or hostnames.";
       };
 
       port = mkOption {
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 7056d414e9e..125dad9f83f 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -307,6 +307,7 @@ in
   spacecookie = handleTest ./spacecookie.nix {};
   spike = handleTest ./spike.nix {};
   sonarr = handleTest ./sonarr.nix {};
+  sslh = handleTest ./sslh.nix {};
   strongswan-swanctl = handleTest ./strongswan-swanctl.nix {};
   sudo = handleTest ./sudo.nix {};
   switchTest = handleTest ./switch-test.nix {};
diff --git a/nixos/tests/sslh.nix b/nixos/tests/sslh.nix
new file mode 100644
index 00000000000..2a800aa52d0
--- /dev/null
+++ b/nixos/tests/sslh.nix
@@ -0,0 +1,83 @@
+import ./make-test-python.nix {
+  name = "sslh";
+
+  nodes = {
+    server = { pkgs, lib, ... }: {
+      networking.firewall.allowedTCPPorts = [ 443 ];
+      networking.interfaces.eth1.ipv6.addresses = [
+        {
+          address = "fe00:aa:bb:cc::2";
+          prefixLength = 64;
+        }
+      ];
+      # sslh is really slow when reverse dns does not work
+      networking.hosts = {
+        "fe00:aa:bb:cc::2" = [ "server" ];
+        "fe00:aa:bb:cc::1" = [ "client" ];
+      };
+      services.sslh = {
+        enable = true;
+        transparent = true;
+        appendConfig = ''
+          protocols:
+          (
+            { name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; probe: "builtin"; },
+            { name: "http"; host: "localhost"; port: "80"; probe: "builtin"; },
+          );
+        '';
+      };
+      services.openssh.enable = true;
+      users.users.root.openssh.authorizedKeys.keyFiles = [ ./initrd-network-ssh/id_ed25519.pub ];
+      services.nginx = {
+        enable = true;
+        virtualHosts."localhost" = {
+          addSSL = false;
+          default = true;
+          root = pkgs.runCommand "testdir" {} ''
+            mkdir "$out"
+            echo hello world > "$out/index.html"
+          '';
+        };
+      };
+    };
+    client = { ... }: {
+      networking.interfaces.eth1.ipv6.addresses = [
+        {
+          address = "fe00:aa:bb:cc::1";
+          prefixLength = 64;
+        }
+      ];
+      networking.hosts."fe00:aa:bb:cc::2" = [ "server" ];
+      environment.etc.sshKey = {
+        source = ./initrd-network-ssh/id_ed25519; # dont use this anywhere else
+        mode = "0600";
+      };
+    };
+  };
+
+  testScript = ''
+    start_all()
+
+    server.wait_for_unit("sslh.service")
+    server.wait_for_unit("nginx.service")
+    server.wait_for_unit("sshd.service")
+    server.wait_for_open_port(80)
+    server.wait_for_open_port(443)
+    server.wait_for_open_port(22)
+
+    for arg in ["-6", "-4"]:
+        client.wait_until_succeeds(f"ping {arg} -c1 server")
+
+        # check that ssh through sslh works
+        client.succeed(
+            f"ssh {arg} -p 443 -i /etc/sshKey -o StrictHostKeyChecking=accept-new server 'echo $SSH_CONNECTION > /tmp/foo{arg}'"
+        )
+
+        # check that 1/ the above ssh command had an effect 2/ transparent proxying really works
+        ip = "fe00:aa:bb:cc::1" if arg == "-6" else "192.168.1."
+        server.succeed(f"grep '{ip}' /tmp/foo{arg}")
+
+        # check that http through sslh works
+        assert client.succeed(f"curl {arg} http://server:443").strip() == "hello world"
+  '';
+}