{tsuki/dosei}: set up wstunnel
This commit is contained in:
parent
8946e517a9
commit
09d0bc29e0
|
@ -111,7 +111,7 @@
|
||||||
in [
|
in [
|
||||||
# (self: super: { pcloud = nonrecursive-unstable-pkgs.pcloud; })
|
# (self: super: { pcloud = nonrecursive-unstable-pkgs.pcloud; })
|
||||||
(self: super: {
|
(self: super: {
|
||||||
inherit (nonrecursive-unstable-pkgs) atuin;
|
inherit (nonrecursive-unstable-pkgs) atuin wstunnel;
|
||||||
})
|
})
|
||||||
(self: super: {
|
(self: super: {
|
||||||
mpv-unwrapped = super.mpv-unwrapped.override {
|
mpv-unwrapped = super.mpv-unwrapped.override {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
./services/avahi.nix
|
./services/avahi.nix
|
||||||
./services/docker.nix
|
./services/docker.nix
|
||||||
./services/jenkins.nix
|
./services/jenkins.nix
|
||||||
|
./services/wstunnel.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
../../../modules/wstunnel.nix
|
||||||
|
];
|
||||||
|
disabledModules = [
|
||||||
|
"services/networking/wstunnel.nix"
|
||||||
|
];
|
||||||
|
|
||||||
|
# NOTE: Contains
|
||||||
|
# - WSTUNNEL_HTTP_UPGRADE_PATH_PREFIX
|
||||||
|
# - WSTUNNEL_RESTRICT_HTTP_UPGRADE_PATH_PREFIX
|
||||||
|
sops.secrets."wstunnel/http-upgrade-path-prefix-envvars" = {
|
||||||
|
sopsFile = ../../../secrets/common.yaml;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.wstunnel = {
|
||||||
|
enable = true;
|
||||||
|
clients."ws-tsuki" = {
|
||||||
|
connectTo = "wss://ws.nani.wtf";
|
||||||
|
localToRemote = [
|
||||||
|
"tcp://10022:localhost:22"
|
||||||
|
];
|
||||||
|
environmentFile = config.sops.secrets."wstunnel/http-upgrade-path-prefix-envvars".path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
./services/taskserver.nix
|
./services/taskserver.nix
|
||||||
./services/vaultwarden.nix
|
./services/vaultwarden.nix
|
||||||
./services/vscode-server.nix
|
./services/vscode-server.nix
|
||||||
|
./services/wstunnel.nix
|
||||||
|
|
||||||
./services/scrapers/nhk-easy-news/default.nix
|
./services/scrapers/nhk-easy-news/default.nix
|
||||||
];
|
];
|
||||||
|
|
|
@ -51,6 +51,11 @@
|
||||||
"osuchan".servers."localhost:${s ports.osuchan}" = { };
|
"osuchan".servers."localhost:${s ports.osuchan}" = { };
|
||||||
"plex".servers."localhost:${s ports.plex}" = { };
|
"plex".servers."localhost:${s ports.plex}" = { };
|
||||||
"vaultwarden".servers."unix:${sa.vaultwarden.newSocketAddress}" = { };
|
"vaultwarden".servers."unix:${sa.vaultwarden.newSocketAddress}" = { };
|
||||||
|
"wstunnel".servers = let
|
||||||
|
inherit (config.services.wstunnel.servers."ws-tsuki".listen) host port;
|
||||||
|
in {
|
||||||
|
"${host}:${s port}" = { };
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
virtualHosts = let
|
virtualHosts = let
|
||||||
|
@ -189,6 +194,8 @@
|
||||||
# };
|
# };
|
||||||
# })
|
# })
|
||||||
|
|
||||||
|
(proxy ["ws"] "http://wstunnel" enableWebsockets)
|
||||||
|
|
||||||
(host ["h7x4-stickers"] {})
|
(host ["h7x4-stickers"] {})
|
||||||
(host ["pingu-stickers"] {})
|
(host ["pingu-stickers"] {})
|
||||||
]));
|
]));
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
../../../modules/wstunnel.nix
|
||||||
|
];
|
||||||
|
disabledModules = [
|
||||||
|
"services/networking/wstunnel.nix"
|
||||||
|
];
|
||||||
|
|
||||||
|
# NOTE: Contains
|
||||||
|
# - WSTUNNEL_HTTP_UPGRADE_PATH_PREFIX
|
||||||
|
# - WSTUNNEL_RESTRICT_HTTP_UPGRADE_PATH_PREFIX
|
||||||
|
sops.secrets."wstunnel/http-upgrade-path-prefix-envvars" = {
|
||||||
|
sopsFile = ../../../secrets/common.yaml;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.wstunnel = {
|
||||||
|
enable = true;
|
||||||
|
servers."ws-tsuki" = {
|
||||||
|
listen = {
|
||||||
|
host = "127.0.0.1";
|
||||||
|
port = 8789;
|
||||||
|
};
|
||||||
|
enableHTTPS = false;
|
||||||
|
environmentFile = config.sops.secrets."wstunnel/http-upgrade-path-prefix-envvars".path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,469 @@
|
||||||
|
{ config
|
||||||
|
, lib
|
||||||
|
, pkgs
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.wstunnel;
|
||||||
|
|
||||||
|
hostPortToString = { host, port }: "${host}:${toString port}";
|
||||||
|
|
||||||
|
hostPortSubmodule = {
|
||||||
|
options = {
|
||||||
|
host = lib.mkOption {
|
||||||
|
description = "The hostname.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
port = lib.mkOption {
|
||||||
|
description = "The port.";
|
||||||
|
type = lib.types.port;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
commonOptions = {
|
||||||
|
enable = lib.mkEnableOption "this `wstunnel` instance." // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
package = lib.mkPackageOption pkgs "wstunnel" { };
|
||||||
|
|
||||||
|
autoStart =
|
||||||
|
lib.mkEnableOption "starting this wstunnel instance automatically." // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
extraArgs = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Extra command line arguments to pass to `wstunnel`.
|
||||||
|
Attributes of the form `argName = true;` will be translated to `--argName`,
|
||||||
|
and `argName = \"value\"` to `--argName value`.
|
||||||
|
'';
|
||||||
|
type = with lib.types; attrsOf (either str bool);
|
||||||
|
default = { };
|
||||||
|
example = {
|
||||||
|
"someNewOption" = true;
|
||||||
|
"someNewOptionWithValue" = "someValue";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
loggingLevel = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Passed to --log-lvl
|
||||||
|
|
||||||
|
Control the log verbosity. i.e: TRACE, DEBUG, INFO, WARN, ERROR, OFF
|
||||||
|
For more details, checkout [EnvFilter](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#example-syntax)
|
||||||
|
'';
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
example = "INFO";
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
environmentFile = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Environment file to be passed to the systemd service.
|
||||||
|
Useful for passing secrets to the service to prevent them from being
|
||||||
|
world-readable in the Nix store.
|
||||||
|
Note however that the secrets are passed to `wstunnel` through
|
||||||
|
the command line, which makes them locally readable for all users of
|
||||||
|
the system at runtime.
|
||||||
|
'';
|
||||||
|
type = lib.types.nullOr lib.types.path;
|
||||||
|
default = null;
|
||||||
|
example = "/var/lib/secrets/wstunnelSecrets";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
serverSubmodule = { config, ... }: {
|
||||||
|
options = commonOptions // {
|
||||||
|
listen = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Address and port to listen on.
|
||||||
|
Setting the port to a value below 1024 will also give the process
|
||||||
|
the required `CAP_NET_BIND_SERVICE` capability.
|
||||||
|
'';
|
||||||
|
type = lib.types.submodule hostPortSubmodule;
|
||||||
|
default = {
|
||||||
|
host = "0.0.0.0";
|
||||||
|
port = if config.enableHTTPS then 443 else 80;
|
||||||
|
};
|
||||||
|
defaultText = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
host = "0.0.0.0";
|
||||||
|
port = if enableHTTPS then 443 else 80;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
restrictTo = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Accepted traffic will be forwarded only to this service.
|
||||||
|
'';
|
||||||
|
type = lib.types.listOf (lib.types.submodule hostPortSubmodule);
|
||||||
|
default = [ ];
|
||||||
|
example = [{
|
||||||
|
host = "127.0.0.1";
|
||||||
|
port = 51820;
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
|
enableHTTPS = lib.mkOption {
|
||||||
|
description = "Use HTTPS for the tunnel server.";
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
tlsCertificate = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
TLS certificate to use instead of the hardcoded one in case of HTTPS connections.
|
||||||
|
Use together with `tlsKey`.
|
||||||
|
'';
|
||||||
|
type = lib.types.nullOr lib.types.path;
|
||||||
|
default = null;
|
||||||
|
example = "/var/lib/secrets/cert.pem";
|
||||||
|
};
|
||||||
|
|
||||||
|
tlsKey = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
TLS key to use instead of the hardcoded on in case of HTTPS connections.
|
||||||
|
Use together with `tlsCertificate`.
|
||||||
|
'';
|
||||||
|
type = lib.types.nullOr lib.types.path;
|
||||||
|
default = null;
|
||||||
|
example = "/var/lib/secrets/key.pem";
|
||||||
|
};
|
||||||
|
|
||||||
|
useACMEHost = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Use a certificate generated by the NixOS ACME module for the given host.
|
||||||
|
Note that this will not generate a new certificate - you will need to do so with `security.acme.certs`.
|
||||||
|
'';
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
example = "example.com";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
clientSubmodule = { config, ... }: {
|
||||||
|
options = commonOptions // {
|
||||||
|
connectTo = lib.mkOption {
|
||||||
|
description = "Server address and port to connect to.";
|
||||||
|
type = lib.types.str;
|
||||||
|
example = "https://wstunnel.server.com:8443";
|
||||||
|
};
|
||||||
|
|
||||||
|
localToRemote = lib.mkOption {
|
||||||
|
description = ''Listen on local and forwards traffic from remote.'';
|
||||||
|
type = lib.types.listOf (lib.types.str);
|
||||||
|
default = [ ];
|
||||||
|
example = [
|
||||||
|
"tcp://1212:google.com:443"
|
||||||
|
"unix:///tmp/wstunnel.sock:g.com:443"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
remoteToLocal = lib.mkOption {
|
||||||
|
description = "Listen on remote and forwards traffic from local. Only tcp is supported";
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [
|
||||||
|
"tcp://1212:google.com:443"
|
||||||
|
"unix://wstunnel.sock:g.com:443"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
addNetBind = lib.mkEnableOption "Whether add CAP_NET_BIND_SERVICE to the tunnel service, this should be enabled if you want to bind port < 1024";
|
||||||
|
|
||||||
|
httpProxy = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Proxy to use to connect to the wstunnel server (`USER:PASS@HOST:PORT`).
|
||||||
|
|
||||||
|
::: {.warning}
|
||||||
|
Passwords specified here will be world-readable in the Nix store!
|
||||||
|
To pass a password to the service, point the `environmentFile` option
|
||||||
|
to a file containing `PROXY_PASSWORD=<your-password-here>` and set
|
||||||
|
this option to `<user>:$PROXY_PASSWORD@<host>:<port>`.
|
||||||
|
Note however that this will also locally leak the passwords at
|
||||||
|
runtime via e.g. /proc/<pid>/cmdline.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
soMark = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Mark network packets with the SO_MARK sockoption with the specified value.
|
||||||
|
Setting this option will also enable the required `CAP_NET_ADMIN` capability
|
||||||
|
for the systemd service.
|
||||||
|
'';
|
||||||
|
type = lib.types.nullOr lib.types.ints.unsigned;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
upgradePathPrefix = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Use a specific HTTP path prefix that will show up in the upgrade
|
||||||
|
request to the `wstunnel` server.
|
||||||
|
Useful when running `wstunnel` behind a reverse proxy.
|
||||||
|
'';
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
example = "wstunnel";
|
||||||
|
};
|
||||||
|
|
||||||
|
tlsSNI = lib.mkOption {
|
||||||
|
description = "Use this as the SNI while connecting via TLS. Useful for circumventing hostname-based firewalls.";
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
tlsVerifyCertificate = lib.mkOption {
|
||||||
|
description = "Whether to verify the TLS certificate of the server. It might be useful to set this to `false` when working with the `tlsSNI` option.";
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# The original argument name `websocketPingFrequency` is a misnomer, as the frequency is the inverse of the interval.
|
||||||
|
websocketPingInterval = lib.mkOption {
|
||||||
|
description = "Frequency at which the client will send websocket ping to the server.";
|
||||||
|
type = lib.types.nullOr lib.types.ints.unsigned;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
upgradeCredentials = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Use these credentials to authenticate during the HTTP upgrade request
|
||||||
|
(Basic authorization type, `USER:[PASS]`).
|
||||||
|
|
||||||
|
::: {.warning}
|
||||||
|
Passwords specified here will be world-readable in the Nix store!
|
||||||
|
To pass a password to the service, point the `environmentFile` option
|
||||||
|
to a file containing `HTTP_PASSWORD=<your-password-here>` and set this
|
||||||
|
option to `<user>:$HTTP_PASSWORD`.
|
||||||
|
Note however that this will also locally leak the passwords at runtime
|
||||||
|
via e.g. /proc/<pid>/cmdline.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
customHeaders = lib.mkOption {
|
||||||
|
description = "Custom HTTP headers to send during the upgrade request.";
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
default = { };
|
||||||
|
example = {
|
||||||
|
"X-Some-Header" = "some-value";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
generateServerUnit = name: serverCfg: {
|
||||||
|
name = "wstunnel-server-${name}";
|
||||||
|
value =
|
||||||
|
let
|
||||||
|
certConfig = config.security.acme.certs.${serverCfg.useACMEHost};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
description = "wstunnel server - ${name}";
|
||||||
|
requires = [ "network.target" "network-online.target" ];
|
||||||
|
after = [ "network.target" "network-online.target" ];
|
||||||
|
wantedBy = lib.optional serverCfg.autoStart "multi-user.target";
|
||||||
|
|
||||||
|
environment.RUST_LOG = serverCfg.loggingLevel;
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "exec";
|
||||||
|
EnvironmentFile =
|
||||||
|
lib.optional (serverCfg.environmentFile != null) serverCfg.environmentFile;
|
||||||
|
DynamicUser = true;
|
||||||
|
SupplementaryGroups =
|
||||||
|
lib.optional (serverCfg.useACMEHost != null) certConfig.group;
|
||||||
|
PrivateTmp = true;
|
||||||
|
AmbientCapabilities =
|
||||||
|
lib.optionals (serverCfg.listen.port < 1024) [ "CAP_NET_BIND_SERVICE" ];
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
RestrictNamespaces = "uts ipc pid user cgroup";
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 2;
|
||||||
|
RestartSteps = 20;
|
||||||
|
RestartMaxDelaySec = "5min";
|
||||||
|
};
|
||||||
|
|
||||||
|
script = with serverCfg; ''
|
||||||
|
${lib.getExe package} \
|
||||||
|
server \
|
||||||
|
${lib.cli.toGNUCommandLineShell { } (
|
||||||
|
lib.recursiveUpdate
|
||||||
|
{
|
||||||
|
restrict-to = map hostPortToString restrictTo;
|
||||||
|
# TODO: fix this upstream
|
||||||
|
# tls-certificate = if useACMEHost != null
|
||||||
|
# then "${certConfig.directory}/fullchain.pem"
|
||||||
|
# else "${tlsCertificate}";
|
||||||
|
# tls-private-key = if useACMEHost != null
|
||||||
|
# then "${certConfig.directory}/key.pem"
|
||||||
|
# else "${tlsKey}";
|
||||||
|
}
|
||||||
|
extraArgs
|
||||||
|
)} \
|
||||||
|
${lib.escapeShellArg "${if enableHTTPS then "wss" else "ws"}://${hostPortToString listen}"}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
generateClientUnit = name: clientCfg: {
|
||||||
|
name = "wstunnel-client-${name}";
|
||||||
|
value = {
|
||||||
|
description = "wstunnel client - ${name}";
|
||||||
|
requires = [ "network.target" "network-online.target" ];
|
||||||
|
after = [ "network.target" "network-online.target" ];
|
||||||
|
wantedBy = lib.optional clientCfg.autoStart "multi-user.target";
|
||||||
|
|
||||||
|
environment.RUST_LOG = clientCfg.loggingLevel;
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "exec";
|
||||||
|
EnvironmentFile =
|
||||||
|
lib.optional (clientCfg.environmentFile != null) clientCfg.environmentFile;
|
||||||
|
DynamicUser = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
AmbientCapabilities =
|
||||||
|
(lib.optionals clientCfg.addNetBind [ "CAP_NET_BIND_SERVICE" ]) ++
|
||||||
|
(lib.optionals (clientCfg.soMark != null) [ "CAP_NET_ADMIN" ]);
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
RestrictNamespaces = "uts ipc pid user cgroup";
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 2;
|
||||||
|
RestartSteps = 20;
|
||||||
|
RestartMaxDelaySec = "5min";
|
||||||
|
};
|
||||||
|
|
||||||
|
script = with clientCfg; ''
|
||||||
|
${lib.getExe package} \
|
||||||
|
client \
|
||||||
|
${lib.cli.toGNUCommandLineShell { } (
|
||||||
|
lib.recursiveUpdate
|
||||||
|
{
|
||||||
|
local-to-remote = localToRemote;
|
||||||
|
remote-to-local = remoteToLocal;
|
||||||
|
http-headers = lib.mapAttrsToList (n: v: "${n}:${v}") customHeaders;
|
||||||
|
http-proxy = httpProxy;
|
||||||
|
socket-so-mark = soMark;
|
||||||
|
http-upgrade-path-prefix = upgradePathPrefix;
|
||||||
|
tls-sni-override = tlsSNI;
|
||||||
|
tls-verify-certificate = tlsVerifyCertificate;
|
||||||
|
websocket-ping-frequency-sec = websocketPingInterval;
|
||||||
|
http-upgrade-credentials = upgradeCredentials;
|
||||||
|
}
|
||||||
|
extraArgs
|
||||||
|
)} \
|
||||||
|
${lib.escapeShellArg connectTo}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.wstunnel = {
|
||||||
|
enable = lib.mkEnableOption "wstunnel";
|
||||||
|
|
||||||
|
servers = lib.mkOption {
|
||||||
|
description = "`wstunnel` servers to set up.";
|
||||||
|
type = lib.types.attrsOf (lib.types.submodule serverSubmodule);
|
||||||
|
default = { };
|
||||||
|
example = {
|
||||||
|
"wg-tunnel" = {
|
||||||
|
listen = {
|
||||||
|
host = "0.0.0.0";
|
||||||
|
port = 8080;
|
||||||
|
};
|
||||||
|
enableHTTPS = true;
|
||||||
|
tlsCertificate = "/var/lib/secrets/fullchain.pem";
|
||||||
|
tlsKey = "/var/lib/secrets/key.pem";
|
||||||
|
restrictTo = [{
|
||||||
|
host = "127.0.0.1";
|
||||||
|
port = 51820;
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
clients = lib.mkOption {
|
||||||
|
description = "`wstunnel` clients to set up.";
|
||||||
|
type = lib.types.attrsOf (lib.types.submodule clientSubmodule);
|
||||||
|
default = { };
|
||||||
|
example = {
|
||||||
|
"wg-tunnel" = {
|
||||||
|
connectTo = "wss://wstunnel.server.com:8443";
|
||||||
|
localToRemote = [
|
||||||
|
"tcp://1212:google.com:443"
|
||||||
|
"tcp://2:n.lan:4?proxy_protocol"
|
||||||
|
];
|
||||||
|
remoteToLocal = [
|
||||||
|
"socks5://[::1]:1212"
|
||||||
|
"unix://wstunnel.sock:g.com:443"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
systemd.services =
|
||||||
|
(lib.mapAttrs' generateServerUnit (lib.filterAttrs (n: v: v.enable) cfg.servers)) //
|
||||||
|
(lib.mapAttrs' generateClientUnit (lib.filterAttrs (n: v: v.enable) cfg.clients));
|
||||||
|
|
||||||
|
assertions =
|
||||||
|
(lib.mapAttrsToList
|
||||||
|
(name: serverCfg: {
|
||||||
|
assertion =
|
||||||
|
!(serverCfg.useACMEHost != null && serverCfg.tlsCertificate != null);
|
||||||
|
message = ''
|
||||||
|
Options services.wstunnel.servers."${name}".useACMEHost and services.wstunnel.servers."${name}".{tlsCertificate, tlsKey} are mutually exclusive.
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
cfg.servers) ++
|
||||||
|
|
||||||
|
(lib.mapAttrsToList
|
||||||
|
(name: serverCfg: {
|
||||||
|
assertion =
|
||||||
|
(serverCfg.tlsCertificate == null && serverCfg.tlsKey == null) ||
|
||||||
|
(serverCfg.tlsCertificate != null && serverCfg.tlsKey != null);
|
||||||
|
message = ''
|
||||||
|
services.wstunnel.servers."${name}".tlsCertificate and services.wstunnel.servers."${name}".tlsKey need to be set together.
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
cfg.servers) ++
|
||||||
|
|
||||||
|
(lib.mapAttrsToList
|
||||||
|
(name: clientCfg: {
|
||||||
|
assertion = !(clientCfg.localToRemote == [ ] && clientCfg.remoteToLocal == [ ]);
|
||||||
|
message = ''
|
||||||
|
Either one of services.wstunnel.clients."${name}".localToRemote or services.wstunnel.clients."${name}".remoteToLocal must be set.
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
cfg.clients);
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = with lib.maintainers; [ alyaeanyx rvdp neverbehave ];
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
nix:
|
nix:
|
||||||
access-tokens: ENC[AES256_GCM,data:K1V98nx+w0uoOY9ONDxbaZT9jbEbMqpzyYWaSrQIYfo2bm1HLeTHPqp2rqRFIPu5gD/5SqY2FW4Pak92it4S7o9liiI=,iv:/c6Mr3WQsbW7nBaa5NIG3pzatSyC9UE5zDpKjuD/FG0=,tag:8V344qvOVrgh5XHlinuFyw==,type:str]
|
access-tokens: ENC[AES256_GCM,data:K1V98nx+w0uoOY9ONDxbaZT9jbEbMqpzyYWaSrQIYfo2bm1HLeTHPqp2rqRFIPu5gD/5SqY2FW4Pak92it4S7o9liiI=,iv:/c6Mr3WQsbW7nBaa5NIG3pzatSyC9UE5zDpKjuD/FG0=,tag:8V344qvOVrgh5XHlinuFyw==,type:str]
|
||||||
|
wstunnel:
|
||||||
|
http-upgrade-path-prefix-envvars: ENC[AES256_GCM,data:aS7Kvpj9aHtaiKZiakDuvdiDcVYFMkYv9FIH060Dbkahk6v+2bbxzgKcRtnDnLlphtGlZD7yWRcbvlYiG7Y5mRNS1X5PkspQwFKKnwGGHiWgfun9yxB6VHvPdb4W4SNA8QfRmqH4XmJUfDSPmZfh5Ggzhy7/74avC0vfqKBvQ+ml4fjqTmdS6EkFGrrUwIXFrjiCqdxnNYmp8I/L1b22R5YoY/JTsc4mG6N9s3B75GvsYI2EDG4vQ7EMyktd2CHsXJgNFRQUM+GzBbkO4VvG,iv:EbuV/2L+p4A+aloC6uQYiFFF7Lsz5A5RTGMuHMqtTpI=,tag:DThZOERbXuUdDJso7ertbg==,type:str]
|
||||||
ssh:
|
ssh:
|
||||||
secret-config:
|
secret-config:
|
||||||
home: ENC[AES256_GCM,data:eUfhQb6yYYV3951sdwZpA1f8k+79mm1bMYY4EP+tn1g7DEHXG9XHYKPL3FLJMkaaXSWv5jbBZ3zrGodJPMH9VbcFOjvSdz9u56DnmyeR3S7Pwgj1YbELDn9akeVRpjcB1w2k8hn2vNIY1MV4vg==,iv:LQpS168sxPVegrlPJNZrVZE+GsZAMxRSl4EaHO6FFxg=,tag:w5SNj7LkYd+22SbLVbtsDQ==,type:str]
|
home: ENC[AES256_GCM,data:eUfhQb6yYYV3951sdwZpA1f8k+79mm1bMYY4EP+tn1g7DEHXG9XHYKPL3FLJMkaaXSWv5jbBZ3zrGodJPMH9VbcFOjvSdz9u56DnmyeR3S7Pwgj1YbELDn9akeVRpjcB1w2k8hn2vNIY1MV4vg==,iv:LQpS168sxPVegrlPJNZrVZE+GsZAMxRSl4EaHO6FFxg=,tag:w5SNj7LkYd+22SbLVbtsDQ==,type:str]
|
||||||
|
@ -47,8 +49,8 @@ sops:
|
||||||
UllPc1JCTXoxUERMM05abjhnR0g0d2sK/wyBVH6Dxris4TF05POtYQbWj4DWOeID
|
UllPc1JCTXoxUERMM05abjhnR0g0d2sK/wyBVH6Dxris4TF05POtYQbWj4DWOeID
|
||||||
RAdf30dDVtmg4qPwsHiIQ8f10gA1DrgIrcae0JS5VZcRLRw5/4+g9Q==
|
RAdf30dDVtmg4qPwsHiIQ8f10gA1DrgIrcae0JS5VZcRLRw5/4+g9Q==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2024-06-25T18:25:28Z"
|
lastmodified: "2024-06-28T13:06:09Z"
|
||||||
mac: ENC[AES256_GCM,data:GGjXTEHVHAWrr0QHc3O4bMpGi1wFge6AbK7XEwRiOqh4W1Zow2CEcfGZxW5TLLayfB9lXemeKtrZWsqBOCXtHkd670KbxxKInE3FvJbjME8ZODAMpknYX4BXBGt6ksC03Tm4ri1JIy1OxDVXG4qb8skNtna4YkIiUf+ErTihakA=,iv:YGKnVl9QCLLTqdQfpiTbv31vEGEoolzMWtyEFvJekYI=,tag:8j+dnOqHfupKTAl1GQ09Mg==,type:str]
|
mac: ENC[AES256_GCM,data:H19kxVh+pcjGhD78WHQYMGQ/0HY/F4NF6sYCvjn4hqPfFTJDDcVJ7QFxm2LL4Zz/+KNcI3qvnXO/g/MyaVxyJMyKC9LFwHT/0TwMRW1uHSBahPASFYvN0/h+6hp6TI9/DPeWjKEGk+1j1tU665YpnqYdOtRUfQEB02fmLf2jSiw=,iv:b0b4m/SlGNXBQ3ulLhbSHngSLZiFipPV+yAD6MG8vAo=,tag:B3oHJkWlFpY+g6dVkApDMw==,type:str]
|
||||||
pgp:
|
pgp:
|
||||||
- created_at: "2024-06-26T07:42:59Z"
|
- created_at: "2024-06-26T07:42:59Z"
|
||||||
enc: |-
|
enc: |-
|
||||||
|
|
Loading…
Reference in New Issue