<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Certificates on blog.iankulin.com</title><link>https://blog.iankulin.com/tags/certificates/</link><description>Recent content in Certificates on blog.iankulin.com</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Mon, 31 Mar 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iankulin.com/tags/certificates/index.xml" rel="self" type="application/rss+xml"/><item><title>Manually adding SSL certs in Nginx Proxy Manager</title><link>https://blog.iankulin.com/manually-adding-ssl-certs-in-nginx-proxy-manager/</link><pubDate>Mon, 31 Mar 2025 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/manually-adding-ssl-certs-in-nginx-proxy-manager/</guid><description>&lt;p&gt;A large part of the reason for my use of Nginx Proxy manager over vanilla NGINX, is that it has built-in Let&amp;rsquo;s Encrypt certificate requesting and renewing. This works perfectly for all my public facing services, and until recently, my homelab services. Before I dive into how I&amp;rsquo;ve fixed the problem I ran into, I better explain how my homelab domain is set up, and before I do that, an over-simplified description of how the SSL system works is required&lt;/p&gt;
&lt;h3 id="ssl"&gt;SSL&lt;/h3&gt;
&lt;p&gt;SSL (Secure Socket Layer) on a web site (the little padlock you see in the browser when you visit an https:// site) does three things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It tells you that this web site you&amp;rsquo;ve visited is controlled by the same people who own the domain name. This is important to prevent someone hijacking your request to &amp;ldquo;mysecurebank.com&amp;rdquo; and sending it to their password stealing website.&lt;/li&gt;
&lt;li&gt;It encrypts the traffic between the web-browser and the website so it can&amp;rsquo;t be spied on.&lt;/li&gt;
&lt;li&gt;It detects is someone has tried to tamper with the traffic between the web-browser and the website.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For all this to work, there needs to be some way of assuring the certificate issuer that the entity claiming a certificate for the domain, has control of the website that the domain is pointing to. The simplest way to do this is for the certificate issuer to give you a token, you install that in a secret directory on the web server, then the certificate issuer can check it exists. This proves to them that you own the website, and they can issue you the certificate.&lt;/p&gt;
&lt;p&gt;This process is essentially what happens when you use &lt;a href="https://certbot.eff.org/"&gt;Certbot&lt;/a&gt; to obtain a &lt;a href="https://letsencrypt.org/"&gt;Let&amp;rsquo;s Encrypt&lt;/a&gt; SSL certificate. It works great as long as your website is public to the internet so it can be contacted by the certificate issuer. But, that&amp;rsquo;s not the case for my homelab services. They are on an internal network, deliberately not contactable from the wild internet.&lt;/p&gt;
&lt;h3 id="ssl-on-an-internal-network"&gt;SSL on an internal network&lt;/h3&gt;
&lt;p&gt;There is less need for SSL on an internal network. You probably assume there&amp;rsquo;s no one to spy on your traffic, or to fiddle with it, and you know you have control of your apps. Apart from not trusting that, there&amp;rsquo;s a couple of other benefits - you often can&amp;rsquo;t save your passwords for unsecured sites, you can get annoying warning messages, and some apps just straight up won&amp;rsquo;t let you use some functionality without it. This is the case for my Forgejo instance that wants working SSL to allow me to git push to it.&lt;/p&gt;
&lt;h3 id="homelab-ssl"&gt;Homelab SSL&lt;/h3&gt;
&lt;p&gt;There is a way around this - basically we need to assure the certificate issuer that we&amp;rsquo;re in control, but instead of exposing a token on the (unreachable) web server, we add it as a record in the DNS of the domain (called DNS Challenge). The logic of this is that if you control the DNS you control where it points and therefore the web server. This is the first part of the Homelab SSL setup - obtaining the certificate with DNS challenge. The second part is using the DNS to point the domain at an internal website address. My domain and DNS are public - you could enter the domain name in a browser, but it resolves to an address inside my network. This is all much better explained by Wolfgang than me.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/qlcVx-k-02E?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;

&lt;h3 id="the-problem-ive-run-into"&gt;The problem I&amp;rsquo;ve run into&lt;/h3&gt;
&lt;p&gt;This all worked perfectly when I first set it up. Nginx Proxy Manager (NPM) has a plugin for my domain provider (&lt;a href="http://porkbun.com"&gt;porkbun&lt;/a&gt;) which uses their API to save the token into my DNS settings. The UX for this is that I tell Nginx Proxy Manager that I want to use &amp;ldquo;DNS Challenge&amp;rdquo; for a certificate request, and (by using an API key I&amp;rsquo;ve setup on Porkbun and given to NPM) it does all the fiddling around to obtain the certificate then installs them.&lt;/p&gt;
&lt;p&gt;I must of had that running for a year or so, with the certificates magically being renewed every couple of months with no input from my until just recently. I&amp;rsquo;m not exactly sure what&amp;rsquo;s happened - the error messages that I&amp;rsquo;m not smart enough to sort out suggest that the plugin&amp;rsquo;s operations to install the token at the domain provider is not working. I don&amp;rsquo;t know if it&amp;rsquo;s an API problem, or there&amp;rsquo;s been an NPM update that&amp;rsquo;s broken the plugin, or just something else has changed in my setup. What ever it is, turning everything off and on again, updating everything, and trying manually have not worked. So time for plan B.&lt;/p&gt;
&lt;h3 id="manual-certificates"&gt;Manual Certificates&lt;/h3&gt;
&lt;p&gt;Porkbun (and for all I know other domain sellers) provide a facility to download a &amp;lsquo;certificate bundle&amp;rsquo; directly from them - they are just doing that Let&amp;rsquo;s Encrypt dance directly - missing the NPM and Porkbun API step from the above.&lt;/p&gt;
&lt;p&gt;The certificate bundle contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;public.key.pem&lt;/li&gt;
&lt;li&gt;private.key.pem&lt;/li&gt;
&lt;li&gt;domain.cert.pem&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And when you go to add a custom certificate in NPM you have these options:&lt;/p&gt;
&lt;img src="https://blog.iankulin.com/images/screenshot-2025-03-08-at-15.47.04.png" width="981" alt=""&gt;
&lt;p&gt;As you can see your certificate (domain.cert.pem) goes in the certificate slot, and the Certificate Key it&amp;rsquo;s asking for is your private key (private.key.pem). You don&amp;rsquo;t need the intermediate key - this is the same for all Let&amp;rsquo;s Encrypt certificates.&lt;/p&gt;
&lt;p&gt;Doing the certificates this way is less good than having them automatically renewed. Currently Let&amp;rsquo;s Encrypt certificates are good for 90 days, so every three months my monitoring system will let me know they only have a couple of weeks left and I&amp;rsquo;ll have to repeat this manual process. There has been talk of shortening this time which would make that process even more annoying, so hopefully I can sort out the issue in NPM, or find out if Traefik or Caddy have the necessary plugins to do DNS challenge certificates.&lt;/p&gt;
&lt;p&gt;But in the meantime, my internal web apps are all up and secure.&lt;/p&gt;
&lt;h3 id="this-is-not-free"&gt;This is not free&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s Encrypt, and to a lesser extent Certbot have changed the web substantially. Obtaining and installing certificates used to be a difficult and costly process, but these two &amp;lsquo;free&amp;rsquo; services have turned that around. If you run a website and use these services I highly recommend you support the non-profits that keep them in existence as I do.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Let&amp;rsquo;s Encrypt - &lt;a href="https://letsencrypt.org/donate/"&gt;have a donation page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Certbot - is provided by the EFF who do other work can be &lt;a href="https://supporters.eff.org/donate/support-work-on-certbot"&gt;donated to here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Certbot - adding more virtual hosts</title><link>https://blog.iankulin.com/certbot-adding-more-virtual-hosts/</link><pubDate>Sun, 15 Oct 2023 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/certbot-adding-more-virtual-hosts/</guid><description>&lt;p&gt;I&amp;rsquo;ve got a domain that&amp;rsquo;s not currently used, so I&amp;rsquo;m going to set it up as a virtual host under NGINX. This server is already serving two domains set up with Certbot for SSL. Is it going to be possible to add another site and have Certbot manage the certificates for it after I&amp;rsquo;ve run Certbot once?&lt;/p&gt;
&lt;p&gt;When I googled around to find out, I didn&amp;rsquo;t find anything - which is usually a sign I&amp;rsquo;m either asking a wrong question, or it&amp;rsquo;s so little drama that no one ever mentions it. I decided just to move the site, check it was all working for the http version, then run Certbot and see what it said.&lt;/p&gt;
&lt;p&gt;Since I already had Certbot installed, I just ran &lt;code&gt;sudo certbot --nginx&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.iankulin.com/images/screen-shot-2023-09-03-at-10.03.19-am.png"&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-09-03-at-10.03.19-am.png" width="900" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s probably worth explaining at this point that Certbot does not obtain separate certificates for each domain (which is what I&amp;rsquo;d been doing when I was doing this manually), but instead grabs a single certificate that includes all the domains, and stores it under the the first domain - in the case above, for agnet.&lt;/p&gt;
&lt;p&gt;I hit &amp;ldquo;E&amp;rdquo; for Expand, and Certbot did it&amp;rsquo;s thing by acquiring the new certificate expanded to cover the new domain and installed it. No drama.&lt;/p&gt;
&lt;h3 id="what-if-you-already-have-a-certificate-from-another-provider"&gt;What if you already have a certificate from another provider?&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve got two more domains to move from another server, but both of these already have active SSL certificates that I obtained via Porkbun. Is that going to be a problem? Can Let&amp;rsquo;s Encrypt (who actually does the certificates for Porkbun) include these sites on the combined certificate on my main VPS so I can use Certbot to maintain them? Let&amp;rsquo;s see.&lt;/p&gt;
&lt;p&gt;I went through the same routine - created a nginx conf for the virtual host in &lt;code&gt;/etc/nginx/sites-available/&lt;/code&gt;, created a simple index.html in &lt;code&gt;/var/www/drysea.xyz&lt;/code&gt; and then symlinked the conf file into &lt;code&gt;/etc/nginx/sites-enabled&lt;/code&gt;. Then changed the A records for the DNS to point to the server address and waited for them to propagate so I could test the http version of the site.&lt;/p&gt;
&lt;p&gt;After that, I ran the sudo certbot &amp;ndash;nginx command again, and exactly as before, it asked if I wanted to expand the existing certificate. I did that, and the site can now be visited securely with no warning about the incorrect certificate. So that&amp;rsquo;s all worked well.&lt;/p&gt;
&lt;p&gt;It is allowable for a site to have more than one active, valid SSL certificate. This often happens in the exact scenario we&amp;rsquo;ve got here where domains are being moved around. There is a security implication for this though. A &lt;a href="https://www.csoonline.com/article/561111/dns-record-will-help-prevent-unauthorized-ssl-certificates.html"&gt;system&lt;/a&gt; of entering a particular DNS record that would prevent certificates being issued by all but one particular certificate authority exists, but is not widely used.&lt;/p&gt;
&lt;p&gt;It is probably a good idea for my to change my configuration on Porkbun to stop it from going on generating certificates that are not needed though, so I&amp;rsquo;ll go ahead and revoke that.&lt;/p&gt;</description></item><item><title>Save Proxmox password in Chrome</title><link>https://blog.iankulin.com/save-proxmox-password-in-chrome/</link><pubDate>Sat, 11 Feb 2023 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/save-proxmox-password-in-chrome/</guid><description>&lt;p&gt;When I installed Proxmox, I&amp;rsquo;d used a secure, and therefore absurdly long and complicated root password. I do use a password manager, but don&amp;rsquo;t have it integrated into Chrome, so it was buggging me having to find it and paste it in each time - why wasn&amp;rsquo;t Chrome offering to save it for me?&lt;/p&gt;
&lt;p&gt;Well, you&amp;rsquo;d guess it was something to do with this. I feel like Chrome is trying to tell me something here:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-02-04-at-7.06.49-am.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;Seems like a certificate thing. &lt;a href="https://forum.proxmox.com/threads/how-can-i-save-pve-web-loginpassword-on-firefox-chrome.46180/"&gt;These peeps&lt;/a&gt; say that I need to import the CA from PVE, and one more &lt;a href="https://pve.proxmox.com/wiki/Import_certificate_in_browser"&gt;googlestep reveals&lt;/a&gt; the certificate is on the Proxmox machine at &lt;code&gt;/etc/pve/pve-root-ca.pem&lt;/code&gt; so we need to grab that.&lt;/p&gt;
&lt;img src="https://blog.iankulin.com/images/aint.jpg" width="90" alt=""&gt;
&lt;p&gt;A while ago, I wrote a post about &lt;a href="https://blog.iankulin.com/copying-a-file-via-ssh/"&gt;using scp to copy files over ssh&lt;/a&gt;, and you should totally know how to do that, but my daily drive for secure file copying is now &lt;a href="https://filezilla-project.org/"&gt;filezilla&lt;/a&gt;. Once you have a bundle of servers in VM&amp;rsquo;s and containers that you revisit and move stuff around all the time, its just a big productivity step-up to have that list of hosts and credentials a tap away, plus having the visual arrangement of nested folders works for my brain somehow.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-02-04-at-7.14.40-am-1.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;On Mac, certificates need to live in the KeyChain, so you just drag the file into the certificates page. But it won&amp;rsquo;t be trusted, so you need to go in and manually do that. Where it says &amp;ldquo;Use System Defaults&amp;rdquo; change it to &amp;ldquo;Always Trust&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-02-04-at-7.19.54-am-1.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;It was annoying at this stage to find that Chrome was still saying it was insecure - even though it had changed to saying the certificate was valid.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-02-04-at-7.20.50-am.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;Looking at the settings for the site in Chrome, there&amp;rsquo;s an option for &amp;ldquo;Insecure Content&amp;rdquo; I try changing that to &amp;ldquo;Allow&amp;rdquo;, but really I&amp;rsquo;m guessing by this stage.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-02-04-at-7.21.15-am.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;But it actually does help - I&amp;rsquo;ve got the little padlock. That wasn&amp;rsquo;t quite the end since Chrome still wasn&amp;rsquo;t offering to save the password, but clearing the cache fixed that.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.iankulin.com/images/screen-shot-2023-02-04-at-7.24.08-am.png"&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-02-04-at-7.24.08-am.png" width="566" alt=""&gt;&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>