blob: 66122a53e842fb27ed7f33d3450cdf995c68af9e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
# This module configures a WireGuard for qBittorrent to use.
{config, ...}: let
wgInterface = "wg0";
wgPort = 51820;
in {
# TODO: Use Peer as DNS server: https://arc.net/l/quote/axlprdca
# Create a connection to Mullvad's WireGuard server.
networking.wireguard.interfaces = {
${wgInterface} = {
# The port to use for communication. This should also be opened in the firewall.
ips = ["10.2.0.2/32"];
privateKeyFile = config.age.secrets.mullvad-wg-key.path;
allowedIPsAsRoutes = false;
listenPort = wgPort;
# Create a differente networking namespace to isolate the qBittorent
# process. I decided not to do this because connecting the WebUI to NGINX
# becomes a bit tricky then. I will keep it around just in case I take up
# this issue again sometime later.
#
# Remember, you would also need to set NetworkNamespacePath= on
# qBittorrent [0]. The network namespace would when be located under
# /run/netns/${wgNamespace}.
#
# [0]: https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#NetworkNamespacePath=
#
# interfaceNamespace = wgNamespace;
# preSetup = ''
# echo "Setting up namespace: ${wgNamespace}"
# ${pkgs.iproute2}/bin/ip netns add ${wgNamespace}
# ${pkgs.iproute2}/bin/ip -n ${wgNamespace} link set lo up
# '';
# postShutdown = ''
# echo "Tearing down namespace: ${wgNamespace}"
# ${pkgs.iproute2}/bin/ip netns del "${wgNamespace}"
# '';
# Since this is a client configuration, we only need a single peer: the Mullvad server.
peers = [
{
# The public key of the server.
publicKey = "9WowgFUh2itRfPh2SoaJsJHvxzXBZuD+xqdmBAf2CB4=";
# The location of the server.
endpoint = "149.50.217.161:${toString wgPort}";
# Which destination IPs should be directed to this ip/pubkey pair. In
# this case, we send all packets to our only peer.
#
# NOTE: It is important the we either use a network namespace or set
# `allowedIPsAsRoutes = false` as otherwise we run into the loop
# routing problem.
#
# See: https://wiki.archlinux.org/title/WireGuard#Loop_routing
# See: https://cohost.org/linuwus/post/5040530-an-unexpected-soluti
allowedIPs = ["0.0.0.0/0" "::/0"];
# Send keepalives messages. Important to keep NAT tables alive.
persistentKeepalive = 25;
}
];
};
};
# Here we load the secret file containing this clients private key. It is
# defined in the configuration file from Mullvad's website.
age.secrets.mullvad-wg-key.file = ../../../secrets/mullvad-wg.key.age;
networking.firewall = {
# Clients and peers use the same port. I'm actually not sure we need to
# accept incomming connections as clients participating in the wireguard
# protocol.
allowedUDPPorts = [wgPort];
# This is a weird fix. Apparently the rpfilter set up as part of
# nixos-rpfilter in the 'mangle' table will block WireGuard traffic.
# Setting this to "loose" somehow fixes that.
#
# See: https://discourse.nixos.org/t/solved-minimal-firewall-setup-for-wireguard-client/7577/2?u=linnnus
# See: https://github.com/NixOS/nixpkgs/issues/51258#issuecomment-448005659
checkReversePath = "loose";
};
# Configure qBittorrent to only torrent through the wireguard interface.
services.qbittorrent.settings = {
Bittorrent = {
"Session\\Interface" = wgInterface;
"Session\\InterfaceName" = wgInterface;
};
};
# We also instruct qBittorrent to wait for the wireguard interface to come
# online. This lets us avoid an awkward interim where qBittorrent is live
# but can't torrent anything.
#
# FIXME: Maybe not strictly necessary.
systemd.services.qbittorrent.unitConfig.After = ["wireguard-${wgInterface}.target"];
}
|