{"id":1216,"date":"2021-06-01T19:17:45","date_gmt":"2021-06-01T17:17:45","guid":{"rendered":"https:\/\/www.boettrich.info\/blog\/?p=1216"},"modified":"2021-09-29T16:01:33","modified_gmt":"2021-09-29T14:01:33","slug":"lets-encrypt-on-pfsense-haproxy","status":"publish","type":"post","link":"https:\/\/www.boettrich.info\/blog\/beitrag\/lets-encrypt-on-pfsense-haproxy\/","title":{"rendered":"Let&#8217;s encrypt on PFsense &#038; HAproxy"},"content":{"rendered":"\n<p>I got this running for a couple of years now and i&#8217;m pretty satisified. The main goal is to have the pfsense handle all the certificate stuff like issuing and renewing the lets-encrypt certificates and not to have those tasks on the backend servers. This includes having the pfsense and the HAproxy handling the acme-challenges as well.<\/p>\n\n\n\n<p>pfSense does not do this out of the box &#8211; one has to install a package and and additional script for handling the validation process. <\/p>\n\n\n\n<p>Unfortunatelly i never documented the setup nor did i save the links to some usefull sites&#8230;.<\/p>\n\n\n\n<p>So here we go to have at least some links and information saved. <\/p>\n\n\n\n<p>To have the pfSense box getting a certificate by itself one has to install the &#8222;ACME&#8220;-client in the package manager of the web ui. The intallation should be a straightforward process as the installer takes care of all the dependencies. Next is the creation of an account in the acme client.<\/p>\n\n\n\n<p>The ACME client is cappable of renewing certificates about to expire &#8211; but we need to handle the validation process &#8211; at least once for issuing a new certificate. To process acme challenges\/ validations automated with pfsense and HAproxy we need to configure a local lua script served by HAproxy.<\/p>\n\n\n\n<p>Right now i use this ACME domain validation plugin:<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/janeczku\/haproxy-acme-validation-plugin\">GitHub &#8211; janeczku\/haproxy-acme-validation-plugin: Zero-downtime ACME \/ Let&#8217;s Encrypt certificate issuing for HAProxy<\/a><\/p>\n\n\n\n<p>The haproxy-acme-validation plugin already has a good documentation about how and why one needs this kind of script.<\/p>\n\n\n\n<p>So in the first step we need to register a new account key &#8211; i choose &#8222;testing&#8220; in the ACME Server Section:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Fill in the marked fields<\/li><li>Click &#8222;Create new account key&#8220;<\/li><li>&#8222;Register ACME account key&#8220;<\/li><li>&#8222;Save&#8220;<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"764\" src=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-1024x764.png\" alt=\"\" class=\"wp-image-1325\" srcset=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-1024x764.png 1024w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-300x224.png 300w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-768x573.png 768w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image.png 1047w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Now your newly created key should appear in th list:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"279\" src=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-1-1024x279.png\" alt=\"\" class=\"wp-image-1328\" srcset=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-1-1024x279.png 1024w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-1-300x82.png 300w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-1-768x209.png 768w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-1.png 1222w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Before we can issue a new TLS certificate with this key, we need to make sure that the CA can verify we are authorized to issue certificates for this domain. Usually you do this by signing a contract and name persons to do that &#8211; these persons authenticate theirselfes to the CA using apporpriate means, for example a smartcard or a certificate. <\/p>\n\n\n\n<p>Let&#8217;s Encrypt provides multiple ways to prove your&#8217;re authorized to issue certificates for this domain &#8211; in this case here i choose to use the &#8222;HTTP-01 challenge&#8220; type. For this validation mechanism type we need to &#8222;install&#8220; the mentioned &#8222;haproxy-acme-validation plugin&#8220;.<\/p>\n\n\n\n<p>For this we go to the haproxy configuration and define a http-only frontend for this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"118\" src=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-2-1024x118.png\" alt=\"\" class=\"wp-image-1330\" srcset=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-2-1024x118.png 1024w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-2-300x35.png 300w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-2-768x89.png 768w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-2.png 1230w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>In this frontend we define the following settings:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-3.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"297\" src=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-3-1024x297.png\" alt=\"\" class=\"wp-image-1331\" srcset=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-3-1024x297.png 1024w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-3-300x87.png 300w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-3-768x223.png 768w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-3.png 1173w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>And actions:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-4.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"421\" src=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-4-1024x421.png\" alt=\"\" class=\"wp-image-1332\" srcset=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-4-1024x421.png 1024w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-4-300x123.png 300w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-4-768x316.png 768w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-4.png 1056w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Afterwards we have to &#8222;install&#8220; the script handling the validation challenge &#8211; this can be found under HAproxy -&gt; Files . We do make a copy of the &#8222;errorfile&#8220; (which should already be there in a default setup i guess :-) ) &#8230;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/09\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"361\" src=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/09\/image-1024x361.png\" alt=\"\" class=\"wp-image-1445\" srcset=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/09\/image-1024x361.png 1024w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/09\/image-300x106.png 300w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/09\/image-768x271.png 768w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/09\/image.png 1131w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>&#8230; and make the following changes and copy\/paste the script in into the large textbox:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-5.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"225\" src=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-5-1024x225.png\" alt=\"\" class=\"wp-image-1334\" srcset=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-5-1024x225.png 1024w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-5-300x66.png 300w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-5-768x169.png 768w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-5.png 1143w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>As we are using a pfSense here, haproxy run&#8217;s in a chroot-environment so we don&#8217;t have to configure the path inside the script :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>8&lt;&lt;\n-- When HAProxy is *not* configured with the 'chroot' option you must set an absolute path here and pass \n-- that as 'webroot-path' to the letsencrypt client\n\nacme.conf = {\n\t&#91;\"non_chroot_webroot\"] = \"\"\n}\n&gt;&gt;8<\/code><\/pre>\n\n\n\n<p>So with this we&#8217;re now able to request a new certificate :-)<\/p>\n\n\n\n<p>Create a new one &#8211; fill in the fields as shown and click save.<\/p>\n\n\n\n<p>The &#8222;Root folder:&#8220; path here has to be: \/tmp\/haproxy_chroot\/.well-known\/acme-challenge\/<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-8.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"716\" src=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-8-1024x716.png\" alt=\"\" class=\"wp-image-1340\" srcset=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-8-1024x716.png 1024w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-8-300x210.png 300w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-8-768x537.png 768w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-8.png 1152w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Afterwards click &#8222;Issue\/Renew&#8220; and a couple of seconds later you should see an output reporting the successfull issue of a certificate:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-10.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"848\" src=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-10-1024x848.png\" alt=\"\" class=\"wp-image-1343\" srcset=\"https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-10-1024x848.png 1024w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-10-300x248.png 300w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-10-768x636.png 768w, https:\/\/www.boettrich.info\/blog\/wp-content\/uploads\/2021\/06\/image-10.png 1151w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>So that&#8217;s it &#8211; we setup the acme plugin, installed the haproxy-acme-validation plugin and issued a certificate :-) <\/p>\n\n\n\n<p>From now on &#8211; if configured in the &#8222;general settings&#8220; tab &#8211; the certificate(s) will be renewed automatically.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I got this running for a couple of years now and i&#8217;m pretty satisified. The main goal is to have the pfsense handle all the certificate stuff like issuing and renewing the lets-encrypt certificates and not to have those tasks on the backend servers. This includes having the pfsense and the HAproxy handling the acme-challenges&hellip;&nbsp;<a href=\"https:\/\/www.boettrich.info\/blog\/beitrag\/lets-encrypt-on-pfsense-haproxy\/\" rel=\"bookmark\">Weiterlesen &raquo;<span class=\"screen-reader-text\">Let&#8217;s encrypt on PFsense &#038; HAproxy<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"categories":[1,6],"tags":[],"class_list":["post-1216","post","type-post","status-publish","format-standard","hentry","category-beitrag","category-technik"],"_links":{"self":[{"href":"https:\/\/www.boettrich.info\/blog\/wp-json\/wp\/v2\/posts\/1216","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.boettrich.info\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.boettrich.info\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.boettrich.info\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.boettrich.info\/blog\/wp-json\/wp\/v2\/comments?post=1216"}],"version-history":[{"count":21,"href":"https:\/\/www.boettrich.info\/blog\/wp-json\/wp\/v2\/posts\/1216\/revisions"}],"predecessor-version":[{"id":1448,"href":"https:\/\/www.boettrich.info\/blog\/wp-json\/wp\/v2\/posts\/1216\/revisions\/1448"}],"wp:attachment":[{"href":"https:\/\/www.boettrich.info\/blog\/wp-json\/wp\/v2\/media?parent=1216"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.boettrich.info\/blog\/wp-json\/wp\/v2\/categories?post=1216"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.boettrich.info\/blog\/wp-json\/wp\/v2\/tags?post=1216"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}