Compare commits
4 Commits
aaa1800d0c
...
440401a391
Author | SHA1 | Date | |
---|---|---|---|
440401a391 | |||
42c0dcae2d | |||
7159868b57 | |||
ab2cc0cc0a |
9
TODO.md
9
TODO.md
@ -52,15 +52,6 @@
|
|||||||
- https://ampache.org/
|
- https://ampache.org/
|
||||||
- replace nextcloud with seafile
|
- replace nextcloud with seafile
|
||||||
|
|
||||||
### VPN container
|
|
||||||
- use wireguard for vpn
|
|
||||||
- https://github.com/triffid/pia-wg/blob/master/pia-wg.sh
|
|
||||||
- https://github.com/pia-foss/manual-connections
|
|
||||||
- port forwarding for vpn
|
|
||||||
- transmission using forwarded port
|
|
||||||
- https://www.wireguard.com/netns/
|
|
||||||
- one way firewall for vpn container
|
|
||||||
|
|
||||||
### Networking
|
### Networking
|
||||||
- tailscale for p2p connections
|
- tailscale for p2p connections
|
||||||
- remove all use of zerotier
|
- remove all use of zerotier
|
||||||
|
@ -6,6 +6,15 @@
|
|||||||
# https://github.com/pia-foss/manual-connections
|
# https://github.com/pia-foss/manual-connections
|
||||||
# https://github.com/thrnz/docker-wireguard-pia/blob/master/extra/wg-gen.sh
|
# https://github.com/thrnz/docker-wireguard-pia/blob/master/extra/wg-gen.sh
|
||||||
|
|
||||||
|
# TODO turn on firewall for VPN interface
|
||||||
|
# TODO handle potential errors (or at least print status, success, and failures to the console)
|
||||||
|
# TODO handle 2 month limit for port
|
||||||
|
# TODO handle VPN container with different name
|
||||||
|
# - TODO parameterize names of systemd services so that multiple wg VPNs could coexist in theory easier
|
||||||
|
# - TODO implement this module such that the wireguard VPN doesn't have to live in a container
|
||||||
|
# TODO add some variance to the port forward timer
|
||||||
|
# TODO look at wg-gen script for example of looking up a random server in a region and connect to that (user should not need to specify IP addr)
|
||||||
|
|
||||||
with builtins;
|
with builtins;
|
||||||
|
|
||||||
let
|
let
|
||||||
@ -17,9 +26,22 @@ let
|
|||||||
# PIA_TOKEN only lasts 24hrs
|
# PIA_TOKEN only lasts 24hrs
|
||||||
PIA_TOKEN=`curl -s -u "$PIA_USER:$PIA_PASS" https://www.privateinternetaccess.com/gtoken/generateToken | jq -r '.token'`
|
PIA_TOKEN=`curl -s -u "$PIA_USER:$PIA_PASS" https://www.privateinternetaccess.com/gtoken/generateToken | jq -r '.token'`
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
refreshPIAPort = ''
|
||||||
|
signature=`sed '1q;d' /tmp/${cfg.interfaceName}-port-renewal`
|
||||||
|
payload=`sed '2q;d' /tmp/${cfg.interfaceName}-port-renewal`
|
||||||
|
bind_port_response=`curl -Gs -m 5 --connect-to "${cfg.serverHostname}::${cfg.serverIp}:" --cacert "${./ca.rsa.4096.crt}" --data-urlencode "payload=$payload" --data-urlencode "signature=$signature" "https://${cfg.serverHostname}:19999/bindPort"`
|
||||||
|
'';
|
||||||
|
|
||||||
|
portForwarding = cfg.forwardPortForTransmission || cfg.forwardedPort != null;
|
||||||
in {
|
in {
|
||||||
options.pia.wireguard = {
|
options.pia.wireguard = {
|
||||||
enable = lib.mkEnableOption "Enable private internet access";
|
enable = lib.mkEnableOption "Enable private internet access";
|
||||||
|
wireguardListenPort = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
description = "The port wireguard listens on for this VPN connection";
|
||||||
|
default = 51820;
|
||||||
|
};
|
||||||
serverHostname = lib.mkOption {
|
serverHostname = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "zurich406";
|
default = "zurich406";
|
||||||
@ -33,30 +55,36 @@ in {
|
|||||||
default = "piaw";
|
default = "piaw";
|
||||||
};
|
};
|
||||||
forwardedPort = lib.mkOption {
|
forwardedPort = lib.mkOption {
|
||||||
type = lib.types.port;
|
type = lib.types.nullOr lib.types.port;
|
||||||
description = "The port to redirect port forwarded TCP VPN traffic too";
|
description = "The port to redirect port forwarded TCP VPN traffic too";
|
||||||
default = 15050;
|
default = null;
|
||||||
};
|
};
|
||||||
# TODO allow disabling this
|
forwardPortForTransmission = lib.mkEnableOption "PIA port forwarding for transmission should be performed.";
|
||||||
portForwarding = lib.mkEnableOption "Enables PIA port fowarding";
|
|
||||||
|
|
||||||
# TODO implement this such that the wireguard VPN doesn't have to live in a container
|
|
||||||
useInVPNContainer = lib.mkEnableOption "Configures the PIA WG VPN for use in the VPN container";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = cfg.forwardPortForTransmission != (cfg.forwardedPort != null);
|
||||||
|
message = ''
|
||||||
|
The PIA forwarded port cannot simultaneously be used by transmission and redirected to another port.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
vpn-container.mounts = [ "/tmp/${cfg.interfaceName}.conf" "/tmp/${cfg.interfaceName}-address.conf" ];
|
vpn-container.mounts = [ "/tmp/${cfg.interfaceName}.conf" "/tmp/${cfg.interfaceName}-address.conf" ];
|
||||||
containers.vpn.interfaces = [ cfg.interfaceName ];
|
containers.vpn.interfaces = [ cfg.interfaceName ];
|
||||||
|
|
||||||
|
# TODO: while this is much better than "loose" networking, it seems to have issues with firewall restarts
|
||||||
# allow traffic for wireguard interface to pass since wireguard trips up rpfilter
|
# allow traffic for wireguard interface to pass since wireguard trips up rpfilter
|
||||||
# networking.firewall = {
|
# networking.firewall = {
|
||||||
# extraCommands = ''
|
# extraCommands = ''
|
||||||
# ip46tables -t raw -I nixos-fw-rpfilter -p udp -m udp --sport 51820 -j RETURN
|
# ip46tables -t raw -I nixos-fw-rpfilter -p udp -m udp --sport ${toString cfg.wireguardListenPort} -j RETURN
|
||||||
# ip46tables -t raw -I nixos-fw-rpfilter -p udp -m udp --dport 51820 -j RETURN
|
# ip46tables -t raw -I nixos-fw-rpfilter -p udp -m udp --dport ${toString cfg.wireguardListenPort} -j RETURN
|
||||||
# '';
|
# '';
|
||||||
# extraStopCommands = ''
|
# extraStopCommands = ''
|
||||||
# ip46tables -t raw -D nixos-fw-rpfilter -p udp -m udp --sport 51820 -j RETURN || true
|
# ip46tables -t raw -D nixos-fw-rpfilter -p udp -m udp --sport ${toString cfg.wireguardListenPort} -j RETURN || true
|
||||||
# ip46tables -t raw -D nixos-fw-rpfilter -p udp -m udp --dport 51820 -j RETURN || true
|
# ip46tables -t raw -D nixos-fw-rpfilter -p udp -m udp --dport ${toString cfg.wireguardListenPort} -j RETURN || true
|
||||||
# '';
|
# '';
|
||||||
# };
|
# };
|
||||||
networking.firewall.checkReversePath = "loose";
|
networking.firewall.checkReversePath = "loose";
|
||||||
@ -88,11 +116,14 @@ in {
|
|||||||
|
|
||||||
${getPIAToken}
|
${getPIAToken}
|
||||||
|
|
||||||
|
# generate wireguard keys
|
||||||
privKey=$(wg genkey)
|
privKey=$(wg genkey)
|
||||||
pubKey=$(echo "$privKey" | wg pubkey)
|
pubKey=$(echo "$privKey" | wg pubkey)
|
||||||
|
|
||||||
|
# authorize our WG keys with the PIA server we are about to connect to
|
||||||
wireguard_json=`curl -s -G --connect-to "$WG_HOSTNAME::$WG_SERVER_IP:" --cacert "${./ca.rsa.4096.crt}" --data-urlencode "pt=$PIA_TOKEN" --data-urlencode "pubkey=$pubKey" https://$WG_HOSTNAME:1337/addKey`
|
wireguard_json=`curl -s -G --connect-to "$WG_HOSTNAME::$WG_SERVER_IP:" --cacert "${./ca.rsa.4096.crt}" --data-urlencode "pt=$PIA_TOKEN" --data-urlencode "pubkey=$pubKey" https://$WG_HOSTNAME:1337/addKey`
|
||||||
|
|
||||||
|
# create wg-quick config file
|
||||||
rm -f /tmp/${cfg.interfaceName}.conf /tmp/${cfg.interfaceName}-address.conf
|
rm -f /tmp/${cfg.interfaceName}.conf /tmp/${cfg.interfaceName}-address.conf
|
||||||
touch /tmp/${cfg.interfaceName}.conf /tmp/${cfg.interfaceName}-address.conf
|
touch /tmp/${cfg.interfaceName}.conf /tmp/${cfg.interfaceName}-address.conf
|
||||||
chmod 700 /tmp/${cfg.interfaceName}.conf /tmp/${cfg.interfaceName}-address.conf
|
chmod 700 /tmp/${cfg.interfaceName}.conf /tmp/${cfg.interfaceName}-address.conf
|
||||||
@ -100,13 +131,15 @@ in {
|
|||||||
[Interface]
|
[Interface]
|
||||||
# Address = $(echo "$wireguard_json" | jq -r '.peer_ip')
|
# Address = $(echo "$wireguard_json" | jq -r '.peer_ip')
|
||||||
PrivateKey = $privKey
|
PrivateKey = $privKey
|
||||||
ListenPort = 51820
|
ListenPort = ${toString cfg.wireguardListenPort}
|
||||||
[Peer]
|
[Peer]
|
||||||
PersistentKeepalive = 25
|
PersistentKeepalive = 25
|
||||||
PublicKey = $(echo "$wireguard_json" | jq -r '.server_key')
|
PublicKey = $(echo "$wireguard_json" | jq -r '.server_key')
|
||||||
AllowedIPs = 0.0.0.0/0
|
AllowedIPs = 0.0.0.0/0
|
||||||
Endpoint = $WG_SERVER_IP:$(echo "$wireguard_json" | jq -r '.server_port')
|
Endpoint = $WG_SERVER_IP:$(echo "$wireguard_json" | jq -r '.server_port')
|
||||||
" >> /tmp/${cfg.interfaceName}.conf
|
" >> /tmp/${cfg.interfaceName}.conf
|
||||||
|
|
||||||
|
# create file storing the VPN ip address PIA assigned to us
|
||||||
echo "$wireguard_json" | jq -r '.peer_ip' >> /tmp/${cfg.interfaceName}-address.conf
|
echo "$wireguard_json" | jq -r '.peer_ip' >> /tmp/${cfg.interfaceName}-address.conf
|
||||||
|
|
||||||
# Create wg interface now so it inherits from the namespace with internet access
|
# Create wg interface now so it inherits from the namespace with internet access
|
||||||
@ -118,7 +151,9 @@ in {
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
preStop = ''
|
preStop = ''
|
||||||
|
# cleanup wireguard interface
|
||||||
ip link del ${cfg.interfaceName}
|
ip link del ${cfg.interfaceName}
|
||||||
|
rm -f /tmp/${cfg.interfaceName}.conf /tmp/${cfg.interfaceName}-address.conf
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -138,24 +173,26 @@ in {
|
|||||||
|
|
||||||
script = ''
|
script = ''
|
||||||
# pseudo calls wg-quick
|
# pseudo calls wg-quick
|
||||||
# wg-quick down /tmp/${cfg.interfaceName}.conf
|
# Near equivalent of "wg-quick up /tmp/${cfg.interfaceName}.conf"
|
||||||
# cannot actually call wg-quick because the interface has to be already created at this point
|
# cannot actually call wg-quick because the interface has to be already
|
||||||
|
# created before the container taken ownership of the interface
|
||||||
# assumes wg interface was already created
|
# Thus, assumes wg interface was already created:
|
||||||
# ip link add ${cfg.interfaceName} type wireguard
|
# ip link add ${cfg.interfaceName} type wireguard
|
||||||
|
|
||||||
myaddress=`cat /tmp/${cfg.interfaceName}-address.conf`
|
myaddress=`cat /tmp/${cfg.interfaceName}-address.conf`
|
||||||
|
|
||||||
wg setconf ${cfg.interfaceName} /tmp/${cfg.interfaceName}.conf
|
wg setconf ${cfg.interfaceName} /tmp/${cfg.interfaceName}.conf
|
||||||
ip -4 address add $myaddress dev ${cfg.interfaceName}
|
ip -4 address add $myaddress dev ${cfg.interfaceName}
|
||||||
ip link set mtu 1420 up dev ${cfg.interfaceName}
|
ip link set mtu 1420 up dev ${cfg.interfaceName}
|
||||||
wg set ${cfg.interfaceName} fwmark 51820
|
wg set ${cfg.interfaceName} fwmark ${toString cfg.wireguardListenPort}
|
||||||
ip -4 route add 0.0.0.0/0 dev ${cfg.interfaceName} table 51820
|
ip -4 route add 0.0.0.0/0 dev ${cfg.interfaceName} table ${toString cfg.wireguardListenPort}
|
||||||
|
|
||||||
# TODO is this needed?
|
# TODO is this needed?
|
||||||
ip -4 rule add not fwmark 51820 table 51820
|
ip -4 rule add not fwmark ${toString cfg.wireguardListenPort} table ${toString cfg.wireguardListenPort}
|
||||||
ip -4 rule add table main suppress_prefixlength 0
|
ip -4 rule add table main suppress_prefixlength 0
|
||||||
# sysctl -q net.ipv4.conf.all.src_valid_mark=1
|
|
||||||
|
# The rest of the script is only for only for port forwarding skip if not needed
|
||||||
|
if [ ${lib.boolToString portForwarding} == false ]; then exit 0; fi
|
||||||
|
|
||||||
# Reserve port
|
# Reserve port
|
||||||
${getPIAToken}
|
${getPIAToken}
|
||||||
@ -175,30 +212,55 @@ in {
|
|||||||
echo $signature >> /tmp/${cfg.interfaceName}-port-renewal
|
echo $signature >> /tmp/${cfg.interfaceName}-port-renewal
|
||||||
echo $payload >> /tmp/${cfg.interfaceName}-port-renewal
|
echo $payload >> /tmp/${cfg.interfaceName}-port-renewal
|
||||||
|
|
||||||
# redirect the fowarded port
|
# The first port refresh triggers the port to be actually allocated
|
||||||
# iptables -A INPUT -i ${cfg.interfaceName} -p tcp --dport $port -j ACCEPT
|
${refreshPIAPort}
|
||||||
# iptables -A INPUT -i ${cfg.interfaceName} -p udp --dport $port -j ACCEPT
|
|
||||||
# iptables -A INPUT -i ${cfg.interfaceName} -p tcp --dport ${toString cfg.forwardedPort} -j ACCEPT
|
${lib.optionalString (cfg.forwardedPort != null) ''
|
||||||
# iptables -A INPUT -i ${cfg.interfaceName} -p udp --dport ${toString cfg.forwardedPort} -j ACCEPT
|
# redirect the fowarded port
|
||||||
# iptables -A PREROUTING -t nat -i ${cfg.interfaceName} -p tcp --dport $port -j REDIRECT --to-port ${toString cfg.forwardedPort}
|
iptables -A INPUT -i ${cfg.interfaceName} -p tcp --dport $port -j ACCEPT
|
||||||
# iptables -A PREROUTING -t nat -i ${cfg.interfaceName} -p udp --dport $port -j REDIRECT --to-port ${toString cfg.forwardedPort}
|
iptables -A INPUT -i ${cfg.interfaceName} -p udp --dport $port -j ACCEPT
|
||||||
|
iptables -A INPUT -i ${cfg.interfaceName} -p tcp --dport ${toString cfg.forwardedPort} -j ACCEPT
|
||||||
|
iptables -A INPUT -i ${cfg.interfaceName} -p udp --dport ${toString cfg.forwardedPort} -j ACCEPT
|
||||||
|
iptables -A PREROUTING -t nat -i ${cfg.interfaceName} -p tcp --dport $port -j REDIRECT --to-port ${toString cfg.forwardedPort}
|
||||||
|
iptables -A PREROUTING -t nat -i ${cfg.interfaceName} -p udp --dport $port -j REDIRECT --to-port ${toString cfg.forwardedPort}
|
||||||
|
''}
|
||||||
|
|
||||||
|
${lib.optionalString cfg.forwardPortForTransmission ''
|
||||||
|
# assumes no auth needed for transmission
|
||||||
|
curlout=$(curl localhost:9091/transmission/rpc 2>/dev/null)
|
||||||
|
regex='X-Transmission-Session-Id\: (\w*)'
|
||||||
|
if [[ $curlout =~ $regex ]]; then
|
||||||
|
sessionId=''${BASH_REMATCH[1]}
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set the port in transmission
|
||||||
|
data='{"method": "session-set", "arguments": { "peer-port" :'$port' } }'
|
||||||
|
curl http://localhost:9091/transmission/rpc -d "$data" -H "X-Transmission-Session-Id: $sessionId"
|
||||||
|
''}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
preStop = ''
|
preStop = ''
|
||||||
wg-quick down /tmp/${cfg.interfaceName}.conf
|
wg-quick down /tmp/${cfg.interfaceName}.conf
|
||||||
|
|
||||||
# stop redirecting the forwarded port
|
# The rest of the script is only for only for port forwarding skip if not needed
|
||||||
# iptables -D INPUT -i ${cfg.interfaceName} -p tcp --dport $port -j ACCEPT
|
if [ ${lib.boolToString portForwarding} == false ]; then exit 0; fi
|
||||||
# iptables -D INPUT -i ${cfg.interfaceName} -p udp --dport $port -j ACCEPT
|
|
||||||
# iptables -D INPUT -i ${cfg.interfaceName} -p tcp --dport ${toString cfg.forwardedPort} -j ACCEPT
|
${lib.optionalString (cfg.forwardedPort != null) ''
|
||||||
# iptables -D INPUT -i ${cfg.interfaceName} -p udp --dport ${toString cfg.forwardedPort} -j ACCEPT
|
# stop redirecting the forwarded port
|
||||||
# iptables -D PREROUTING -t nat -i ${cfg.interfaceName} -p tcp --dport $port -j REDIRECT --to-port ${toString cfg.forwardedPort}
|
iptables -D INPUT -i ${cfg.interfaceName} -p tcp --dport $port -j ACCEPT
|
||||||
# iptables -D PREROUTING -t nat -i ${cfg.interfaceName} -p udp --dport $port -j REDIRECT --to-port ${toString cfg.forwardedPort}
|
iptables -D INPUT -i ${cfg.interfaceName} -p udp --dport $port -j ACCEPT
|
||||||
|
iptables -D INPUT -i ${cfg.interfaceName} -p tcp --dport ${toString cfg.forwardedPort} -j ACCEPT
|
||||||
|
iptables -D INPUT -i ${cfg.interfaceName} -p udp --dport ${toString cfg.forwardedPort} -j ACCEPT
|
||||||
|
iptables -D PREROUTING -t nat -i ${cfg.interfaceName} -p tcp --dport $port -j REDIRECT --to-port ${toString cfg.forwardedPort}
|
||||||
|
iptables -D PREROUTING -t nat -i ${cfg.interfaceName} -p udp --dport $port -j REDIRECT --to-port ${toString cfg.forwardedPort}
|
||||||
|
''}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
vpn-container.config.systemd.services.pia-vpn-wireguard-forward-port = {
|
vpn-container.config.systemd.services.pia-vpn-wireguard-forward-port = {
|
||||||
enable = cfg.portForwarding;
|
enable = portForwarding;
|
||||||
description = "PIA VPN WireGuard Tunnel Port Forwarding";
|
description = "PIA VPN WireGuard Tunnel Port Forwarding";
|
||||||
after = [ "pia-vpn-wireguard.service" ];
|
after = [ "pia-vpn-wireguard.service" ];
|
||||||
requires = [ "pia-vpn-wireguard.service" ];
|
requires = [ "pia-vpn-wireguard.service" ];
|
||||||
@ -209,26 +271,16 @@ in {
|
|||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
};
|
};
|
||||||
|
|
||||||
script = ''
|
script = refreshPIAPort;
|
||||||
signature=`sed '1q;d' /tmp/${cfg.interfaceName}-port-renewal`
|
|
||||||
payload=`sed '2q;d' /tmp/${cfg.interfaceName}-port-renewal`
|
|
||||||
bind_port_response=`curl -Gs -m 5 --connect-to "${cfg.serverHostname}::${cfg.serverIp}:" --cacert "${./ca.rsa.4096.crt}" --data-urlencode "payload=$payload" --data-urlencode "signature=$signature" "https://${cfg.serverHostname}:19999/bindPort"`
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
vpn-container.config.systemd.timers.pia-vpn-wireguard-forward-port = {
|
vpn-container.config.systemd.timers.pia-vpn-wireguard-forward-port = {
|
||||||
enable = cfg.portForwarding;
|
enable = portForwarding;
|
||||||
partOf = [ "pia-vpn-wireguard-forward-port.service" ];
|
partOf = [ "pia-vpn-wireguard-forward-port.service" ];
|
||||||
wantedBy = [ "timers.target" ];
|
wantedBy = [ "timers.target" ];
|
||||||
timerConfig.OnCalendar = "*:0/10"; # 10 minutes
|
timerConfig.OnCalendar = "*:0/10"; # 10 minutes
|
||||||
};
|
};
|
||||||
|
|
||||||
# TODO enable firewall on the PIA interface
|
|
||||||
# TODO handle errors
|
|
||||||
# TODO handle 2 month limit for port
|
|
||||||
# TODO print status, success, and failures to the console
|
|
||||||
# TODO handle VPN container with different name
|
|
||||||
|
|
||||||
age.secrets."pia-login.conf".file = ../../secrets/pia-login.conf;
|
age.secrets."pia-login.conf".file = ../../secrets/pia-login.conf;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -44,7 +44,7 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
pia.wireguard.enable = !cfg.useOpenVPN;
|
pia.wireguard.enable = !cfg.useOpenVPN;
|
||||||
pia.wireguard.portForwarding = !cfg.useOpenVPN;
|
pia.wireguard.forwardPortForTransmission = !cfg.useOpenVPN;
|
||||||
|
|
||||||
containers.${cfg.containerName} = {
|
containers.${cfg.containerName} = {
|
||||||
ephemeral = true;
|
ephemeral = true;
|
||||||
|
@ -16,5 +16,7 @@
|
|||||||
./owncast.nix
|
./owncast.nix
|
||||||
./mailserver.nix
|
./mailserver.nix
|
||||||
./nextcloud.nix
|
./nextcloud.nix
|
||||||
|
./iodine.nix
|
||||||
|
./searx.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
20
common/server/iodine.nix
Normal file
20
common/server/iodine.nix
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.iodine.server;
|
||||||
|
in {
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
# iodine DNS-based vpn
|
||||||
|
services.iodine.server = {
|
||||||
|
ip = "192.168.99.1";
|
||||||
|
domain = "tun.neet.dev";
|
||||||
|
passwordFile = "/run/agenix/iodine";
|
||||||
|
};
|
||||||
|
age.secrets.iodine.file = ../../secrets/iodine.age;
|
||||||
|
networking.firewall.allowedUDPPorts = [ 53 ];
|
||||||
|
|
||||||
|
networking.nat.internalInterfaces = [
|
||||||
|
"dns0" # iodine
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
29
common/server/searx.nix
Normal file
29
common/server/searx.nix
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.searx;
|
||||||
|
in {
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.searx = {
|
||||||
|
environmentFile = "/run/agenix/searx";
|
||||||
|
settings = {
|
||||||
|
server.port = 43254;
|
||||||
|
server.secret_key = "@SEARX_SECRET_KEY@";
|
||||||
|
engines = [ {
|
||||||
|
name = "wolframalpha";
|
||||||
|
shortcut = "wa";
|
||||||
|
api_key = "@WOLFRAM_API_KEY@";
|
||||||
|
engine = "wolframalpha_api";
|
||||||
|
} ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.nginx.virtualHosts."search.neet.space" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://localhost:${toString config.services.searx.settings.server.port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
age.secrets.searx.file = ../../secrets/searx.age;
|
||||||
|
};
|
||||||
|
}
|
@ -124,8 +124,9 @@
|
|||||||
in {
|
in {
|
||||||
s0 = mkDeploy "s0" "s0";
|
s0 = mkDeploy "s0" "s0";
|
||||||
router = mkDeploy "router" "192.168.1.228";
|
router = mkDeploy "router" "192.168.1.228";
|
||||||
|
ponyo = mkDeploy "ponyo" "ponyo.neet.dev";
|
||||||
};
|
};
|
||||||
|
|
||||||
# checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib;
|
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -9,17 +9,23 @@
|
|||||||
|
|
||||||
system.autoUpgrade.enable = true;
|
system.autoUpgrade.enable = true;
|
||||||
|
|
||||||
|
# p2p mesh network
|
||||||
|
services.tailscale.exitNode = true;
|
||||||
services.zerotierone.enable = true;
|
services.zerotierone.enable = true;
|
||||||
|
|
||||||
|
# email server
|
||||||
mailserver.enable = true;
|
mailserver.enable = true;
|
||||||
|
|
||||||
|
# nextcloud
|
||||||
services.nextcloud.enable = true;
|
services.nextcloud.enable = true;
|
||||||
|
|
||||||
|
# git
|
||||||
services.gitea = {
|
services.gitea = {
|
||||||
enable = true;
|
enable = true;
|
||||||
hostname = "git.neet.dev";
|
hostname = "git.neet.dev";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# IRC
|
||||||
services.thelounge = {
|
services.thelounge = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 9000;
|
port = 9000;
|
||||||
@ -31,12 +37,14 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# mumble
|
||||||
services.murmur = {
|
services.murmur = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 23563;
|
port = 23563;
|
||||||
domain = "voice.neet.space";
|
domain = "voice.neet.space";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# IRC bot
|
||||||
services.drastikbot = {
|
services.drastikbot = {
|
||||||
enable = true;
|
enable = true;
|
||||||
wolframAppIdFile = "/run/agenix/wolframalpha";
|
wolframAppIdFile = "/run/agenix/wolframalpha";
|
||||||
@ -46,7 +54,7 @@
|
|||||||
owner = config.services.drastikbot.user;
|
owner = config.services.drastikbot.user;
|
||||||
};
|
};
|
||||||
|
|
||||||
# wrap radio in a VPN
|
# music radio
|
||||||
vpn-container.enable = true;
|
vpn-container.enable = true;
|
||||||
vpn-container.config = {
|
vpn-container.config = {
|
||||||
services.radio = {
|
services.radio = {
|
||||||
@ -54,11 +62,6 @@
|
|||||||
host = "radio.runyan.org";
|
host = "radio.runyan.org";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# tailscale
|
|
||||||
services.tailscale.exitNode = true;
|
|
||||||
|
|
||||||
# icecast endpoint + website
|
|
||||||
services.nginx.virtualHosts."radio.runyan.org" = {
|
services.nginx.virtualHosts."radio.runyan.org" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
@ -73,6 +76,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# matrix home server
|
||||||
services.matrix = {
|
services.matrix = {
|
||||||
enable = true;
|
enable = true;
|
||||||
host = "neet.space";
|
host = "neet.space";
|
||||||
@ -90,45 +94,13 @@
|
|||||||
secret = "a8369a0e96922abf72494bb888c85831b";
|
secret = "a8369a0e96922abf72494bb888c85831b";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
# pin postgresql for matrix (will need to migrate eventually)
|
||||||
services.postgresql.package = pkgs.postgresql_11;
|
services.postgresql.package = pkgs.postgresql_11;
|
||||||
|
|
||||||
services.searx = {
|
|
||||||
enable = false;
|
|
||||||
environmentFile = "/run/agenix/searx";
|
|
||||||
settings = {
|
|
||||||
server.port = 43254;
|
|
||||||
server.secret_key = "@SEARX_SECRET_KEY@";
|
|
||||||
engines = [ {
|
|
||||||
name = "wolframalpha";
|
|
||||||
shortcut = "wa";
|
|
||||||
api_key = "@WOLFRAM_API_KEY@";
|
|
||||||
engine = "wolframalpha_api";
|
|
||||||
} ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
services.nginx.virtualHosts."search.neet.space" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://localhost:${toString config.services.searx.settings.server.port}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
age.secrets.searx.file = ../../secrets/searx.age;
|
|
||||||
|
|
||||||
# iodine DNS-based vpn
|
# iodine DNS-based vpn
|
||||||
services.iodine.server = {
|
services.iodine.server.enable = true;
|
||||||
enable = true;
|
|
||||||
ip = "192.168.99.1";
|
|
||||||
domain = "tun.neet.dev";
|
|
||||||
passwordFile = "/run/agenix/iodine";
|
|
||||||
};
|
|
||||||
age.secrets.iodine.file = ../../secrets/iodine.age;
|
|
||||||
networking.firewall.allowedUDPPorts = [ 53 ];
|
|
||||||
|
|
||||||
networking.nat.internalInterfaces = [
|
|
||||||
"dns0" # iodine
|
|
||||||
];
|
|
||||||
|
|
||||||
|
# proxied web services
|
||||||
services.nginx.enable = true;
|
services.nginx.enable = true;
|
||||||
services.nginx.virtualHosts."jellyfin.neet.cloud" = {
|
services.nginx.virtualHosts."jellyfin.neet.cloud" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
@ -144,13 +116,14 @@
|
|||||||
locations."/".proxyPass = "http://s0.zt.neet.dev:4533";
|
locations."/".proxyPass = "http://s0.zt.neet.dev:4533";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# TODO replace with a proper file hosting service
|
||||||
services.nginx.virtualHosts."tmp.neet.dev" = {
|
services.nginx.virtualHosts."tmp.neet.dev" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
root = "/var/www/tmp";
|
root = "/var/www/tmp";
|
||||||
};
|
};
|
||||||
|
|
||||||
# redirect to github
|
# redirect runyan.org to github
|
||||||
services.nginx.virtualHosts."runyan.org" = {
|
services.nginx.virtualHosts."runyan.org" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
@ -159,6 +132,7 @@
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# owncast live streaming
|
||||||
services.owncast.enable = true;
|
services.owncast.enable = true;
|
||||||
services.owncast.hostname = "live.neet.dev";
|
services.owncast.hostname = "live.neet.dev";
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user