Gå til innhold
  • Bli medlem
Støtt hjemmeautomasjon.no!

Sikre Homeseer med kryptering (TLS) ved hjelp av "nginx"


ZoRaC

Anbefalte innlegg

Disclaimer:

Jeg har ingen ekspertkunnskap om dette emne, men har kjørt med dette oppsettet en god stund og mener det er satt opp på en sikker måte (basert på forskjellige guider på nett). Jeg tar likevel ikke noe ansvar for evt "sikkerhetshull" som måtte bli innført ved å følge denne oppskriften. :) 

 

Homeseer har en innstilling for å bruke https, men den har ikke blitt oppdatert på lang tid og fungerer delvis ikke i det hele tatt og baserer seg på krypteringsmetoder som ikke er regnet som sikre lengre.

 

Hvorfor bør man kjøre kryptering?

All kommunikasjon mot HS-serveren direkte (ikke via myHS) går ukryptert på nettverket. Dvs at hvem som helst som har tilgang til nettverket et eller annet sted på veien fra deg og til serveren, kan se all kommunikasjon (også brukernavn/passord). Det er også enkelt for uvedkommende å sette opp en falsk HomeSeer-server og dermed lure deg til å taste inn brukernavn/passord mot den, fordi du ikke kan verifisere at det faktisk er "din" server du logger deg på.

 

Hvordan?

Siden HomeSeer sin krypteringsløsning er ubrukelig, må vi sette opp en tjeneste (som kan kjøre på samme maskin) som tar seg av krypteringen/sikkerheten, før kommunikasjonen sendes videre til HomeSeer. Til dette bruker vi "nginx" som "reverse proxy". Nginx er en webserver, som kan sammenlignes med Apache (som kanskje er mer kjent).

Se bilde som illustrerer dette:

 1*rnzxfcy2N_ffJPnBundJQw.jpeg

 

Forutsetninger:

Jeg kjører dette på Linux (Ubuntu 16.04) og noen av trinnene vil nok være forskjellige på Windows. Da er vi så heldig at @Moskus kjører tilsvarende oppsett på Windows og kan "fill out the blanks"! ;) 

 

Komme i gang:

1. Klargjøre Homeseer

nginx skal overta kommunikasjonen mot klienten, dermed må den svare på forespørsler på de vanlige web-portene (80 og 443), i stedet for HomeSeer.

a. Start derfor med å bytte port som HomeSeer lytter på til f.eks port 85 via "tools->setup->network-> server port (80=default)".

b. Slå av "System is Discoverable Using UPNP".

c. Slå på "No Password Required for Local/Same Network Login (Web Browser/HSTouch)".

Restart HS og sjekk at du fortsatt kommer inn via http://<ip>:85 før du går videre (merk at om du kjører brannmur på serveren eller noe sted mellom deg og serveren, så må du også der legge til åpning for port 85 midlertidig, inntil du har alt oppe og går).

 

2. Last ned og installer nginx:
Guide for Ubuntu 16.04

Hvis du bruker ufw-brannmuren, bruk "Nginx Full" (ikke bare "Nginx HTTP", som det står i den guiden).

 

3. Sett opp kryptering med sertifikater på nginx

Her har du 2 valg:

a. Skaffe et offentlig sertifikat

Offenlig sertifikat kan f.eks være fra letsencrypt.org eller man kan kjøpe ett ganske billig. Det forutsetter at man har et domene som peker mot routeren din hjemme (f.eks via DynDns) og at man har satt opp portforwarding på portene på routeren mot HS-serveren (80 og 443). Dette er i utgangspunktet litt mer komplisert enn alternativ b, men det gjør at man slipper å få slike advarsler fra nettleseren:

chrome-your-connection-is-not-private.pn

 

I tillegg vil man kunne verifisere at man faktisk snakker med SIN server med et slikt sertifitkat, for med alternativ b, så kan man i utgangspunktet ikke verifisere om advarselen kommer fra sin server eller om noen har satt opp en falsk server som utgir seg for å være din. Man kan oppnå dette i alternativ b også, men det er litt mer jobb.

 

b. Bruke et "selvsignert" sertifikat

Det betyr at serveren signerer sitt eget sertifikat og klientene har da ingen sertifikatutsteder (CA, Certificate Authority) de kan verifisere at sertifikatet er ekte mot.

 

Jeg har valgt en variant av alternativ b, for jeg har ikke eksponert HS mot internett (jeg bruker VPN inn på nettverket mitt og så kommuniserer jeg med HS på LANet). Mitt hovedformål var å sørge for at informasjonen var kryptert og det oppnår man med alternativ b. Jeg har likevel omgått den advarselen og sikret at jeg får verifisert at det er MIN server jeg kobler på. ;) 

 

Alternativ a:

Her er en guide på hvordan bruke letsencrypt.org sine gratis sertifikater mot nginx på Ubuntu 16.04:

https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04

Dette forutsetter at port 80 og 443 videresendes fra routeren din til HS-serveren og at du har et domene tilknyttet IPen til routeren din.

 

Alternativ b:

Her er en guide på hvordan utstede egne sertifikater for nginx på Ubuntu 16.04:

https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-in-ubuntu-16-04

 

Jeg har egentlig valgt å ingen av alternativene over, jeg kjører pfSense som router og den har en egen "certificate manager". Jeg har valgt å utstede sertifikater via den, som jeg har overført og installert på HS-serveren. Deretter har jeg lastet ned CA-sertifikatet (altså sertifikatutsteder-sertifikatet) fra pfSense og installert dette som et godkjent root-sertifikat på PCen min og mobilen min. Det gjør at når jeg går inn på webserveren fra PCen/mobilen, så slipper jeg den advarselen som er vist over, for PCen/mobilen verifiserer da mot pfSense at sertifikatet er ekte/gyldig. På den måten oppnår jeg at jeg får både kryptert kommunikasjonen OG jeg får verifisert at serveren faktisk er min server og ikke en falsk en.

 

Før du går videre, sjekk at du får opp standard websiden til nginx via https://<ip> (bruker du alternativ b, må du bekrefte at du ønsker å gå videre forbi sikkerhetsadvarselen før du får opp siden).

 

4. Da er det klart for å konfigurere nginx som reverse proxy mot HS:

Opprinnelig hentet fra denne tråden:

https://forums.homeseer.com/showthread.php?t=178990

 

Ta først en backup av /etc/nginx/sites-available/default.

Bytt den deretter ut med denne filen (husk å endre filbane til HS-mappen din!).

 

Her er filen jeg bruker (jeg har gjort noen endringer på den før jeg la den ut her, for jeg bruker nginx til andre tjenester også, så jeg håper jeg ikke har tatt vekk noe som må være der):

Spoiler

##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

#rewrites http to https
  server {
    listen      80;
    server_name your.server.com;
    rewrite     ^   https://$server_name$request_uri? permanent;
  }


# Default server configuration
#
server {
    server_name your.server.com;

    # SSL configuration
    #
      listen 443 ssl http2 default_server;
    # listen [::]:443 ssl default_server;
    #
    # Note: You should disable gzip for SSL traffic.
    # See: https://bugs.debian.org/773332
    #
    # Read up on ssl_ciphers to ensure a secure configuration.
    # See: https://bugs.debian.org/765782
    #
    # Self signed certs generated by the ssl-cert package
    # Don't use them in a production server!
    #
    # include snippets/snakeoil.conf;

    include snippets/self-signed.conf; # Disse må du endre til å være det samme som i trinn 3!
    include snippets/ssl-params.conf;  # Disse må du endre til å være det samme som i trinn 3!

    proxy_intercept_errors on;
    # Don’t show the Nginx version number (in error pages / headers)
    server_tokens off;
    error_log /var/log/nginx/error.log;

    root /usr/local/HomeSeer/html;
    add_header X-Whom direct;

    # Opprett en brukerkonto som beskrevet her: https://www.digitalocean.com/community/tutorials/how-to-set-up-basic-http-authentication-with-nginx-on-ubuntu-14-04
    auth_basic "Krever autentisering!";
    auth_basic_user_file '/etc/nginx/.htpasswd';

    # "satisfy any" betyr at man kommer inn med rett passord ELLER om man har en IP-match under (altså uten passord)
    # "satisfy all" betyr at man kommer inn med rett passord OG en IP-match under (altså både IP og passord)
    satisfy any; 
    allow 127.0.0.1;
    allow 192.168.1.0/24;
    deny  all;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    #Prevents hidden files (beginning with a period) from being served
    location ~ \/\. { access_log off; log_not_found off; deny all; }
    
    # serve HS3 json api via proxy
        location ~* \/(JSON|json) {
    
          proxy_http_version 1.1;
          proxy_set_header Connection "";
    
          satisfy any;
          auth_basic "Krever autentisering!";
          auth_basic_user_file '/etc/nginx/.htpasswd';
          allow 127.0.0.1;
	  allow 192.168.1.0/24;
          deny  all;
    
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_pass http://127.0.0.1:85 ;
          add_header X-Whom json;
          expires -1;
    }

    # Serve homeseer files the ones without dot in the path
    location ~* (?<![\.\/]...)$ {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;      
      proxy_pass http://127.0.0.1:85 ;
      add_header X-Whom HS3;
      expires -1;
    }

    #serve static files 
    location ~* ^.+\.(?:css|cur|js|png|gif|htc|ico|txt|xml|otf|ttf|eot|woff|svg)$ {
      try_files $uri $uri/ /error/HTTP404.html;
      add_header X-Whom all;
      add_header Cache-Control public;
      expires max;
    }

    #serve jpeg, csv, html variables files including jpeg from my IPcam
    location ~* ^.+\.(?:jpe?g|csv|html)$ {
      try_files $uri $uri/ /error/HTTP404.html;
      add_header X-Whom vary;
      expires -1;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    location ~ /\.ht {
      deny all;
    }
}	

 

 

Da er det bare å ta en "sudo nginx -t", for å sjekke at det ikke er noe feil i konfig, deretter "sudo service nginx reload" og sjekke at du kommer inn på HS3 ved å gå på både http://<ip> og https://<ip> :) 

 

Til slutt fjerner du den midlertidige åpningen for port 85 i brannmuren (hvis du kjører ufw, så må 127.0.0.1 fortsatt ha tilgang, men ingen andre).

 

Et par ekstra sikkerhetsmekanismer å vurdere:

1. Sette " "tools->setup->network->Bind Server to IP Address" til 127.0.0.1, slik at man MÅ inn via nginx (ellers kan man logge på via http://<ip>:85, uten passord!)
(dette er jo også løsbart ved å blokkere tilgangen til port 85 i brannmur i stedet)

2. Sette opp "fail2ban", slik at ugyldige pålogginger fører til IP-ban

3. Sette opp IP-filter i brannmuren (f.eks pfSense), slik at bare norske IP-adresser blir sluppet gjennom

4. Sette opp "monit" til å monitorere både HS og nginx og restarte tjenestene automatisk hvis de feiler

Endret av ZoRaC
  • Like 3
  • Thanks 3
Lenke til kommentar
Del på andre sider

  • 3 uker senere...

Interessant...

Jeg forsøkte å "gjøre om" informasjonen din fra nginx-conf til noe som kunne passet inn i apache sine conf-filer, men uten hell.

 

Bruker allerede apache ssl (self signed) på min linux-server og kunne gjerne tenkt meg å bruke det videre, uten nginx i tillegg.

Har du noen forslag til hvordan dette kan gjøres i apache isteden?

 

Lenke til kommentar
Del på andre sider

2 minutter siden, Salvesen skrev:

Denne må du nesten utdype, hvilken kommunikasjon tenker du på? 

 

Alle kommunikasjon mot webinterfacet og JSON-interfacet.

 

Så hvis jeg setter opp et falsk AP på en kafé og du bruker det til å logge på Homeseer hjemme (via port forward, ikke MyHS), så har jeg full kontroll over huset ditt etterpå. 

Lenke til kommentar
Del på andre sider

6 minutter siden, ZoRaC skrev:

 

Alle kommunikasjon mot webinterfacet og JSON-interfacet.

 

Så hvis jeg setter opp et falsk AP på en kafé og du bruker det til å logge på Homeseer hjemme (via port forward, ikke MyHS), så har jeg full kontroll over huset ditt etterpå. 

 

Aha slik ja, her i gården går alt via MyHs. Tror jeg iallefall. 

 

EDIT: Jeg har iallefall ingen porter forwarded ift homeseer, men jeg har jo en del som går over nett og kommuniserer med homeseer som alexa, imperihome osv. Men alt dette går over myhs om jeg ikke bommer helt? 

Endret av Salvesen
  • Like 1
Lenke til kommentar
Del på andre sider

  • 5 uker senere...
Sitat

 

Changes in 3.0.0.398 (BETA):

* Added SSL support to web server, configure on Labs tab in setup. For Linux, MONO 5 is probably required

 

 

Noen som har testet dette? Kanskje er vi så heldig å få SSL/TLS-støtte direkte i HS igjen!

  • Like 1
Lenke til kommentar
Del på andre sider

On 11/21/2017 at 21:47, ZoRaC said:

 

Nei, dessverre. 

 

Ok. Jeg får nok installere nginx ved siden av apache for å teste det. Har det på en raspberry pi, og virker jo temmelig ålreit.

På grunn av behov for å stadig hente ut info via json, og tidvis sende (trigge enkelte events, bl.a.), så hadde det vært svært kjekt å kunne låse passord-fri tilgang til enkelte IPer/mac-adresser/devices mens andre vil måtte skrive inn passord. I tillegg så er det jo fordelen å kunne koble til Homeseer direkte via WAN fremfor å bruke MyHS.

 

59 minutes ago, ZoRaC said:

 

Noen som har testet dette? Kanskje er vi så heldig å få SSL/TLS-støtte direkte i HS igjen!

 

Ingen altfor kritiske enheter tilkoblet foreløpig, men har til tider opplevd litt ustabil funksjon (z-wave støpsler som slutter å svare) så jeg holder meg unna beta-versjoner så godt det lar seg gjøre. Har de stipulert neste final release?

Lenke til kommentar
Del på andre sider

  • 5 måneder senere...
1 time siden, ZoRaC skrev:

Noen har har brukt den nye SSL/TLS-funksjonen som kom i HS .398? Er den såpass god at man kan gå over til den i stedet for nginx?

De som har greie på det mer enn meg (men kanskje ikke deg?) påstår så, men jeg har ikke byttet selv. Har imidlertid tenkt å teste engang...

Lenke til kommentar
Del på andre sider

  • 1 år senere...

Deler konfig'en min hvis noen syns det er interessant. 

 

Jeg kjører letsencrypt docker fra linuxserver.io på en unraid server som jeg bruker til noen nettsider. Ønsket derfor homeseer tilgjengelig på subdomain slik som "homeseer.minserver.no".

Letsencrypt docker'en har altså nginx, letsencrypt med automatisk fornying av sertifikat og fail2ban innebygd. Du kan fint kjøre dockeren på windows/linux også, men jeg kjører den på unraid.

 

Jeg ønsket også at autoriseringen skjer på nginx slik at jeg kan bruke fail2ban, men ønsket også at homeseer skulle autorisere slik at jeg kan sette forskjellige tilganger på de forskjellige i familien. Har derfor også portforwarded nginx slik at jeg har tilgang utenifra uten å gå via myhs, da det er mye raskere, slipper å gå via en tredjepart og jeg får flere brukerkontoer uten å betale ekstra i året.


Først så aktiverte jeg ssl på homeseer så nginx kan snakke kryptert med homeseer.

Deretter var det bare å sette opp nginx serveren, legge inn config og restarte den. 
Så må vi legge inn brukernavn og passord til users i .htpasswd filen til nginx. NB: Viktig at det er samme brukernavn og passord her som du bruker på homeseer!!

Beskrevet her: https://github.com/linuxserver/docker-letsencrypt#security-and-password-protection

 

Tilslutt gikk jeg på windows firewall (advanced), inbound rules og satt hs3 tcp til å kun snakke med nginx serveren på scope (remote ip). Måtte også sette "allow edge traversal" på advanced på hs3 i windows firwall. 

 

OBS:
Dersom dette er din default server må linje 5 endre til:

listen 443 ssl default_server;

 

Spoiler

#HomeSeer server
server {
	listen 80;

	listen 443 ssl;

	if ($scheme = http) {
		return 301 https://homeseer.minserver.no$request_uri;
	}
	
	add_header Strict-Transport-Security "max-age=31535000; includeSubDomains" always;

	root /config/www;
	index index.html index.htm index.php;
	
	server_name homeseer.minserver.no;
	
	ssl_certificate /config/keys/letsencrypt/fullchain.pem;
	ssl_certificate_key /config/keys/letsencrypt/privkey.pem;
	ssl_dhparam /config/nginx/dhparams.pem;
	ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
	ssl_prefer_server_ciphers on;

	client_max_body_size 0;
 
 set $upstream 192.168.xx.xxx:443;


    # If you'd like to password protect your sites, you can use htpasswd. Run the following command on your host to 
	# generate the htpasswd file docker exec -it letsencrypt htpasswd -c /config/nginx/.htpasswd <username>
	
    # You can add multiple user:pass to .htpasswd. For the first user, use the above command, for others, use the above 
	# command without the -c flag, as it will force deletion of the existing .htpasswd and creation of a new one
	
	
    auth_basic "Krever autentisering!";
    auth_basic_user_file '/config/nginx/.htpasswd';
	
  location / {
		client_max_body_size 10m;
		client_body_buffer_size 128k;

		#Timeout if the real server is dead
		proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;

		# Advanced Proxy Config
		send_timeout 5m;
		proxy_read_timeout 240;
		proxy_send_timeout 240;
		proxy_connect_timeout 240;

		# Basic Proxy Config
		proxy_set_header Host $host:$server_port;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto https;
		proxy_redirect  http://  $scheme://;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
		proxy_cache_bypass $cookie_session;
		proxy_no_cache $cookie_session;
		proxy_buffers 32 4k;
		proxy_pass https://192.168.xx.xxx:443/;
	}
}	

 

 

Endret av Bjonness
  • Like 2
Lenke til kommentar
Del på andre sider

Bli med i samtalen

Du kan publisere innhold nå og registrere deg senere. Hvis du har en konto, logg inn nå for å poste med kontoen din.

Gjest
Skriv svar til emnet...

×   Du har limt inn tekst med formatering.   Lim inn uten formatering i stedet

  Du kan kun bruke opp til 75 smilefjes.

×   Lenken din har blitt bygget inn på siden automatisk.   Vis som en ordinær lenke i stedet

×   Tidligere tekst har blitt gjenopprettet.   Tøm tekstverktøy

×   Du kan ikke lime inn bilder direkte. Last opp eller legg inn bilder fra URL.

×
×
  • Opprett ny...

Viktig informasjon

Vi har plassert informasjonskapsler/cookies på din enhet for å gjøre denne siden bedre. Du kan justere dine innstillinger for informasjonskapsler, ellers vil vi anta at dette er ok for deg.