#!/bin/bash set -e if [ -f vars ]; then source vars; fi if [ -z "$ENCRYPT" ]; then echo "NO ENVIRONMENT VARIABLES" exit 1 fi #ENC="openssl enc -e -aes-256-ctr -salt -pbkdf2 -iter 1000000 -in - -out - -a -A -pass pass:'$ENCRYPT'" DEC="openssl enc -d -aes-256-ctr -pbkdf2 -iter 1000000 -in - -out - -a -A -pass pass:'$ENCRYPT'" TS="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" SPOTIFY_CONF="U2FsdGVkX1+s2vvCD6sn5ts2Yud6ioFvf8P5HG8bywURvHFBrkutWFABkGwvrG3McQCgQgQN3nxq9h8vK5Cql2TH3VRA89q7oyqJvyjzm8SD82cH15/ktu/HweKhdhqKGggO3/FRiQwxkqXanzoaRjqCkYEW4s+GM5r+97d1koM9rKknfgotZNfBTxUcad7Qqn4yliaJKnYMRFqA/c0TLkWcIb/YNa/3dZJAUNtu6LmQdv/xF5uVIOLKvLmHjftS8RQjzjrlX2bDFXx4Xh6nQzV5Kow8PIPUJWRbHHDWAD6LKnwk5brHspggwMeNthozPcxOdb3o0UH7EG9UKuhls/i5WbRov3saDiG5tBS4La3uXDRsaO3TG+yI3lVtJatsSQlW7IpfrB9Z5n/DUAxq6l9e6QcVydjg30NHLaaqlVP5V2JRObQD2jETXPbPW8G+Jr6f7BhjmhNn3HH7G5oiUe2GpL8At2CVIHzFarch1xmDTQFD3J+QLz9clV95He0sQEwtAu2W8kYv4FahFz7PWCKnKO4PJoYn2QXf51Jk5Mj9XteregHly6UUTLSyILipWbNVMqQEXSgx4aFeyzIJb42DCuINj2Nj5qXp5BJs8iAgSgkwDKBACzJTnxa8sW1r8+I1sAJtHTFM66B1s61H5WTJEWcye3Yx7xdSP1IzdTOAz92BlBqtKQGRjOgb6SuISBm2lAQgByWr0yT0bKAS+ranAx1N60+LwckbmoGasff52tvdZG/RMBaxqHO5fUyrTrlrvvGq2X3wv3v/VDWc8qFeFNXqLbEUuVcXL5tFBMqZbHsumgCS4/P+a3t5k/3KSDG7QMc2Wg9eVFhvpLtIYR+WuFUPN7omAk++g5fExNO+IEd//RUI/OGdF8YBLRYDLw5i9+nfsUE9iTKmueoZpxq8K/LVrNmcNcBVeA/oz+0ra+OvTGkusF2PZdvsT8wVtdvqWAUDtl+nPfnIQLhKD2hepr6Dnn6YAm6eMaqqzIXGush+QG9Ox1Sh34CtwgDPI8draZiWG1SfxD3qyOWWGjF5hR3f9NOXiNvVmPWpBpmTtsiNZhmqGIZVsrdS9qUOe37Ja4qVdawYJNPh6+EPuN2w8nvSR/Y1B0qg1YW9JlhX/ycjP/wiSqyyK5lWVvXuMYEkHbu5vMPk4dAd6GpAlxkmvjHw3x7QfHijYarp060TYLCHGZG1dmRnXhfnb3fI95lo6yJbiSkim8D/mzUXle8YJkembs+ZdOuBQM4RAwJYoQNevOnYibdibKtlqLmA+lTq4cLdL/opWlvuYPvpiBaCVOaxOwPmkXyQlJsUoLtZlXo+48+TPhCoPXD9Ya7BoQQvn8fVERvM9xSfnLox6eVbkxtjiLhUHKHKUuP3AQPMCd59MCNtLuTXg7Naliv/CxPJ8aIJ1WL8lhu+S+IuC6ky69zRL+EMDK469vdpq3ajqIv2fJcvZB4beZR2GWGwf+eSM7PupWDfJ5dZauHiTfufMZ3MiaxaCLtPPHQn1bUiMl0mj0Od5LPvt2ALgTbfJ9goWmpaX2ZX8n0XXduclWg9OElV9iI6BKklYr3EO++UW/IA9hjQGeMkwEG0YKWzEPK/AsDzfVUtfYvjBRr3gi5YHzyS736jttjajieCPUNHWshbrfGExZhrWdeufzxDq8DMeIlzuRposNMElfE048P6dB++8XiX2i8aVFxEbIHKot88QoU+pzbbDsc/T65kkNhrI05s0/dJs42nCkpoil9wplGWMrukGHIvLO5XaFGfj65xnudVfdNeAUDuGYfMYzp4Rdzidb8vudn1oyjPXbBw/6R5YZoX9nhgrI8/Vib1VE5IGhfegKIBcSoku8xil6pehAWhELAEgD/HfP8L69MbAX/SiGx7uBba1/ZZUSr8WusaS3sItaO7v9iAGjGLTScCql/ZVqn0T/BxlkU1T2OjqCrbCEVbQXUTX+fcCaBKkfOiGDzzDkAI26RcXOw2qf3E1GFk2RZ5zgkf9vEXCzhIunEevsB4ZDGB2xYaX2tou3dcuxylx9xzJAlxtXmm5i8yccKuUZeFHij0hlpAW6sSeU/v0CMLpWx19vHizgipKULtg4QuymE6KdKzZsNchyfiTkEracyzjXD8BDRXX6ay5dz3AAamNMhI/b7UibsC4LwKg9C+QZOaef34LUEdooEubJ5ifF8hACATsTas9mgRg7v8P54sGjHf1rKYY39u70SrSo4+vERRPc4KHkieTILNRmXXPis=" if ! TSCMD=`which tailscale 2> /dev/null`; then echo "Fel: tailscale hittades inte. Installera det först." exit 1 fi get_ts_ip() { tailscale ip -4 | tr -d ' ' } # Färgkoder (ANSI) BOLD='\033[1m' GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[0;33m' RED='\033[0;31m' NC='\033[0m' # No Color log() { _level="$1" _msg="$2" _time=$(date +%H:%M:%S) case "$_level" in "info") printf "${_time} ${BLUE}🔹 INFO${NC} | %s\n" "$_msg" ;; "ok") printf "${_time} ${GREEN}✅ OK${NC} | %s\n" "$_msg" ;; "warn") printf "${_time} ${YELLOW}⚠️ WARN${NC} | ${BOLD}%s${NC}\n" "$_msg" ;; "error") printf "${_time} ${RED}🚫 ERR${NC} | ${BOLD}${RED}%s${NC}\n" "$_msg" >&2 ;; *) printf "${_time} | %s\n" "$_msg" ;; esac } try_silent() { "$@" >/dev/null 2>&1 || true } disable_updates() { systemctl mask apt-daily.service apt-daily.timer apt-daily-upgrade.service apt-daily-upgrade.timer echo 'APT::Periodic::Unattended-Upgrade "0";' > /etc/apt/apt.conf.d/10periodic sleep 2 pkill -9 apt pkill -9 dpkg dpkg --configure -a } dist_upgrade() { dpkg --get-selections | grep hold | cut -f1 | xargs sudo apt-mark unhold apt-get remove -y --purge "^nvidia-.*" "^libnvidia-.*" "^cuda-.*" apt update DEBIAN_FRONTEND=noninteractive \ UCF_FORCE_CONFOLD=1 \ DEBIAN_PRIORITY=critical \ apt upgrade -y DEBIAN_FRONTEND=noninteractive \ UCF_FORCE_CONFOLD=1 \ DEBIAN_PRIORITY=critical \ apt dist-upgrade -y apt autoremove -y apt install update-manager-core -y DEBIAN_FRONTEND=noninteractive \ UCF_FORCE_CONFOLD=1 \ DEBIAN_PRIORITY=critical \ do-release-upgrade -f DistUpgradeViewNonInteractive } prereqs() { apt-get update apt-get install --fix-missing -y xvfb x11vnc fluxbox alsa-utils xdotool x11-utils x11-xserver-utils pulseaudio pulseaudio-utils libsoxr0 curl gnupg software-properties-common dbus-user-session ethtool irqbalance } decompress() { if [ -z "$1" ]; then echo "Fel: data saknas!" >&2 exit 1 fi DATA="$1" if [ -z "$2" ]; then echo "Fel: målkatalog saknas!" >&2 exit 1 fi DIR="$2" echo $DATA | $DEC | xz -d | tar --acls --xattrs -xpf - -C $DIR } update_tailscale_default() { if [ ! -f /etc/default/tailscaled ]; then echo "Fel: Konfigurationsfilen $FILE saknas. Avbryter." exit 1 fi CURRENT_PORT=$(grep '^PORT=' /etc/default/tailscaled | cut -d'"' -f2) if [ -z "$CURRENT_PORT" ]; then echo "Fel: Kunde inte hitta någon PORT-variabel i $FILE." exit 1 fi CURRENT_FLAGS=$(grep '^FLAGS=' /etc/default/tailscaled | cut -d'"' -f2) cat << EOF | tee /etc/default/tailscaled > /dev/null # Set the port to listen on for incoming VPN packets. # Remote nodes will automatically be informed about the new port number, # but you might want to configure this in order to set external firewall # settings. PORT="$CURRENT_PORT" # Extra flags you might want to pass to tailscaled. FLAGS="$CURRENT_FLAGS" TS_DEBUG_MTU=1330 EOF } install_spotify() { if command -v spotify >/dev/null 2>&1; then log info "Spotify finns redan på: $(command -v spotify)" log info "Avbryter." return 0 fi URL="https://archive.org/download/spotify-client_1.2.74.477.g3be53afe_amd64/spotify-client_1.2.74.477.g3be53afe_amd64.deb" FILE="spotify-client.deb" # 1. Kontrollera att nödvändiga verktyg finns for cmd in wget dpkg apt-get; do if ! command -v "$cmd" > /dev/null 2>&1; then echo "Fel: Verktyget $cmd saknas." >&2 exit 1 fi done # 2. Ladda ner filen echo "Laddar ner Spotify..." # -O sparar till specifikt filnamn, --show-progress ger visuell feedback wget -O "$FILE" "$URL" # 3. Förbered systemet (uppdatera paketlistor) echo "Uppdaterar paketlistor..." sudo apt-get update -y # 4. Installera paketet echo "Installerar $FILE..." # Vi använder dpkg för själva filen. Detta kommer troligen ge beroendefel först. # Genom att använda '||' efter kommandot kan vi hantera felet trots 'set -e' if ! sudo dpkg -i "$FILE"; then echo "Hanterar saknade beroenden..." # 5. Fixa trasiga beroenden (viktigt steg för .deb-filer) sudo apt-get install -f -y fi # 6. Städa upp echo "Rensar temporära filer..." rm "$FILE" echo "Installation klar!" } pulse_config() { mkdir -p ~user/.config/pulse cat << EOF > ~user/.config/pulse/default.pa load-module module-native-protocol-unix auth-anonymous=1 socket=/run/user/1000/pulse/native load-module module-cli-protocol-unix load-module module-dbus-protocol load-module module-systemd-login load-module module-stream-restore load-module module-device-restore load-module module-always-sink load-module module-alsa-sink device=hw:Loopback,0,0 sink_name=spotify_sink rate=44100 format=s32le channels=2 load-module module-alsa-source device=hw:Loopback,1,0 source_name=spotify_out set-default-sink spotify_sink load-module module-null-sink sink_name=fallback_sink EOF cat << EOF > ~user/.config/pulse/client.conf autospawn = no EOF cat << EOF > ~user/.config/pulse/daemon.conf exit-idle-time = -1 daemonize = no default-sample-format = s32le default-sample-rate = 44100 EOF } spotify_startup_script() { cat << 'EOF' #!/bin/bash export DISPLAY=:99 export USER_ID=$(id -u) export XDG_RUNTIME_DIR="/run/user/$USER_ID" export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus" export PULSE_SERVER="unix:$XDG_RUNTIME_DIR/pulse/native" export PULSE_RUNTIME_PATH="/run/user/$(id -u)/pulse" # 1. STÄDA DÖDA PROCESSER (Förhindrar "Display already in use") rm -f /tmp/.X99-lock rm -f /tmp/.X11-unix/X99 # 2. STARTA XVFB (Virtuell Skärm) echo "Startar Xvfb..." Xvfb :99 -screen 0 1280x1024x24 +extension RANDR & XVFB_PID=$! sleep 2 # Stäng av strömsparfunktioner i X (Kritiskt för att Spotify inte ska somna) xset -display :99 s off xset -display :99 -dpms xset -display :99 s noblank # 3. Start x11vnc x11vnc -display :99 -listen `tailscale ip -4 | tr -d ' '` -rfbport 5901 -forever -bg -passwd password # 4. STARTA SPOTIFY echo "Rensar Spotify-cache för stabilitet..." rm -rf ~/.cache/spotify #rm -rf ~/.config/spotify/Users/*/ad-state-storage.bnk echo "Startar Spotify..." spotify --start-maximized & SPOTIFY_PID=$! echo "Spotify startad (PID: $SPOTIFY_PID)" sleep 5 # 5. KEEP-ALIVE LOOP (Barnvakten) ( while kill -0 $SPOTIFY_PID 2>/dev/null; do # Försök "väcka" fönstret via D-Bus/X11 xdotool search --onlyvisible --class "spotify" windowactivate --sync 2>/dev/null # Simulera fysisk aktivitet xdotool mousemove_relative 1 1 xdotool mousemove_relative -- -1 -1 xdotool key Shift_L # Gör detta varje minut sleep 60 done ) & # 6. VÄNTA UT PROCESSEN wait $SPOTIFY_PID kill $XVFB_PID EOF } spotify_service() { cat << EOF [Unit] Description=Spotify Headless Service (Xvfb + PulseAudio) Requires=dbus.socket pulseaudio.service After=network.target sound.target dbus.socket pulseaudio.service [Service] Type=simple # Miljövariabler som systemd injicerar i processen Environment=DISPLAY=:99 Environment=PULSE_LATENCY_MSEC=100 ExecStart=/home/user/start_spotify.sh Restart=always RestartSec=10 # Städa upp om tjänsten stoppas ExecStop=/usr/bin/pkill -u user -f "Xvfb :99" ExecStop=/usr/bin/pkill -u user -f "x11vnc" ExecStop=/usr/bin/pkill -u user -f "spotify" [Install] WantedBy=default.target EOF } sysctl_network() { cat << EOF net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 net.core.default_qdisc = fq net.ipv4.tcp_congestion_control = bbr net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.core.rmem_default = 262144 net.core.wmem_default = 262144 net.core.optmem_max = 65535 net.core.busy_poll=50 net.core.busy_read=50 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 net.ipv4.udp_rmem_min=8192 net.ipv4.udp_wmem_min=8192 net.netfilter.nf_conntrack_max = 524288 net.netfilter.nf_conntrack_tcp_timeout_established = 3600 net.netfilter.nf_conntrack_expect_max=1000 #net.ipv4.conf.all.accept_redirects = 0 #net.ipv4.conf.all.send_redirects = 0 #net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.default.rp_filter = 2 net.ipv4.conf.all.rp_filter = 2 net.ipv4.tcp_syncookies = 1 net.ipv4.ip_no_pmtu_disc = 0 net.ipv4.tcp_mtu_probing = 1 net.core.bpf_jit_enable = 1 net.core.bpf_jit_harden = 2 EOF } sysctl_performance() { echo 1 > /proc/sys/net/core/bpf_jit_enable 2>/dev/null || true echo 1 > /proc/sys/net/core/bpf_jit_harden 2>/dev/null || true echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor } ethtool_network() { for iface in $(ls /sys/class/net); do if [ "$iface" == "lo" ]; then continue; fi # Exkludera virtuella docker/veth interfaces om så önskas if [[ "$iface" == veth* ]] || [[ "$iface" == docker* ]] || [[ "$iface" == br* ]] || [[ "$iface" == vxlan* ]] || [[ "$iface" == dummy* ]]; then continue; fi log info "Optimizing interface: $iface" CPU_COUNT=$(nproc) log "info" "Antal kärnor #$CPU_COUNT" HW_MAX=$(ethtool -l "$iface" 2>/dev/null | grep -A 5 "Pre-set maximums" | grep "Combined:" | awk '{print $2}') if [ -n "$HW_MAX" ] && [ "$HW_MAX" -gt 1 ]; then if [ "$CPU_COUNT" -lt "$HW_MAX" ]; then TARGET_QUEUES=$CPU_COUNT else TARGET_QUEUES=$HW_MAX fi log info " -> CPU Cores: $CPU_COUNT, NIC Max: $HW_MAX. Setting queues to: $TARGET_QUEUES" try_silent ethtool -L "$iface" combined "$TARGET_QUEUES" else log warn " -> Could not read max channels for $iface, skipping queue optimization." fi try_silent ethtool -G "$iface" rx max tx max try_silent ethtool -K "$iface" gro on try_silent ethtool -K "$iface" gso on try_silent ethtool -K "$iface" sg on try_silent ethtool -K "$iface" tso on try_silent ethtool -K "$iface" gso-udp-tunnel4 on try_silent ethtool -K "$iface" gso-udp-tunnel6 on try_silent ethtool -K "$iface" tx-udp_tnl-segmentation on try_silent ethtool -K "$iface" rx-udp-gro-forwarding on try_silent ethtool -K "$iface" rx-gro-list off try_silent ethtool -N "$iface" rx-flow-hash udp4 sdfn try_silent ethtool -N "$iface" rx-flow-hash udp6 sdfn try_silent ethtool -C "$iface" adaptive-rx on adaptive-tx on try_silent ip link set dev "$iface" txqueuelen 5000 # Status check check_offload() { local feat=$1 local status=$(ethtool -k "$iface" 2>/dev/null | grep "$feat:" | awk '{print $2}') if [[ "$status" == "on" ]]; then log ok " > Feature: $feat is ON" else if [ -z "$status" ]; then log warn " > Feature: $feat not supported by driver" else log warn " > Feature: $feat is OFF" fi fi } check_offload "gso-udp-tunnel4" check_offload "tx-udp_tnl-segmentation" check_offload "rx-udp-gro-forwarding" GRO_LIST=$(ethtool -k "$iface" 2>/dev/null | grep "rx-gro-list:" | awk '{print $2}') if [[ "$GRO_LIST" == "off" ]]; then log ok " > Feature: rx-gro-list is OFF (Optimal)" else log warn " > Feature: rx-gro-list is $GRO_LIST (Might cause overhead)" fi HASH_UDP4=$(ethtool -n "$iface" rx-flow-hash udp4 2>/dev/null | grep "IP SA" ) if [[ "$HASH_UDP4" == *"L4 bytes"* ]]; then log ok " > RSS Hashing: UDP4 uses IP + Ports (4-tuple)" else log warn " > RSS Hashing: UDP4 might be 2-tuple only (check 'ethtool -n $iface rx-flow-hash udp4')" fi done } hostnamectl set-hostname vast1 disable_updates || true log info "Installerar prereqs" prereqs && log ok "Klart!" || log error "Kunde inte installera alla paket" $TSCMD update --yes log info "Stoppar tailscaled" systemctl stop tailscaled > /dev/null 2>&1 && log ok "stoppad" || log warn "ej stoppad/redan stoppad" log info "uppdaterar tailscale defaults" update_tailscale_default log info "tar bort /var/lib/tailscale" rm -Rf /var/lib/tailscale > /dev/null 2>&1 && log ok "borttaget" || log warn "kunde inte ta bort" log info "packar upp tailscale state" decompress $TS /var/lib log ok "klart!" systemctl start tailscaled > /dev/null 2>&1 && log ok "startad" || log error "ej startad" # Spotify echo "" echo "" log info "Installerar Spotify" install_spotify && log ok "Installerad!" || log error "Installation misslyckad" log info "Tar bort ~/.config/spotify" rm -Rf /home/user/.config/spotify > /dev/null 2>&1 && log ok "borttaget" || log warn "kunde inte ta bort" log info "packar upp spotify state" decompress $SPOTIFY_CONF /home/user chown -R user:users /home/user/.config log ok "klart!" # DBUS + PulseAudio echo "" echo "" log info "Kofigurerar Pulseaudio" modprobe snd-aloop echo "snd-aloop" | tee /etc/modules-load.d/snd-aloop.conf usermod -aG audio user pulse_config && log ok "Klart" || log error "pulse_config() gick fel" log info "Startar användartjänster" loginctl enable-linger user systemctl start user@1000.service # Spotify user script log info "Skapar spotify startscript" { spotify_startup_script > ~user/start_spotify.sh chown user:users ~user/start_spotify.sh && chmod 755 ~user/start_spotify.sh } && log ok "Klart." || log error "Kunde inte skapa spotify-script." log info "Skapar spotify-tjänst" { file=".config/systemd/user/spotify-headless.service" su - user -c "mkdir -p $(dirname /home/user/$file)" || true spotify_service > ~user/$file chown user:users ~user/$file chmod 444 ~user/$file } && log ok "Klart." || log error "Kunde inte skapa spotify-tjänst." log info "Konfigurerar spotify-tjänst" { su - user -c 'XDG_RUNTIME_DIR="/run/user/1000" DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus" systemctl --user daemon-reload' su - user -c 'XDG_RUNTIME_DIR="/run/user/1000" DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus" systemctl --user enable spotify-headless.service' su - user -c 'XDG_RUNTIME_DIR="/run/user/1000" DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus" systemctl --user restart spotify-headless.service' || true } && log ok "Klart." || log error "Kunde inte konfigurera spotify-tjänst."