mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-07-08 03:26:08 +03:00
Merge master into staging-next
This commit is contained in:
commit
883232c00d
125 changed files with 3340 additions and 1238 deletions
|
@ -686,6 +686,7 @@
|
|||
./services/networking/vsftpd.nix
|
||||
./services/networking/wakeonlan.nix
|
||||
./services/networking/websockify.nix
|
||||
./services/networking/wg-quick.nix
|
||||
./services/networking/wicd.nix
|
||||
./services/networking/wireguard.nix
|
||||
./services/networking/wpa_supplicant.nix
|
||||
|
|
|
@ -7,18 +7,19 @@ let
|
|||
cfg = config.services.packagekit;
|
||||
|
||||
packagekitConf = ''
|
||||
[Daemon]
|
||||
KeepCache=false
|
||||
'';
|
||||
[Daemon]
|
||||
DefaultBackend=${cfg.backend}
|
||||
KeepCache=false
|
||||
'';
|
||||
|
||||
vendorConf = ''
|
||||
[PackagesNotFound]
|
||||
DefaultUrl=https://github.com/NixOS/nixpkgs
|
||||
CodecUrl=https://github.com/NixOS/nixpkgs
|
||||
HardwareUrl=https://github.com/NixOS/nixpkgs
|
||||
FontUrl=https://github.com/NixOS/nixpkgs
|
||||
MimeUrl=https://github.com/NixOS/nixpkgs
|
||||
'';
|
||||
[PackagesNotFound]
|
||||
DefaultUrl=https://github.com/NixOS/nixpkgs
|
||||
CodecUrl=https://github.com/NixOS/nixpkgs
|
||||
HardwareUrl=https://github.com/NixOS/nixpkgs
|
||||
FontUrl=https://github.com/NixOS/nixpkgs
|
||||
MimeUrl=https://github.com/NixOS/nixpkgs
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
|
@ -33,26 +34,32 @@ in
|
|||
installing software. Software utilizing PackageKit can install
|
||||
software regardless of the package manager.
|
||||
'';
|
||||
};
|
||||
|
||||
# TODO: integrate with PolicyKit if the nix backend matures to the point
|
||||
# where it will require elevated permissions
|
||||
backend = mkOption {
|
||||
type = types.enum [ "test_nop" ];
|
||||
default = "test_nop";
|
||||
description = ''
|
||||
PackageKit supports multiple different backends and <literal>auto</literal> which
|
||||
should do the right thing.
|
||||
</para>
|
||||
<para>
|
||||
On NixOS however, we do not have a backend compatible with nix 2.0
|
||||
(refer to <link xlink:href="https://github.com/NixOS/nix/issues/233">this issue</link> so we have to force
|
||||
it to <literal>test_nop</literal> for now.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
services.dbus.packages = [ pkgs.packagekit ];
|
||||
services.dbus.packages = with pkgs; [ packagekit ];
|
||||
|
||||
systemd.services.packagekit = {
|
||||
description = "PackageKit Daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig.ExecStart = "${pkgs.packagekit}/libexec/packagekitd";
|
||||
serviceConfig.User = "root";
|
||||
serviceConfig.BusName = "org.freedesktop.PackageKit";
|
||||
serviceConfig.Type = "dbus";
|
||||
};
|
||||
systemd.packages = with pkgs; [ packagekit ];
|
||||
|
||||
environment.etc."PackageKit/PackageKit.conf".text = packagekitConf;
|
||||
environment.etc."PackageKit/Vendor.conf".text = vendorConf;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -10,35 +10,38 @@ in
|
|||
services.plex = {
|
||||
enable = mkEnableOption "Plex Media Server";
|
||||
|
||||
# FIXME: In order for this config option to work, symlinks in the Plex
|
||||
# package in the Nix store have to be changed to point to this directory.
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/plex";
|
||||
description = "The directory where Plex stores its data files.";
|
||||
description = ''
|
||||
The directory where Plex stores its data files.
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open ports in the firewall for the media server
|
||||
Open ports in the firewall for the media server.
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "plex";
|
||||
description = "User account under which Plex runs.";
|
||||
description = ''
|
||||
User account under which Plex runs.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "plex";
|
||||
description = "Group under which Plex runs.";
|
||||
description = ''
|
||||
Group under which Plex runs.
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
managePlugins = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
|
@ -80,73 +83,48 @@ in
|
|||
description = "Plex Media Server";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = ''
|
||||
test -d "${cfg.dataDir}/Plex Media Server" || {
|
||||
echo "Creating initial Plex data directory in \"${cfg.dataDir}\"."
|
||||
mkdir -p "${cfg.dataDir}/Plex Media Server"
|
||||
chown -R ${cfg.user}:${cfg.group} "${cfg.dataDir}"
|
||||
}
|
||||
|
||||
# Copy the database skeleton files to /var/lib/plex/.skeleton
|
||||
# See the the Nix expression for Plex's package for more information on
|
||||
# why this is done.
|
||||
install --owner ${cfg.user} --group ${cfg.group} -d "${cfg.dataDir}/.skeleton"
|
||||
for db in "com.plexapp.plugins.library.db"; do
|
||||
if [ ! -e "${cfg.dataDir}/.skeleton/$db" ]; then
|
||||
cp "${cfg.package}/usr/lib/plexmediaserver/Resources/base_$db" "${cfg.dataDir}/.skeleton/$db"
|
||||
fi
|
||||
chmod u+w "${cfg.dataDir}/.skeleton/$db"
|
||||
chown ${cfg.user}:${cfg.group} "${cfg.dataDir}/.skeleton/$db"
|
||||
done
|
||||
|
||||
# If managePlugins is enabled, setup symlinks for plugins.
|
||||
${optionalString cfg.managePlugins ''
|
||||
echo "Preparing plugin directory."
|
||||
PLUGINDIR="${cfg.dataDir}/Plex Media Server/Plug-ins"
|
||||
test -d "$PLUGINDIR" || {
|
||||
mkdir -p "$PLUGINDIR";
|
||||
chown ${cfg.user}:${cfg.group} "$PLUGINDIR";
|
||||
}
|
||||
|
||||
echo "Removing old symlinks."
|
||||
# First, remove all of the symlinks in the directory.
|
||||
for f in `ls "$PLUGINDIR/"`; do
|
||||
if [[ -L "$PLUGINDIR/$f" ]]; then
|
||||
echo "Removing plugin symlink $PLUGINDIR/$f."
|
||||
rm "$PLUGINDIR/$f"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Symlinking plugins."
|
||||
for path in ${toString cfg.extraPlugins}; do
|
||||
dest="$PLUGINDIR/$(basename $path)"
|
||||
if [[ ! -d "$path" ]]; then
|
||||
echo "Error symlinking plugin from $path: no such directory."
|
||||
elif [[ -d "$dest" || -L "$dest" ]]; then
|
||||
echo "Error symlinking plugin from $path to $dest: file or directory already exists."
|
||||
else
|
||||
echo "Symlinking plugin at $path..."
|
||||
ln -s "$path" "$dest"
|
||||
fi
|
||||
done
|
||||
''}
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
PermissionsStartOnly = "true";
|
||||
ExecStart = "\"${cfg.package}/usr/lib/plexmediaserver/Plex Media Server\"";
|
||||
|
||||
# Run the pre-start script with full permissions (the "!" prefix) so it
|
||||
# can create the data directory if necessary.
|
||||
ExecStartPre = let
|
||||
preStartScript = pkgs.writeScript "plex-run-prestart" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
|
||||
# Create data directory if it doesn't exist
|
||||
if ! test -d "$PLEX_DATADIR"; then
|
||||
echo "Creating initial Plex data directory in: $PLEX_DATADIR"
|
||||
install -d -m 0755 -o "${cfg.user}" -g "${cfg.group}" "$PLEX_DATADIR"
|
||||
fi
|
||||
'';
|
||||
in
|
||||
"!${preStartScript}";
|
||||
|
||||
ExecStart = "${cfg.package}/bin/plexmediaserver";
|
||||
KillSignal = "SIGQUIT";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
|
||||
environment = {
|
||||
PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR=cfg.dataDir;
|
||||
PLEX_MEDIA_SERVER_HOME="${cfg.package}/usr/lib/plexmediaserver";
|
||||
# Configuration for our FHS userenv script
|
||||
PLEX_DATADIR=cfg.dataDir;
|
||||
PLEX_PLUGINS=concatMapStringsSep ":" builtins.toString cfg.extraPlugins;
|
||||
|
||||
# The following variables should be set by the FHS userenv script:
|
||||
# PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR
|
||||
# PLEX_MEDIA_SERVER_HOME
|
||||
|
||||
# Allow access to GPU acceleration; the Plex LD_LIBRARY_PATH is added
|
||||
# by the FHS userenv script.
|
||||
LD_LIBRARY_PATH="/run/opengl-driver/lib";
|
||||
|
||||
PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS="6";
|
||||
PLEX_MEDIA_SERVER_TMPDIR="/tmp";
|
||||
PLEX_MEDIA_SERVER_USE_SYSLOG="true";
|
||||
LD_LIBRARY_PATH="/run/opengl-driver/lib:${cfg.package}/usr/lib/plexmediaserver/lib";
|
||||
LC_ALL="en_US.UTF-8";
|
||||
LANG="en_US.UTF-8";
|
||||
};
|
||||
|
|
312
nixos/modules/services/networking/wg-quick.nix
Normal file
312
nixos/modules/services/networking/wg-quick.nix
Normal file
|
@ -0,0 +1,312 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.networking.wg-quick;
|
||||
|
||||
kernel = config.boot.kernelPackages;
|
||||
|
||||
# interface options
|
||||
|
||||
interfaceOpts = { ... }: {
|
||||
options = {
|
||||
address = mkOption {
|
||||
example = [ "192.168.2.1/24" ];
|
||||
default = [];
|
||||
type = with types; listOf str;
|
||||
description = "The IP addresses of the interface.";
|
||||
};
|
||||
|
||||
dns = mkOption {
|
||||
example = [ "192.168.2.2" ];
|
||||
default = [];
|
||||
type = with types; listOf str;
|
||||
description = "The IP addresses of DNS servers to configure.";
|
||||
};
|
||||
|
||||
privateKey = mkOption {
|
||||
example = "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=";
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Base64 private key generated by wg genkey.
|
||||
|
||||
Warning: Consider using privateKeyFile instead if you do not
|
||||
want to store the key in the world-readable Nix store.
|
||||
'';
|
||||
};
|
||||
|
||||
privateKeyFile = mkOption {
|
||||
example = "/private/wireguard_key";
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Private key file as generated by wg genkey.
|
||||
'';
|
||||
};
|
||||
|
||||
listenPort = mkOption {
|
||||
default = null;
|
||||
type = with types; nullOr int;
|
||||
example = 51820;
|
||||
description = ''
|
||||
16-bit port for listening. Optional; if not specified,
|
||||
automatically generated based on interface name.
|
||||
'';
|
||||
};
|
||||
|
||||
preUp = mkOption {
|
||||
example = literalExample ''
|
||||
${pkgs.iproute}/bin/ip netns add foo
|
||||
'';
|
||||
default = "";
|
||||
type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines;
|
||||
description = ''
|
||||
Commands called at the start of the interface setup.
|
||||
'';
|
||||
};
|
||||
|
||||
preDown = mkOption {
|
||||
example = literalExample ''
|
||||
${pkgs.iproute}/bin/ip netns del foo
|
||||
'';
|
||||
default = "";
|
||||
type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines;
|
||||
description = ''
|
||||
Command called before the interface is taken down.
|
||||
'';
|
||||
};
|
||||
|
||||
postUp = mkOption {
|
||||
example = literalExample ''
|
||||
${pkgs.iproute}/bin/ip netns add foo
|
||||
'';
|
||||
default = "";
|
||||
type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines;
|
||||
description = ''
|
||||
Commands called after the interface setup.
|
||||
'';
|
||||
};
|
||||
|
||||
postDown = mkOption {
|
||||
example = literalExample ''
|
||||
${pkgs.iproute}/bin/ip netns del foo
|
||||
'';
|
||||
default = "";
|
||||
type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines;
|
||||
description = ''
|
||||
Command called after the interface is taken down.
|
||||
'';
|
||||
};
|
||||
|
||||
table = mkOption {
|
||||
example = "main";
|
||||
default = null;
|
||||
type = with types; nullOr str;
|
||||
description = ''
|
||||
The kernel routing table to add this interface's
|
||||
associated routes to. Setting this is useful for e.g. policy routing
|
||||
("ip rule") or virtual routing and forwarding ("ip vrf"). Both numeric
|
||||
table IDs and table names (/etc/rt_tables) can be used. Defaults to
|
||||
"main".
|
||||
'';
|
||||
};
|
||||
|
||||
mtu = mkOption {
|
||||
example = 1248;
|
||||
default = null;
|
||||
type = with types; nullOr int;
|
||||
description = ''
|
||||
If not specified, the MTU is automatically determined
|
||||
from the endpoint addresses or the system default route, which is usually
|
||||
a sane choice. However, to manually specify an MTU to override this
|
||||
automatic discovery, this value may be specified explicitly.
|
||||
'';
|
||||
};
|
||||
|
||||
peers = mkOption {
|
||||
default = [];
|
||||
description = "Peers linked to the interface.";
|
||||
type = with types; listOf (submodule peerOpts);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# peer options
|
||||
|
||||
peerOpts = {
|
||||
options = {
|
||||
publicKey = mkOption {
|
||||
example = "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=";
|
||||
type = types.str;
|
||||
description = "The base64 public key the peer.";
|
||||
};
|
||||
|
||||
presharedKey = mkOption {
|
||||
default = null;
|
||||
example = "rVXs/Ni9tu3oDBLS4hOyAUAa1qTWVA3loR8eL20os3I=";
|
||||
type = with types; nullOr str;
|
||||
description = ''
|
||||
Base64 preshared key generated by wg genpsk. Optional,
|
||||
and may be omitted. This option adds an additional layer of
|
||||
symmetric-key cryptography to be mixed into the already existing
|
||||
public-key cryptography, for post-quantum resistance.
|
||||
|
||||
Warning: Consider using presharedKeyFile instead if you do not
|
||||
want to store the key in the world-readable Nix store.
|
||||
'';
|
||||
};
|
||||
|
||||
presharedKeyFile = mkOption {
|
||||
default = null;
|
||||
example = "/private/wireguard_psk";
|
||||
type = with types; nullOr str;
|
||||
description = ''
|
||||
File pointing to preshared key as generated by wg pensk. Optional,
|
||||
and may be omitted. This option adds an additional layer of
|
||||
symmetric-key cryptography to be mixed into the already existing
|
||||
public-key cryptography, for post-quantum resistance.
|
||||
'';
|
||||
};
|
||||
|
||||
allowedIPs = mkOption {
|
||||
example = [ "10.192.122.3/32" "10.192.124.1/24" ];
|
||||
type = with types; listOf str;
|
||||
description = ''List of IP (v4 or v6) addresses with CIDR masks from
|
||||
which this peer is allowed to send incoming traffic and to which
|
||||
outgoing traffic for this peer is directed. The catch-all 0.0.0.0/0 may
|
||||
be specified for matching all IPv4 addresses, and ::/0 may be specified
|
||||
for matching all IPv6 addresses.'';
|
||||
};
|
||||
|
||||
endpoint = mkOption {
|
||||
default = null;
|
||||
example = "demo.wireguard.io:12913";
|
||||
type = with types; nullOr str;
|
||||
description = ''Endpoint IP or hostname of the peer, followed by a colon,
|
||||
and then a port number of the peer.'';
|
||||
};
|
||||
|
||||
persistentKeepalive = mkOption {
|
||||
default = null;
|
||||
type = with types; nullOr int;
|
||||
example = 25;
|
||||
description = ''This is optional and is by default off, because most
|
||||
users will not need it. It represents, in seconds, between 1 and 65535
|
||||
inclusive, how often to send an authenticated empty packet to the peer,
|
||||
for the purpose of keeping a stateful firewall or NAT mapping valid
|
||||
persistently. For example, if the interface very rarely sends traffic,
|
||||
but it might at anytime receive traffic from a peer, and it is behind
|
||||
NAT, the interface might benefit from having a persistent keepalive
|
||||
interval of 25 seconds; however, most users will not need this.'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
writeScriptFile = name: text: ((pkgs.writeShellScriptBin name text) + "/bin/${name}");
|
||||
|
||||
generateUnit = name: values:
|
||||
assert assertMsg ((values.privateKey != null) != (values.privateKeyFile != null)) "Only one of privateKey or privateKeyFile may be set";
|
||||
let
|
||||
preUpFile = if values.preUp != "" then writeScriptFile "preUp.sh" values.preUp else null;
|
||||
postUp =
|
||||
optional (values.privateKeyFile != null) "wg set ${name} private-key <(cat ${values.privateKeyFile})" ++
|
||||
(concatMap (peer: optional (peer.presharedKeyFile != null) "wg set ${name} peer ${peer.publicKey} preshared-key <(cat ${peer.presharedKeyFile})") values.peers) ++
|
||||
optional (values.postUp != null) values.postUp;
|
||||
postUpFile = if postUp != [] then writeScriptFile "postUp.sh" (concatMapStringsSep "\n" (line: line) postUp) else null;
|
||||
preDownFile = if values.preDown != "" then writeScriptFile "preDown.sh" values.preDown else null;
|
||||
postDownFile = if values.postDown != "" then writeScriptFile "postDown.sh" values.postDown else null;
|
||||
configDir = pkgs.writeTextFile {
|
||||
name = "config-${name}";
|
||||
executable = false;
|
||||
destination = "/${name}.conf";
|
||||
text =
|
||||
''
|
||||
[interface]
|
||||
${concatMapStringsSep "\n" (address:
|
||||
"Address = ${address}"
|
||||
) values.address}
|
||||
${concatMapStringsSep "\n" (dns:
|
||||
"DNS = ${dns}"
|
||||
) values.dns}
|
||||
'' +
|
||||
optionalString (values.table != null) "Table = ${values.table}\n" +
|
||||
optionalString (values.mtu != null) "MTU = ${toString values.mtu}\n" +
|
||||
optionalString (values.privateKey != null) "PrivateKey = ${values.privateKey}\n" +
|
||||
optionalString (values.listenPort != null) "ListenPort = ${toString values.listenPort}\n" +
|
||||
optionalString (preUpFile != null) "PreUp = ${preUpFile}\n" +
|
||||
optionalString (postUpFile != null) "PostUp = ${postUpFile}\n" +
|
||||
optionalString (preDownFile != null) "PreDown = ${preDownFile}\n" +
|
||||
optionalString (postDownFile != null) "PostDown = ${postDownFile}\n" +
|
||||
concatMapStringsSep "\n" (peer:
|
||||
assert assertMsg (!((peer.presharedKeyFile != null) && (peer.presharedKey != null))) "Only one of presharedKey or presharedKeyFile may be set";
|
||||
"[Peer]\n" +
|
||||
"PublicKey = ${peer.publicKey}\n" +
|
||||
optionalString (peer.presharedKey != null) "PresharedKey = ${peer.presharedKey}\n" +
|
||||
optionalString (peer.endpoint != null) "Endpoint = ${peer.endpoint}\n" +
|
||||
optionalString (peer.persistentKeepalive != null) "PersistentKeepalive = ${toString peer.persistentKeepalive}\n" +
|
||||
optionalString (peer.allowedIPs != []) "AllowedIPs = ${concatStringsSep "," peer.allowedIPs}\n"
|
||||
) values.peers;
|
||||
};
|
||||
configPath = "${configDir}/${name}.conf";
|
||||
in
|
||||
nameValuePair "wg-quick-${name}"
|
||||
{
|
||||
description = "wg-quick WireGuard Tunnel - ${name}";
|
||||
requires = [ "network-online.target" ];
|
||||
after = [ "network.target" "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment.DEVICE = name;
|
||||
path = [ pkgs.kmod pkgs.wireguard-tools ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
|
||||
script = ''
|
||||
${optionalString (!config.boot.isContainer) "modprobe wireguard"}
|
||||
wg-quick up ${configPath}
|
||||
'';
|
||||
|
||||
preStop = ''
|
||||
wg-quick down ${configPath}
|
||||
'';
|
||||
};
|
||||
in {
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
networking.wg-quick = {
|
||||
interfaces = mkOption {
|
||||
description = "Wireguard interfaces.";
|
||||
default = {};
|
||||
example = {
|
||||
wg0 = {
|
||||
address = [ "192.168.20.4/24" ];
|
||||
privateKey = "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=";
|
||||
peers = [
|
||||
{ allowedIPs = [ "192.168.20.1/32" ];
|
||||
publicKey = "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=";
|
||||
endpoint = "demo.wireguard.io:12913"; }
|
||||
];
|
||||
};
|
||||
};
|
||||
type = with types; attrsOf (submodule interfaceOpts);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf (cfg.interfaces != {}) {
|
||||
boot.extraModulePackages = [ kernel.wireguard ];
|
||||
environment.systemPackages = [ pkgs.wireguard-tools ];
|
||||
# This is forced to false for now because the default "--validmark" rpfilter we apply on reverse path filtering
|
||||
# breaks the wg-quick routing because wireguard packets leave with a fwmark from wireguard.
|
||||
networking.firewall.checkReversePath = false;
|
||||
systemd.services = mapAttrs' generateUnit cfg.interfaces;
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue