Steg för att säkra vår VPS

Denna handledning visar hur man förbereder och säkrar en Virtual Private Server (VPS) med Debian GNU / Linux. Innan vi börjar antas vissa saker:

  1. Du har en mellanliggande nivå av förtrogenhet med GNU / Linux.
  2. Det finns en VPS för personligt bruk som vi har tillgång till via SSH.
  3. VPS har den dedikerade externa ipv4 250.250.250.155 och vår leverantör äger 250.250.0.0/16-blocket. (1)
  4. I vår VPS har vi bara http, https och ssh-tjänster aktiverade för åtkomst utifrån.
  5. Extern DNS aktiveras inte eftersom det vanligtvis görs i vår leverantörspanel. (2)
  6. Det kommer att fungera som en superanvändare.

installation

Som ett första steg, låt oss uppdatera servern och installera några paket som vi behöver:

# aptitude update & aptitude safe-upgrade # aptitude -RvW installera dropbear gesftpserver sslh iptables-persistent ulogd fail2ban nginx-light apache2-utils dnsutils telnet ghostscript poppler-utils zip zip upp unrar-fri p7zip-full mindre multitail tee mc

konfiguration

Nu ska vi skapa en arbetsanvändare. Att arbeta som root på en server är osäkert, så vi skapar först en speciell användare:

adduser-operatör usermod -aG sudo-operatör

Det första kommandot skapar operatörsanvändaren, det andra lägger till det i gruppen sudo, vilket gör att du kan köra applikationer som root.

Justera behörigheter för superanvändare

För att arbeta regelbundet kommer vi att använda användaren operatör tidigare skapat måste vi justera kommandokörningsalternativen som superanvändare, för vilken vi kör följande kommando:

visudo

Detta kommando tillåter i princip att ändra filen / etc / sudoers; där vi bör innehålla dessa rader:

Standardvärden env_reset, timestamp_timeout = 0% sudo ALL = (ALL: ALL) ALL

I första raden läggs alternativet till standardvärdena tidsstämpel_tid vilket gör det möjligt att ställa in löptidens utgångstid (i minuter) när sudo-kommandot körs. Standard är 5, men det är ibland osäkert av två skäl:

  1. Om vi ​​av misstag lämnar vår dator inloggad innan lösenordet löper ut, kan någon utföra ett kommando som root utan några begränsningar.
  2. Om vi ​​genom okunnighet kör ett program eller skript som innehåller skadlig kod innan lösenordet löper ut, kan applikationen ha tillgång till vårt system som superanvändare utan vårt uttryckliga medgivande.

Så för att undvika risker har vi satt värdet till noll, det vill säga varje gång sudo-kommandot körs måste lösenordet anges. Om ett negativt värde är satt till -1 är effekten att lösenordet aldrig går ut, vilket skulle ge motsatt resultat av vad vi vill ha.

I den andra raden klargörs att sudogruppen kan utföra valfritt kommando på vilken dator som helst, vilket är vanligt, även om det kan justeras. (3) Det finns de som för enkelhets skull sätter raden på följande sätt för att undvika att behöva skriva lösenordet:

% sudo ALL = (ALL: ALL) NOPASSWD: ALL

Men som vi förklarade tidigare är det riskabelt och därför rekommenderas det inte.

Inaktivera omstart

Av säkerhetsskäl kommer vi också att inaktivera omstart med tangentkombinationen Ctrl + Alt + Del, för vilken vi måste lägga till den här raden i filen / Etc / inittab:

ca: 12345: ctrlaltdel: / bin / echo "Ctrl + Alt + Del har inaktiverats."

Ersätt OpenSSH med DropBear

De flesta VPS levereras med OpenSSH installerat, vilket verkligen är mycket användbart, men om vi inte behöver utnyttja alla funktioner i OpenSSH, finns det lättare alternativ för en VPS, till exempel dropbear, vilket vanligtvis är tillräckligt för regelbunden användning. En nackdel med denna applikation är dock att den inte kommer med en integrerad SFTP-server, och det är därför vi i början installerade paketet gesftpserver.

För att konfigurera Dropbear ändrar vi filen / etc / default / dropbear så att den innehåller dessa två rader:

NO_START = 0 DROPBEAR_EXTRA_ARGS = "- w -p 127.0.0.1:22 -I 1200 -m"

Den första raden möjliggör helt enkelt tjänsten, och den andra gör flera saker:

  1. Undvik root-åtkomst.
  2. Det får tjänsten att lyssna på port 22 i det lokala gränssnittet (vi kommer att förklara varför senare).
  3. Ställer in väntetiden (20 minuter).

SSLH

Port 22 (SSH) är välkänd och är i allmänhet en av de första som hackare försöker bryta mot, så vi använder istället port 443 (SSL). Det händer att den här porten används för säker surfning via HTTPS.

Av denna anledning kommer vi att använda sslh-paketet, som inte är något annat än en multiplexer som analyserar paketen som anländer till port 443 och dirigerar dem internt till en eller annan tjänst beroende på om typen av trafik är SSH eller SSL.

SSLH kan inte lyssna på ett gränssnitt där en annan tjänst redan lyssnar, varför vi tidigare fick Dropbear att lyssna på det lokala gränssnittet.

Vad vi nu behöver göra är att indikera att man ska sslh gränssnittet och porten genom vilken den ska lyssna och vart paketen ska omdirigeras beroende på typ av tjänst, och för detta ändrar vi konfigurationsfilen / etc / default / sslh:

DAEMON = / usr / sbin / sslh DAEMON_OPTS = "- användare sslh --listen 250.250.250.155:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile / var / run / sslh / sslh. pid "KÖR = ja

Slutligen startar vi om tjänsterna:

service ssh stop && service dropbear start && service sslh restart

Efter det tidigare kommandot kommer vår säkra session troligen att avbrytas, i vilket fall det räcker att logga in igen, men den här gången med arbetsanvändaren och använder port 443. Om sessionen inte avbryts, är det lämpligt att stänga den och börja om. med lämpliga värden.

Om allt fungerar korrekt kan vi fortsätta arbeta som root och avinstallera OpenSSH om vi vill:

sudo su - aptitude -r rensning openssh-server

brandväggar

Nästa sak vi ska göra är att separera loggarna från brandväggen till den separata filen /var/log/brandvägg.log för att underlätta vidare analys, varför vi installerade ulogd-paketet vid start. För detta kommer vi att redigera filen /etc/logd.conf för att justera relevant avsnitt:

[LOGEMU] file = "/ var / log / firewall.log" sync = 1

Därefter kommer vi att ändra rotationsfilen / etc / logrotate / ulogd för att hålla en daglig rotation (med datum) och spara komprimerade salvor i katalogen / var / log / ulog /:

/var/log/ulog/*.log /var/log/firewall.log {daglig dateext saknas komprimera fördröjning komprimera shareskript skapa 640 root adm postrotate /etc/init.d/ulogd reload mv /var/log/firewall.log-* .gz / var / log / ulog / slutskript}

Sedan skapar vi netfilterreglerna genom att utföra följande:

IPT = $ (vilka iptabeller) IPEXT = 250.250.250.155 IPEXTBLK = 250.250.0.0 / 16 IPBCAST = 255.255.255.255 $ IPT -F $ IPT -X $ IPT -Z $ IPT -A INPUT -i lo -j ACCEPT $ IPT - P INPUT DROP $ IPT -P FORWARD DROP $ IPT -P OUTPUT ACCEPT $ IPT -A INPUT -m state --state INVALID -j ULOG --ulog-prefix IN_INVALID $ IPT -A INPUT -p igmp -j ULOG --ulog -prefix IN_IGMP $ IPT -A INPUT -m pkttype --pkt-typ sändning -j ULOG --ulog-prefix IN_BCAST $ IPT -A INPUT -m pkttype --pkt-typ multicast -j ULOG --ulog-prefix IN_MCAST $ IPT -A FORWARD -j ULOG --ulog-prefix FORWARD $ IPT -N ICMP_IN $ IPT -A INPUT!  -i lo -p icmp -j ICMP_IN $ IPT -A ICMP_IN -p icmp -f -j ULOG --ulog-prefix IN_ICMP_FRAGMENTED $ IPT -A ICMP_IN -p icmp -m icmp -m längd!  --längd 28: 1322 -j ULOG --ulog-prefix IN_ICMP_INVALIDSIZE $ IPT -A ICMP_IN -p icmp -m icmp -m hashlimit --hashlimit-över 4 / sek --hashlimit-mode srcip --hashlimit-srcmask 24 - -hashlimit-namn icmpflood -j ULOG --ulog-prefix IN_ICMP_FLOOD $ IPT -A ICMP_IN -p icmp -m icmp -m hashlimit --hashlimit-upp till 64kb / min --hashlimit-mode srcip --hashlimit-srcmask 24 - hashlimit -namn icmpattack -j ULOG --ulog-prefix IN_ICMP_FLOOD $ IPT -A ICMP_IN -p icmp -m icmp -m u32!  --u32 "0x4 & 0x3fff = 0x0" -j ULOG --ulog-prefix IN_ICMP_ATTACK $ IPT -A ICMP_IN -p icmp -m icmp!  --icmp-typ eko-begäran -m tillstånd --stat NEW - j ULOG --ulog-prefix IN_ICMP_INVALID $ IPT -A ICMP_IN -p icmp -m icmp --icmp-typ echo-begäran -j ULOG --ulog- prefix IN_ICMP $ IPT -A ICMP_IN -p icmp -m icmp --icmp-typ echo-begäran -m gräns - begränsa 1 / sek - begränsa burst 4 -j ACCEPTERA $ IPT -A ICMP_IN -p icmp-m icmp --icmp-typ eko-svar -m gräns - begränsa 2 / sek - begränsa burst 4 -j ACCEPT $ IPT -A ICMP_IN -p icmp -m icmp --icmp-typ destination-ouppnåelig -m gräns - gräns 2 / sek - limit-burst 4 -j ACCEPT $ IPT -A ICMP_IN -p icmp -m icmp --icmp-typ tidsöverskridande -m limit --limit 2 / sec - limit-burst 4 -j ACCEPT $ IPT -A ICMP_IN -p icmp -m icmp --icmp-typ parameter-problem -m gräns - begränsa 2 / sek - begränsa burst 4 -j ACCEPT $ IPT -A ICMP_IN -j RETUR $ IPT -N UDP_IN $ IPT -A INGÅNG!  -i lo -p udp -j UDP_IN $ IPT -A UDP_IN!  -jag!  -p udp -f -j ULOG --ulog-prefix IN_UDP_FRAGMENTED $ IPT -A UDP_IN -p udp -m udp - sport 53-m längd!  --längd 28: 576 -j ULOG --ulog-prefix IN_UDP_DNS_INVALIDSIZE $ IPT -A UDP_IN -p udp -m udp --dport 53 -m -stat --state NEW -j ULOG --ulog-prefix IN_UDP_DNSREQUEST $ IPT - En UDP_IN -p udp -m udp --dport 53 -m -state --state NEW -j REJECT --reject-med icmp-port-unreachable $ IPT -A UDP_IN -p udp -m udp!  --sport 53!  -s $ IPEXTBLK!  -d $ IPBCAST -m tillstånd --stat NYTT -j ULOG --ulog-prefix IN_UDP $ IPT -A UDP_IN -p udp -m udp -m tillstånd --stat ESTABLERAD, RELATERAD -j ACCEPT $ IPT -A UDP_IN -j RETUR $ IPT -N TCP_IN $ IPT -A INGÅNG!  -i lo -p tcp -j TCP_IN $ IPT -A TCP_IN!  -jag!  -p tcp -f -j ULOG --ulog-prefix IN_TCP_FRAGMENTED $ IPT -A TCP_IN -p tcp -m tcp --sport 53 -m state --state ESTABLISHED, RELATED -m längd!  --längd 513: 1500 -j ULOG --ulog-prefix IN_TCP_DNS_INVALIDSIZE $ IPT -A TCP_IN -p tcp -m tcp --dport 53 -m state --state NEW -j ULOG --ulog-prefix IN_TCP_DNS $ IPT -A TCP_IN -p tcp -m tcp --dport 53 -m tillstånd --stat NYTT -j REJECT - avvisa-med icmp-port-oåtkomlig $ IPT -A TCP_IN -p tcp -m tcp -m multiport!  --dports 80,443 -m tillstånd --stat NEW - j ULOG --ulog-prefix IN_TCP $ IPT -A TCP_IN -p tcp -m tcp -m multiport --dports 80,443 -m tillstånd --stat NEW - m hashlimit - hashlimit -upto 4 / sec --hashlimit-burst 16 --hashlimit-mode srcip --hashlimit-name navreq -j ACCEPT $ IPT -A TCP_IN -p tcp -m tcp -m multiport --dports 80,443 -m state - state ESTABLISHED -m är begränsad!  --connlimit-över 16 -j ACCEPT $ IPT -A TCP_IN -p tcp -m tcp -m multiport! 

Med den tidigare konfigurationen bör vår VPS vara rimligt säker, men om vi önskar kan vi säkra den lite mer, för vilken vi kan använda några mer avancerade regler.

Inte alla VPS tillåter installation av extra moduler för netfilter, men det är mycket användbart psd, vilket gör att du kan undvika portavsökningar. Tyvärr är den här modulen inte integrerad i netfilter som standard, så det är nödvändigt att installera vissa paket och sedan bygga modulen:

aptitude -RvW installera iptables-dev xtables-addons-source module-assistant module-assistant --verbose --text-mode auto-install xtables-addons-source

När ovanstående är gjort kan vi lägga till en sådan regel:

iptables -A INPUT -m psd --psd-vikt-tröskel 15 --psd-fördröjning-tröskel 2000 --psd-lo-port-vikt 3 --psd-hi-portar-vikt 1 -j ULOG --ulog- prefix IN_PORTSCAN

Den tidigare regeln innebär i grunden att vi kommer att skapa en räknare som kommer att öka med 3 varje gång ett försök görs för att komma åt en port lägre än 1024 och med 1 varje gång ett försök görs för att komma åt en port högre än 1023, och när denna räknare når 15 under en period på mindre än 20 sekunder, kommer paketen att registreras av ulog som ett försök till portscan. Paketen kan fortfarande kasseras på en gång, men i det här fallet tänker vi använda fail2ban, som vi konfigurerar senare.

När reglerna har skapats måste vi vidta vissa försiktighetsåtgärder för att göra dem bestående, annars förlorar vi dem när servern startas om. Det finns flera sätt att uppnå detta; I denna handledning använder vi det iptables-persistenta paketet som vi installerade i början, vilket lagrar reglerna i /etc/iptables/rules.v4 y /etc/iptables/rules.v6 för ipv6.

iptables-save> /etc/iptables/rules.v4

I själva verket, även om användningen av ipv6 på Kuba ännu inte är utbredd, kan vi mycket väl skapa några grundläggande regler:

IPT = $ (vilka ip6tabeller) $ IPT -P INPUT DROP $ IPT -P FORWARD DROP $ IPT -P OUTPUT ACCEPT $ IPT -A INPUT -i lo -j ACCEPT $ IPT -A INPUT! -i lo -m state --state ESTABLISHED, RELATED -j ACCEPT unset IPT

Dessa regler kan också göras bestående:

ip6tables-save> /etc/iptables/rules.v6

Slutligen för att öka säkerheten rensar vi brandväggens register och startar om tjänsterna:

echo -n> /var/log/firewall.log tjänsten logrotate starta om tjänsten ulogd starta om tjänsten iptables-beständig omstart

nginx

Vi kommer att använda Nginx som en webbserver, eftersom VPS-enheter tenderar att ha en minskad mängd RAM-minne jämfört med en riktig server, så det är i allmänhet bekvämt att ha något lättare än Apache.

Innan vi konfigurerar Nginx skapar vi ett certifikat (inget lösenord) för användning över HTTPS:

cd / etc / nginx openssl genrsa -des3 -out cert.key 4096 cp -v cert.key cert.key.original openssl req -new-key cert.key -out cert.csr openssl rsa -in cert.key.original - ut cert.nyckel openssl x509 -req -dagar 365 -in cert.csr -signkey cert.key -out cert.crt

När detta är klart skapar vi en lösenordsfil för användaren "elusuario":

htpasswd -c .htpasswd användaren

Därefter ändrar vi filen / Etc / nginx / sites-available / default för att ställa in standardwebbplatsinställningarna. Det kan se ut så här:

server {server_name localhost; index index.html index.htm default.html default.htm; root / var / www; plats / {# ställ in ordningen för verifiering och sidan som ska laddas, om URI inte hittas try_files $ uri $ uri / /index.html; }} server {lyssna 127.0.0.1:443; servernamn localhost; index index.html index.htm default.html default.htm; root / var / www; ssl på; ssl_certificate cert.crt; ssl_certificate_key cert.key; ssl_session_timeout 5m; # Aktivera HTTPS endast över TLS (säkrare än SSL) ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # ge preferenser till höghållfasta [HIGH] -kodare, # flytta medelstyrka [MEDIUM] -kodare till slutet av listan, # inaktivera lågstyrka [LOW] -kodare (40 och 56 bitar) # inaktivera kodningar med exportalgoritmer [ EXP] # inaktivera nollkodare [eNULL] utan autentisering [aNULL], SSL (version 2 och 3) och DSS (endast tillåta nycklar upp till 1024 bitar) ssl_ciphers HIGH: + MEDIUM :! LOW :! EXP:! ANULL :! eNULL :! SSLv3 :! SSLv2 :! DSS; # Föredrar serverns krypteringsmetoder (som standard används klientens) ssl_prefer_server_ciphers on; plats / {# aktivera autentisering auth_basic "Login"; auth_basic_user_file /etc/nginx/.htpasswd; # ställ in ordningen för verifiering och sidkoden som ska laddas om URI try_files $ uri $ uri / = 404 inte hittades; # tillåt skapandet av ett index för autentiserade användare autoindex på; autoindex_exakt_storlek av; autoindex_localtime på; }}

Vi kontrollerar att konfigurationen är korrekt:

nginx -t

Slutligen startar vi om tjänsten:

service nginx omstart

Fail2Ban

Innan du börjar konfigurera Fail2Ban, för att öka säkerheten, stoppar vi tjänsten och rensar registret:

fail2ban-client stop echo -n> /var/log/fail2ban.log

Därefter skapar vi konfigurationsfilen /etc/fail2ban/jail.local med följande anpassade innehåll:

# Anpassad konfigurationsfil /etc/fail2ban/jail.local # [STANDARD] findtime = 43200; 12 timmar varaktighet = 86400; 1 dag maxretry = 3; förbudet träder i kraft efter det fjärde försöket [ssh] enabled = false [nginx-auth] enabled = true filter = nginx-auth action = iptables-multiport [name = NoAuthFailures, port = "http, https"] logpath = / var / log / nginx * / * error * .log [nginx-badbots] enabled = true filter = apache-badbots action = iptables-multiport [name = BadBots, port = "http, https"] logpath = / var / log / nginx * /*access*.log bantime = 4; 604800 veckas maxretry = 1 [nginx-login] aktiverat = true filter = nginx-login action = iptables-multiport [name = NoLoginFailures, port = "http, https"] logpath = / var / log / nginx * / * access *. loggtid = 0; 1800 minuter [nginx-noscript] aktiverat = sann åtgärd = iptables-multiport [namn = NoScript, port = "http, https"] filter = nginx-noscript logpath = /var/log/nginx*/*access*.log maxretry = 30 [nginx-proxy] enabled = true action = iptables-multiport [name = NoProxy, port = "http, https"] filter = nginx-proxy logpath = /var/log/nginx*/*access*.log bantime = 0 ; 604800 veckas maxretry = 1 [brandvägg] aktiverad = sann åtgärd = iptables-multiport [namn = brandvägg] filter = brandvägg loggväg = /var/log/firewall.log maxretry = 0

När detta är klart skapar vi i katalogen /etc/fail2ban/filters.d/ följande filer:

# /etc/fail2ban/filter.d/nginx-auth.conf # Authfilter # Blockerar IP-adresser som inte autentiseras med grundläggande autentisering # [Definition] failregex = ingen användare / lösenord tillhandahölls för grundläggande autentisering. * klient: användare. * hittades inte i. * klient: användare. * lösenordsmatchning. * klient: ignoreregex =
# /etc/fail2ban/filter.d/nginx-login.conf # Inloggningsfilter # Blockerar IP-adresser som inte autentiseras med hjälp av webbapplikationens inloggningssida # Skanningsåtkomstlogg för HTTP 200 + POST / sessioner => misslyckad inloggning # [Definition ] failregex = ^ -. * POST / sessioner HTTP / 1 \ .. "200 ignoreregex =
# /etc/fail2ban/filter.d/nginx-noscript.conf # Noscript filter # Blockera IP-adresser som försöker köra skript som .php, .pl, .exe och andra roliga skript. # Matchningar t.ex. # 192.168.1.1 - - "GET /something.php # [Definition] failregex = ^ -. * GET. * (\. Php | \ .asp | \ .exe | \ .pl | \ .cgi | \ scgi) ignoreregex =
# /etc/fail2ban/filter.d/proxy.conf # Proxy filter # Blockera IP-adresser som försöker använda servern som proxy. # Matchningar t.ex. # 192.168.1.1 - - "FÅ http://www.something.com/ # [Definition] failregex = ^ -. * FÅ http. * Ignoreregex =
# /etc/fail2ban/filter.d/firewall.conf # Brandväggsfilter # [Definition] failregex = ^. * IN_ (INVALID | PORTSCAN | UDP | TCP |). * SRC = . * $ ignoreregex =

Slutligen startar vi tjänsten och laddar konfigurationen:

fail2ban-service -b fail2ban-client reload

Verifiering

Som ett sista steg kan vi se posterna med svans -f o multitail - följ alla. I själva verket erbjuder den senare applikationen fördelen att den låter dig visa flera filer samtidigt och ger grundläggande syntaxmarkering.

Om ett e-postkonto inte är konfigurerat i VPS, är det tillrådligt att inaktivera ett varningsmeddelande som visas när multitail startas, för vilket vi kommer att utföra följande kommando:

eko "check_mail: 0"> ~ / .multitailrc

I själva verket kan vi väl skapa ett alias (4) för att snabbt se loggarna med ett kort kommando, till exempel "flog":

alias flog = 'multitail --follow-all /var/log/firewall.log /var/log/fail2ban.log'

1) Dessa är fiktiva värden.
2) Det är enkelt att aktivera andra tjänster när du förstår hur det fungerar.
3) För mer information, kör man sudoers.
4) Valfritt kan läggas till ~ / .bash_aliases-filen


Innehållet i artikeln följer våra principer om redaktionell etik. Klicka på för att rapportera ett fel här.

6 kommentarer, lämna din

Lämna din kommentar

Din e-postadress kommer inte att publiceras.

*

*

  1. Ansvarig för uppgifterna: Miguel Ángel Gatón
  2. Syftet med uppgifterna: Kontrollera skräppost, kommentarhantering.
  3. Legitimering: Ditt samtycke
  4. Kommunikation av uppgifterna: Uppgifterna kommer inte att kommuniceras till tredje part förutom enligt laglig skyldighet.
  5. Datalagring: databas värd för Occentus Networks (EU)
  6. Rättigheter: När som helst kan du begränsa, återställa och radera din information.

  1.   MSX sade

    Det finns några intressanta saker, +1

  2.   yukiteru sade

    @Hugo den här raden i konfigurationen:

    ssl_protocols SSLv3 TLSv1;

    Jag skulle ta bort SSLv3 från den eftersom det protokollet inte längre är säkert, inte ens i Debian Jessie, många tjänster har konfigurerats för att undvika att använda det protokollet av den anledningen.

    Information om ämnet här:

    https://www.linode.com/docs/security/security-patches/disabling-sslv3-for-poodle
    http://disablessl3.com/

    1.    Hugo sade

      Tanken var egentligen inte att erbjuda huvudtjänsterna via HTTPS, utan att förklara hur man använder port 443 för SSH utan att förlora möjligheten att använda den för HTTPS om det behövs, men tack för varningen.

      Hur som helst har jag uppdaterat artikeln för att ändra nginx-konfigurationen lite och för övrigt inkludera några kommentarer för att klargöra saker lite mer med detta av krypteringsmekanismerna och för att fixa några mindre fel.

  3.   Daniel PZ sade

    Tack så mycket för denna fantastiska handledning, nu kommer jag att omsätta den i praktiken! : D, fortsätt det Från Linux, du överraskar mig alltid, hälsningar från Peru.

  4.   Ñandekuera sade

    Tack så mycket för att dela.

  5.   fernando sade

    mycket bra guide och det kommer från pärlor nu när jag började i den här bloggen men ännu mer nu när jag ska montera min första vps och fortfarande med många problem men den här artikeln har tagit mig ur många tvivel, tack och hälsningar