feat: add port offset handling for auto SSH devices
This commit is contained in:
parent
2c1316a0a6
commit
3385709208
3 changed files with 34 additions and 9 deletions
|
|
@ -36,6 +36,7 @@ rec {
|
||||||
sshUser = "root";
|
sshUser = "root";
|
||||||
key = secrets.byName.autossh_remote_proxy_key.path;
|
key = secrets.byName.autossh_remote_proxy_key.path;
|
||||||
known_hosts = secrets.byName.autossh_remote_proxy_known_hosts.path;
|
known_hosts = secrets.byName.autossh_remote_proxy_known_hosts.path;
|
||||||
|
portOffset = 10000;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -19,22 +19,31 @@ let
|
||||||
getRemotePortMap = device:
|
getRemotePortMap = device:
|
||||||
autoSshValidation.getRemotePortMap device;
|
autoSshValidation.getRemotePortMap device;
|
||||||
|
|
||||||
resolveRemotePort = remotePortMap: endpoint:
|
getPortOffset = device:
|
||||||
|
autoSshValidation.getPortOffset device;
|
||||||
|
|
||||||
|
ensurePortRange = context: port:
|
||||||
|
if builtins.isInt port && port >= 1 && port <= 65535 then
|
||||||
|
port
|
||||||
|
else
|
||||||
|
throw "${context} must be in range 1..65535.";
|
||||||
|
|
||||||
|
resolveRemotePort = remotePortMap: portOffset: endpoint:
|
||||||
let
|
let
|
||||||
localPort =
|
localPort =
|
||||||
if endpoint ? port then
|
if endpoint ? port then
|
||||||
endpoint.port
|
ensurePortRange "Endpoint port '${toString endpoint.port}'" endpoint.port
|
||||||
else
|
else
|
||||||
throw "Endpoint is missing required field: port.";
|
throw "Endpoint is missing required field: port.";
|
||||||
overrides = lib.filter (entry: entry.localPort == localPort) remotePortMap;
|
overrides = lib.filter (entry: entry.localPort == localPort) remotePortMap;
|
||||||
in
|
in
|
||||||
if overrides != [] then
|
if overrides != [] then
|
||||||
(builtins.head overrides).remotePort
|
ensurePortRange "remotePortMap remotePort '${toString (builtins.head overrides).remotePort}'" (builtins.head overrides).remotePort
|
||||||
else
|
else
|
||||||
localPort;
|
ensurePortRange "Computed remote port (local ${toString localPort} + offset ${toString portOffset})" (localPort + portOffset);
|
||||||
|
|
||||||
mapEndpointToForward = remotePortMap: endpoint: {
|
mapEndpointToForward = remotePortMap: portOffset: endpoint: {
|
||||||
remote = resolveRemotePort remotePortMap endpoint;
|
remote = resolveRemotePort remotePortMap portOffset endpoint;
|
||||||
localAddress = "localhost";
|
localAddress = "localhost";
|
||||||
localPort = endpoint.port;
|
localPort = endpoint.port;
|
||||||
};
|
};
|
||||||
|
|
@ -50,6 +59,7 @@ let
|
||||||
else
|
else
|
||||||
throw "Auto SSH device is missing required field: domain.";
|
throw "Auto SSH device is missing required field: domain.";
|
||||||
remotePortMap = getRemotePortMap device;
|
remotePortMap = getRemotePortMap device;
|
||||||
|
portOffset = getPortOffset device;
|
||||||
matchedEndpoints =
|
matchedEndpoints =
|
||||||
lib.filter (endpoint:
|
lib.filter (endpoint:
|
||||||
if endpoint.force_ssl && endpoint.port == 80 then
|
if endpoint.force_ssl && endpoint.port == 80 then
|
||||||
|
|
@ -61,8 +71,8 @@ let
|
||||||
) endpoints;
|
) endpoints;
|
||||||
forwards = lib.concatMap (endpoint:
|
forwards = lib.concatMap (endpoint:
|
||||||
let
|
let
|
||||||
baseForward = mapEndpointToForward remotePortMap endpoint;
|
baseForward = mapEndpointToForward remotePortMap portOffset endpoint;
|
||||||
httpRedirectForward = mapEndpointToForward remotePortMap (endpointForHttpRedirect endpoint);
|
httpRedirectForward = mapEndpointToForward remotePortMap portOffset (endpointForHttpRedirect endpoint);
|
||||||
in
|
in
|
||||||
if endpoint.force_ssl then
|
if endpoint.force_ssl then
|
||||||
[ baseForward httpRedirectForward ]
|
[ baseForward httpRedirectForward ]
|
||||||
|
|
|
||||||
|
|
@ -53,9 +53,23 @@ let
|
||||||
else
|
else
|
||||||
device.auto_ssh.remotePortMap;
|
device.auto_ssh.remotePortMap;
|
||||||
|
|
||||||
|
getPortOffset = device:
|
||||||
|
if !(device ? auto_ssh) then
|
||||||
|
0
|
||||||
|
else if !builtins.isAttrs device.auto_ssh then
|
||||||
|
throw "Device auto_ssh must be an attrset when present."
|
||||||
|
else if !(device.auto_ssh ? portOffset) then
|
||||||
|
0
|
||||||
|
else if !builtins.isInt device.auto_ssh.portOffset then
|
||||||
|
throw "Device auto_ssh.portOffset must be an int."
|
||||||
|
else if device.auto_ssh.portOffset < 0 then
|
||||||
|
throw "Device auto_ssh.portOffset must be >= 0."
|
||||||
|
else
|
||||||
|
device.auto_ssh.portOffset;
|
||||||
|
|
||||||
isSafeName = name:
|
isSafeName = name:
|
||||||
builtins.match "^[a-z_][a-z0-9_-]*$" name != null;
|
builtins.match "^[a-z_][a-z0-9_-]*$" name != null;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit getDevices getAutoSshDevices getAutoSshDomains getAutoSshConfig getRemotePortMap isSafeName;
|
inherit getDevices getAutoSshDevices getAutoSshDomains getAutoSshConfig getRemotePortMap getPortOffset isSafeName;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue