HOWTO: Säker exponering av Apache på Internet (Raspian)

Hur gör man för att ... ? Hur fungerar ... ? Steg för steg-guider och förklarande artiklar finns i detta forum.
Många guider finner också på vår blogg: https://blog.m.nu/
Kategoriregler
Vill du visa bilder i ditt inlägg? Använd funktionen "Ladda upp bilaga" nedanför textrutan!
flyvert
Hemautomation - det är mer än en hobby
Inlägg: 393
Blev medlem: 22 aug 2013, 00:48
Ort: Västerås

HOWTO: Säker exponering av Apache på Internet (Raspian)

Inlägg av flyvert »

Har du sett konstigheter i din /var/log/apache2/access.log efter att ha lagt ut din Apache web server på Internet? :?

Orolig att någon eller något försöker hacka din RPi eller köra en bruteforceattack på ditt "halvsäkra" lösenord? :shock:

En första enklare åtgärd är ju att inte använda standardportnumren (80, HTTP samt 443 HTTPS) vid portforwarderingen utan lägga sig på något högt femsiffrigt.

Sen kan man ju försöka "bomba" otillåtna IP adresser, skapa lösenord för login, etc. men du kommer troligen inte att komma till en position att du känner dig helt tillfreds. O väl inne i din RPi kan "inbrottstjuven" fortsätta att hacka dina maskiner på ditt "säkra" intranät... :evil:

En relativt säker åtgärd är att låsa ned Apache så den kräver s.k. certifikat från externa webklienter! :idea:

Problemet är att certifikat inte skapar sig själva samt att det är rätt krångligt med alla prylar man måste kunna om OpenSSL (det inbyggda kryptosystemet i Rasbian).

Observera att den föreslagna lösningen bygger på att du har skaffat DynDNS, etc. eller eget domännamn - att bara känna till sin egen externa IP adress fungerar inte speciellt bra då certifikaten måste knytas till ett Fully Qualified Domain Name (FQDN) för att inte ge larm om "Certificate error" i webläsaren.

Här är några artiklar i ämnet, men det finns säkert fler (o bättre):
http://www.madboa.com/geek/openssl/
https://wiki.debian.org/Self-Signed_Certificate
http://pages.cs.wisc.edu/~zmiller/ca-howto/

Jag skrivit ihop ett utkast till skript som tar en igenom de värsta stegen med OpenSSL:
setupca.txt
Skript för att skapa certifikat, m.m.
(1.92 KiB) Nerladdad 388 gånger
Här är en testkörning:
exempelkörning.txt
Exempelkörning av setupca
(3.99 KiB) Nerladdad 353 gånger

Här kommer lite kommentarer som kan hjälpa din igenom första gångerna:

1a. Kopiera in skriptet till din RPi o kör det med "sudo setupca"
Ett fullständigt exempel medföljer - ha det bredvid första gången du kör!
1b. Först kollar skriptet att den kan skapa en katalog att förvara diverse filer på (/usr/local/ssl).
Finns det filer i den frågar den om den skall ta bort allt (som i exemplet), dvs tänk på att redan skapade cert blir oanvändbara iom att du skapar en ny CA. Det kan vara idé att flytta ut klientbitarna (steg 4) till ett eget skript o behålla CA- och servercerten när du väl fått dem att fungera.

*** Generating CA root private key

2a. Skriptet frågar nu efter lösenordet till ditt CA (välj något bra, men börja med nåt skitenkelt, t.ex. 1234 innan du kör "skarpt".
2b. Verifiera lösenordet

*** Create CA public certificate
2c. Nu skall vi skapa ett certifikat åt din CA - mata in lösenordet till din CA (ja, tredje gången...)
2d. Svara på frågorna; som allra minst måste du fylla i FQDN (här bör du mata in ditt domännamn eller DynDNS - jag skrev "local" som duger för internt test av HTTPS och certifikaten)

Nu har vi skapat en CA! (du har väl läst på...)

*** Creating web server private key:
*** Create web server certificate request

3a. Nu skall vi skapa ett servercert att köra din Apache på
3b. Svara på frågorna; som allra minst måste du fylla i FQDN (här bör du mata in din RPIs hostname, jag skrev RPI2.local som min testmaskin heter).
3c. Slå <Enter> på "extrafrågorna"
3d. Mata in lösenordet till din CA

*** Creating web client private key
*** Creating web client certificate request

4a. Nu skall vi skapa ett klientcert som måste installeras i klienterna för att webservern skall acceptera dem.
4b. Svara på frågorna; som allra minst måste du fylla i frågan om FQDN o där angav jag mitt namn... flyvert
4c. Slå <Enter> på "extrafrågorna"
4d. Mata in lösenordet till din CA

*** Creating web client PKCS12 file

4e. Nu skall vi skapa en PKCS12 fil innehållande "nyckeln" till din webserver som IE, Opera, Safari, etc, etc "vet" vad den skall göra med
4f. Mata in ett exportlösenord (detta lösenord bör inte vara samma som CA lösen, välj ett annat som du kan "avslöja" för dina vänner som skall läsa in PKCS12 filen.


När skriptet skapat CA:t och certifikaten listar det alla filer det skrivit till /usr/local/ssl:

*** Files on /usr/local/ssl:
/usr/local/ssl/servercakey.pem: PEM RSA private key
/usr/local/ssl/webclientrequest.txt: PEM certificate request
/usr/local/ssl/webserver.key: PEM RSA private key Denna fil behöver Apache för att köra HTTPS
/usr/local/ssl/webserverrequest.txt: PEM certificate request
/usr/local/ssl/webserver.crt: PEM certificate Denna fil behöver Apache för att köra HTTPS
/usr/local/ssl/caroot.crt: PEM certificate Denna fil behöver Apache för att köra HTTPS
/usr/local/ssl/caroot.srl: ASCII text
/usr/local/ssl/webclient.crt: PEM certificate
/usr/local/ssl/webclient.p12: data Maila denna till din smartphone eller ta med den på USB sticka, etc till de klienter som skall få komma in
/usr/local/ssl/webclient.key: PEM RSA private key

Nu kan vi konfa upp Apache att köra HTTPS på port 443 och där bara släppa in klienter med rätt certifikat (vi moddar INTE port 80 så från ditt intranät kan vem som helst komma in utan cert; vi låser endast HTTPS porten (443) som du sen kan forwardera i din firewall).

Aktivera SSL i Apache
$ sudo a2enmod ssl

Addera följande rader i slutet på: /etc/apache2/apache.conf (justera ServerName så att det matchar):
<VirtualHost *:443>
ServerName RPI2.local:443
SSLEngine on
SSLCertificateFile /usr/local/ssl/webserver.crt
SSLCertificateKeyFile /usr/local/ssl/webserver.key
SSLCACertificateFile /usr/local/ssl/caroot.crt
SSLVerifyClient require
SSLVerifyDepth 2
</VirtualHost>


Starta om Apache
$ sudo service apache2 restart

Installera P12 filen i dina webbrowser(s) som skall kunna komma åt servern från Internet:

- iPhone/iPad - skicka filen till din webmail; läs mailet i paddan/fånen och klicka på attachmentet (P12 filen). Mata in lösenordet från steg 4f.

- Android - samma som iFån; kan kräva att du sätter lösenord på enheten. Skall gå att komma runt ifall du inte vill låsa ned den - såg nåt om det när jag provade att installera på en Android-surfplatta.

- Windows - dubbelklicka P12 filen och tryck next, next (välj alla default). Lösenordet som i steg 4f

- iOS - troligen samma som iFån



Så här kan man kolla certen på Windows:
Certificate Manager på Windows 7
Certificate Manager på Windows 7
För att komma till denna dialog; gör som följer:

a) Start->Run... mmc.exe
b) File->Add/Remove Snap-in
c) Välj "Certificates" och allt default därefter.
d) Expandera Certificates - Current user->Personal->Certificates



Starta en webbrowser på ditt intranät och prova med HTTP adressen först (för att kontrollera att Apache lever överhuvudtaget)

Ändra adressen från "http://..." till "https://..." - o prova igen.
Klaffar allt nu så kommer din browser först att säga att servern saknar certifikat som går att lita på, men sen skall startsidan visas. I IE måste man acceptera varningen samt välja "Continue to this unsafe website (not recommended)"

Nu är det dags att prova att exponera HTTPS porten (443) på Internet via s.k. portforwadering i sin brandvägg eller outer (men även nu bör man välja ett högt portnummer för att i möjligaste mån slippa riktade DOS-attacker som kan sysselsätta RPi:n med att försöka förhandla kryptotunnlar med klienter som inte har rätt certifikat).

Stäng av Wifit-på din smartphone, starta dess webbrowser o knappa in adressen https://FQDN-eller-domännamn:det-5-siffriga-portnumret, t.ex. https://flyvert.homeip.net:54321

För att slippa varningarna om att servern är "osäker" måste man installera webserverns certifikat (/usr/local/ssl/webserver.crt) under "Intermediate Certification Authorities" och även ditt CAs (/usr/local/ssl/caroot.crt) under "Trusted root certification authorities" på datorns certifikatstorage eftersom vi gjort ett "selfsigned" och inte köpt ett officiellt cert från någon leverantör.

OBS: Använder du HTTPS via intranätadressen kommer du alltid att få varningen eftersom certifikatet är utställt på din externa FQDN.

I iOS tror jag man endast första gången får frågan "Do you want to trust this..." vilket fixar biffen once and for all utan nå meck med filer.

I IE har jag för mig att man kan klicka på den rödmarkerade HTTPS adressen och sen välja att installera certifikatet direkt utan att maila/flytta den med USB sticka, etc. Fungerar inte det får man dra in .crt filerna via manuell import. Vid nästa tillfälle skall jag försöka komplettera P12-filen med CA certet och webserver certet så att "alla" kommer i samma förpackning.

OBS: Alla filerna under /usr/local/ssl är att anses som hemligheter och skall inte vara läsbara för någon annan än root. Slarva inte med P12 filen heller - den är nyckeln till din webserver.

Man kan givetvis skapa flera klientcert o ge dem olika behörigheter, accessnivåer, etc. till din webserver.

Vill du läsa på mer om detta, studera tex begreppen "HTTPS", "CA", "PKI", "CRL" genom att söka efter dem på internet.

/f
Om traktorn stjälper; håll i ratten, hoppa ej!
flyvert
Hemautomation - det är mer än en hobby
Inlägg: 393
Blev medlem: 22 aug 2013, 00:48
Ort: Västerås

Re: HOWTO: Säker exponering av Apache på Internet (Raspian)

Inlägg av flyvert »

Hmm... till dess fixen för "Heartbleed buggen" är fixad i Apache/OpenSSL o man fixat nya cert o nycklar finns potentiella risker med att använda denna metod.

Även solen har fläckar... :cry:

/f
Om traktorn stjälper; håll i ratten, hoppa ej!
bosse123
Gillar hemautomation
Inlägg: 44
Blev medlem: 04 jan 2014, 18:13
Ort: Alingsås

Re: HOWTO: Säker exponering av Apache på Internet (Raspian)

Inlägg av bosse123 »

Vilken otroligt seriös och välskriven howto!
Snyggt jobbat!

För att fylla på lite så föreslår jag två alternativ:
1, tunnla in till din server, så behöver du inte oroa dig överhuvudtaget, exempelvis på detta sätt:
http://gargamel.nu/2009/02/tunnla-till- ... med-putty/

En gyllene medelväg skulle kunna vara att byta port men i övrigt låta det vara öppet mot omvärlden,

Och oavsett port säkra upp med "fail2ban" på dels ett jail mot felinloggningar men inte minst mot olika sqlinjectioner ,
Fail2ban har som bekant ett flertal förkonfigurerade jail för apache, och det går även att skapa egna jail för sina egna logfiler.
Exempel:
http://www.fail2ban.org/wiki/index.php/Apache
Skriv svar