host: init istal server

This commit is contained in:
Dmitriy Pleshevskiy 2023-07-28 17:08:13 +03:00
parent 1ef0e86b9d
commit 40d83f4883
Signed by: pleshevskiy
GPG key ID: 79C4487B44403985
19 changed files with 243 additions and 31 deletions

Binary file not shown.

View file

@ -24,7 +24,8 @@ MACHINES := \
VPS := \
magenta \
canigou
canigou \
istal
.PHONY: help
help:

View file

@ -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"
];
};
};
}

View file

@ -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-}"

View file

@ -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;
};
}

Binary file not shown.

View file

@ -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
'';
}

View file

@ -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"

View file

@ -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
{
publicKey = "mzVH0N3q7UE/XjMwgRks+D8KFuIj91VkOK2ytgjsnkw=";
allowedIPs = [ "10.100.0.3/32" ];
persistentKeepalive = 15;
allowedIPs = [ "10.20.30.4/32" ];
}
];
};

View file

@ -60,4 +60,10 @@ in
targetHost = (import ./canigou/data.secret.nix).addr;
};
istal = {
system = "x86_64-linux";
targetHost = (import ./istal/data.secret.nix).addr;
};
}

View file

@ -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;
};

Binary file not shown.

View file

@ -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;
}

View file

@ -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"; };
}

Binary file not shown.

View file

@ -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";
};
}

View file

@ -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" ];

Binary file not shown.

Binary file not shown.