Ojačajte svoje staro prijenosno računalo: praktična izrada ojačanog Linux poslužitelja
Staro prijenosno računalo već sadrži nekoliko značajki koje malim poslužiteljima često nedostaju: napajanje potpomognuto baterijom, zaslon i tipkovnicu za hitni pristup te hardver dizajniran za tihi rad. Uz discipliniranu konfiguraciju Linuxa može postati sposoban privatni poslužitelj, a ne improvizirani stroj uravnotežen ispod stola.
Ova konfiguracija koristi Debian stable, WireGuard, OpenSSH, nftables, LUKS-šifrirani spremnik podataka, systemd nadzor i šifrirane udaljene sigurnosne kopije. Nakon nestanka struje, računalo se automatski pokreće i vraća udaljenu administraciju. Zaštićeni podaci ostaju zaključani sve dok ih administrator izričito ne otključa.
Namjerni kompromis jest nešifrirani operacijski sustav sa šifriranim podacima aplikacija. Omogućuje nenadzirani oporavak bez pohranjivanja zaporke podatkovnog volumena na prijenosnom računalu. Napadač s fizičkim pristupom može pregledati ili izmijeniti operacijski sustav, stoga upotrijebite šifriranje cijelog diska i mjereno pokretanje kada je ta prijetnja važnija od automatskog oporavka.
Preduvjeti i arhitektura
Započnite s podržanim 64-bitnim prijenosnim računalom, pouzdanom pohranom, Ethernetom ako je dostupan i čistom instalacijom Debian stablea. Tijekom instalacije izradite administrativnog korisnika pod imenom admin. Ne izlažite računalo izravno javnom Internetu.
Također trebate drugi uređaj za administraciju WireGuarda i zasebno računalo za sigurnosne kopije s podrškom za SSH. Primjeri koriste ove dokumentacijske adrese:
10.44.0.1: WireGuard adresa prijenosnog računala10.44.0.2: WireGuard adresa administratora51820/udp: WireGuard na usmjerivaču i prijenosnom računalu2222/tcp: SSH, dostupan samo putem WireGuarda
Ako se prijenosno računalo nalazi iza usmjerivača, proslijedite UDP priključak 51820 na njegovu LAN adresu. Promjenjiva javna adresa zahtijeva dinamički DNS. Primjer krajnje točke klijenta server.example.net označava DNS naziv kojim upravljate; to nije usluga koju pruža ovaj vodič.
Dobivena je konfiguracija namjerno mala:
/etc/wireguard/wg0.conf
/etc/ssh/sshd_config.d/60-hardened.conf
/etc/nftables.conf
/etc/fstab
/etc/systemd/logind.conf.d/server.conf
/etc/systemd/system/vault-health.service
/etc/systemd/system/vault-health.timer
/etc/systemd/system/restic-vault.service
/etc/systemd/system/restic-vault.timer
/usr/local/sbin/vault-open
/usr/local/sbin/vault-health
/var/lib/vault.luks
/srv/vault
Najprije uspostavite administrativni put
Povežite se putem pouzdanog LAN-a i instalirajte osnovne pakete. Sve naredbe za računalo u ovom članku izvršavaju se na prijenosnom računalu, osim ako nisu izričito označene kao naredbe klijenta.
sudo apt update
sudo apt install wireguard nftables cryptsetup openssh-server \
unattended-upgrades smartmontools restic
sudo systemctl enable --now ssh nftables
sudo systemctl enable --now unattended-upgrades
Naredbe za sigurnosne kopije ciljaju Restic 0.16.x do 0.18.x. Prije nastavka provjerite verziju paketa naredbom restic version. Ako vaša distribucija isporučuje verziju izvan tog raspona, proučite dokumentaciju za to izdanje umjesto da pretpostavite jednako ponašanje.
Na administratorovu uređaju izradite Ed25519 ključ naredbom ssh-keygen -t ed25519, a zatim njegov javni ključ instalirajte u /home/admin/.ssh/authorized_keys. Potvrdite da druga SSH sesija temeljena na ključu radi prije onemogućavanja lozinki.
Izgradite WireGuard tunel
Generirajte ključ poslužitelja kao root kako bi njegova dopuštenja bila ispravna:
sudo install -d -m 0700 /etc/wireguard
sudo sh -c 'umask 077; wg genkey > /etc/wireguard/server.key'
sudo sh -c 'wg pubkey < /etc/wireguard/server.key'
sudo wg genkey | tee client.key | wg pubkey > client.pub
Zadnje dvije datoteke privremeni su materijal klijenta stvoren u trenutačnom direktoriju. Sigurno prenesite client.key na administratorov uređaj, zabilježite client.pub i nakon testiranja uklonite lokalnu kopiju privatnog ključa.
Upotrijebite sudoedit /etc/wireguard/wg0.conf i umetnite privatni ključ poslužitelja te sadržaj datoteke client.pub:
[Interface]
Address = 10.44.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY
[Peer]
PublicKey = ADMIN_CLIENT_PUBLIC_KEY
AllowedIPs = 10.44.0.2/32
Ovdje su vrijednosti velikim slovima zamjene za ključeve koje ste upravo generirali, a ne doslovna konfiguracija. Na administratorovu uređaju konfigurirajte:
[Interface]
Address = 10.44.0.2/32
PrivateKey = ADMIN_CLIENT_PRIVATE_KEY
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = server.example.net:51820
AllowedIPs = 10.44.0.1/32
PersistentKeepalive = 25
Omogućite tunel poslužitelja naredbom sudo systemctl enable --now wg-quick@wg0. Pokrenite klijenta i provjerite ping 10.44.0.1 prije mijenjanja SSH-a ili pravila vatrozida.
Ograničite SSH i vatrozid
Izradite /etc/ssh/sshd_config.d/60-hardened.conf pomoću sudoedit:
Port 2222
ListenAddress 10.44.0.1
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AllowUsers admin
X11Forwarding no
AllowAgentForwarding no
PermitTunnel no
MaxAuthTries 3
LoginGraceTime 30
Prije ponovnog učitavanja provjerite valjanost: sudo sshd -t. Ostavite postojeću sesiju otvorenom, pokrenite sudo systemctl reload ssh i uspostavite novu sesiju naredbom ssh -p 2222 [email protected].
Na namjenskom novom računalu sačuvajte isporučeni vatrozid prije uređivanja:
sudo cp --no-clobber /etc/nftables.conf /etc/nftables.conf.factory
sudoedit /etc/nftables.conf
Upotrijebite ovaj skup pravila. Zamijenite enp3s0 fizičkim sučeljem koje prijavljuje ip -brief link.
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iifname "lo" accept
ct state established,related accept
ct state invalid drop
ip protocol icmp accept
ip6 nexthdr ipv6-icmp accept
iifname "enp3s0" udp dport 51820 accept
iifname "wg0" ip saddr 10.44.0.0/24 tcp dport 2222 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Pokrenite sudo nft -c -f /etc/nftables.conf za provjeru sintakse, a zatim sudo systemctl reload nftables. Ponovno testirajte WireGuard i novu SSH vezu. Ulazna pravila sada odbijaju LAN SSH i svaku neželjenu uslugu osim WireGuarda.
Izradite šifriranu pohranu aplikacija
LUKS spremnik temeljen na datoteci izbjegava nagađanje naziva uređaja diska i slučajno formatiranje pogrešnog diska. Nešto je sporiji od namjenske particije i ne može premašiti svoj datotečni sustav podloge, ali ga je lako odrediti po veličini, sigurnosno kopirati i ukloniti.
Sljedeće stvara novi spremnik od 100 GiB. Najprije potvrdite da /var/lib/vault.luks ne postoji i da df -h /var/lib pokazuje dovoljno prostora. Zaustavite se ako bilo koji uvjet nije ispunjen.
sudo test ! -e /var/lib/vault.luks
sudo fallocate --length 100G /var/lib/vault.luks
sudo chmod 0600 /var/lib/vault.luks
sudo cryptsetup luksFormat --type luks2 /var/lib/vault.luks
sudo cryptsetup open /var/lib/vault.luks vault
sudo mkfs.ext4 -L vault /dev/mapper/vault
sudo install -d -m 0750 -o admin -g admin /srv/vault
luksFormat uništava sadržaj cilja, zbog čega se smije koristiti samo na novostvorenom spremniku. Odaberite dugu, jedinstvenu zaporku i pohranite kopiju za oporavak izvan prijenosnog računala.
Dodajte ovaj točan unos u /etc/fstab:
/dev/mapper/vault /srv/vault ext4 noauto,nosuid,nodev,noexec 0 2
Izradite /usr/local/sbin/vault-open pomoću sudoedit:
#!/bin/sh
set -eu
if ! cryptsetup status vault >/dev/null 2>&1; then
cryptsetup open /var/lib/vault.luks vault
fi
if ! mountpoint -q /srv/vault; then
mount /srv/vault
fi
chown admin:admin /srv/vault
printf '%s\n' "Vault is open and mounted at /srv/vault"
Postavite sudo chmod 0750 /usr/local/sbin/vault-open. Nakon ponovnog pokretanja povežite se putem WireGuarda, pokrenite sudo /usr/local/sbin/vault-open i unesite zaporku. Usluge koje koriste ovaj volumen trebaju deklarirati RequiresMountsFor=/srv/vault i ne smiju tiho zapisivati u prazan direktorij točke montiranja.
Konfigurirajte šifrirane udaljene sigurnosne kopije
Na zasebnom SSH poslužitelju izradite ograničeni račun pod imenom backup i prazan direktorij u njegovu vlasništvu, poput /srv/restic/laptop. Konfigurirajte root na prijenosnom računalu namjenskim SSH ključem i prikvačite ključ računala za sigurnosne kopije u /root/.ssh/known_hosts. Prije automatizacije interaktivno provjerite tu vezu.
Izradite /etc/restic/vault.env s načinom rada 0600:
RESTIC_REPOSITORY=sftp:[email protected]:/srv/restic/laptop
RESTIC_PASSWORD_FILE=/etc/restic/password
Izradite /etc/restic/password pomoću sudoedit, u njega stavite zasebnu lozinku spremišta visoke entropije i postavite obje datoteke na root:root s načinom rada 0600. Inicijalizirajte samo novo prazno spremište:
sudo env $(sudo cat /etc/restic/vault.env) restic init
sudo env $(sudo cat /etc/restic/vault.env) restic backup /srv/vault
sudo env $(sudo cat /etc/restic/vault.env) restic snapshots
Budući da je prosljeđivanje raščlanjenih datoteka okruženja kroz ljusku krhko, automatizacija bi trebala omogućiti systemdu da izravno pročita datoteku. Izradite /etc/systemd/system/restic-vault.service:
[Unit]
Description=Encrypted backup of the vault
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
EnvironmentFile=/etc/restic/vault.env
ExecCondition=/usr/bin/mountpoint -q /srv/vault
ExecStart=/usr/bin/restic backup --one-file-system /srv/vault
ExecStart=/usr/bin/restic forget --keep-daily 7 --keep-weekly 5 --keep-monthly 12
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=7
Pokraj nje izradite restic-vault.timer:
[Unit]
Description=Nightly vault backup
[Timer]
OnCalendar=*-*-* 03:15:00
RandomizedDelaySec=20m
Persistent=true
[Install]
WantedBy=timers.target
Pokrenite sudo systemctl daemon-reload i sudo systemctl enable --now restic-vault.timer. Nizak I/O prioritet sprječava da sigurnosne kopije preopterete stari disk. Pokrenite restic prune zasebno tijekom prozora održavanja jer kompakcija spremišta može biti zahtjevna.
Sigurnosna kopija nije dokazana dok se ne obnovi. Povremeno upotrijebite restic restore latest --target s novim privremenim direktorijem na računalu s dovoljno prostora, usporedite važne datoteke i nakon toga uklonite testnu kopiju.
Dodajte vidljive provjere stanja
Nadzor bi trebao razlikovati zaključani vault od nedostupnog poslužitelja. Izradite /usr/local/sbin/vault-health:
#!/bin/sh
set -u
failed=0
for unit in wg-quick@wg0 ssh nftables; do
systemctl is-active --quiet "$unit" || {
logger -p daemon.err -t vault-health "$unit is not active"
failed=1
}
done
if mountpoint -q /srv/vault; then
usage=$(df -P /srv/vault | awk 'NR == 2 {gsub("%","",$5); print $5}')
if [ "$usage" -ge 85 ]; then
logger -p daemon.warning -t vault-health \
"vault filesystem is ${usage}% full"
failed=1
fi
else
logger -p daemon.warning -t vault-health "vault is locked or unmounted"
failed=1
fi
exit "$failed"
Učinite ga izvršnim i definirajte oneshot uslugu koja ga pokreće svakih pet minuta:
[Unit]
Description=Check hardened server health
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/vault-health
Odgovarajući mjerač vremena koristi OnBootSec=5m, OnUnitActiveSec=5m i WantedBy=timers.target. Nakon omogućavanja pregledajte rezultate naredbama journalctl -t vault-health i systemctl list-timers. Također rasporedite smartctl -H za stvarni fizički disk pronađen pomoću lsblk; nikada nemojte pretpostaviti da je to /dev/sda.
Pripremite se za nestanke struje i toplinske kvarove
U firmveru omogućite „restore after AC loss” ako je dostupno. Baterija prijenosnog računala djeluje kao mali UPS, ali napuhnuta, pregrijana ili nepouzdana baterija opasnost je, a ne otpornost. Provjerite hlađenje, održavajte ventilacijske otvore prohodnima i pratite temperaturu pohrane te SMART povijest.
Izradite /etc/systemd/logind.conf.d/server.conf:
[Login]
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
HandleLidSwitchDocked=ignore
Primijenite ga naredbom sudo systemctl restart systemd-logind. Na ovom namjenskom poslužitelju spriječite slučajnu obustavu naredbom sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target. To je moguće poništiti naredbom systemctl unmask.
Uobičajeni putovi kvara
- WireGuard ostvaruje rukovanja, ali SSH ne radi: potvrdite da klijent usmjerava
10.44.0.1/32, da SSH sluša na toj adresi i da nftables vidi pakete nawg0. - WireGuard nikada ne ostvaruje rukovanje: provjerite prosljeđivanje na usmjerivaču, javni DNS, naziv fizičkog sučelja, vrijeme sustava i razmijenjene javne ključeve.
- Vault se otvara, ali se ne može montirati: provjerite
cryptsetup status vault,journalctl -kifsck.ext4 -n /dev/mapper/vault. Opcija-nobavlja provjeru samo za čitanje. - Restic radi interaktivno, ali ne iz systemda: provjerite rootov SSH ključ, prikvačeni ključ računala, dopuštenja datoteke okruženja, DNS i
journalctl -u restic-vault.service. - Datoteke se pojavljuju dok je vault zaključan: usluga je zapisivala u temeljni direktorij točke montiranja. Zaustavite je, sigurno premjestite te datoteke i dodajte
RequiresMountsFor=/srv/vault.
Završna provjera
- Potvrdite da WireGuard i SSH samo s ključem rade izvan kućnog LAN-a.
- Provjerite jesu li LAN veze na TCP 2222 i druge neželjene priključke odbijene.
- Ponovno pokrenite sustav tijekom planiranog prozora održavanja i potvrdite da se udaljena administracija vraća dok vault ostaje zaključan.
- Otključajte vault, pokrenite ovisne usluge i potvrdite vlasništvo i opcije montiranja.
- Pokrenite sigurnosnu kopiju, navedite njezinu snimku i dovršite testno vraćanje.
- Pregledajte dnevnike stanja, sigurnosnih kopija, SSH-a, WireGuarda, kernela i nftablesa.
- Zabilježite postupke oporavka za LUKS i Restic negdje što ne ovisi o ovom prijenosnom računalu.
Najjači dio ove konfiguracije nije nijedan pojedinačni paket. To je razdvajanje odgovornosti: WireGuard izlaže jedan uski ulaz, SSH autentificira administratore, LUKS štiti podatke u mirovanju, Restic štiti neovisne kopije, systemd čini kvarove vidljivima, a nešifrirani osnovni sustav vraća pristup nakon prekida rada. Tako staro prijenosno računalo prestaje biti pametan eksperiment i počinje se ponašati kao infrastruktura.