mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-15 22:36:23 +01:00
e3e6e94010
Adds a module for rathole package. The package itself and this module is very similar to frp, so the options and tests are not very far off from those for frp.
165 lines
4.9 KiB
Nix
165 lines
4.9 KiB
Nix
{
|
|
pkgs,
|
|
lib,
|
|
config,
|
|
...
|
|
}:
|
|
|
|
let
|
|
cfg = config.services.rathole;
|
|
settingsFormat = pkgs.formats.toml { };
|
|
py-toml-merge =
|
|
pkgs.writers.writePython3Bin "py-toml-merge"
|
|
{
|
|
libraries = with pkgs.python3Packages; [
|
|
tomli-w
|
|
mergedeep
|
|
];
|
|
}
|
|
''
|
|
import argparse
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
import tomli_w
|
|
import tomllib
|
|
from mergedeep import merge
|
|
|
|
parser = argparse.ArgumentParser(description="Merge multiple TOML files")
|
|
parser.add_argument(
|
|
"files",
|
|
type=Path,
|
|
nargs="+",
|
|
help="List of TOML files to merge",
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
merged: dict[str, Any] = {}
|
|
|
|
for file in args.files:
|
|
with open(file, "rb") as fh:
|
|
loaded_toml = tomllib.load(fh)
|
|
merged = merge(merged, loaded_toml)
|
|
|
|
print(tomli_w.dumps(merged))
|
|
'';
|
|
in
|
|
|
|
{
|
|
options = {
|
|
services.rathole = {
|
|
enable = lib.mkEnableOption "Rathole";
|
|
|
|
package = lib.mkPackageOption pkgs "rathole" { };
|
|
|
|
role = lib.mkOption {
|
|
type = lib.types.enum [
|
|
"server"
|
|
"client"
|
|
];
|
|
description = ''
|
|
Select whether rathole needs to be run as a `client` or a `server`.
|
|
Server is a machine with a public IP and client is a device behind NAT,
|
|
but running some services that need to be exposed to the Internet.
|
|
'';
|
|
};
|
|
|
|
credentialsFile = lib.mkOption {
|
|
type = lib.types.path;
|
|
default = "/dev/null";
|
|
description = ''
|
|
Path to a TOML file to be merged with the settings.
|
|
Useful to set secret config parameters like tokens, which
|
|
should not appear in the Nix Store.
|
|
'';
|
|
example = "/var/lib/secrets/rathole/config.toml";
|
|
};
|
|
|
|
settings = lib.mkOption {
|
|
type = settingsFormat.type;
|
|
default = { };
|
|
description = ''
|
|
Rathole configuration, for options reference
|
|
see the [example](https://github.com/rapiz1/rathole?tab=readme-ov-file#configuration) on GitHub.
|
|
Both server and client configurations can be specified at the same time, regardless of the selected role.
|
|
'';
|
|
example = {
|
|
server = {
|
|
bind_addr = "0.0.0.0:2333";
|
|
services.my_nas_ssh = {
|
|
token = "use_a_secret_that_only_you_know";
|
|
bind_addr = "0.0.0.0:5202";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
systemd.services.rathole = {
|
|
requires = [ "network.target" ];
|
|
after = [ "network.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
description = "Rathole ${cfg.role} Service";
|
|
|
|
serviceConfig =
|
|
let
|
|
name = "rathole";
|
|
configFile = settingsFormat.generate "${name}.toml" cfg.settings;
|
|
runtimeDir = "/run/${name}";
|
|
ratholePrestart =
|
|
"+"
|
|
+ (pkgs.writeShellScript "rathole-prestart" ''
|
|
DYNUSER_UID=$(stat -c %u ${runtimeDir})
|
|
DYNUSER_GID=$(stat -c %g ${runtimeDir})
|
|
${lib.getExe py-toml-merge} ${configFile} '${cfg.credentialsFile}' |
|
|
install -m 600 -o $DYNUSER_UID -g $DYNUSER_GID /dev/stdin ${runtimeDir}/${mergedConfigName}
|
|
'');
|
|
mergedConfigName = "merged.toml";
|
|
in
|
|
{
|
|
Type = "simple";
|
|
Restart = "on-failure";
|
|
RestartSec = 5;
|
|
ExecStartPre = ratholePrestart;
|
|
ExecStart = "${lib.getExe cfg.package} --${cfg.role} ${runtimeDir}/${mergedConfigName}";
|
|
DynamicUser = true;
|
|
LimitNOFILE = "1048576";
|
|
RuntimeDirectory = name;
|
|
RuntimeDirectoryMode = "0700";
|
|
# Hardening
|
|
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
|
CapabilityBoundingSet = "CAP_NET_BIND_SERVICE";
|
|
LockPersonality = true;
|
|
MemoryDenyWriteExecute = true;
|
|
PrivateDevices = true;
|
|
PrivateMounts = true;
|
|
PrivateTmp = true;
|
|
# PrivateUsers=true breaks AmbientCapabilities=CAP_NET_BIND_SERVICE
|
|
ProcSubset = "pid";
|
|
ProtectClock = true;
|
|
ProtectControlGroups = true;
|
|
ProtectHome = true;
|
|
ProtectHostname = true;
|
|
ProtectKernelLogs = true;
|
|
ProtectKernelModules = true;
|
|
ProtectKernelTunables = true;
|
|
ProtectProc = "invisible";
|
|
ProtectSystem = "strict";
|
|
RemoveIPC = true;
|
|
RestrictAddressFamilies = [
|
|
"AF_INET"
|
|
"AF_INET6"
|
|
];
|
|
RestrictNamespaces = true;
|
|
RestrictRealtime = true;
|
|
RestrictSUIDSGID = true;
|
|
SystemCallArchitectures = "native";
|
|
UMask = "0066";
|
|
};
|
|
};
|
|
};
|
|
|
|
meta.maintainers = with lib.maintainers; [ xokdvium ];
|
|
}
|