diff --git a/.agenix_config.nix b/.agenix_config.nix index c1dea44..c133e78 100644 Binary files a/.agenix_config.nix and b/.agenix_config.nix differ diff --git a/Makefile b/Makefile index f641350..71629aa 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,8 @@ MACHINES := \ VPS := \ magenta \ - canigou + canigou \ + istal .PHONY: help help: diff --git a/data.nix b/data.nix index 14daf74..4c8b5b1 100644 --- a/data.nix +++ b/data.nix @@ -5,6 +5,9 @@ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJKo68e8EuKlgYG/mxEsMsfWLHXkRulpscGZUD9lXbaEyTvaGalc82T4d7wXHgUi8/xpRbsfxxTV1bl1I7X+Vq7xmzfMP5a0NBIv5Lnh5C9WHEq1aw4fUFCxD5cwy9kt1jV3pSEN/+H5cg4T0OCVRikUZvfB9wng15fdw6JYoZWhWBwZHfISHhXqTXGDnMO7MvzFCl7Ek5WBvH6LoThJFVvKkab6Zg15FtuqNpCat0yEb5QMoFUbyp2Wm0eFU5eUVnlqC6IgG765Pbz+v4sJJo0q3+sZlIgzPeav3d7FEgZeqq+UZA3Hp+4T5ww+XEHDalxsB60VDeq85snVTO8XGt" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDXNG/QeViH/SboWxbONAub/eim3NRm5MDtJA7gyTz7r" ]; + janistal = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOkFRGVFRu418QaoiPlOhw923QKe28FV1Dw41ywmOhsD" + ]; }; }; } diff --git a/home/modules/window_manager/scripts/external_ip.sh b/home/modules/window_manager/scripts/external_ip.sh index 0b22bc6..d02656a 100755 --- a/home/modules/window_manager/scripts/external_ip.sh +++ b/home/modules/window_manager/scripts/external_ip.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -res=$(dig +timeout=3 +short myip.opendns.com @resolver1.opendns.com 2>/dev/null) +res=$(dig +timeout=3 +retry=0 +short myip.opendns.com @resolver1.opendns.com 2>/dev/null) if [ -z "$res+x" ]; then text="NO CONN" echo "%{F@error@}${text}%{F-}" diff --git a/nixos/hosts/asus-gl553vd/default.nix b/nixos/hosts/asus-gl553vd/default.nix index 68912db..62b4c49 100644 --- a/nixos/hosts/asus-gl553vd/default.nix +++ b/nixos/hosts/asus-gl553vd/default.nix @@ -70,7 +70,7 @@ }; local.wireguard = { enable = true; - ip = "10.100.0.3/24"; + ip = "10.20.30.4/24"; privateKeyFile = config.age.secrets.wireguard-asus-gl553vd-private.path; }; } diff --git a/nixos/hosts/canigou/data.secret.nix b/nixos/hosts/canigou/data.secret.nix index 5c95ed5..cb378e6 100644 Binary files a/nixos/hosts/canigou/data.secret.nix and b/nixos/hosts/canigou/data.secret.nix differ diff --git a/nixos/hosts/canigou/services/update_ru_routes.nix b/nixos/hosts/canigou/services/update_ru_routes.nix new file mode 100644 index 0000000..fc2bb15 --- /dev/null +++ b/nixos/hosts/canigou/services/update_ru_routes.nix @@ -0,0 +1,23 @@ +{ writeShellScriptBin +, symlinkJoin +, makeWrapper +, bind +, iptables +, ipcalc +, jq +, gawk +, curl +}: +let + update_ru_routes_unwrapped = writeShellScriptBin "update_ru_routes" (builtins.readFile ./update_ru_routes.sh); +in +symlinkJoin { + name = "update_ru_routes"; + + paths = [ update_ru_routes_unwrapped ] ++ [ bind.dnsutils iptables jq gawk curl ipcalc ]; + buildInputs = [ makeWrapper ]; + + postBuild = '' + wrapProgram $out/bin/update_ru_routes --prefix PATH : $out/bin + ''; +} diff --git a/nixos/hosts/canigou/services/update_ru_routes.sh b/nixos/hosts/canigou/services/update_ru_routes.sh new file mode 100644 index 0000000..60dd391 --- /dev/null +++ b/nixos/hosts/canigou/services/update_ru_routes.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +function ProgressBar { + let _progress=(${1}*100/${2}*100)/100 + let _done=(${_progress}*4)/10 + let _left=40-$_done + _fill=$(printf "%${_done}s") + _empty=$(printf "%${_left}s") + printf "\rAdd routes to route table (${1}/${2}): [${_fill// /#}${_empty// /-}] ${_progress}%%" +} + +# Variables +file_raw="russian_subnets_list_raw.txt" +# file_user="subnets_user_list.txt" +file_for_calc="russian_subnets_list_raw_for_calc.txt" +file_processed="russian_subnets_list_processed.txt" +gateway_for_internal_ip=`ip route | awk '/default/ {print $3; exit}'` +interface=`ip route | awk '/default/ {print $5; exit}'` + +# Get addresses RU segment +echo "Download RU subnets..." +curl --progress-bar "https://stat.ripe.net/data/country-resource-list/data.json?resource=ru" | jq -r ".data.resources.ipv4[]" > $file_raw + +echo "Deaggregate subnets..." +cat $file_raw |grep "-" > $file_for_calc +cat $file_raw |grep -v "-" > $file_processed +for line in $(cat $file_for_calc); do + ipcalc --no-decorate -d $line >> $file_processed; +done + +# if [ -e $file_user ]; then echo "Add user subnets..."; cat $file_user |grep -v "#" >> $file_processed; fi + +# Flush route table +echo "Flush route table (down interface $interface)..." +ifdown $interface > /dev/null 2>&1 +echo "Up interface $interface..." +ifup $interface > /dev/null 2>&1 + +# Add route +routes_count_in_file=`wc -l $file_processed` +routes_count_current=0 +for line in $(cat $file_processed); do + ip route add $line via $gateway_for_internal_ip dev $interface + let "routes_count_current+=1" + ProgressBar ${routes_count_current} ${routes_count_in_file} +done +echo "" + +echo "Remove temp files..." +rm $file_raw $file_processed $file_json $file_for_calc + +routes_count=`ip r | wc -l` +echo "Routes in routing table: $routes_count" diff --git a/nixos/hosts/canigou/services/wireguard.nix b/nixos/hosts/canigou/services/wireguard.nix index 10b0add..5743be1 100644 --- a/nixos/hosts/canigou/services/wireguard.nix +++ b/nixos/hosts/canigou/services/wireguard.nix @@ -1,10 +1,17 @@ { config, pkgs, ... }: let + istalData = import ../../istal/data.secret.nix; + canigouData = import ../data.secret.nix; - port = canigouData.wireguardPort; + port = canigouData.wireguard.port; + + update_ru_routes = pkgs.callPackage ./update_ru_routes.nix { }; in { + boot.kernel.sysctl."net.ipv4.ip_forward" = 1; + boot.kernel.sysctl."net.ipv4.conf.all.forwarding" = 1; + # enable NAT networking.nat = { enable = true; @@ -16,43 +23,52 @@ in allowedUDPPorts = [ port ]; }; - networking.wireguard.interfaces = { + environment.systemPackages = [ update_ru_routes ]; + + networking.wg-quick.interfaces = { # "wg0" is the network interface name. You can name the interface arbitrarily. wg0 = { # Determines the IP address and subnet of the server's end of the tunnel interface. - ips = [ "10.100.0.1/24" ]; + address = [ "10.20.30.1/32" ]; # The port that WireGuard listens to. Must be accessible by the client. listenPort = port; # This allows the wireguard server to route your traffic to the internet and hence be like a VPN # For this to work you have to set the dnsserver IP of your router (or dnsserver of choice) in your clients - postSetup = '' - ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o eth0 -j MASQUERADE + postUp = '' + gateway=`${pkgs.iproute}/bin/ip route | ${pkgs.gawk}/bin/awk '/default/ {print $3; exit}'` + interface=`${pkgs.iproute}/bin/ip route | ${pkgs.gawk}/bin/awk '/default/ {print $5; exit}'` + ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -o $interface -j MASQUERADE + ${pkgs.iproute}/bin/ip rule add from ${canigouData.addr} table main + ${pkgs.iproute}/bin/ip route add 193.0.6.150 via $gateway dev $interface ''; - - # This undoes the above command - postShutdown = '' - ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.100.0.0/24 -o eth0 -j MASQUERADE + preDown = '' + gateway=`${pkgs.iproute}/bin/ip route | ${pkgs.gawk}/bin/awk '/default/ {print $3; exit}'` + interface=`${pkgs.iproute}/bin/ip route | ${pkgs.gawk}/bin/awk '/default/ {print $5; exit}'` + ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -o $interface -j MASQUERADE + ${pkgs.iproute}/bin/ip rule del from ${canigouData.addr} table main + ${pkgs.iproute}/bin/ip route del 193.0.6.150 via $gateway dev $interface ''; # Path to the private key file. privateKeyFile = config.age.secrets.wireguard-canigou-private.path; peers = [ - # List of allowed peers. + # Istal { - # Home - publicKey = "Gg+p7tysAhu2X841weBiQrqoKXh6kvcmDiCY62rLwQg="; - # List of IPs assigned to this peer within the tunnel subnet. Used to configure routing. - allowedIPs = [ "10.100.0.2/32" ]; - persistentKeepalive = 15; + publicKey = istalData.wireguard.publicKey; + allowedIPs = [ "10.20.30.2/32" "0.0.0.0/0" ]; } + # Home + { + publicKey = "Gg+p7tysAhu2X841weBiQrqoKXh6kvcmDiCY62rLwQg="; + allowedIPs = [ "10.20.30.3/32" ]; + } + # Asus { - # Asus publicKey = "mzVH0N3q7UE/XjMwgRks+D8KFuIj91VkOK2ytgjsnkw="; - allowedIPs = [ "10.100.0.3/32" ]; - persistentKeepalive = 15; + allowedIPs = [ "10.20.30.4/32" ]; } ]; }; diff --git a/nixos/hosts/default.nix b/nixos/hosts/default.nix index ddf5680..028490d 100644 --- a/nixos/hosts/default.nix +++ b/nixos/hosts/default.nix @@ -60,4 +60,10 @@ in targetHost = (import ./canigou/data.secret.nix).addr; }; + + istal = { + system = "x86_64-linux"; + + targetHost = (import ./istal/data.secret.nix).addr; + }; } diff --git a/nixos/hosts/home/default.nix b/nixos/hosts/home/default.nix index a20aa9d..9931e1d 100644 --- a/nixos/hosts/home/default.nix +++ b/nixos/hosts/home/default.nix @@ -98,7 +98,7 @@ }; local.wireguard = { enable = true; - ip = "10.100.0.2/24"; + ip = "10.20.30.3/24"; privateKeyFile = config.age.secrets.wireguard-home-private.path; }; diff --git a/nixos/hosts/istal/data.secret.nix b/nixos/hosts/istal/data.secret.nix new file mode 100644 index 0000000..972f4da Binary files /dev/null and b/nixos/hosts/istal/data.secret.nix differ diff --git a/nixos/hosts/istal/default.nix b/nixos/hosts/istal/default.nix new file mode 100644 index 0000000..f606b70 --- /dev/null +++ b/nixos/hosts/istal/default.nix @@ -0,0 +1,27 @@ +{ pkgs, ... }: + +let + data = import ../../../data.nix; +in +{ + imports = [ + ./hardware-configuration.nix + ./networking.secret.nix # generated at runtime by nixos-infect + + ../../modules/nix.nix + ../../shared/common.nix + ../../shared/fail2ban + + ./services/wireguard.nix + ]; + + boot.kernelPackages = pkgs.linuxPackages_6_1; + boot.tmp.cleanOnBoot = true; + zramSwap.enable = true; + + networking.hostName = "istal"; + networking.domain = "local"; + + services.openssh.enable = true; + users.users.root.openssh.authorizedKeys.keys = data.publicKeys.users.janistal; +} diff --git a/nixos/hosts/istal/hardware-configuration.nix b/nixos/hosts/istal/hardware-configuration.nix new file mode 100644 index 0000000..bb179a4 --- /dev/null +++ b/nixos/hosts/istal/hardware-configuration.nix @@ -0,0 +1,14 @@ +{ modulesPath, ... }: +{ + imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; + boot.loader.grub = { + efiSupport = true; + efiInstallAsRemovable = true; + device = "nodev"; + }; + fileSystems."/boot" = { device = "/dev/disk/by-uuid/C324-9FC0"; fsType = "vfat"; }; + boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi" ]; + boot.initrd.kernelModules = [ "nvme" ]; + fileSystems."/" = { device = "/dev/vda2"; fsType = "ext4"; }; + +} diff --git a/nixos/hosts/istal/networking.secret.nix b/nixos/hosts/istal/networking.secret.nix new file mode 100644 index 0000000..611e00b Binary files /dev/null and b/nixos/hosts/istal/networking.secret.nix differ diff --git a/nixos/hosts/istal/services/wireguard.nix b/nixos/hosts/istal/services/wireguard.nix new file mode 100644 index 0000000..f665266 --- /dev/null +++ b/nixos/hosts/istal/services/wireguard.nix @@ -0,0 +1,60 @@ +{ config, pkgs, ... }: + +let + canigouData = import ../../canigou/data.secret.nix; + + istalData = import ../data.secret.nix; + inherit (istalData.wireguard) port; +in +{ + boot.kernel.sysctl."net.ipv4.ip_forward" = 1; + boot.kernel.sysctl."net.ipv4.conf.all.forwarding" = 1; + + # enable NAT + networking.nat = { + enable = true; + externalInterface = "enp0s5"; + internalInterfaces = [ "wg0" ]; + }; + + networking.wg-quick.interfaces = { + # "wg0" is the network interface name. You can name the interface arbitrarily. + wg0 = { + # Determines the IP address and subnet of the server's end of the tunnel interface. + address = [ "10.20.30.2/32" ]; + + # The port that WireGuard listens to. Must be accessible by the client. + listenPort = port; + + # This allows the wireguard server to route your traffic to the internet and hence be like a VPN + # For this to work you have to set the dnsserver IP of your router (or dnsserver of choice) in your clients + postUp = '' + ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -o enp0s5 -j MASQUERADE + ''; + + # This undoes the above command + preDown = '' + ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -o enp0s5 -j MASQUERADE + ''; + + # Path to the private key file. + privateKeyFile = config.age.secrets.wireguard-istal-private.path; + + peers = [ + # List of allowed peers. + { + publicKey = canigouData.wireguard.publicKey; + # List of IPs assigned to this peer within the tunnel subnet. Used to configure routing. + allowedIPs = [ "10.20.30.0/24" ]; + endpoint = "${canigouData.addr}:${toString canigouData.wireguard.port}"; + persistentKeepalive = 25; + } + ]; + }; + }; + + age.secrets.wireguard-istal-private = { + file = ../../../../secrets/wireguard-istal-private.age; + mode = "0400"; + }; +} diff --git a/nixos/modules/wireguard-client.nix b/nixos/modules/wireguard-client.nix index c8bb44c..07b5551 100644 --- a/nixos/modules/wireguard-client.nix +++ b/nixos/modules/wireguard-client.nix @@ -3,10 +3,12 @@ let cfg = config.local.wireguard; - canigouData = import ../hosts/canigou/data.secret.nix; + # externalServerData = import ../hosts/istal/data.secret.nix; + serverData = import ../hosts/canigou/data.secret.nix; + # serverData = import ../hosts/istal/data.secret.nix; - serverAddr = canigouData.addr; - serverPort = canigouData.wireguardPort; + serverAddr = serverData.addr; + serverPort = serverData.wireguard.port; # Run `ip route` to show gateway defaultGateway = "192.168.0.1"; @@ -29,27 +31,34 @@ in allowedUDPPorts = [ serverPort ]; # Clients and peers can use the same port, see listenport }; # Enable WireGuard - networking.wireguard.interfaces = { + networking.wg-quick.interfaces = { # "wg0" is the network interface name. You can name the interface arbitrarily. wg0 = { # Determines the IP address and subnet of the client's end of the tunnel interface. - ips = [ cfg.ip ]; + address = [ cfg.ip ]; + listenPort = serverPort; # to match firewall allowedUDPPorts (without this wg uses random port numbers) # Path to the private key file. privateKeyFile = cfg.privateKeyFile; - # Add a more specific ip route allowing trafgfic to the VPN via the default gateway + # Add a more specific ip route allowing traffic to the VPN via the default gateway # Source: https://discourse.nixos.org/t/route-all-traffic-through-wireguard-interface/1480/18 - postSetup = "${pkgs.iproute}/bin/ip route add ${serverAddr} via ${defaultGateway}"; - postShutdown = "${pkgs.iproute}/bin/ip route del ${serverAddr} via ${defaultGateway}"; + /* + postUp = '' + ${pkgs.iproute}/bin/ip route add ${serverAddr} via ${defaultGateway} + ''; + preDown = '' + ${pkgs.iproute}/bin/ip route del ${serverAddr} via ${defaultGateway} + ''; + */ peers = [ # For a client configuration, one peer entry for the server will suffice. { # Public key of the server (not a file path). - publicKey = "nFqvL30dkKkhOt+fLJ+EJNmp9GjkXVjmpz1WRI1pG0A="; + publicKey = serverData.wireguard.publicKey; # Forward all the traffic via VPN. allowedIPs = [ "0.0.0.0/0" ]; diff --git a/nixos/shared/networking.secret.nix b/nixos/shared/networking.secret.nix index 8f091be..3d8a086 100644 Binary files a/nixos/shared/networking.secret.nix and b/nixos/shared/networking.secret.nix differ diff --git a/secrets/wireguard-istal-private.age b/secrets/wireguard-istal-private.age new file mode 100644 index 0000000..b4cb8c7 Binary files /dev/null and b/secrets/wireguard-istal-private.age differ