rosenpass: refactor, add module and test (#254813)
This commit is contained in:
parent
924c682627
commit
cc6c2d32f2
9 changed files with 507 additions and 52 deletions
|
@ -121,6 +121,8 @@
|
|||
|
||||
- [Soft Serve](https://github.com/charmbracelet/soft-serve), a tasty, self-hostable Git server for the command line. Available as [services.soft-serve](#opt-services.soft-serve.enable).
|
||||
|
||||
- [Rosenpass](https://rosenpass.eu/), a service for post-quantum-secure VPNs with WireGuard. Available as [services.rosenpass](#opt-services.rosenpass.enable).
|
||||
|
||||
## Backward Incompatibilities {#sec-release-23.11-incompatibilities}
|
||||
|
||||
- `network-online.target` has been fixed to no longer time out for systems with `networking.useDHCP = true` and `networking.useNetworkd = true`.
|
||||
|
|
|
@ -1047,6 +1047,7 @@
|
|||
./services/networking/redsocks.nix
|
||||
./services/networking/resilio.nix
|
||||
./services/networking/robustirc-bridge.nix
|
||||
./services/networking/rosenpass.nix
|
||||
./services/networking/routedns.nix
|
||||
./services/networking/rpcbind.nix
|
||||
./services/networking/rxe.nix
|
||||
|
|
233
nixos/modules/services/networking/rosenpass.nix
Normal file
233
nixos/modules/services/networking/rosenpass.nix
Normal file
|
@ -0,0 +1,233 @@
|
|||
{ config
|
||||
, lib
|
||||
, options
|
||||
, pkgs
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
attrValues
|
||||
concatLines
|
||||
concatMap
|
||||
filter
|
||||
filterAttrsRecursive
|
||||
flatten
|
||||
getExe
|
||||
mdDoc
|
||||
mkIf
|
||||
optional
|
||||
;
|
||||
|
||||
cfg = config.services.rosenpass;
|
||||
opt = options.services.rosenpass;
|
||||
settingsFormat = pkgs.formats.toml { };
|
||||
in
|
||||
{
|
||||
options.services.rosenpass =
|
||||
let
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mdDoc
|
||||
mkOption
|
||||
;
|
||||
inherit (lib.types)
|
||||
enum
|
||||
listOf
|
||||
nullOr
|
||||
path
|
||||
str
|
||||
submodule
|
||||
;
|
||||
in
|
||||
{
|
||||
enable = lib.mkEnableOption (mdDoc "Rosenpass");
|
||||
|
||||
package = lib.mkPackageOption pkgs "rosenpass" { };
|
||||
|
||||
defaultDevice = mkOption {
|
||||
type = nullOr str;
|
||||
description = mdDoc "Name of the network interface to use for all peers by default.";
|
||||
example = "wg0";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
|
||||
options = {
|
||||
public_key = mkOption {
|
||||
type = path;
|
||||
description = mdDoc "Path to a file containing the public key of the local Rosenpass peer. Generate this by running {command}`rosenpass gen-keys`.";
|
||||
};
|
||||
|
||||
secret_key = mkOption {
|
||||
type = path;
|
||||
description = mdDoc "Path to a file containing the secret key of the local Rosenpass peer. Generate this by running {command}`rosenpass gen-keys`.";
|
||||
};
|
||||
|
||||
listen = mkOption {
|
||||
type = listOf str;
|
||||
description = mdDoc "List of local endpoints to listen for connections.";
|
||||
default = [ ];
|
||||
example = literalExpression "[ \"0.0.0.0:10000\" ]";
|
||||
};
|
||||
|
||||
verbosity = mkOption {
|
||||
type = enum [ "Verbose" "Quiet" ];
|
||||
default = "Quiet";
|
||||
description = mdDoc "Verbosity of output produced by the service.";
|
||||
};
|
||||
|
||||
peers =
|
||||
let
|
||||
peer = submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
|
||||
options = {
|
||||
public_key = mkOption {
|
||||
type = path;
|
||||
description = mdDoc "Path to a file containing the public key of the remote Rosenpass peer.";
|
||||
};
|
||||
|
||||
endpoint = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = mdDoc "Endpoint of the remote Rosenpass peer.";
|
||||
};
|
||||
|
||||
device = mkOption {
|
||||
type = str;
|
||||
default = cfg.defaultDevice;
|
||||
defaultText = literalExpression "config.${opt.defaultDevice}";
|
||||
description = mdDoc "Name of the local WireGuard interface to use for this peer.";
|
||||
};
|
||||
|
||||
peer = mkOption {
|
||||
type = str;
|
||||
description = mdDoc "WireGuard public key corresponding to the remote Rosenpass peer.";
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
mkOption {
|
||||
type = listOf peer;
|
||||
description = mdDoc "List of peers to exchange keys with.";
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = mdDoc "Configuration for Rosenpass, see <https://rosenpass.eu/> for further information.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
warnings =
|
||||
let
|
||||
# NOTE: In the descriptions below, we tried to refer to e.g.
|
||||
# options.systemd.network.netdevs."<name>".wireguardPeers.*.PublicKey
|
||||
# directly, but don't know how to traverse "<name>" and * in this path.
|
||||
extractions = [
|
||||
{
|
||||
relevant = config.systemd.network.enable;
|
||||
root = config.systemd.network.netdevs;
|
||||
peer = (x: x.wireguardPeers);
|
||||
key = (x: if x.wireguardPeerConfig ? PublicKey then x.wireguardPeerConfig.PublicKey else null);
|
||||
description = mdDoc "${options.systemd.network.netdevs}.\"<name>\".wireguardPeers.*.wireguardPeerConfig.PublicKey";
|
||||
}
|
||||
{
|
||||
relevant = config.networking.wireguard.enable;
|
||||
root = config.networking.wireguard.interfaces;
|
||||
peer = (x: x.peers);
|
||||
key = (x: x.publicKey);
|
||||
description = mdDoc "${options.networking.wireguard.interfaces}.\"<name>\".peers.*.publicKey";
|
||||
}
|
||||
rec {
|
||||
relevant = root != { };
|
||||
root = config.networking.wg-quick.interfaces;
|
||||
peer = (x: x.peers);
|
||||
key = (x: x.publicKey);
|
||||
description = mdDoc "${options.networking.wg-quick.interfaces}.\"<name>\".peers.*.publicKey";
|
||||
}
|
||||
];
|
||||
relevantExtractions = filter (x: x.relevant) extractions;
|
||||
extract = { root, peer, key, ... }:
|
||||
filter (x: x != null) (flatten (concatMap (x: (map key (peer x))) (attrValues root)));
|
||||
configuredKeys = flatten (map extract relevantExtractions);
|
||||
itemize = xs: concatLines (map (x: " - ${x}") xs);
|
||||
descriptions = map (x: "`${x.description}`");
|
||||
missingKeys = filter (key: !builtins.elem key configuredKeys) (map (x: x.peer) cfg.settings.peers);
|
||||
unusual = ''
|
||||
While this may work as expected, e.g. you want to manually configure WireGuard,
|
||||
such a scenario is unusual. Please double-check your configuration.
|
||||
'';
|
||||
in
|
||||
(optional (relevantExtractions != [ ] && missingKeys != [ ]) ''
|
||||
You have configured Rosenpass peers with the WireGuard public keys:
|
||||
${itemize missingKeys}
|
||||
But there is no corresponding active Wireguard peer configuration in any of:
|
||||
${itemize (descriptions relevantExtractions)}
|
||||
${unusual}
|
||||
'')
|
||||
++
|
||||
optional (relevantExtractions == [ ]) ''
|
||||
You have configured Rosenpass, but you have not configured Wireguard via any of:
|
||||
${itemize (descriptions extractions)}
|
||||
${unusual}
|
||||
'';
|
||||
|
||||
environment.systemPackages = [ cfg.package pkgs.wireguard-tools ];
|
||||
|
||||
systemd.services.rosenpass =
|
||||
let
|
||||
filterNonNull = filterAttrsRecursive (_: v: v != null);
|
||||
config = settingsFormat.generate "config.toml" (
|
||||
filterNonNull (cfg.settings
|
||||
//
|
||||
(
|
||||
let
|
||||
credentialPath = id: "$CREDENTIALS_DIRECTORY/${id}";
|
||||
# NOTE: We would like to remove all `null` values inside `cfg.settings`
|
||||
# recursively, since `settingsFormat.generate` cannot handle `null`.
|
||||
# This would require to traverse both attribute sets and lists recursively.
|
||||
# `filterAttrsRecursive` only recurses into attribute sets, but not
|
||||
# into values that might contain other attribute sets (such as lists,
|
||||
# e.g. `cfg.settings.peers`). Here, we just specialize on `cfg.settings.peers`,
|
||||
# and this may break unexpectedly whenever a `null` value is contained
|
||||
# in a list in `cfg.settings`, other than `cfg.settings.peers`.
|
||||
peersWithoutNulls = map filterNonNull cfg.settings.peers;
|
||||
in
|
||||
{
|
||||
secret_key = credentialPath "pqsk";
|
||||
public_key = credentialPath "pqpk";
|
||||
peers = peersWithoutNulls;
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
in
|
||||
rec {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
path = [ cfg.package pkgs.wireguard-tools ];
|
||||
|
||||
serviceConfig = {
|
||||
User = "rosenpass";
|
||||
Group = "rosenpass";
|
||||
RuntimeDirectory = "rosenpass";
|
||||
DynamicUser = true;
|
||||
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
|
||||
LoadCredential = [
|
||||
"pqsk:${cfg.settings.secret_key}"
|
||||
"pqpk:${cfg.settings.public_key}"
|
||||
];
|
||||
};
|
||||
|
||||
# See <https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Specifiers>
|
||||
environment.CONFIG = "%t/${serviceConfig.RuntimeDirectory}/config.toml";
|
||||
|
||||
preStart = "${getExe pkgs.envsubst} -i ${config} -o \"$CONFIG\"";
|
||||
script = "rosenpass exchange-config \"$CONFIG\"";
|
||||
};
|
||||
};
|
||||
}
|
|
@ -703,6 +703,7 @@ in {
|
|||
rkvm = handleTest ./rkvm {};
|
||||
robustirc-bridge = handleTest ./robustirc-bridge.nix {};
|
||||
roundcube = handleTest ./roundcube.nix {};
|
||||
rosenpass = handleTest ./rosenpass.nix {};
|
||||
rshim = handleTest ./rshim.nix {};
|
||||
rspamd = handleTest ./rspamd.nix {};
|
||||
rss2email = handleTest ./rss2email.nix {};
|
||||
|
|
217
nixos/tests/rosenpass.nix
Normal file
217
nixos/tests/rosenpass.nix
Normal file
|
@ -0,0 +1,217 @@
|
|||
import ./make-test-python.nix ({ pkgs, ... }:
|
||||
let
|
||||
deviceName = "rp0";
|
||||
|
||||
server = {
|
||||
ip = "fe80::1";
|
||||
wg = {
|
||||
public = "mQufmDFeQQuU/fIaB2hHgluhjjm1ypK4hJr1cW3WqAw=";
|
||||
secret = "4N5Y1dldqrpsbaEiY8O0XBUGUFf8vkvtBtm8AoOX7Eo=";
|
||||
listen = 10000;
|
||||
};
|
||||
};
|
||||
client = {
|
||||
ip = "fe80::2";
|
||||
wg = {
|
||||
public = "Mb3GOlT7oS+F3JntVKiaD7SpHxLxNdtEmWz/9FMnRFU=";
|
||||
secret = "uC5dfGMv7Oxf5UDfdPkj6rZiRZT2dRWp5x8IQxrNcUE=";
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
name = "rosenpass";
|
||||
|
||||
nodes =
|
||||
let
|
||||
shared = peer: { config, modulesPath, ... }: {
|
||||
imports = [ "${modulesPath}/services/networking/rosenpass.nix" ];
|
||||
|
||||
boot.kernelModules = [ "wireguard" ];
|
||||
|
||||
services.rosenpass = {
|
||||
enable = true;
|
||||
defaultDevice = deviceName;
|
||||
settings = {
|
||||
verbosity = "Verbose";
|
||||
public_key = "/etc/rosenpass/pqpk";
|
||||
secret_key = "/etc/rosenpass/pqsk";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ 9999 ];
|
||||
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
networks."rosenpass" = {
|
||||
matchConfig.Name = deviceName;
|
||||
networkConfig.IPForward = true;
|
||||
address = [ "${peer.ip}/64" ];
|
||||
};
|
||||
|
||||
netdevs."10-rp0" = {
|
||||
netdevConfig = {
|
||||
Kind = "wireguard";
|
||||
Name = deviceName;
|
||||
};
|
||||
wireguardConfig.PrivateKeyFile = "/etc/wireguard/wgsk";
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc."wireguard/wgsk" = {
|
||||
text = peer.wg.secret;
|
||||
user = "systemd-network";
|
||||
group = "systemd-network";
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
server = {
|
||||
imports = [ (shared server) ];
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ server.wg.listen ];
|
||||
|
||||
systemd.network.netdevs."10-${deviceName}" = {
|
||||
wireguardConfig.ListenPort = server.wg.listen;
|
||||
wireguardPeers = [
|
||||
{
|
||||
wireguardPeerConfig = {
|
||||
AllowedIPs = [ "::/0" ];
|
||||
PublicKey = client.wg.public;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.rosenpass.settings = {
|
||||
listen = [ "0.0.0.0:9999" ];
|
||||
peers = [
|
||||
{
|
||||
public_key = "/etc/rosenpass/peers/client/pqpk";
|
||||
peer = client.wg.public;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
client = {
|
||||
imports = [ (shared client) ];
|
||||
|
||||
systemd.network.netdevs."10-${deviceName}".wireguardPeers = [
|
||||
{
|
||||
wireguardPeerConfig = {
|
||||
AllowedIPs = [ "::/0" ];
|
||||
PublicKey = server.wg.public;
|
||||
Endpoint = "server:${builtins.toString server.wg.listen}";
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
services.rosenpass.settings.peers = [
|
||||
{
|
||||
public_key = "/etc/rosenpass/peers/server/pqpk";
|
||||
endpoint = "server:9999";
|
||||
peer = server.wg.public;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = { ... }: ''
|
||||
from os import system
|
||||
|
||||
# Full path to rosenpass in the store, to avoid fiddling with `$PATH`.
|
||||
rosenpass = "${pkgs.rosenpass}/bin/rosenpass"
|
||||
|
||||
# Path in `/etc` where keys will be placed.
|
||||
etc = "/etc/rosenpass"
|
||||
|
||||
start_all()
|
||||
|
||||
for machine in [server, client]:
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
|
||||
# Gently stop Rosenpass to avoid crashes during key generation/distribution.
|
||||
for machine in [server, client]:
|
||||
machine.execute("systemctl stop rosenpass.service")
|
||||
|
||||
for (name, machine, remote) in [("server", server, client), ("client", client, server)]:
|
||||
pk, sk = f"{name}.pqpk", f"{name}.pqsk"
|
||||
system(f"{rosenpass} gen-keys --force --secret-key {sk} --public-key {pk}")
|
||||
machine.copy_from_host(sk, f"{etc}/pqsk")
|
||||
machine.copy_from_host(pk, f"{etc}/pqpk")
|
||||
remote.copy_from_host(pk, f"{etc}/peers/{name}/pqpk")
|
||||
|
||||
for machine in [server, client]:
|
||||
machine.execute("systemctl start rosenpass.service")
|
||||
|
||||
for machine in [server, client]:
|
||||
machine.wait_for_unit("rosenpass.service")
|
||||
|
||||
with subtest("ping"):
|
||||
client.succeed("ping -c 2 -i 0.5 ${server.ip}%${deviceName}")
|
||||
|
||||
with subtest("preshared-keys"):
|
||||
# Rosenpass works by setting the WireGuard preshared key at regular intervals.
|
||||
# Thus, if it is not active, then no key will be set, and the output of `wg show` will contain "none".
|
||||
# Otherwise, if it is active, then the key will be set and "none" will not be found in the output of `wg show`.
|
||||
for machine in [server, client]:
|
||||
machine.wait_until_succeeds("wg show all preshared-keys | grep --invert-match none", timeout=5)
|
||||
'';
|
||||
|
||||
# NOTE: Below configuration is for "interactive" (=developing/debugging) only.
|
||||
interactive.nodes =
|
||||
let
|
||||
inherit (import ./ssh-keys.nix pkgs) snakeOilPublicKey snakeOilPrivateKey;
|
||||
|
||||
sshAndKeyGeneration = {
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellApplication {
|
||||
name = "gen-keys";
|
||||
runtimeInputs = [ pkgs.rosenpass ];
|
||||
text = ''
|
||||
HOST="$(hostname)"
|
||||
if [ "$HOST" == "server" ]
|
||||
then
|
||||
PEER="client"
|
||||
else
|
||||
PEER="server"
|
||||
fi
|
||||
|
||||
# Generate keypair.
|
||||
mkdir -vp /etc/rosenpass/peers/$PEER
|
||||
rosenpass gen-keys --force --secret-key /etc/rosenpass/pqsk --public-key /etc/rosenpass/pqpk
|
||||
|
||||
# Set up SSH key.
|
||||
mkdir -p /root/.ssh
|
||||
cp ${snakeOilPrivateKey} /root/.ssh/id_ecdsa
|
||||
chmod 0400 /root/.ssh/id_ecdsa
|
||||
|
||||
# Copy public key to other peer.
|
||||
# shellcheck disable=SC2029
|
||||
ssh -o StrictHostKeyChecking=no $PEER "mkdir -pv /etc/rosenpass/peers/$HOST"
|
||||
scp /etc/rosenpass/pqpk "$PEER:/etc/rosenpass/peers/$HOST/pqpk"
|
||||
'';
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
# Use kmscon <https://www.freedesktop.org/wiki/Software/kmscon/>
|
||||
# to provide a slightly nicer console, and while we're at it,
|
||||
# also use a nice font.
|
||||
# With kmscon, we can for example zoom in/out using [Ctrl] + [+]
|
||||
# and [Ctrl] + [-]
|
||||
niceConsoleAndAutologin.services.kmscon = {
|
||||
enable = true;
|
||||
autologinUser = "root";
|
||||
fonts = [{
|
||||
name = "Fira Code";
|
||||
package = pkgs.fira-code;
|
||||
}];
|
||||
};
|
||||
in
|
||||
{
|
||||
server = sshAndKeyGeneration // niceConsoleAndAutologin;
|
||||
client = sshAndKeyGeneration // niceConsoleAndAutologin;
|
||||
};
|
||||
})
|
|
@ -22,5 +22,6 @@ buildGoModule rec {
|
|||
homepage = "https://github.com/a8m/envsubst";
|
||||
license = licenses.mit;
|
||||
maintainers = with maintainers; [ nicknovitski ];
|
||||
mainProgram = "envsubst";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,85 +1,53 @@
|
|||
{ lib
|
||||
, targetPlatform
|
||||
, fetchFromGitHub
|
||||
, nixosTests
|
||||
, rustPlatform
|
||||
, targetPlatform
|
||||
, installShellFiles
|
||||
, cmake
|
||||
, makeWrapper
|
||||
, pkg-config
|
||||
, removeReferencesTo
|
||||
, coreutils
|
||||
, findutils
|
||||
, gawk
|
||||
, wireguard-tools
|
||||
, bash
|
||||
, libsodium
|
||||
, pkg-config
|
||||
}:
|
||||
|
||||
let
|
||||
rpBinPath = lib.makeBinPath [
|
||||
coreutils
|
||||
findutils
|
||||
gawk
|
||||
wireguard-tools
|
||||
];
|
||||
in
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "rosenpass";
|
||||
version = "0.2.0";
|
||||
version = "unstable-2023-09-28";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = pname;
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-r7/3C5DzXP+9w4rp9XwbP+/NK1axIP6s3Iiio1xRMbk=";
|
||||
rev = "b15f17133f8b5c3c5175b4cfd4fc10039a4e203f";
|
||||
hash = "sha256-UXAkmt4VY0irLK2k4t6SW+SEodFE3CbX5cFbsPG0ZCo=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-g2w3lZXQ3Kg3ydKdFs8P2lOPfIkfTbAF0MhxsJoX/E4=";
|
||||
cargoHash = "sha256-N1DQHkgKgkDQ6DbgQJlpZkZ7AMTqX3P8R/cWr14jK2I=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
cmake # for oqs build in the oqs-sys crate
|
||||
makeWrapper # for the rp shellscript
|
||||
pkg-config # let libsodium-sys-stable find libsodium
|
||||
removeReferencesTo
|
||||
pkg-config
|
||||
rustPlatform.bindgenHook # for C-bindings in the crypto libs
|
||||
installShellFiles
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
bash # for patchShebangs to find it
|
||||
libsodium
|
||||
];
|
||||
|
||||
# otherwise pkg-config tries to link non-existent dynamic libs during the build of liboqs
|
||||
PKG_CONFIG_ALL_STATIC = true;
|
||||
|
||||
# liboqs requires quite a lot of stack memory, thus we adjust the default stack size picked for
|
||||
# new threads (which is used by `cargo test`) to be _big enough_
|
||||
RUST_MIN_STACK = 8 * 1024 * 1024; # 8 MiB
|
||||
buildInputs = [ libsodium ];
|
||||
|
||||
# nix defaults to building for aarch64 _without_ the armv8-a
|
||||
# crypto extensions, but liboqs depends on these
|
||||
preBuild = lib.optionalString targetPlatform.isAarch
|
||||
''NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -march=armv8-a+crypto"'';
|
||||
|
||||
preInstall = ''
|
||||
install -D rp $out/bin/rp
|
||||
wrapProgram $out/bin/rp --prefix PATH : "${ rpBinPath }"
|
||||
for file in doc/*.1
|
||||
do
|
||||
install -D $file $out/share/man/man1/''${file##*/}
|
||||
done
|
||||
preBuild = lib.optionalString targetPlatform.isAarch64 ''
|
||||
NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -march=armv8-a+crypto"
|
||||
'';
|
||||
|
||||
# nix propagates the *.dev outputs of buildInputs for static builds, but that is non-sense for an
|
||||
# executables only package
|
||||
postFixup = ''
|
||||
find -type f -exec remove-references-to -t ${bash.dev} \
|
||||
-t ${libsodium.dev} {} \;
|
||||
postInstall = ''
|
||||
installManPage doc/rosenpass.1
|
||||
'';
|
||||
|
||||
passthru.tests.rosenpass = nixosTests.rosenpass;
|
||||
|
||||
meta = with lib; {
|
||||
description = "Build post-quantum-secure VPNs with WireGuard!";
|
||||
homepage = "https://rosenpass.eu/";
|
||||
license = with licenses; [ mit /* or */ asl20 ];
|
||||
maintainers = with maintainers; [ wucke13 ];
|
||||
platforms = platforms.all;
|
||||
platforms = [ "aarch64-darwin" "aarch64-linux" "x86_64-darwin" "x86_64-linux" ];
|
||||
mainProgram = "rosenpass";
|
||||
};
|
||||
}
|
||||
|
|
30
pkgs/tools/networking/rosenpass/tools.nix
Normal file
30
pkgs/tools/networking/rosenpass/tools.nix
Normal file
|
@ -0,0 +1,30 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, makeWrapper
|
||||
, installShellFiles
|
||||
, coreutils
|
||||
, findutils
|
||||
, gawk
|
||||
, rosenpass
|
||||
, wireguard-tools
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
inherit (rosenpass) version src;
|
||||
pname = "rosenpass-tools";
|
||||
|
||||
nativeBuildInputs = [ makeWrapper installShellFiles ];
|
||||
|
||||
postInstall = ''
|
||||
install -D $src/rp $out/bin/rp
|
||||
installManPage $src/doc/rp.1
|
||||
wrapProgram $out/bin/rp \
|
||||
--prefix PATH : ${lib.makeBinPath [
|
||||
coreutils findutils gawk rosenpass wireguard-tools
|
||||
]}
|
||||
'';
|
||||
|
||||
meta = rosenpass.meta // {
|
||||
description = "This package contains the Rosenpass tool `rp`, which is a script that wraps the `rosenpass` binary.";
|
||||
mainProgram = "rp";
|
||||
};
|
||||
}
|
|
@ -12827,6 +12827,8 @@ with pkgs;
|
|||
|
||||
rosenpass = callPackage ../tools/networking/rosenpass { };
|
||||
|
||||
rosenpass-tools = callPackage ../tools/networking/rosenpass/tools.nix { };
|
||||
|
||||
rot8 = callPackage ../tools/misc/rot8 { };
|
||||
|
||||
rowhammer-test = callPackage ../tools/system/rowhammer-test { };
|
||||
|
|
Loading…
Reference in a new issue