{"id":466,"date":"2023-04-03T20:13:06","date_gmt":"2023-04-03T18:13:06","guid":{"rendered":"https:\/\/jbsoft.nl\/site\/?p=466"},"modified":"2023-04-03T20:39:09","modified_gmt":"2023-04-03T18:39:09","slug":"home-assistant-haproxy-letsencrypttransip","status":"publish","type":"post","link":"https:\/\/jbsoft.nl\/site\/nl\/home-assistant-haproxy-letsencrypttransip\/","title":{"rendered":"Home Assistent + `haproxy` +`LetsEncrypt`+TransIP"},"content":{"rendered":"<p>Deze post gaat over mijn (positieve) ervaring met <code>haproxy<\/code> als reverse proxy voor Home Assistant. Toegang op afstand is nodig als je Home Assistant van buiten uw thuisnetwerk wilt openen.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p id=\"block-672143c0-9b3b-450f-8df7-2edc759e0312\">Als voorwaarde zullen we ook de poort moeten doorsturen <code>443<\/code>(https) in onze router\/firewall naar het gebruikte systeem en zorg ervoor dat we een geldige DNS A\/AAAA- of CNAME-record hebben ingesteld die verwijst naar het openbare IP-adres dat wordt gebruikt om door te sturen.<\/p>\n<\/blockquote>\n\n\n\n<p>Ik wilde <code>LetsEncrypt<\/code> certificaten hebben die worden uitgegeven met behulp van een <a rel=\"noreferrer noopener\" href=\"https:\/\/letsencrypt.org\/docs\/challenge-types\/#http-01-challenge\" target=\"_blank\">DNS-challenge<\/a>. Hiervoor heb ik een Raspberry Pi 3b-bord gebruikt waarop Rasbian (Debian) is ge\u00efnstalleerd. Verder <a rel=\"noreferrer noopener\" href=\"https:\/\/docs.docker.com\/desktop\/install\/debian\/\" target=\"_blank\">installeerde ik<\/a> <code>docker<\/code>, en <code>haproxy<\/code>.<\/p>\n\n\n\n<p>Het installeren van de <code>haproxy<\/code> pakket is zo simpel als:<\/p>\n\n\n\n<p><code>sudo apt-update<\/code> and <code>sudo apt install haproxy<\/code><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Als voorwaarde zullen we ook de poort moeten doorsturen <code>443<\/code>(https) in onze router\/firewall naar het gebruikte systeem en zorg ervoor dat we een geldige DNS A\/AAAA- of CNAME-record hebben ingesteld die verwijst naar het openbare IP-adres dat wordt gebruikt om door te sturen.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\"><code>LetsEncrypt<\/code> met DNS-01 challenge en TransIP API<\/h2>\n\n\n\n<p>In mijn geval worden mijn internetdomeinen beheerd door <a rel=\"noreferrer noopener\" href=\"https:\/\/transip.nl\" target=\"_blank\">TransIP<\/a>, en DNS-toegang heeft <a rel=\"noreferrer noopener\" href=\"https:\/\/api.transip.nl\/rest\/docs.html#domains\" target=\"_blank\">API-ondersteuning<\/a>. In het portaal kunt je een API-sleutel aanmaken en de IP-adressen die u wilt gebruiken voor DNS-toegangen whitelisten. We gebruiken deze API om in te schrijven <code>LetsEncrypt<\/code> certificaten. Het grote voordeel is dat we wild card certificaten kunnen inschrijven of certificaten met interne namen die we niet op het internet willen tonen, en we hoeven poort 80 niet te openen!<\/p>\n\n\n\n<p>Voor de inschrijving van certificaten met <code>LetsEncrypt<\/code> via de TransIP API heb ik de docker image (rbongers\/certbot-dns-transip) van gebruikt <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/roy-bongers\" data-type=\"URL\" data-id=\"https:\/\/github.com\/roy-bongers\" target=\"_blank\">Roy Bongers<\/a> waar alle functionaliteit in zit.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Opzetten <code>LetsEncrypt<\/code><\/h3>\n\n\n\n<p>Maak eerst de mappen aan <code>\/etc\/letsencrypt<\/code>, <code>\/var\/log\/letsencrypt<\/code> and <code>\/etc\/transip<\/code>.<\/p>\n\n\n\n<p>Maak als <code>root<\/code> bestand <code>config.php<\/code> in <code>\/etc\/transip<\/code>. Gebruik de onderstaande link voor het sjabloon:<\/p>\n\n\n\n<p><a href=\"https:\/\/gist.github.com\/jbouwh\/3b6042ed4ca1189e1f37d0f8ff7274e5#file-config-php-L1-L17\">https:\/\/gist.github.com\/jbouwh\/3b6042ed4ca1189e1f37d0f8ff7274e5#file-config-php-L1-L17<\/a><\/p>\n\n\n\n<p>Je dient de verkregen TransIP API key en je TransIP gebruikersnaam in te plakken.<\/p>\n\n\n\n<p>Zorg ervoor dat u uw sleutelbestand beveiligt met <code>sudo chmod 400 \/etc\/transip\/config\/php<\/code> dus dat is alleen-lezen voor root.<\/p>\n\n\n\n<p>Om het certificaat voor de eerste keer in te stellen, maken we een bash-script (ik plaatste het in <code>\/usr\/local\/sbin<\/code>):<\/p>\n\n\n\n<p><a href=\"https:\/\/gist.github.com\/jbouwh\/3b6042ed4ca1189e1f37d0f8ff7274e5#file-certinit-bash-L1-L10\">https:\/\/gist.github.com\/jbouwh\/3b6042ed4ca1189e1f37d0f8ff7274e5#file-certinit-bash-L1-L10<\/a><\/p>\n\n\n\n<p>Vervang de `\u2013cert-name` en het wild card domein (<code>-d certificaatnaam.example.com<\/code>), en vervang het domein door een willekeurige domeinnaam die u bezit. U kunt de <code>-D<\/code> parameter meerdere keren. Voor elk domein wordt een dns-challenge aangemaakt.<\/p>\n\n\n\n<p>Zorg ervoor dat het script uitvoerbaar is <code>chmod +x certinit.bash<\/code>.<\/p>\n\n\n\n<p>Ren nu <code>certinit.bash<\/code> . Het downloadt de afbeelding en start een docker voor de installatie. Dit is interactief, u krijgt enkele vragen zoals uw e-mailadres.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@docker01:\/usr\/local\/sbin# certinit.bash\nUnable to find image 'rbongers\/certbot-dns-transip:latest' locally\nlatest: Pulling from rbongers\/certbot-dns-transip\n330ad28688ae: Pull complete\n882df4fa64e9: Pull complete\n07e271639575: Pull complete\n2d60c5e17079: Pull complete\nf54b294a6f71: Pull complete\n6f27ea6ab430: Pull complete\n0c8c5a3cd6a8: Pull complete\n6436ec8cd157: Pull complete\n350482e0cef8: Pull complete\nfcb8169b6442: Pull complete\nba9658959877: Pull complete\nb9d5ffb589b1: Pull complete\na368f8fc57ed: Pull complete\nDigest: sha256:faec7bc102edf00237041fbce8030249fb55f300da76b637660384c353043bff\nStatus: Downloaded newer image for rbongers\/certbot-dns-transip:latest\nSaving debug log to \/var\/log\/letsencrypt\/letsencrypt.log\nPlugins selected: Authenticator manual, Installer None\nEnter email address (used for urgent renewal and security notices)\n (Enter 'c' to cancel): <strong>user@example.com<\/strong> (your email adres)\n\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nPlease read the Terms of Service at\nhttps:\/\/letsencrypt.org\/documents\/LE-SA-v1.3-September-21-2022.pdf. You must\nagree in order to register with the ACME server. Do you agree?\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n(Y)es\/(N)o: <strong>Y<\/strong>\n\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nWould you be willing, once your first certificate is successfully issued, to\nshare your email address with the Electronic Frontier Foundation, a founding\npartner of the Let's Encrypt project and the non-profit organization that\ndevelops Certbot? We'd like to send you email about our work encrypting the web,\nEFF news, campaigns, and ways to support digital freedom.\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n(Y)es\/(N)o: <strong>N<\/strong>\n\nAccount registered.\nRequesting a certificate for <strong>xxxxxx <\/strong>and <strong>jjjjj<\/strong>\nPerforming the following challenges:\ndns-01 challenge for <strong>xxxx<\/strong>\ndns-01 challenge for <strong>jjjjj<\/strong>\nRunning manual-auth-hook command: \/opt\/certbot-dns-transip\/auth-hook\nOutput from manual-auth-hook command auth-hook:\n[2023-03-31 08:32:03.596791] INFO: Creating TXT record for _acme-challenge with challenge 'FfGM5VPKWKkwR-6ggUhlpoZlQ5-vPGK-JIy25tekb_E' [] []\n[2023-03-31 08:32:06.782752] INFO: Waiting until nameservers (ns0.transip.net, ns1.transip.nl, ns2.transip.eu) are up-to-date [] []\n[2023-03-31 08:32:08.625219] INFO: All nameservers are updated! [] []\n\nRunning manual-auth-hook command: \/opt\/certbot-dns-transip\/auth-hook\nOutput from manual-auth-hook command auth-hook:\n[2023-03-31 08:32:09.659195] INFO: Creating TXT record for _acme-challenge with challenge 'lP_hQVRODhVCiglLiNSZvNky9voGChnTyo407N_xRU4' [] []\n[2023-03-31 08:32:12.628115] INFO: Waiting until nameservers (ns0.transip.net, ns1.transip.nl, ns2.transip.eu) are up-to-date [] []\n[2023-03-31 08:32:13.659641] INFO: All nameservers are updated! [] []\n\nWaiting for verification...\nCleaning up challenges\nRunning manual-cleanup-hook command: \/opt\/certbot-dns-transip\/cleanup-hook\nOutput from manual-cleanup-hook command cleanup-hook:\n[2023-03-31 08:32:16.459605] INFO: Cleaning up record _acme-challenge with value 'FfGM5VPKWKkwR-6ggUhlpoZlQ5-vPGK-JIy25tekb_E' [] []\n\nRunning manual-cleanup-hook command: \/opt\/certbot-dns-transip\/cleanup-hook\nOutput from manual-cleanup-hook command cleanup-hook:\n[2023-03-31 08:32:20.031682] INFO: Cleaning up record _acme-challenge with value 'lP_hQVRODhVCiglLiNSZvNky9voGChnTyo407N_xRU4' [] []\n\n\nIMPORTANT NOTES:\n - Congratulations! Your certificate and chain have been saved at:\n   \/etc\/letsencrypt\/live\/<strong>xxxxxx<\/strong>\/fullchain.pem Uw sleutelbestand is opgeslagen op: \/etc\/letsencrypt\/live\/<strong>xxxxxx<\/strong>\/privkey.pem\n   Your certificate will expire on 202<strong>x-mm-ss<\/strong>. To obtain a new or\n   tweaked version of this certificate in the future, simply run\n   certbot again. To non-interactively renew *all* of your\n   certificates, run \"certbot renew\"\n - If you like Certbot, please consider supporting our work by:\n\n   Donating to ISRG \/ Let's Encrypt:   https:\/\/letsencrypt.org\/donate\n   Donating to EFF:                    https:\/\/eff.org\/donate-le\n<\/code><\/pre>\n\n\n\n<p>Je certificaat wordt aangemaakt in <code>\/etc\/letsencrypt\/live\/{certname}<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Automatische uitgifte instellen<\/h3>\n\n\n\n<p>We willen het certificaat automatisch verlengen en <code>haproxy<\/code> bijwerken om het nieuwe certificaat te gebruiken. Het <code>haproxy<\/code> certificaat wordt geplaatst in <code>\/etc\/haproxy\/cert.pem<\/code>. Om in te schrijven heb ik een bash-script gemaakt <code>certrenew.bash<\/code>:<\/p>\n\n\n\n<p><a href=\"https:\/\/gist.github.com\/jbouwh\/3b6042ed4ca1189e1f37d0f8ff7274e5#file-certrenew-bash-L1-L68\">https:\/\/gist.github.com\/jbouwh\/3b6042ed4ca1189e1f37d0f8ff7274e5#file-certrenew-bash-L1-L68<\/a><\/p>\n\n\n\n<p>Zorg ervoor dat u de <code>basecert<\/code> parameter in het script. en plaats het als <code>certrenew<\/code> in <code>\/usr\/local\/bin\/sbin<\/code> en maak het uitvoerbaar met <code>sudo chmod + x \/etc\/local\/sbin\/certrenew<\/code>.<\/p>\n\n\n\n<p>We moeten <code>certrenew<\/code> een eerste keer uitvoeren om ervoor te zorgen dat het <code>haproxy<\/code> certificaat wordt gemaakt.<\/p>\n\n\n\n<p>Om ervoor te zorgen dat het elke dag ergens tussen 23.00 uur en middernacht draait, maken we er een cronfile (`\/etc\/cron.d\/certrenew`) voor (zie link).<\/p>\n\n\n\n<p><a href=\"https:\/\/gist.github.com\/jbouwh\/3b6042ed4ca1189e1f37d0f8ff7274e5#file-certrenew-cron-L1-L9\">https:\/\/gist.github.com\/jbouwh\/3b6042ed4ca1189e1f37d0f8ff7274e5#file-certrenew-cron-L1-L9<\/a>.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Herstart cron <code>sudo systemctl restart cron<\/code><\/p>\n<\/blockquote>\n\n\n\n<p>Wanneer het script wordt uitgevoerd, wordt gecontroleerd of het certificaat binnen 30 dagen verloopt, in dat geval wordt een nieuw certificaat aangevraagd. Als het proces succesvol was, wordt het certificaat bijgewerkt en opnieuw opgestart <code>haproxy<\/code> met het nieuwe certificaat.<\/p>\n\n\n\n<p>Nu zijn we helemaal klaar, zorg ervoor dat je de logboeken controleert om te zien of de hele installatie correct werkt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Instellen <code>haproxy<\/code><\/h2>\n\n\n\n<p>Als laatste stap kan nu <code>haproxy<\/code> (<code>\/etc\/haproxy\/haproxy.cfg<\/code>)  worden ingesteld met het nieuwe certificaat. <\/p>\n\n\n\n<p>Je kunt <a rel=\"noreferrer noopener\" href=\"https:\/\/gist.github.com\/jbouwh\/3b6042ed4ca1189e1f37d0f8ff7274e5#file-haproxy-cfg-L1-L61\" target=\"_blank\">https:\/\/gist.github.com\/jbouwh\/3b6042ed4ca1189e1f37d0f8ff7274e5#file-haproxy-cfg-L1-L61<\/a> gebruiken als sjabloon voor uw configuratie. U moet de DNS-namen en het interne IP-adres van uw backend wijzigen. In mijn geval heb ik een Raspberry PI met een SD-kaart gebruikt en logging uitgeschakeld om ervoor te zorgen dat de SD-kaart langer meegaat. Als u een SSD hebt aangesloten, kunt u de logging wijzigen.<\/p>\n\n\n\n<p>Zorg ervoor dat u ook installeert <code>\/etc\/haproxy\/dhparam.pem<\/code> (zie de opmerking op de laatste regel van het configuratiebestand over hoe u dit kunt verkrijgen).<\/p>\n\n\n\n<p>In de voorbeeldconfiguratie heb ik de statistiekenpagina ingeschakeld op <code>https:\/\/{jouw_domeinnaam}\/stats<\/code>. Je kunt deze pagina gebruiken om de statistieken te bekijken. <code>acl network_allowed_src src<\/code> wordt gebruikt om te beveiligen dat de pagina alleen toegankelijk is vanaf interne IP-adressen. Zorg ervoor dat je de juiste IP-ranges invult die toegang moeten hebben.<\/p>\n\n\n\n<p>Als je klaar bent, kun je het configuratiebestand testen met:<\/p>\n\n\n\n<p><span class=\"pl-c\"><code>haproxy -f \/etc\/haproxy\/haproxy.cfg -c<\/code><\/span><\/p>\n\n\n\n<p>Als dat goed is, ben je helemaal klaar. Herstart <code>haproxy<\/code> om de nieuwe configuratie te laden met: <code>sudo systemctl restart haproxy<\/code>.<\/p>\n\n\n\n<p>Nu heb je van buitenaf toegang tot Home Assistant. Zorg ervoor dat <a href=\"https:\/\/www.home-assistant.io\/docs\/authentication\/multi-factor-auth\/\" data-type=\"URL\" data-id=\"https:\/\/www.home-assistant.io\/docs\/authentication\/multi-factor-auth\/\" target=\"_blank\" rel=\"noreferrer noopener\">twee-factor-authenticatie is ingesteld <\/a>om de toegang tot uw netwerk te beveiligen.<\/p>","protected":false},"excerpt":{"rendered":"<p>Deze post gaat over mijn (positieve) ervaring met haproxy als reverse proxy voor Home Assistant. Toegang op afstand is nodig als u Home Assistant van buiten uw thuisnetwerk wilt openen. Als voorwaarde moeten we ook poort 443 (https) in onze router\/firewall doorsturen naar het gebruikte systeem en ervoor zorgen dat we een geldige \u2026 <a href=\"https:\/\/jbsoft.nl\/site\/nl\/home-assistant-haproxy-letsencrypttransip\/\" class=\"more-link\">Lees verder <span class=\"screen-reader-text\">\u201cThuis Assistent + `haproxy` +`LetsEncrypt`+TransIP\u201d<\/span><\/a><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19,5],"tags":[],"class_list":["post-466","post","type-post","status-publish","format-standard","hentry","category-docker","category-home-assistant"],"_links":{"self":[{"href":"https:\/\/jbsoft.nl\/site\/nl\/wp-json\/wp\/v2\/posts\/466","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jbsoft.nl\/site\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jbsoft.nl\/site\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jbsoft.nl\/site\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jbsoft.nl\/site\/nl\/wp-json\/wp\/v2\/comments?post=466"}],"version-history":[{"count":2,"href":"https:\/\/jbsoft.nl\/site\/nl\/wp-json\/wp\/v2\/posts\/466\/revisions"}],"predecessor-version":[{"id":468,"href":"https:\/\/jbsoft.nl\/site\/nl\/wp-json\/wp\/v2\/posts\/466\/revisions\/468"}],"wp:attachment":[{"href":"https:\/\/jbsoft.nl\/site\/nl\/wp-json\/wp\/v2\/media?parent=466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jbsoft.nl\/site\/nl\/wp-json\/wp\/v2\/categories?post=466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jbsoft.nl\/site\/nl\/wp-json\/wp\/v2\/tags?post=466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}