<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Openvpn on inetshell</title><link>https://inet.sh/en/tags/openvpn/</link><description>Recent content in Openvpn on inetshell</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 25 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://inet.sh/en/tags/openvpn/index.xml" rel="self" type="application/rss+xml"/><item><title>pfSense: OpenVPN stops accepting clients with 'CRL has expired'</title><link>https://inet.sh/en/posts/pfsense/openvpn-crl-has-expired/</link><pubDate>Fri, 25 Sep 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/en/posts/pfsense/openvpn-crl-has-expired/</guid><description>Every OpenVPN client on a pfSense fails at once with &amp;#39;VERIFY ERROR: depth=0, error=CRL has expired&amp;#39;. The internal CRL expired, or was born expired because of the 9999-day bug (Redmine #13424, a date past 2050 encoded as 1950). How to regenerate it from Cert Manager, the patch for old versions, and how to check it with openssl.</description><content:encoded><![CDATA[<h2 id="tldr">TL;DR</h2>
<p><strong>System → Certificates → Certificate Revocation</strong> → pencil on the CRL the OpenVPN server uses → <strong>Lifetime (Days)</strong> = <code>730</code> → <strong>Save</strong>. Saving regenerates the CRL with valid dates. Then <strong>Status → Services → OpenVPN → Restart</strong>. Clients get back in without changing anything on their side.</p>
<p>If the GUI will not let you set a sane lifetime (versions before 2.7 / 23.01), first <strong>System → Patches</strong> (the <em>System Patches</em> package) → apply <em>Fix for CRL expiration lifetime default and maximum values</em> (<code>a3c1589086ea67d25a28ec14ab95d7fd9ab25fa2</code>), then the step above. Or upgrade pfSense: current versions already carry it.</p>
<h2 id="the-error">The error</h2>
<p>In the server log (Status → System Logs → OpenVPN) and on the client:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">VERIFY ERROR: depth=0, error=CRL has expired: CN=client1, serial=3
</span></span><span class="line"><span class="cl">OpenSSL: error:0A000086:SSL routines::certificate verify failed
</span></span><span class="line"><span class="cl">TLS_ERROR: BIO read tls_read_plaintext error
</span></span><span class="line"><span class="cl">TLS Error: TLS handshake failed
</span></span></code></pre></td></tr></table>
</div>
</div><p>The clue is that <strong>every client fails at once</strong>. An expired certificate takes down one client; an expired CRL takes down the whole server, because it is checked on every handshake.</p>
<h2 id="why-it-happens">Why it happens</h2>
<p>Two roads lead here:</p>
<ol>
<li><strong>The CRL really expired.</strong> Every CRL has a <code>nextUpdate</code>; past that date OpenSSL treats it as invalid and OpenVPN rejects everyone. A CRL created years ago with a short lifetime and never touched ends up like this.</li>
<li><strong>The CRL was born expired.</strong> pfSense generated CRLs with a <strong>9999-day</strong> default, which pushed them past <strong>2050</strong>. X.509 encodes dates up to 2049 as <code>UTCTime</code> with a two-digit year, and pfSense wrote <code>50</code> where <code>GeneralizedTime</code> was due: OpenSSL reads it as <strong>1950</strong> and the CRL &ldquo;expired&rdquo; 75 years ago. That is Redmine <a href="https://redmine.pfsense.org/issues/13424">bug #13424</a>, and it explains why healthy installs started failing in 2022–2023 with nobody touching anything: CRLs regenerated by any change crossed 2050.</li>
</ol>
<p>Netgate&rsquo;s fix lowered the default lifetime to <strong>730 days</strong>, capped the maximum (2050 on 64-bit, 2038 on 32-bit), and ships in current versions; for old ones it remained as a patch in the <em>System Patches</em> package.</p>
<h2 id="checking-it">Checking it</h2>
<p>pfSense writes each OpenVPN server&rsquo;s CRL into its configuration directory:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">ls /var/etc/openvpn/server1/
</span></span><span class="line"><span class="cl">openssl crl -in /var/etc/openvpn/server1/crl-verify -noout -lastupdate -nextupdate
</span></span></code></pre></td></tr></table>
</div>
</div><p>A <code>nextUpdate</code> in the past, or a year of 1950, is the whole diagnosis.</p>
<h2 id="fix">Fix</h2>
<ol>
<li><strong>Identify which CRL the server uses</strong>: VPN → OpenVPN → Servers → edit → <em>Peer Certificate Revocation list</em>.</li>
<li><strong>Regenerate it</strong>: System → Certificates → Certificate Revocation → pencil on that CRL → <strong>Lifetime (Days)</strong> <code>730</code> → Save. Any save rewrites it with <code>lastUpdate</code> = now.</li>
<li><strong>Restart OpenVPN</strong>: Status → Services. OpenVPN re-reads <code>crl-verify</code> when it notices the change, but the restart saves you the wait.</li>
<li><strong>Check again</strong> with the <code>openssl crl</code> above.</li>
</ol>
<p>On a version without the fix, between steps 1 and 2: System → Package Manager → install <em>System_Patches</em> → System → Patches → the patch shows up in the recommended list → <strong>Apply</strong>. Without it, the GUI writes 9999 again and the problem repeats as soon as you save.</p>
<h2 id="traps">Traps</h2>
<ul>
<li><strong>Do not delete the CRL to &ldquo;fix it&rdquo;</strong>: without a CRL, the certificates you revoked become valid again. Edit it.</li>
<li><strong>One CRL per CA</strong>: if you have several OpenVPN servers with different CAs, check each one.</li>
<li><strong>Imported CRLs</strong> (from an external CA) cannot be regenerated from pfSense; request a new one from your CA and import it again.</li>
<li><strong>730 days run out too.</strong> Any revocation, CRL edit, or change to the OpenVPN server regenerates it; if you touch nothing for two years, you are back here. A calendar reminder is cheap.</li>
<li><strong>Past 2038 on 32-bit hardware</strong> the other limit applies; in practice none of that gear should still be your firewall.</li>
</ul>
<p>References: <a href="https://docs.netgate.com/pfsense/en/latest/certificates/crl.html">Certificate Revocation List Management</a> in the Netgate documentation and <a href="https://blog.pasqualefiorillo.it/how-to-fix-crl-has-expired-openvpn-error-on-pfsense/">Pasquale Fiorillo&rsquo;s write-up</a>.</p>
]]></content:encoded></item></channel></rss>