Ubuntu szerver általános biztonsági beállításai (22.04 LTS)

Innen: AdminWiki

Ez a fejezet egy alaptelepített Ubuntu Fossa szervergép nyilvános elérésűvé tételéhez minimálisan szükséges beállításokkal foglalkozik. Az alábbiak jó része a Securing Debian Manual illetve a közismert (és nagyon régi) Zákány-dolgozat alapján készült.

TODO: AppArmor, SELinux, PaX, grsecurity

Kernel paraméterek

TODO!

A beállított paraméterek az alábbi paranccsal (vagy a számítógép újraindításával) érvényesíthetőek:

sudo sysctl --system

File jogosultságok szigorítása

Az alábbi script lefuttatásával megszüntetjük a worldwide olvasható home könyvtárakat, másolatot készítünk a master boot record-ról, és megszigorítjuk néhány fontos könyvtár és file elérhetőségét. Célszerű ezt a scriptet futtatási jog nélkül (pl. chmod 600) a /root/install/security.sh állományba tenni, és indirekt lefuttatni:

sudo mkdir /root/install/
sudo touch /root/install/security.sh
sudo chmod 600 /root/install/security.sh
sudo mcedit /root/install/security.sh
[...]
sudo /bin/bash /root/install/security.sh
#!/bin/sh
# Checklist to set up some security settings.
# From Linux Security Quick Reference Guide - http://www.LinuxSecurity.com
# https://github.com/shadowbq/Cheat-Sheets/blob/master/posix/Linux%20Security%20Quick%20Reference%20Guide.pdf

BOOTDEV=/dev/sda        # Modify, if you boot from another device

sudo chmod -R o-rwx /root    # Hide root's home dir
sudo chmod -R o-rwx /home/*  # Hide user's home dirs

# Save MBR to file - keep a backup on floppy disk or CD!
sudo dd if=$BOOTDEV of=/$(dirname $0)/mbr.`hostname`.`date +%Y%m%d` bs=512 count=1

# Permissions for critical system files
chmod o-r /var/log              # Logfile directory
chmod 600   /etc/crontab          # System-wide crontab
chmod o-x   /etc/logrotate.conf   # Controls rotating of system log files
chmod o-x   /etc/logrotate.d      # Controls rotating of system log files
chmod o-rwx /var/log/wtmp         # Who is logged in now. Use who to view
chmod o-rwx /etc/security         # System access security policy files
chmod o-rwx /etc/init.d           # Program start-up files
chmod o-rwx /etc/ssh              # Secure shell config files
chmod o-rwx /etc/sysctl.conf      # Contains kernel tunable options
chmod o-rwx /etc/sysctl.d         # Contains kernel tunable options (includes)

Megjegyzés: Nem biztos, hogy minden, a scriptben hivatkozott file létezik (és írható), ez indokolja az esetleges hibaüzeneteket.

Partíciók csatolásának szigorítása

Opcionális beállítás, csak akkor használható, ha eleve erre készülve particionáltunk. Előtelepített VM esetén valószínűleg nem alkalmazható.

Ebben a szakaszban a partíciókat úgy csatoljuk fel, hogy csak a / (esetleg még a /srv vagy /srv/chroot) partíció legyen írható és futtatható egyszerre. Célszerű a telepítő által létrehozott /etc/fstab file-t két példányban lemásolni:

sudo cp /etc/fstab /etc/fstab.secure
sudo cp /etc/fstab /etc/fstab.unsecure

és az alábbi táblázat szerint kitölteni (a táblázat forrása a Zákány-dolgozatban található):

partíció fstab.secure fstab.unsecure
root acl,defaults,errors=remount-ro acl,defaults,errors=remount-ro
srv/chroot acl,defaults acl,defaults
boot ro,nosuid,noexec,nodev,acl,defaults acl,defaults
tmp nosuid,noexec,nodev,acl,defaults acl,defaults
usr ro,nodev,acl,defaults acl,defaults
var nosuid,noexec,nodev,user_xattr,acl,defaults user_xattr,acl,defaults
var/www nosuid,noexec,nodev,user_xattr,acl,defaults user_xattr,acl,defaults

Megjegyzés: a táblázat szerinti beállításokkal engedélyezzük a Posix ACL-ek és a /var jellegű partíciókon a kiterjesztett fájlattribútumok használatát is.

Megjegyzés: SSD meghajtó esetén célszerű a discard opcióval engedélyezni a TRIM használatát minden partíción (a swap partíción is!).

Ezt követően, a mindenkori fstab felülírása után, egy partícióra vonatkozóan a biztonságos és az engedékeny konfiguráció között a

sudo mount -o remount /XXX

paranccsal válthatunk.

Ahhoz, hogy biztonságos konfigurációban is lehessen csomagot telepíteni, illetve rendszert frissíteni, hozzunk létre egy bejegyzést az apt.conf.d könyvtárban (ügyeljünk arra, hogy a shell scripttől eltérően a megjegyzés jele a //):

sudo mcedit /etc/apt/apt.conf.d/10security
// Lehetove teszi az apt hasznalatat szigoruan csatolt particiok eseten.
// garancsi.attila@mimoza.hu 2005-04-07

DPkg::Pre-Invoke {
        "/bin/mount -o remount,rw /boot";
        "/bin/mount -o remount,exec,suid /tmp";
        "/bin/mount -o remount,rw /usr";
        "/bin/mount -o remount,exec /var";
};

DPkg::Post-Invoke {
        "/bin/mount -o remount /boot";
        "/bin/mount -o remount /tmp";
        "/bin/mount -o remount /usr";
        "/bin/mount -o remount /var";
};

Ezután az apt használatához már nem kell remountolni (de a szimpla dpkg-hoz - pl. kernel frissítés - vagy tarball-ból telepítéshez igen!)

Felesleges szolgáltatások leállítása

Az Ubutu Fossa-ban a systemd system and service manager az alapértelmezett eszköz a szolgáltatások kezelésére, emiatt - a korábbi Debian/Ubuntu kiadásokkal ellentétben - a /etc/rc${runlevel}.d/ illetve /etc/init.d/ alatti állományok és linkek szerkesztése, illetve a sysv-rc-conf használata elavult. Így a

systemctl list-unit-files --type=service
sudo systemctl enable  SERVICE
sudo systemctl disable SERVICE

parancsok szolgálnak a telepített szolgáltatások listázására, illetve egy-egy szolgáltatás permanens engedélyezésére vagy letiltására (bővebben ld. pl. itt vagy itt). Igyekezzünk tehát a fentieket kizárólag a systemctl használatával megoldani. A nyitott portokról és az azokon figyelő szolgáltatásokról az alábbi parancsok adnak közelítő tájékoztatást:

sudo netstat -tanulp | egrep '(LISTEN)|(ESTAB)' | less
sudo lsof -i | grep 'LISTEN' | less

A listázott szolgáltatásokról egyenként kell eldönteni, hogy van-e velük teendő. A netstat szerint, a leírt alaptelepítés után az alábbi, potenciálisan távolról is elérhető szolgáltatások futnak:

Szolgáltatás Port Leírás Teendő
master TCP:25 SMTP szerver (levélküldés és -fogadás). Szükséges. Kihelyezés után a szervernek tudnia kell levelet fogadni, így ellenőrzendő, hogy ezt a forgalmat a tűzfalon beengedjük-e.
systemd- resolved TCP:53 UDP:53 cache-only DNS szerver helyi szolgáltatásoknak Szükséges. Mivel csak helyi szolgáltatást nyújt, a tűzfalon át nem kell hozzá kapcsolódást engedni.
sshd TCP:22 (vagy ahova konfiguráltuk) Biztonságos távoli shell. Szükséges, ellenőrizni kell, hogy a tűzfalon beengedjük-e.

Megjegyzés: a fenti lista változhat, a netstat eredményét minden esetben egyedileg kell kiértékelni!

A fail2ban telepítése

A fail2ban egy framework, amely hálózati szolgáltatások naplóinak figyelésére, és a szolgáltatással visszaélés (abuse, pl. SSH brute force vagy dictionary attack) jeleit mutató távoli kliensek ideiglenes kitiltására szolgál a csomagszűrő tűzfal (netfilter) átmeneti átkonfigurálásával.

Megjegyzés: a fail2ban (iptables hívásokkal) közvetlenül módosítja a netfilter-t; ufw integráció TODO!.

sudo apt install fail2ban # Függőségként hozza magával a python-t

Telepítés után a fail2ban számos, előre definiált védelme közül csak az SSH van bekapcsolva (ld. /etc/fail2ban/jail.d/defaults-debian.conf). Ha van megbízható (trusted) IP címünk vagy tartományunk, amellyel szemben az SSH védelmet szeretnénk mellőzni, készítsünk egy overlay állományt a védelem átkonfigurálására:

sudo touch /etc/fail2ban/jail.d/sshd.conf; sudo chmod 600 /etc/fail2ban/jail.d/sshd.conf
sudo mcedit /etc/fail2ban/jail.d/sshd.conf
[sshd]
enabled = true
findtime = 600
maxretry = 3
bantime = 600
ignoreip = IP.IP.IP.IP IP.IP.IP.IP/MASK

A majdani publikus kihelyezésre gondolva célszerű bekapcsolni a Postfix védelmét is:

sudo touch /etc/fail2ban/jail.d/postfix.conf; sudo chmod 600 /etc/fail2ban/jail.d/postfix.conf
sudo mcedit /etc/fail2ban/jail.d/postfix.conf
[postfix]
enabled = true

A beállításokat a fail2ban újraindításával érvényesítsük:

sudo systemctl restart fail2ban; sudo tail -f /var/log/fail2ban.log  # Jail 'sshd' started | Jail 'postfix' started

A későbbiekben telepítendő, védeni kívánt egyéb szolgáltatások helyi beállításait az ugyanitt létrehozandó, /etc/fail2ban/jail.d/*.conf beállító állományokban adhatjuk meg.

Opcionális gyors tesztként egy, a telepítés alatt álló szervert TCP-n keresztül elérő gépről (ne a saját munkaállomásunkról!) próbáljunk SSH-n sikertelenül bejelentkezni, és figyeljük a /var/log/fail2ban.log állományban az IP kitiltását, illetve 10 perc utáni újraengedélyezését. Ha megadtunk megbízható IP-t vagy tartományt, ellenőrizhetjük, hogy az innen indított sikertelen lekérésekre a kitiltás nem történik meg.

Csomagszűrő tűzfal beállítása

A házirend szerint valamennyi szervert bastion host-ként kell kialakítani, azaz saját (csomagszűrő) tűzfallal kell rendelkezzen. A gyakorlatban ez a Linux kernel netfilter (iptables) konfigurálását jelenti, amelyet ebben a leírásban az Ubuntu terjesztésben alapértelmezetten telepített UFW (Uncomplicated Firewall) parancssori frontend segítségével valósítunk meg.

Alapértelmezésben az ufw inaktív, és az iptables nem tartalmaz szabályokat:

sudo ufw status      # inactive
sudo iptables -n -L  # mindhárom chain üres
  • Ez a leírás a majdani publikus eléréshez szükséges, alapvető csomagszűrést valósít meg, egy darab hálózati interface-szel rendelkező szervergépen.
  • Ez a leírás csak IPv4-re vonatkozik - IPv6 TODO!

Az IPv6 tiltása

Figyelem: elképzelhető, hogy a hosting vagy a VM hypervisor számára szükséges az IPv6 - erről érdemes előzetesen tájékozódni!

Tisztán IPv4 környezetben opcionálisan érdemes teljesen letiltani az IPv6 forgalmat. Ehhez adjunk hozzá egy kernel paramétert a grub-ban átadott boot paraméterekhez:

sudo mcedit /etc/default/grub
[...]
GRUB_CMDLINE_LINUX_DEFAULT="[...] ipv6.disable=1"
[...]

Érvényesítsük a beállításokat:

sudo update-grub

majd indítsuk újra a gépet.

Ellenőrzés: újraindítás után az ifconfig vagy ip a parancsok kimenete már nem mutat IPv6 címeket.

Az IPv6 tiltását tudassuk az alábbi szolgáltatásokkal is:

  • Postfix
sudo mcedit /etc/postfix/main.cf

Módosítsuk all-ról ipv4-re:

[...]
inet_protocols = ipv4
[...]

Ezután indítsuk újra a szolgáltatást:

sudo systemctl restart postfix

UFW alapbeállítások

Amennyiben az IPv6-ot fentebb letiltottuk, ezt a beállítást vezessük át a /etc/default/ufw állományban is:

sudo mcedit /etc/default/ufw
[...]
# Set to yes to apply rules to support IPv6 (no means only IPv6 on loopback
# accepted). You will need to 'disable' and then 'enable' the firewall for
# the changes to take affect.
IPV6=no
[...]

Ezen kívül érdemes elkülöníteni a csomagszűrés bekapcsolását követően várhatóan terjedelmessé növő tűzfal naplót a kernel naplójától. Ehhez a /etc/rsyslog.d/20-ufw.conf állományban engedélyezzük az alapértelmezetten kikommentezett utolsó sort:

sudo mcedit /etc/rsyslog.d/20-ufw.conf
# Log kernel generated UFW log messages to file
:msg,contains,"[UFW " /var/log/ufw.log

# Uncomment the following to stop logging anything that matches the last rule.
# Doing this will stop logging kernel generated UFW log messages to the file
# normally containing kern.* messages (eg, /var/log/kern.log)
& stop

Ezután állítsunk be egy alap (IPv4) csomagszűrő szabálykészletet.

A bejövő forgalom engedélyezése

Mivel a /etc/default/ufw állományban előírt ufw policy a bejövő forgalom tiltása, mielőtt aktiválnánk a csomagszűrést, mindenképpen engedélyezzük a kívülről csatlakozást legalább az OpenSSH szolgáltatáshoz:

sudo ufw app info OpenSSH   # case-sensitive! - ellenőrizzük a portszámot
sudo ufw allow OpenSSH      # ha a TCP/22-es portot használjuk, állítsuk be a szabályt

A fenti parancsban az alkalmazással együtt települő alkalmazásleírásra (/etc/ufw/applications.d alatti állomány) hivatkoztunk, így nem kellett közvetlenül portszámokat megadni. Ha más portot használunk, írjunk egy specifikus szabályt:

sudo ufw allow in NNNNN/tcp comment 'OpenSSH at NNNNN'  # NNNNN a használt TCP port száma

A létrehozott tűzfal szabályok a tűzfal inaktív állapotában is megtekinthetőek a /etc/ufw/user.rules állományban.

Ezután bekapcsolhatjuk a csomagszűrést:

sudo ufw enable
sudo ufw status verbose  # Status: active
sudo iptables -n -L      # A létrehozott iptables beállítások

Amennyiben a telepítés alatti szervergép Internet mail host (azaz smarthost nélkül küld leveleket), érdemes bekapcsolni a levélfogadáshoz tartozó szabályokat is az esetleges visszapattanó levelek kezelése érdekében. Ehhez használhatjuk a

sudo ufw allow Postfix

parancsot, amely a TCP/25, TCP/465 és TCP/587 portokat fogja engedélyezni.

A kimenő forgalom szigorítása

Alapértelmezetten a kimenő forgalomra az ACCEPT policy van beállítva, azaz a kimenő forgalmat nem szűrjük. Opcionálisan de javasoltan érdemes lehet kifelé csak a ping és traceroute, a DNS lekérés, a levélküldés SMTP-vel (+SMTPs, MSA), az időszinkron NTP protokollal, PGP kulcsszerverek elérése (HKP), a web és az FTP forgalmakat engedélyezni. Opcionálisan az SSH is engedélyezett lehet.

Az ICMP forgalom megtartására szúrjuk be az alábbi parancssort a /etc/ufw/before.rules állományba:

sudo mcedit /etc/ufw/before.rules
[...]
# ok all icmp for output
-A ufw-before-output -p icmp -j ACCEPT

# allow dhcp client to work
[...]

A többi korlátozást az alábbi parancsok egyszeri kiadásával írhatjuk elő:

sudo ufw allow out domain
sudo ufw allow out smtp
sudo ufw allow out smtps
sudo ufw allow out submission
sudo ufw allow out ntp
sudo ufw allow out hkp
sudo ufw allow out http
sudo ufw allow out https
sudo ufw allow out ftp
sudo ufw default reject outgoing  # Minden mást visszadobunk

Ellenőrzésképpen kérjünk egy státuszt:

sudo ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] OpenSSH                    ALLOW IN    Anywhere                  
[ 2] Postfix                    ALLOW IN    Anywhere                  
[ 3] 53                         ALLOW OUT   Anywhere                   (out)
[ 4] 25/tcp                     ALLOW OUT   Anywhere                   (out)
[ 5] 465/tcp                    ALLOW OUT   Anywhere                   (out)
[ 6] 587/tcp                    ALLOW OUT   Anywhere                   (out)
[ 7] 123/udp                    ALLOW OUT   Anywhere                   (out)
[ 8] 11371/tcp                  ALLOW OUT   Anywhere                   (out)
[ 9] 80/tcp                     ALLOW OUT   Anywhere                   (out)
[10] 443/tcp                    ALLOW OUT   Anywhere                   (out)
[11] 21/tcp                     ALLOW OUT   Anywhere                   (out)

Ezzel az alapvető csomagszűrést beállítottuk.

Logcheck

TODO!

Publikus környezetbe kihelyezés

A biztonsági megerősítést követően a szerver publikus környezetbe (DMZ, production) kihelyezhető. A kihelyezésnél figyeljünk:

  • a statikus IP megadására, ha szükséges (/etc/netplan/*.yaml);
  • a domain név esetleges megváltoztatására;
  • amennyiben erre készülve particionáltunk, a szigorú partíció-csatolásra (/etc/fstab.secure);
  • a gép előtti (hosting szintű) esetleges hálózati forgalomszűrés beállíttatására;
  • arra, hogy nyilvánosan elérhető gépeken mindig erős (lehetőleg generált) jelszavak legyenek!

Internet mail host esetén szükség lehet ezen kívül a technikai levelezés átkonfigurálására. Az alábbi paranccsal ellenőrizhetjük, hogy a szerver milyen FQHN-nel (Fully Qualified HostName) jelentkezik be levélküldéskor:

echo "Teszt" | mail -s Teszt helocheck@abuseat.org; sudo tail -f /var/log/mail.log

Ez egy azonnal visszapattanó levelet eredményez, amelybe a helocheck beleírja az általunk ténylegesen használt FQHN-et. Ha ez nem egyezne meg a

dig -x IP.IP.IP.IP # szerver publikus IP címe

paranccsal megtudható reverse-zel, akkor érdemes beállítanunk a helyes (reverse) FQHN-et, mert ezt sok levélfogadó ellenőrzi, és eltérés esetén megbízhatatlannak minősítheti szervergépünket. Ehhez szerkesszük meg a /etc/postfix/main.cf állományt:

sudo mcedit /etc/postfix/main.cf

és szúrjuk be (pl. a fájl végére) a helyes FQHN-et:

[...]
smtp_helo_name=FQHN 

Érvényesítsük a beállításokat:

sudo systemctl reload postfix

és ismételjük meg a helocheck tesztet.

Irodalom