From 315784fc98308d61f8aae223912dcdd9fc57cdf5 Mon Sep 17 00:00:00 2001 From: Alexander Szczepanski Date: Fri, 31 May 2024 13:02:21 +0200 Subject: [PATCH] vps-2024-05-31-13-02-21 --- configs/common.nix | 59 +++++++++++++------- configs/docker.nix | 3 +- configs/hardware.nix | 6 +++ home/bin/wg | 124 +++++++++++++++++++++++++++++++++++++++++++ machine/vps.nix | 92 +++++++++++++++++++++++++++++--- 5 files changed, 255 insertions(+), 29 deletions(-) create mode 100644 configs/hardware.nix create mode 100755 home/bin/wg diff --git a/configs/common.nix b/configs/common.nix index d71b7e5..b1152ed 100755 --- a/configs/common.nix +++ b/configs/common.nix @@ -16,30 +16,50 @@ in { openFirewall = true; extraConfig = "StreamLocalBindUnlink yes"; }; - nextdns = { + # nextdns = { + # enable = true; + # arguments = [ + # "-config" + # secrets.nextdnshash + # "-cache-size" + # "10MB" + # "-listen" + # "127.0.0.1:53" + # "-report-client-info" + # ]; + # }; + + dnscrypt-proxy2 = { enable = true; - arguments = [ - "-config" - secrets.nextdnshash - "-cache-size" - "10MB" - "-listen" - "127.0.0.1:53" - "-report-client-info" - ]; + settings = { + ipv6_servers = true; + require_dnssec = true; + + sources.public-resolvers = { + urls = [ + "https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md" + "https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md" + ]; + cache_file = "/var/lib/dnscrypt-proxy2/public-resolvers.md"; + minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3"; + }; + + # You can choose a specific set of servers from https://github.com/DNSCrypt/dnscrypt-resolvers/blob/master/v3/public-resolvers.md + # server_names = [ ... ]; + }; }; - fwupd.enable = true; + journald = { extraConfig = "SystemMaxUse=500M"; }; }; networking = { nameservers = [ "127.0.0.1" "::1" ]; - hosts = { - "207.180.220.97" = [ "szczepan.ski" ]; - "10.100.0.1" = [ "vps.wg" ]; - "10.100.0.2" = [ "desktop.wg" ]; - "10.100.0.3" = [ "mini.wg" ]; - }; + # hosts = { + # "207.180.220.97" = [ "szczepan.ski" ]; + # "10.100.0.1" = [ "vps.wg" ]; + # "10.100.0.2" = [ "desktop.wg" ]; + # "10.100.0.3" = [ "mini.wg" ]; + # }; # If using dhcpcd: dhcpcd.extraConfig = "nohook resolv.conf"; # If using NetworkManager: @@ -53,6 +73,7 @@ in { btrfs-progs cargo dog + doggo # DNS Resolver du-dust duf gnupg @@ -82,8 +103,6 @@ in { wget ]; - documentation.enable = false; - nix.settings = { auto-optimise-store = true; }; boot = { @@ -96,6 +115,6 @@ in { nix.gc = { automatic = true; dates = "weekly"; - options = "--delete-older-than 30d"; + options = "--delete-older-than 14d"; }; } diff --git a/configs/docker.nix b/configs/docker.nix index 0acd0fc..2b3e7b7 100755 --- a/configs/docker.nix +++ b/configs/docker.nix @@ -12,7 +12,6 @@ docker-compose lazydocker minikube - lazydocker dive ]; -} +} \ No newline at end of file diff --git a/configs/hardware.nix b/configs/hardware.nix new file mode 100644 index 0000000..8acbe03 --- /dev/null +++ b/configs/hardware.nix @@ -0,0 +1,6 @@ +{ config, pkgs, lib, ... }: +{ + services = { + fwupd.enable = true; + }; +} diff --git a/home/bin/wg b/home/bin/wg new file mode 100755 index 0000000..ca2a434 --- /dev/null +++ b/home/bin/wg @@ -0,0 +1,124 @@ +#!/usr/bin/env zsh +PEERFILE=/home/alex/.wgpeers +WGCOMMAND="wg" + +# Make sure peer file exists +if [[ ! -f "$PEERFILE" ]]; then + touch "$PEERFILE" 2>/dev/null + + if [[ "$?" != "0" ]]; then + echo "Peer file $PEERFILE is not accesible by your user" + + exit 0 + fi +fi + +function updatePeerFile() { + local NEWPEERS=() + + # Loop config, extract peers, check peers file, add if not present + while read LINE ; do + # Check if its a peer line + if [[ $LINE == *"peer"* ]]; then + # Isolate peer public key, cut peer: (hardcoded) + PEERPK=$(printf '%s' "$LINE" | cut -c7-) + + # See if we can find peer in peers file + PEERCOUNT=$(grep $PEERPK "$PEERFILE" | wc -l) + + if [[ $PEERCOUNT -eq 0 ]]; then + # Peer not found in peers file, add for later processing + NEWPEERS+=("$PEERPK") + fi + fi + done <<< $("$WGCOMMAND") + + for PEERPK in "${NEWPEERS[@]}"; do + echo -n "Enter friendly name for peer " + tput setaf 7; tput bold + echo -n $PEERPK + tput setaf 9; tput sgr0 + read -r -p " : " PEERNAME + + if [[ "$PEERNAME" == "" ]]; then + PEERNAME="Unnamed peer" + fi + + echo "$PEERPK:$PEERNAME" >> "$PEERFILE" + done +} + +function showConfiguration() { + # Determine if we are using rich (colorful) output or not + local RICHOUTPUT=1; + + if [[ ! -t 1 ]]; then + RICHOUTPUT=0 + fi + + # Run wg through script to preserve color coding + script --flush --quiet /dev/null --command "$WGCOMMAND" | while read LINE ; do + # Check if its a peer line + if [[ $LINE == *"peer"* ]]; then + # Isolate peer public key, cut peer: (incl colors) hardcoded, then cut until first ESC character + PEERPK=$(printf '%s' "$LINE" | cut -c25- | cut -d $(echo -e '\033') -f1) + + # Output peer line + echoLine "$LINE" $RICHOUTPUT 1 + + # See if we can find peer in peers file + PEER=$(grep $PEERPK "$PEERFILE" | cut -d ':' -f2) + + # If we found a friendly name, print that + if [[ "$PEER" != "" ]]; then + # Pretty print friendly name + echoLine "$(printf '%s' "$(tput bold)$(tput setaf 7) friendly name$(tput setaf 9)$(tput sgr0)")" $RICHOUTPUT 0 + echoLine "$(printf '%s' ": $PEER")" $RICHOUTPUT 1 + fi + else + # Non-peer line, just output, but remember indentation + if [[ "$LINE" == *"interface"* ]]; then + echoLine "$LINE" $RICHOUTPUT 1 + else + echoLine " $LINE" $RICHOUTPUT 1 + fi + fi + done +} + +# $1: text, $2 richoutput, $3 print linebreak +function echoLine() { + # Strip any newline characters + local OUTPUTLINE=$(printf '%s' "$1" | sed '$ s/\[\r\n]$//') + + # If not rich output, strip ANSI control codes + if [[ $2 -eq 0 ]]; then + OUTPUTLINE=$(printf '%s' "$OUTPUTLINE" | sed 's/\x1b\[[0-9]\{0,\}m\{0,1\}\x0f\{0,1\}//g') + fi + + # Handle newline printing + if [[ $3 -eq 0 ]]; then + printf '%s' "$OUTPUTLINE" + else + printf '%s\r\n' "$OUTPUTLINE" + fi +} + +# What are we doing? +if [[ $# -gt 0 ]]; then + while getopts :u OPTION; do + case ${OPTION} in + u) updatePeerFile + exit + ;; + esac + done + + echo Usage: wgg.sh [-u] + echo -e " -u\tAdd missing peers to $PEERFILE" + echo "" + echo If no arguments are given, shows wg configuration with friendly peernames added +else + # Show the peer-enriched configuration overview + showConfiguration +fi diff --git a/machine/vps.nix b/machine/vps.nix index 5aeb398..f2dc9a0 100755 --- a/machine/vps.nix +++ b/machine/vps.nix @@ -6,7 +6,10 @@ let in { imports = - [ /etc/nixos/hardware-configuration.nix ../configs/common-server.nix ]; + [ + /etc/nixos/hardware-configuration.nix + ../configs/common-server.nix + ]; boot.loader.grub = { enable = true; @@ -22,6 +25,10 @@ in # "address" = "gw.contabo.net"; # "interface" = "ens18"; # }; + defaultGateway6 = { + address = "fe80::1"; + interface = "ens18"; + }; interfaces.ens18 = { useDHCP = true; # ipv4.addresses = [ { @@ -107,10 +114,12 @@ in allowPing = true; allowedTCPPorts = [ 80 # web + 222 # SSH for gitea 443 # web 9898 # i2p 9899 18080 + 21114 #Rustdesk 21115 #Rustdesk 21116 #Rustdesk 21117 #Rustdesk @@ -121,6 +130,7 @@ in allowedUDPPorts = [ 80 # web 443 # web + 3478 # headscale 9898 # i2p 21116 # Rustdesk 51820 # wireguard @@ -147,15 +157,19 @@ in nyx mkp224o progress + headscale ]; programs = { mtr.enable = true; fuse.userAllowOther = true; + nix-ld.enable = true; }; - security.acme.defaults.email = "webmaster@szczepan.ski"; - security.acme.acceptTerms = true; + security.acme = { + defaults.email = "webmaster@szczepan.ski"; + acceptTerms = true; + }; services = { nginx = { @@ -181,6 +195,11 @@ in enableACME = true; globalRedirect = "alexander.szczepan.ski"; }; + "ipv6.szczepan.ski" = { + forceSSL = true; + enableACME = true; + globalRedirect = "alexander.szczepan.ski"; + }; "alexander.szczepan.ski" = { forceSSL = true; enableACME = true; @@ -204,6 +223,11 @@ in }; }; }; + # "nextcloud.ipv6.szczepan.ski" = { + # forceSSL = true; + # enableACME = true; + # globalRedirect = "nextcloud.szczepan.ski"; + # }; "firefly.szczepan.ski" = { forceSSL = true; enableACME = true; @@ -244,11 +268,26 @@ in enableACME = true; locations = { "/" = { proxyPass = "http://127.0.0.1:8091/"; }; }; }; + "git.szczepan.ski" = { + forceSSL = true; + enableACME = true; + locations = { "/" = { proxyPass = "http://127.0.0.1:8084/"; }; }; + }; "torrents.szczepan.ski" = { forceSSL = true; enableACME = true; locations = { "/" = { proxyPass = "http://127.0.0.1:9091/"; }; }; }; + "headscale.szczepan.ski" = { + forceSSL = true; + enableACME = true; + locations = { + "/" = { + proxyPass = "http://127.0.0.1:8088/"; + proxyWebsockets = true; + }; + }; + }; "syncthing.szczepan.ski" = { forceSSL = true; enableACME = true; @@ -312,6 +351,31 @@ in }; }; + headscale = { + enable = true; + address = "127.0.0.1"; + port = 8088; + # dns = { baseDomain = "example.com"; }; + settings = { + logtail.enabled = false; + server_url = "https://headscale.szczepan.ski"; + ip_prefixes = [ + "100.64.0.0/10" + ]; + dns_config = { + base_domain = "szczepan.ski"; + magic_dns = true; + domains = [ "headscale.szczepan.ski" ]; + nameservers = [ + "1.1.1.1" + "9.9.9.9" + ]; + }; + }; + }; + + tailscale.enable = true; + webdav = { enable = true; user = "alex"; @@ -353,7 +417,7 @@ in }; i2pd = { - enable = true; + enable = false; ifname = "ens18"; address = "207.180.220.97"; # TCP & UDP @@ -412,7 +476,7 @@ in }; icecast = { - enable = true; + enable = false; hostname = "254ryojirydttsaealusydhwyjfe2rpschdaduok4czhg45of6ua.b32.i2p"; listen = { port = 13337; @@ -514,6 +578,7 @@ in }; extraPruneArgs = "--save-space --stats"; exclude = [ + "/home/alex/storage" "/home/alex/storagebox" "/home/alex/docker/jellyfin/data" "/home/alex/.cache" @@ -536,8 +601,21 @@ in }; - # Limit stack size to reduce memory usage - systemd.services.fail2ban.serviceConfig.LimitSTACK = 256 * 1024; + systemd.services = { + # Limit stack size to reduce memory usage + fail2ban.serviceConfig.LimitSTACK = 256 * 1024; + + goaccess = { + description = "GoAccess real-time web log analysis"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + script = "${pkgs.gzip}/bin/zcat -f /var/log/nginx/access.* | ${pkgs.goaccess}/bin/goaccess - -o /var/www/goaccess/index.html --log-format='%v %h %^[%d:%t %^]%^\"%r\" %s %b \"%R\" \"%u\"' --real-time-html --ws-url=wss://goaccess.szczepan.ski:443/ws --port 7890 --time-format \"%H:%M:%S\" --date-format \"%d/%b/%Y\""; + # serviceConfig = { + # ExecStart = "${pkgs.bash}/bin/bash -c "${pkgs.gzip}/bin/zcat -f /var/log/nginx/access.* | ${pkgs.goaccess}/bin/goaccess -o /var/www/goaccess/index.html --log-format='%v %h %^[%d:%t %^]%^\"%r\" %s %b \"%R\" \"%u\"' --real-time-html --ws-url=wss://goaccess.szczepan.ski:443/ws --port 7890 --time-format \"%H:%M:%S\" --date-format \"%d/%b/%Y\"'"; + # # ExecStop = "/bin/kill -9 ${MAINPID}"; + # }; + }; + }; system.stateVersion = "23.11"; }