Grunnleggende Webserver sikring

Bilde av Dev Asangbam fra Unsplash

Bilde av Dev Asangbam fra Unsplash

En gjennomgang av sikring av servere som er åpen mot internett
Sist oppdatert 1. august 2021

Denne guiden tar utgangspunkt i at du akkurat har satt opp en webserver hos linode som kjører Ubuntu 20.04. Målet med guiden er å vise et minimum av sikkerhetstiltak en webserver som er tilgjengelig over internett bør ha før noe som helst skal servers på den.

Forskjellen mellom Linux distroene og andre tilbydere av Virtuelle Private Servere (VPS) er relativt liten for å oppnå samme resultat. Målet her er å gi ett godt grunnlag og en god introduksjon til temaet sikring av servere på internett.

Første innlogging

Opprett sudo bruker, fjern root fra SSH

Logg inn med den utdelte root brukeren til severen via SSH.

ssh root@<server-IP-adresse>

Før du gjør noe som helst annet anbefales det å sette opp en sudo bruker, så du kan umiddelbart slutte å bruke root brukeren.

adduser <ditt-brukernavn>

Når du oppretter en bruker i Ubuntu 20.04 blir du bedt om å skrive inn passord umiddelbart. Sett ett komplisert passord, som du vil slite med å huske, og som det er vanskelig for noen andre å gjette seg frem til. Videre må du legge til denne brukeren i listen over sudo brukere.

visudo

Denne kommandoen vil åpne rettighetsfilen /etc/sudoers.tmp med teksredigeringsprogrammet nano. Finn den kommenterte linjen "# User privilege specification". skriv nøyaktig det samme som står bak root, bare på en ny linje med ditt brukernavn først. Det er også mulig å legge til brukeren i sudoers brukergruppen for å oppnå det samme resultatet, men jeg synes det er letter å legge til sudo privilegier på denne måten.

/etc/sudoers.tmp
# User privilege specification
root ALL=(ALL:ALL) ALL
<dittbrukernavn> ALL=(ALL:ALL) ALL

Trykk Ctrl+S for å lagre, og Ctrl+X for å lukke nano. Når dette er gjort kan du logge inn med den nye brukeren ned su-kommandoen (switch user), og teste om den har fått sudo tilganger, og samtidig oppdatere systemet.

su <ditt-brukernavn>
sudo apt update
sudo apt upgrade

Hvis alt gikk som det skulle er du klar til å logge helt ut fra SSH økten som root, og inn som den nye brukeren din. Avslutt SSH økten ved å trykke Ctrl-D. Og logg inn med den nye brukeren.

ssh <dittbrukernavn>@<server-IP-adresse>

Siden de aller fleste brute-force hacker angrep gjøres av roboter mot root brukeren. Det aller første vi gjør å deaktivere muligheten for å logge inn via SSH som root brukeren.

Åpne configurasjons filen for SSH deamonen, og endre PermitRootLogin fra "yes" til "no".

sudo vim /etc/ssh/sshd_config
/etc/ssh/sshd_config
# Authentication:

PermitRootLogin no

Når det er gjort må SSH deamonen restartes for at endringene skal tas i bruk.

sudo systemctl restart sshd

Brannmur

Begrense hvilke porter som er åpne ut mot verden.

Brannmur er den enkleste måten å begrense hvor mange vindu som er åpne fra verden og inn til serveren vår.

Jeg liker å bruke UFW (Uncomplicated FireWall) siden den som navnet antyder, er ganske ukomplisert, og lett å forstå.

Default med UFW er at alt er stengt. Så for hver tjeneste man ønsker å serve, legger man til den tjenesten i en hviteliste over hvilke data pakker som slipper igjennom brannmuren.

Før jeg skrur den på må jeg legge til SSH i listen over tjenester som den slipper igjennom. Hvis jeg ikke legger til SSH, vil jeg ikke klare å logge inn via SSH til serveren når brannmuren er aktivert.

Det som er supert med UFW er at man veldig raskt kan legge til tjenester i hvitelisten basert på tjeneste type eller navn.

sudo ufw allow ssh
Rules updated
Rules updated (v6)

Da er det klart for å aktivere brannmuren.

sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Hvis alt gikk som det skulle, er jeg fortsatt innlogget. Om det ikke gikk bra, og jeg ble kastet ut av SSH økten er det bare å bruke Linode sin virtuelle LISH terminal, på samme måte som om jeg tilkoblet en fysisk server med skjerm og tastatur for å rette feilen.

Når brannmuren er i drift kan vi sjekke status på brannmuren.

sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
22/tcp (v6)                ALLOW IN    Anywhere (v6)

Ved å lese statusen kan vi nå se at UFW ikke slipper igjennom noe utenifra med mindre det er spesifikt definert, og den slipper ut all trafikk. Med andre ord så funker den som en vanlig klient, med mindre noe annet er spesifisert. Videre kan vi se listen over unntak fra regelen.

I vårt tilfellet slipper brannmuren igjennom trafikk til port 22, som da er SSH tilkoblinger. Ingen annen trafikk slipper igjennom. Så når vi er klare til å for eksempel starte en webserver må vi legge til de nødvendige portene 80 (HTTP) og 443 (HTTPS).

Fail2Ban

Sikring av SSH mot brute-force angrep

Fail2ban er en python basert inntrenger forbyggende system (IPD) løsning som følger med på innloggings logger. Den kan settes opp slik at den blokkerer innlogginger fra IP-adresser som mislyktes å logge inn - for eksempel 3 ganger.

Med fail2ban installert er det lett å sikre seg mot brute-force angrep hvor en hacker forsøker å logge inn med en liste av brukernavn og passord, i håp om å til slutt klare å finne en kombinasjon som gjør at de klarer å logge seg inn.

Start med å installere fail2ban:

sudo apt install fail2ban

Når det er ferdig installert, naviger til mappen med configurasjons filene, lag en kopi av jail.conf, som du døper jail.local. Alle endringene du trenger å gjøre med oppsettet av fail2ban skal gjøres i denne filen.

cd /etc/fail2ban/
sudo cp jail.conf jail.local

Disse .local filene er de konfigurasjons filene som vil bli brukt av fail2ban, hvis fail2ban finner de. Det som er supert med disse filene er at de ikke blir endret når du oppdaterer fail2ban på ett senere tidspunkt.

Åpne jail.local og aktiver overvåkning av SSH ved å legge til linjen "enabled = true",

Hvis du ønsker å endre på de forhåndssatte varigheten på en utestengelse, hvor raskt man må skrive feil, og hvor mange forsøk man får før en IP-adresse blir blokkert, kan det også gjøres i denne filen.

Hvis du har en statisk IP-adresse der du jobber ifra kan det være nyttig å legge inn den adressen i listen over ignoreip så den ikke feilaktig blir blokkert.

Når endringene er gjort må fail2ban restartes for at endringene skal bli tatt i bruk.

sudo nano jail.local
jail.local
# "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban
# will not ban a host which matches an address in this list. Several addresses
# can be defined using space (and/or comma) separator.
ignoreip = 127.0.0.1/8 ::1 123.456.78.90

# "bantime" is the number of seconds that a host is banned.
bantime  = 1d ; <--- 1 day

# A host is banned if it has generated "maxretry" during the last "findtime".
findtime  = 20m ; <--- 20 minutes

# "maxretry" is the number of failures before a host get banned.
maxretry = 5

[sshd]
enabled  = true
sudo systemctl restart fail2ban

For å teste om fail2ban er i drift og følger med på sshd, kjør denne kommandoen

sudo fail2ban-client status
Status
|- Number of jail:      1
`- Jail list:   sshd

Da skal alt være klart til at fail2ban kan starte. For at den skal starte å fungere som den skal må maskinen restartes.

sudo restart now

Når maskinen starter igjen skal fail2ban kjøre, og du bør ikke bli overasket om den allerede etter noen minutter har bannet noen IP-adresser.

sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 2
|  |- Total failed:     10
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 2
   |- Total banned:     2
   `- Banned IP list:   221.181.185.199 221.131.165.119

Sette riktig tidssone

Så klokkeslett i logger og annet stemmer med din egen

Først må du finne ut hvilken tidssone du selv er i

date
Sun 27 Dec 2020 11:46:14 AM UTC
timedatectl list-timezones
.........
Europe/Minsk
Europe/Monaco
Europe/Moscow
Europe/Oslo
Europe/Paris
Europe/Prague
.........

Utifra listen henter kopierer jeg ut riktig tidssone, og bruker den til å sette rett tidssone

sudo timedatectl set-timezone <din-tidssone>

Da er kan jeg sjekke at tidssonen stemmer med å bruke date kommandoen igjen.

date
Sun 27 Dec 2020 12:48:15 PM CET

24t tidsformat

I Norge bruker vi ikke AM/PM

Siden jeg ikke liker å bruke AM/PM, men heller vil ha 24timers format på klokken endrer jeg dette med:

sudo localectl set-locale LC_TIME=en_GB.UTF-8

Dette forandrer tidsformatet til den britiske måten å vise tid på. For at endringene skal vises må du logge ut og inn igjenn fra maskinen.

date
Sun 27 Dec 12:50:02 CET 2020

Resultatet er at det i (allefall for meg) blir litt lettere å lese systemlogger.