2019-09-19

Som en Microsoft Exchange - fast gratis

Man kan givetvis diskutera det lämpliga, eller olämpliga, i att köra en egen e-postserver. De allra flesta nöjer sig med att ha sin e-post på webbhotellet, eller i en molntjänst som iCloud eller hos Google. Det finns också de som är av åsikten att e-post är viktigt och något privat och därför ska man ha kontroll över den och då kan man väl utan omsvep konstatera att företag som Google faller bort tämligen omgående.

Hur som haver är det inte svårt att hitta en programvara att hantera sin e-post med. Det är heller inte svårt att hitta en programvara som gör det gratis. Vad som däremot kan vara lite knivigt är att hitta en e-postserver som är modern och trevlig att använda, inte enbart för dig som administratör utan också för de som faktiskt ska använda den i slutändan.. du vet… svärmor, dina barn och några kompisar. För det brukar bli så med tiden - man har en e-postserver och vips så har det flyttat in 20 personer med sin e-post på den.

Detta är inte en guide till hur du väljer e-postserver. Vissa går all in och bygger den från grunden på en Linux eller FreeBSD-server där varje inställning och justering görs för hand. Andra köper en programvara eller laddar ner ett gratis paket som ger dig hela tjolabaletten uppsatt och klart. Jag har valt att göra ett sorts mellanting mellan de två men det återkommer jag till senare. Detta är inte heller en guide till hur du håller skräppost borta från din e-postserver, för där kan jag varmt rekommendera att du antingen kör ett eget filter för ändamålet (det finns flera att välja mellan, jag rekommenderar helhjärtat EFA) eller så använder du en molntjänst som exempelvis Inumbo som drivs av vännerna på Halon Security.

Jag tänkte sätta igång och pensionera min gamla e-postserver. Den kör programvaran Kerio Connect, och det är egentligen inget fel på Kerio Connect i sig men min licens är från 2015, fortfarande helt laglig att köra, men det innebär också att jag kör en e-postserver från år 2015 som inte är patchad sedan år 2015. Anledningen till att jag aldrig förnyade licensen efter det året var enkelt: företaget som då ägde Kerio Connect gick över till en prenumerationsmodell för att stödja synkronisering av e-post via ActiveSync-protokollet. Stannade man kvar på den version jag kört fram tills idag så ingick det i licensen vilket sannolikt kostade Kerio, som bolaget då hette, ordentliga pengar i form av licensavgifter till Microsoft som i sin tur äger ActiveSync-protokollet. Den version av Kerio Connect jag kör vägrar dessutom låta sig installeras på något nyare än exempelvis CentOS 6.9, vilket är en version av CentOS som är ganska gammal. Kort sagt: det är läge att uppgradera.

Jag satte därför tänderna i Zimbra. Detta är en e-postplattform som har ett antal år på nacken, vilket dels märks i form av dess webbaserade administrationsgränssnitt som inte ens kan göra en mor glad, och dels för att hela klabbet är skrivet i Java. Jodå - du läste rätt: Java. Bortsett från det, och en del annat, så är Zimbra en ganska trevlig e-postplattform. Betalar man för sig får man tonvis med lull-lull som exempelvis nyss nämnda ActiveSync. Kör man gratisvarianten får man det inte.

Varför är då ActiveSync så viktigt? Framförallt handlar det om hur mobila klienter, både iOS och Android, ansluter sig till e-postservrar över Internet. Ska man stödja kalendersynk via Caldav, adressbokssynk via Carddav, IMAP och SMTP till klienter över internet innebär det ett antal portar som ska öppnas i en brandvägg och inte sällan kan det strula eftersom ett protokoll som IMAP gärna kan se lite annorlunda ut beroende på vem som programmerat servern i fråga. Det är som man brukar säga: det som är så bra med standarder är att det finns så många av dem.

ActiveSync löser allt detta. Anslutningen är krypterad över SSL och därmed är det en port, 443, som öppnas. Det är allt. Kalender, kontaktbok, anteckningar och givetvis e-post synkroniseras över detta protokoll och som sylt på pannkakan blir det också enklare för en slutanvändare att faktiskt ansluta sig.

Zimbra i sin gratisversion vill inte prata ActiveSync. Det är i sig inte så konstigt - det måste ju finnas flera goda anledningar till att betala för programvaran och de tjänster som kommer med en betald licens. Men om man inte, eller kan, eller ens måste så kan man få Zimbra att prata ActiveSync, och det är egentligen inte så fasligt svårt.

Installera och konfigurera

Jag förutsätter att du gjort det enda civiliserade valet och installerat Zimbra på CentOS. När detta skrivs har CentOS 7.7 precis landat, när du läser detta kan det vara CentOS 8 eller 9 som gäller. Oavsett vad finns det gott om guider om hur man installerar Zimbra på CentOS så hitta en sådan som är skriven så pass nära i tiden från när du läser den - en guide från 2015 innehåller garanterat saker och ting som inte fungerar längre.

Logga sedan in på din Zimbra-server och skriv följande som root:

wget -O z-push.tar.gz http://download.z-push.org/final/2.3/z-push-2.3.7.tar.gz
mkdir -p /var/www/z-push
tar cf z-push.tar.gz --strip-components=1 -C /var/www/z-push

Nu har du laddat ner och packat upp z-push och lagt filerna på rätt ställe. Dags att installera Z-push backend för Zimbra så du får synkronisering av inte enbart e-post utan också kalender och adressbok:

wget -O zpushzimbra.tar.gz https://sourceforge.net/projects/zimbrabackend/files/latest/download
mkdir -p /var/www/z-push/backend/zimbra
tar xf zpushzimbra.tar.gz -C /var/www/z-push/backend/zimbra

Z-push är skrivet i PHP. Därför måste vi (tyvärr) installera PHP:

yum install -y php-pecl-memcached php-cli php-soap php-process php-mbstring php-fpm -y

När detta aningen obehagliga installationsmoment är ur vägen är det “bara” lite småsaker kvar. Först skapar vi lite kataloger:

mkdir -p /var/log/z-push /var/lib/z-push
chown apache: /var/log/z-push /var/lib/z-push

Nu börjar vi komma till den roliga delen: dags att konfigurera Z-push. Öppna /var/www/z-push/config.php med din favoriteditor och leta fram följande rad:

define('USE_X_FORWARDED_FOR_HEADER', false);

Ändra denna rad till:

define('USE_X_FORWARDED_FOR_HEADER', true);

Därefter ska vi redigera filen /var/www/z-push/backend/zimbra/config.php. Leta fram följande rad:

define('ZIMBRA_URL', 'https://YourZimbraInstallationURL.com');

Denna rad ska ändras till adressen till din Zimbra-server, och notera mycket noga vad du skriver här för det är helt avgörande om det ska fungera. Jag kommer strax till varför. I mitt fall ser raden ut såhär:

define('ZIMBRA_URL', 'https://mail01.fidonet.io');

Bara några ändringar kvar, och detta måste du göra som användaren zimbra. Öppna filen /opt/zimbra/conf/nginx/templates/nginx.conf.web.https.default.template och gör följande ändringar:

location ^~ /Microsoft-Server-ActiveSync
     {
         # Begin stray redirect hack
          
       ......

         # End stray redirect hack
 
-      # Proxy to Zimbra Upstream
-        proxy_pass          ${web.upstream.target};
-        proxy_read_timeout  ${web.upstream.polling.timeout};
-        proxy_buffering     off;
+        # Z-PUSH start
+        include /etc/nginx-php-fpm.conf;
+        # Z-PUSH end

         # For audit
       .......
   }

Där det är ett minustecken till vänster ska raden raderas, plustecken ska raden läggas till.

Som root skapar du sedan filen /etc/nginx-php-fpm.conf med följande innehåll:

fastcgi_param   QUERY_STRING            $query_string;
fastcgi_param   REQUEST_METHOD          $request_method;
fastcgi_param   CONTENT_TYPE            $content_type;
fastcgi_param   CONTENT_LENGTH          $content_length;

fastcgi_param   SCRIPT_NAME             $fastcgi_script_name;
fastcgi_param   PATH_INFO               $fastcgi_path_info;
fastcgi_param   PATH_TRANSLATED         $document_root$fastcgi_path_info;
fastcgi_param   REQUEST_URI             $request_uri;
fastcgi_param   DOCUMENT_URI            $document_uri;
fastcgi_param   DOCUMENT_ROOT           $document_root;
fastcgi_param   SERVER_PROTOCOL         $server_protocol;

fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;
fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;

fastcgi_param   REMOTE_ADDR             $remote_addr;
fastcgi_param   REMOTE_PORT             $remote_port;
fastcgi_param   SERVER_ADDR             $server_addr;
fastcgi_param   SERVER_PORT             $server_port;
fastcgi_param   SERVER_NAME             $server_name;

fastcgi_param   HTTPS                   $https;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param   REDIRECT_STATUS         200;

fastcgi_param HTTP_PROXY "";
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME /var/www/z-push/index.php;

client_max_body_size 20m;
client_body_buffer_size 128k;
keepalive_timeout  65;

# max_execution_time is 900
proxy_read_timeout 910;
fastcgi_read_timeout 910;

sendfile  on;

Därefter bygger du om Zimbras konfiguration:

sudo -u zimbra /opt/zimbra/bin/zmconfigdctl restart

Aktivera PHP-FPM:

systemctl enable php-fpm
systemctl start php-fpm

… och slutligen startar du om Zimbras proxy:

sudo -u zimbra /opt/zimbra/bin/zmproxyctl restart

Klart? Jodå. Minns du hur jag lite tidigare gav dig rådet att noga lägga på minnet vilken adress du angav till Zimbra-servern i filen /var/www/z-push/backend/zimbra/config.php? Om du lägger upp flera e-postdomäner i Zimbra, vilket är högst sannolikt att du gör, så är det oerhört viktigt att alla dessa kopplas till samma värdnamn

I mitt exempel ovan har jag skapat domänen fidonet.io och kopplar den till mail01.fidonet.io. Skapar jag en domän i Zimbra som heter joacimmelin.se måste även den i Zimbras domänkonfiguration i fältet Public service host name kopplas till det namn din Zimbra-server har, inget annat.

Nu kan du testa att koppla upp din iOS- eller Android-enhet mot din Zimbra-server genom att skapa ett nytt Exchange-konto i enheten. Du kan få mata in servernamn manuellt om du inte skapat DNS-records med autodiscovery och dylikt, och du behöver inte ange något på raden för domän när du skapar Exchange-kontot manuellt i iOS. Har du väldigt många brev i din brevlåda kommer din server att gå på knäna ganska omgående - jag har gett min Zimbra-server fyra processorkärnor och 16 gigabyte minne men när 3-4 stycken ActiveSync-klienter börjar hamra på servern och ska synkronisera sina brevlådor så kommer du snart märka att Zimbra med ActiveSync är som IT-världens Kakmonster och bara vill ha mer.. och mer…

Det var det hela. Lycka till!

2019-09-15

ESXi 6.5 och UPS-hantering via NUT

För galningar som jag som kör ett mindre datacenter hemma och dessutom bor på landet (med allt vad det innebär i form av ett elnät som både ger och tar…) kan det vara trevligt att ha batteribackuper till sina servrar och lagringsenheter, en så kallad UPS. Enligt alla former av gängse tradition och standard köper man givetvis UPS:er från APC när sånt ska göras och jag har tre stycken sådana kopplade till mina servrar. APC är trevliga eftersom de fungerar med i princip allt, från macOS till Linux och FreeBSD stödjer dem utan minsta bråk.

Det finns dock en plattform som är lite bråkig när det gäller att prata med UPS:er via USB-anslutning och det är VMware:s virtualiseringsplattform ESXi. Inte för att VMware är elaka på något sätt (åtminstone inte i detta avseende) men de tar sina grejer på allvar och därför anser de att man ska prata via sina UPS:er via nätverkskablage istället för USB. Lite underligt kanske med tanke på att du faktiskt kan tappa nätverket vid ett strömavbrott, men den diskussionen lämnar vi till ett annat tillfälle.

Det finns dock vägar runt detta. Systemet heter Network UPS Tools, NUT, och fungerar i praktiken som en brygga mellan dina UPS:er, som du ansluter till en dator (det kan vara en lagringsserver som kör FreeNAS eller en Raspberry Pi med Linux på, för att ta två exempel) via USB och sedan pratar andra enheter, exempelvis din brandvägg som kör PFSense, lagringsenhet som kör FreeNAS, valfri server som kör Windows eller Linux eller vad du vill, med denna NUT-server via en klientprogramvara. Känner NUT-servern av att din UPS körs på batterier kommer den tala om det för alla NUT-klienter som pratar med denna server och sedan kan de agera utifrån de inställningar du gett dem. I praktiken är detta det VMware vill göra med nätverksanslutna UPS:er men det går via en tredje part i form av en separat serverdator.

I mitt fall har jag valt att ansluta en av mina UPS:er till en av mina servrar som kör FreeNAS. På denna server har jag sedan konfigurerat upp en master för NUT. Detta finns väl dokumenterat så det är inget jag tänker gå in på närmare här (förutom att du inte ska glömma att ange LISTEN IP-adress-till-freenas-servern i fältet för Auxilary Parameters (upsd.conf)).

Nä, det roliga kommer när vi ska få igång detta på ESXi 6.5, som jag kör. Anledningen till att jag inte kör något nyare är dels för att mina servrar är till åren komna och inte stödjer något nyare, och dels gillar jag att ligga några versioner bakom för stabilitetens skull. Webbgränssnittet i ESXi 6.5 är så pass bra så det fungerar utan Flash eller nåt annat trams även i webbläsaren på en Mac eller i Linux vilket är uppskattat så jag har i praktiken ingen anledning att uppgradera till något nyare.

Det första man gör är att ladda ner programvaran för ESXi i form av klienten för NUT. Jag har lagt den på min server så du hittar den här. Som filnamnet antyder så är denna VIB, som insticksprogrammen för ESXi kallas, skriven för ESXi 5.0 men den fungerar utmärkt även med ESXi 6.5 med ett par förbehåll som jag återkommer till. Slå på SSH i din ESXi-server och sedan laddar du upp filen via SCP till /tmp. Packa upp med tar -xvzf NutClient-ESXi-2.1.0.tar.gz.

I paketet finns det ett script som installerar NUT-klienten, men det är saker du behöver göra innan du kör igång det.

Först och främst finns ett antal parametrar att mata in via esxcfg-advcfg-kommandot. Innan du gör det så måste du tala om för ESXi att du accepterar tredjepartsprogram med detta kommando:

esxcli software acceptance set --level=CommunitySupported

Därefter kan du sätta igång och skicka in följande kommandon:

esxcfg-advcfg -A NutUpsName -T string -E 'upsmon' -F upsmon@10.0.1.69
esxcfg-advcfg -A NutUser -T string -E 'upsmon@stor05' -F upsmon
esxcfg-advcfg -A NutPassword -T string -E 'upsmon' -F upsmon
esxcfg-advcfg -A NutFinalDelay -T int -E '120' -N 0 -M 120 -F 60000
esxcfg-advcfg -A NutMailTo -T string -E 'ange-mail-adress' -F ange-mail-adress
esxcfg-advcfg -A NutSendMail -T int -E 'NUT send mail notification (1=yes 0=no)' -N 0 -M 1 -F 0

Dessa kommandon kan du givetvis också mata in i scriptet som du ska köra nedan om du ska göra denna installation på flera servrar.

Därefter kör du installationsscriptet:

sh upsmon-install.sh

Om du som jag gillar att spara på el så kanske du inte har några hårddiskar i din ESXi-server utan kör den från ett USB-minne. Det kan, givetvis, diskuteras hur smart detta är med tanke på att USB-minnen knappast har en obegränsad livslängd vid återkommande skrivningar men om man som jag skickar alla loggar till en Syslog-server och i praktiken aldrig skriver på USB-stickan så håller det ganska länge. I mitt fall var det dock en av mina ESXi-servrar som gav följande felmeddelande:

[root@vh02:/tmp] sh upsmon-install.sh
Installation Result
   Message: WARNING: Only live system was updated, the change is not persistent.
   Reboot Required: false
   VIBs Installed: Margar_bootbank_upsmon_2.7.4-2.1.0
   VIBs Removed:
   VIBs Skipped:

Detta innebär i praktiken att det du “skrivit” till ditt USB-minne kommer vara borta vid nästa omstart. Dags att installera om med andra ord.

Om du däremot haft en lyckad installation av detta kommer tjänsten dels dyka upp som en tjänst i ESXi:s webbgränssnitt och dels, efter omstart, kan du också in och pilla på inställningarna för tjänsten under avancerade tjänster (System -> Advanced Settings) där du kan leta efter strängar som UserVars.Nut… så hittar du allt.

Vi är dock inte klara där.

Glöm inte att se till att NUT-tjänsten också startas när din ESXi-server startas.

Du behöver skapa filen /etc/ups/upsmon.conf. Denna ska skapas vid installation av tjänsten men det sker inte, inte heller katalogen /etc/ups skapas. Filen ser ut så här och skapas enklast med vi:

MONITOR ups@10.0.1.69 1 upsmon upsmon slave

Syntaxen är alltså monitor upsnamn@upserver nummer på UPS (oftast 1), användarnamn, lösenord och att detta är en slav.

Om allt är som det ska kan du nu testa kommunikationen med UPS:en. Gå till katalogen /opt/nut/bin och kör ./upsc ups@10.0.1.69.

Fungerar allt kommer du få uppföljande:

[root@vh03:/opt/nut/bin] ./upsc ups@10.0.1.69
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 50
battery.mfr.date: 2006/11/11
battery.runtime: 540
battery.runtime.low: 120
battery.temperature: 38.7
battery.type: PbAc
battery.voltage: 27.1
battery.voltage.nominal: 24.0
device.mfr: American Power Conversion
device.model: Smart-UPS 1000
device.serial: AS0646123225
device.type: ups
driver.name: usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: /dev/ugen1.3
driver.parameter.synchronous: no
driver.version: 2.7.4
driver.version.data: APC HID 0.96
driver.version.internal: 0.41
input.sensitivity: high
input.transfer.high: 253
input.transfer.low: 208
input.voltage: 236.1
output.current: 1.70
output.frequency: 50.0
output.voltage: 236.1
output.voltage.nominal: 230.0
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.delay.start: 30
ups.firmware: 652.13.I
ups.firmware.aux: 7.3
ups.load: 48.7
ups.mfr: American Power Conversion
ups.mfr.date: 2006/11/11
ups.model: Smart-UPS 1000
ups.productid: 0002
ups.serial: AS0646123225
ups.status: OL
ups.test.result: No test initiated
ups.timer.reboot: -1
ups.timer.shutdown: -1
ups.timer.start: -1
ups.vendorid: 051d

Har du kommit så här långt så har du nu en fungerade UPS-lösning för ESXi 6.5. Glöm inte att faktiskt testa det hela också genom att helt sonika dra strömkabeln på UPS:en och kontrollera så allt stängs ner ordentligt.

2019-09-09

Haproxy med Let's Encrypt

Det kan verka som voodoo att få vissa saker att fungera men genom att mecka, mecka och mecka lite till har jag fått fram en fungerande modell för hur man får Let’s Encrypt att fungera med Haproxy. Värt att notera är att jag baserar denna guide på Haproxy v2.0.5 kompilerad på CentOS 7.6.1810. Det finns saker jag gör i min konfigurationsfil som kommer tas bort i framtida versioner av Haproxy (i synnerhet användandet av ‘reqadd’) så det kommer jag behöva skriva om, men det är då det.

Det första du gör är, givetvis, att installera Haproxy. Hur din konfiguration ser ut varierar givetvis från fall till fall men det finns ett par saker du kan ha med som gör livet lite enklare. Som jag sa så har jag kompilerat upp Haproxy på CentOS 7 från källkoden. Jag använde följande parametrar för det för att få in stöd för SystemD och lite annat:

make -j 4 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_CRYPT_H=1 USE_LIBCRYPT=1 USE_SYSTEMD=1

I övrigt finns det guider för hur du gör installationen på bästa sätt med CentOS 7, och det är varmt rekommenderat att göra installationen från källkod då den version som finns i CentOS 7-repot är gammal som gatan och saknar stöd för en hel del roliga saker, exempelvis stöd för http/2 vilket kom i version 1.8 av Haproxy, vilket är trevligt i kombination med SSL.

Väl att notera är också att Haproxy gärna vill använda /var/run/haproxy/ när den startar för sin socket. Det går givetvis att ändra i /etc/haproxy/haproxy.cfg om man vill det men som standard kan denna inställning finnas i konfigurationsfilen.

Under inställningarna för global kan du lägga in inställningarna för hur SSL-certen ska hanteras av Haproxy. Mina ser ut så här:

tune.ssl.default-dh-param 4096
   ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AE
S128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-
DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
   ssl-default-bind-options no-sslv3 no-tls-tickets
   ssl-default-server-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-
AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDS
A-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
   ssl-default-server-options no-sslv3 no-tls-tickets

Genom att använda ACL:er kan du göra redirects redan i Haproxy för att skicka trafiken från http till https.

Under avsnittet för frontend sätter du följande (hämtat från min egna konfiguration):

  acl is_joacimmelin            hdr_end(host) -i www.joacimmelin.se
  acl is_joacimmelin            hdr_end(host) -i joacimmelin.se

Därefter lägger du in följande i samma kodavsnitt:

  redirect scheme https if { hdr(Host) -i www.joacimmelin.se } !{ ssl_fc }
 redirect scheme https if { hdr(Host) -i joacimmelin.se } !{ ssl_fc }

Vill du ändå tillåta både http och https-trafik kan du lägga in följande i samma kodavsnitt:

use_backend  nginx if is_joacimmelin

Namnet “nginx” är namnet på min backend där alla webbservrarna ligger inlagda. Du kan givetvis döpa den till vad du vill.

Nu kommer vi till det lite knepigare avsnittet, frontend för https.

Jag börjar det så här:

frontend https_front
  compression algo gzip
  compression type text/html text/plain text/javascript application/javascript application/xml text/css
  bind *:443 ssl crt-list /etc/ssl/crt-list.txt alpn h2,http/1.1
  reqadd X-Forwarded-Proto:\ https
  acl is_joacimmelin             hdr_end(host) -i www.joacimmelin.se
  acl is_joacimmelin             hdr_end(host) -i joacimmelin.se
  use_backend             nginx if is_joacimmelin

Den kanske viktigaste raden av den alla är rad fyra där vi binder en fil som heter /etc/ssl/crt-list.txt till ssl-hanteringen i Haproxy. Där finns för övrigt också en parameter som heter h2 som slår på http/2, vilket varmt rekommenderas.

Certifikathantering i Let’s Encrypt

Filen jag nämnde ovan (crt-list.txt) ser i mitt fall ut så här:

 /etc/letsencrypt/live/joacimmelin.se/joacimmelin.se

Sökvägen till filen är väl ganska tydlig, men filnamnet (joacimmelin.se)? För att detta ska fungera måste man göra ett kombinerat cert av de filer man får från Let’s Encrypt och det gör man på detta sätt:

DOMAIN='joacimmelin.se' bash -c 'cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/letsencrypt/live/$DOMAIN/joacimmelin.se'

I filen /etc/ssl/crt-list.txt kan jag sedan lista hur många certifikat jag vill för hur många domäner eller subdomäner jag vill och Haproxy kommer kolla i filen varje gång när den https-request ska hanteras och därmed skyffla över certifikatet och ladda sidan. Eftersom jag terminerar certifikatet i Haproxy kan jag skicka webbtrafiken bakåt till backend över port 80 och förutom att Wordpress behöver lite smisk för att det ska fungera (löses enklast i form av en plugin, givetvis…) så är det riktigt smidigt att bygga sin webbplattform på detta sätt.

Eftersom man skapar sina certifikat med Let’s Encrypt och certbot på Haproxy-maskinen kan man hantera den biten på lite olika sätt. Det enklaste, men kanske inte snyggaste, är att lägga in ett script i Crontab som var tredje-femte dag eller så helt sonika stoppar Haproxy, exekvererar Certbots renew-funktion, sedan kör man sammanslagningen av certifikatfilerna till ett kombinerat cert (som jag visade tidigare) och slutligen startar man Haproxy igen. Ungefär så här kan det se ut:

 #!/bin/bash
systemctl start haproxy
/usr/bin/certbot renew --standalone
DOMAIN='joacimmelin.se' bash -c 'cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/letsencrypt/live/$DOMAIN/joacimmelin.se'
systemctl start haproxy  

Lycka till!