1<!DOCTYPE html> 2<html class="theme-dark" lang="en"> 3 4<head> 5 <meta charset="utf-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <title>step-ca Certificate Revocation</title> 8 <link rel="stylesheet" href="/assets/built/screen.css?v=fbe86d181e"> 9 10 <link rel="canonical" href="https://www.networktechguy.com/step-ca-certificate-revocation/"> 11 <meta name="referrer" content="no-referrer-when-downgrade"> 12 13 <meta property="og:site_name" content="NetworkTechGuy.com"> 14 <meta property="og:type" content="article"> 15 <meta property="og:title" content="step-ca Certificate Revocation"> 16 <meta property="og:description" content="In previous posts we successfully deployed our own PKI with step-ca and even configured traefik to use ACME protocol to request certificates from our PKI server. Now we are going to add an additional feature to our PKI, which is active certificate revocation. 17 18Smallstepâs step-ca as CA with ACME"> 19 <meta property="og:url" content="https://www.networktechguy.com/step-ca-certificate-revocation/"> 20 <meta property="og:image" content="https://www.networktechguy.com/content/images/2024/09/smallstep-2.png"> 21 <meta property="article:published_time" content="2024-09-29T22:57:39.000Z"> 22 <meta property="article:modified_time" content="2024-09-29T22:57:39.000Z"> 23 <meta property="article:tag" content="smallstep"> 24 <meta property="article:tag" content="step"> 25 <meta property="article:tag" content="step-ca"> 26 <meta property="article:tag" content="pki"> 27 28 <meta property="article:publisher" content="https://www.facebook.com/ghost"> 29 <meta name="twitter:card" content="summary_large_image"> 30 <meta name="twitter:title" content="step-ca Certificate Revocation"> 31 <meta name="twitter:description" content="In previous posts we successfully deployed our own PKI with step-ca and even configured traefik to use ACME protocol to request certificates from our PKI server. Now we are going to add an additional feature to our PKI, which is active certificate revocation. 32 33Smallstepâs step-ca as CA with ACME"> 34 <meta name="twitter:url" content="https://www.networktechguy.com/step-ca-certificate-revocation/"> 35 <meta name="twitter:image" content="https://www.networktechguy.com/content/images/2024/09/smallstep-2.png"> 36 <meta name="twitter:label1" content="Written by"> 37 <meta name="twitter:data1" content="Nenad Karlovcec"> 38 <meta name="twitter:label2" content="Filed under"> 39 <meta name="twitter:data2" content="smallstep, step, step-ca, pki"> 40 <meta name="twitter:site" content="@ghost"> 41 <meta name="twitter:creator" content="@xnex"> 42 <meta property="og:image:width" content="311"> 43 <meta property="og:image:height" content="162"> 44 45
45<script type="application/ld+json"> 46{ 47 "@context": "https://schema.org", 48 "@type": "Article", 49 "publisher": { 50 "@type": "Organization", 51 "name": "NetworkTechGuy.com", 52 "url": "https://www.networktechguy.com/", 53 "logo": { 54 "@type": "ImageObject", 55 "url": "https://www.networktechguy.com/favicon.ico", 56 "width": 48, 57 "height": 48 58 } 59 }, 60 "author": { 61 "@type": "Person", 62 "name": "Nenad Karlovcec", 63 "image": { 64 "@type": "ImageObject", 65 "url": "https://www.networktechguy.com/content/images/2022/06/profilna.jpg", 66 "width": 960, 67 "height": 960 68 }, 69 "url": "https://www.networktechguy.com/author/nex/", 70 "sameAs": [ 71 "https://www.karlovcec.net", 72 "https://twitter.com/xnex" 73 ] 74 }, 75 "headline": "step-ca Certificate Revocation", 76 "url": "https://www.networktechguy.com/step-ca-certificate-revocation/", 77 "datePublished": "2024-09-29T22:57:39.000Z", 78 "dateModified": "2024-09-29T22:57:39.000Z", 79 "image": { 80 "@type": "ImageObject", 81 "url": "https://www.networktechguy.com/content/images/2024/09/smallstep-2.png", 82 "width": 311, 83 "height": 162 84 },
85 "keywords": "smallstep, step, step-ca, pki", 86 "description": "In previous posts we successfully deployed our own PKI with step-ca and even configured traefik to use ACME protocol to request certificates from our PKI server. Now we are going to add an additional feature to our PKI, which is active certificate revocation.\n\nSmallstepâs step-ca as CA with ACME supportIn this blog post, we will go through the basic installation process and install both the step-ca and step-cli tool that will help us manage our CA and certificates issued by the CA.NetworkTechGuy", 87 "mainEntityOfPage": "https://www.networktechguy.com/step-ca-certificate-revocation/" 88} 89 </script>
89 90 91 <meta name="generator" content="Ghost 5.109"> 92 <link rel="alternate" type="application/rss+xml" title="NetworkTechGuy.com" href="https://www.networktechguy.com/rss/"> 93
93<script defer src="https://cdn.jsdelivr.net/ghost/portal@~2.49/umd/portal.min.js" data-i18n="true" data-ghost="https://www.networktechguy.com/" data-key="53622933082ad9942fbcd6911f" data-api="https://www.networktechguy.com/ghost/api/content/" data-locale="en" crossorigin="anonymous"></script>
93<style id="gh-members-styles">.gh-post-upgrade-cta-content, 94.gh-post-upgrade-cta { 95 display: flex; 96 flex-direction: column; 97 align-items: center; 98 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 99 text-align: center; 100 width: 100%; 101 color: #ffffff; 102 font-size: 16px; 103} 104 105.gh-post-upgrade-cta-content { 106 border-radius: 8px; 107 padding: 40px 4vw; 108} 109 110.gh-post-upgrade-cta h2 { 111 color: #ffffff; 112 font-size: 28px; 113 letter-spacing: -0.2px; 114 margin: 0; 115 padding: 0; 116} 117 118.gh-post-upgrade-cta p { 119 margin: 20px 0 0; 120 padding: 0; 121} 122 123.gh-post-upgrade-cta small { 124 font-size: 16px; 125 letter-spacing: -0.2px; 126} 127 128.gh-post-upgrade-cta a { 129 color: #ffffff; 130 cursor: pointer; 131 font-weight: 500; 132 box-shadow: none; 133 text-decoration: underline; 134} 135 136.gh-post-upgrade-cta a:hover { 137 color: #ffffff; 138 opacity: 0.8; 139 box-shadow: none; 140 text-decoration: underline; 141} 142 143.gh-post-upgrade-cta a.gh-btn { 144 display: block; 145 background: #ffffff; 146 text-decoration: none; 147 margin: 28px 0 0; 148 padding: 8px 18px; 149 border-radius: 4px; 150 font-size: 16px; 151 font-weight: 600; 152} 153 154.gh-post-upgrade-cta a.gh-btn:hover { 155 opacity: 0.92; 156}</style> 157
157<script defer src="https://cdn.jsdelivr.net/ghost/sodo-search@~1.5/umd/sodo-search.min.js" data-key="53622933082ad9942fbcd6911f" data-styles="https://cdn.jsdelivr.net/ghost/sodo-search@~1.5/umd/main.css" data-sodo-search="https://www.networktechguy.com/" data-locale="en" crossorigin="anonymous"></script>
157 158 159 <link href="https://www.networktechguy.com/webmentions/receive/" rel="webmention"> 160
160<script defer src="/public/cards.min.js?v=fbe86d181e"></script>
160 161 <link rel="stylesheet" type="text/css" href="/public/cards.min.css?v=fbe86d181e"> 162
162<script defer src="/public/comment-counts.min.js?v=fbe86d181e" data-ghost-comments-counts-api="https://www.networktechguy.com/members/api/comments/counts/"></script>
162 163
163<script defer src="/public/member-attribution.min.js?v=fbe86d181e"></script>
163<style>:root {--ghost-accent-color: #3daa9b;}</style> 164 <link 165 rel="stylesheet" 166 href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.2/styles/default.min.css" 167 integrity="sha256-48w2xk74a+0hWSZT2qyC/X5MNkwyyDRDNqoT99v1LJA=" 168 crossorigin="anonymous" 169/> 170 171<style> 172 .u-object-fit { 173 object-fit: contain!important; 174 width: 100%; 175 height: auto; 176 max-height: 100%; 177 display: block; 178 margin: auto; 179 position: absolute; 180 top: 50%; 181 transform: translateY(-50%); 182 } 183 184 .single-media { 185 position: relative; 186 } 187</style> 188 189<style> 190.kg-card.kg-bookmark-card, 191.kg-card.kg-bookmark-card .kg-bookmark-container { 192 background-color: #282c35 !important; 193 color: #ffffff; 194 transition: background-color 0.3s, color 0.3s; /* Add transition for smoother effect */ 195} 196 197.kg-card.kg-bookmark-card .kg-bookmark-title, 198.kg-card.kg-bookmark-card .kg-bookmark-description, 199.kg-card.kg-bookmark-card .kg-bookmark-metadata .kg-bookmark-author { 200 color: #ffffff; /* Set the initial color for title and description text */ 201} 202 203.kg-card.kg-bookmark-card .kg-bookmark-container:hover { 204 background-color: #ffffff !important; /* Change background color on hover */ 205 color: #000000 !important; /* Change text color on hover */ 206} 207 208.kg-card.kg-bookmark-card .kg-bookmark-container:hover .kg-bookmark-title, 209.kg-card.kg-bookmark-card .kg-bookmark-container:hover .kg-bookmark-description, 210.kg-card.kg-bookmark-card .kg-bookmark-container:hover .kg-bookmark-metadata .kg-bookmark-author { 211 color: #000000 !important; /* Change text color on hover */ 212} 213</style> 214<!-- Matomo -->
215<script> 216 var _paq = window._paq = window._paq || []; 217 /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ 218 _paq.push(['trackPageView']); 219 _paq.push(['enableLinkTracking']); 220 (function() { 221 var u="//analytics.karlonet.com/"; 222 _paq.push(['setTrackerUrl', u+'matomo.php']); 223 _paq.push(['setSiteId', '2']); 224 var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; 225 g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); 226 })(); 227</script>
227 228<!-- End Matomo Code --> 229</head> 230 231<body class='post-template tag-smallstep tag-step tag-step-ca tag-pki is-head-left-logo'> 232<div class="site"> 233 234 <header id="gh-head" class="gh-head gh-outer"> 235 <div class="gh-head-inner gh-inner"> 236 <div class="gh-head-brand"> 237 <div class="gh-head-brand-wrapper"> 238 <a class="gh-head-logo" href="https://www.networktechguy.com"> 239 NetworkTechGuy.com 240 </a> 241 </div> 242 <button class="gh-search gh-icon-btn" aria-label="Search this site" data-ghost-search><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" width="20" height="20"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg></button> 243 <button class="gh-burger"></button> 244 </div> 245 246 <nav class="gh-head-menu"> 247 <ul class="nav"> 248 <li class="nav-home"><a href="https://www.networktechguy.com/">Home</a></li> 249 <li class="nav-about"><a href="https://www.networktechguy.com/about/">About</a></li> 250</ul> 251 252 </nav> 253 254 <div class="gh-head-actions"> 255 <button class="gh-search gh-icon-btn" aria-label="Search this site" data-ghost-search><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" width="20" height="20"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg></button> 256 <div class="gh-head-members"> 257 <a class="gh-head-link" href="#/portal/signin" data-portal="signin">Sign in</a> 258 <a class="gh-head-btn gh-btn gh-primary-btn" href="#/portal/signup" data-portal="signup">Subscribe</a> 259 </div> 260 </div> 261 </div> 262 </header> 263 264 265 <div class="site-content"> 266 267<main class="site-main"> 268 269 <article class="single post tag-smallstep tag-step tag-step-ca tag-pki featured"> 270 271 <header class="single-header gh-canvas"> 272 <div class="single-meta"> 273 <span class="single-meta-item single-meta-date"> 274 <time datetime="2024-09-29"> 275 Sep 29, 2024 276 </time> 277 </span> 278 <span class="single-meta-item single-meta-length"> 279 10 min read 280 </span> 281 <span class="single-meta-item single-meta-tag"> 282 <a class="post-tag post-tag-smallstep" href="/tag/smallstep/"> 283 smallstep 284 </a> 285 </span> 286 </div> 287 288 <h1 class="single-title">step-ca Certificate Revocation</h1> 289 290 291 </header> 292 293 <div class="single-content gh-content gh-canvas"> 294 <p>In previous posts we successfully deployed our own PKI with <code>step-ca</code> and even configured <code>traefik</code> to use ACME protocol to request certificates from our PKI server. Now we are going to add an additional feature to our PKI, which is active certificate revocation. </p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://www.networktechguy.com/smallsteps-step-ca-as-ca-with-acme-support/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Smallstepâs step-ca as CA with ACME support</div><div class="kg-bookmark-description">In this blog post, we will go through the basic installation process and install both the step-ca and step-cli tool that will help us manage our CA and certificates issued by the CA.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.networktechguy.com/favicon.ico" alt=""><span class="kg-bookmark-author">NetworkTechGuy.com</span><span class="kg-bookmark-publisher">Nenad Karlovcec</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://www.networktechguy.com/content/images/2024/09/smallstep-1.png" alt=""></div></a></figure><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://www.networktechguy.com/using-traefik-with-local-ca-with-acme-support/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Using traefik with local CA with ACME support</div><div class="kg-bookmark-description">How to use custom PKI through ACME calls with traefik.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.networktechguy.com/favicon.ico" alt=""><span class="kg-bookmark-author">NetworkTechGuy.com</span><span class="kg-bookmark-publisher">Nenad Karlovcec</span></div></div>
294<div class="kg-bookmark-thumbnail"><img src="https://www.networktechguy.com/content/images/2024/09/logo-traefik-proxy-logo.svg" alt=""></div></a></figure><p>Please keep in mind that active revocation via CRLs (Certificate Revocation Lists) is not a perfect solution to certificate revocation - ideally, you would be issuing short-lived certificates that you will just let expire. Another issue is that it heavily relies on browsers to do the work, and since they use different methods to check validity of a certificate, results may vary. Once expired, certificate can no longer be used for authentication. Additionally, you can set the certificate to be revoked via <code>step-ca</code> and, once revoked, it cannot be renewed. </p><p>For that reason, <a href="https://smallstep.com/?ref=networktechguy.com" rel="noreferrer"><em>Smallstep</em></a> actually recommends passive revocation through short-lived certificates. However, sometimes your services will require certificates that have CRLs included in them - one recent example for me was when I tried installing a new certificate for a test Exchange server. There was simply no way to get it to work (or I couldn't figure out how to do it) without having the extra extension in the certificate (<em>X509v3 CRL Distribution Points</em>). And so I went researching on how to get the CRL working with my <code>step-ca</code> installation. Luckily, with the version of <code>step-ca</code> I'm running, you are able to enable a minimal <em>Certificate Revocation List</em> server. I don't know if this is a new thing or something, as on some other parts of their documentation, they specifically state that they don't support active revocation, but I'm not going to complain about that ð.</p><p>So let's take a look at what needs to be done. There are actually a few steps:</p><ul><li>modify your existing <code>step-ca</code> server's <code>ca.json</code> file to enable insecure port and URL for the CRL</li><li>create a new template for your <em>intermediate</em> <em>CA</em> that is used for signing all your certificates; once that is completed, you will generate a new <em>intermediate CA</em> and its accompanying key</li><li>you will also want to create a <em>leaf</em> template for all your new certificates to include the <em>CRL</em> as well</li><li>finally, you will want to modify your <code>ca.json</code> file again to include the new leaf template when issuing certificates</li></ul><h2 id="modify-ca-server-configuration">Modify CA server configuration</h2><p>Let's start with modifying our <em>CA</em> server configuration. There's a few things that need to be added at the start:</p><pre><code class="language-bash"> "insecureAddress": ":80", 295 "crl": { 296 "enabled": true, 297 "cacheDuration": "8h0m0s", 298 "idpURL": "http://ca.demo.networktechguy.com/1.0/crl" 299 },</code></pre><p>Looking from the beginning of the file, it should be fit something like this:</p><pre><code class="language-bash">$ cat config/ca.json 300 301{ 302 "root": "/etc/step-ca/certs/root_ca.crt", 303 "federatedRoots": null, 304 "crt": "/etc/step-ca/certs/intermediate_ca.crt", 305 "key": "/etc/step-ca/secrets/intermediate_ca_key", 306 "address": ":443", 307 "insecureAddress": ":80", 308 "commonName": "NetworkTechGuy.com Demo CA", 309 "crl": { 310 "enabled": true, 311 "cacheDuration": "8h0m0s", 312 "idpURL": "http://ca.demo.networktechguy.com/1.0/crl" 313 }, 314 "dnsNames": [ 315 "ca.demo.networktechguy.com", 316 "10.75.1.10" 317 ], 318 319---OUTPUT OMITTED---</code></pre><p>At this point I would restart the service as it is easier to troubleshoot potential problems while we are just beginning with the process:</p><pre><code class="language-bash">sudo systemctl restart step-ca 320sudo systemctl status step-ca 321</code></pre><p>If you get something like this for status:</p><pre><code class="language-bash"> Active: active (running) since Sun 2024-09-29 14:39:29 EDT; 1s ago</code></pre><p>It means that the service has been successfully restarted. If not, check the logs with <code>journalctl</code>:</p><pre><code class="language-bash">
321sudo journalctl -u step-ca</code></pre><h2 id="create-new-intermediate-ca-template-file">Create new intermediate CA template file</h2><p>New template file will be <code>intermediate.tpl</code> and we can place it in the <code>/etc/step-ca/templates</code> directory. Content should be something like this:</p><pre><code class="language-json">{ 322 "subject": {{ toJson .Subject }}, 323 "keyUsage": ["certSign", "crlSign"], 324 "basicConstraints": { 325 "isCA": true, 326 "maxPathLen": 0 327 }, 328 "crlDistributionPoints": ["http://ca.demo.networktechguy.com/1.0/crl"] 329}</code></pre><p>We can now generate new <em>intermediate CA</em>:</p><pre><code class="language-bash">step certificate create \ 330 --template /etc/step-ca/templates/intermediate.tpl \ 331 --ca $(step path)/certs/root_ca.crt \ 332 --ca-key $(step path)/secrets/root_ca_key \ 333 --not-after 87660h \ 334 "NetworkTechGuy.com CA Intermediate CA" \ 335 $(step path)/certs/intermediate_ca.crt \ 336 $(step path)/secrets/intermediate_ca_key</code></pre><p>Please note that, for this command to work, you need to have completed the setup of the server as explained <a href="https://www.networktechguy.com/smallsteps-step-ca-as-ca-with-acme-support/" rel="noreferrer">here</a>, otherwise use full path (<code>/etc/step-ca/</code>) instead of variables (<code>$(step path)/</code>).</p><p>The whole process should look something like this:</p><pre><code class="language-bash">$ sudo step certificate create \ 337--template /etc/step-ca/templates/intermediate.tpl \ 338--ca $(step path)/certs/root_ca.crt \ 339--ca-key $(step path)/secrets/root_ca_key \ 340--not-after 87660h \ 341"NetworkTechGuy.com CA Intermediate CA" \ 342$(step path)/certs/intermediate_ca.crt \ 343$(step path)/secrets/intermediate_ca_key 344 345Please enter the password to decrypt /etc/step-ca/secrets/root_ca_key: �������� 346Please enter the password to encrypt the private key: �������� 347â Would you like to overwrite /etc/step-ca/secrets/intermediate_ca_key [y/n]: y 348â Would you like to overwrite /etc/step-ca/certs/intermediate_ca.crt [y/n]: y 349Your certificate has been saved in /etc/step-ca/certs/intermediate_ca.crt. 350Your private key has been saved in /etc/step-ca/secrets/intermediate_ca_key.</code></pre><p>As you can see, you will be asked to overwrite the existing <em>intermediate</em> cert and key. Since all of your certificates are authenticated against the <code>root</code> CA, and we are not changing that, feel free to do so.</p><p>If we inspect the newly created certificate, we can see that it now includes the needed extension:</p><pre><code class="language-bash">$ step certificate inspect /etc/step-ca/certs/intermediate_ca.crt 351 352Certificate: 353---OUTPUT OMITTED--- 354 X509v3 CRL Distribution Points: 355 Full Name: 356 URI:http://ca.demo.networktechguy.com/1.0/crl 357---OUTPUT OMITTED---</code></pre><p>Next, we will restart the service and check the status:</p><pre><code class="language-bash">$ sudo systemctl restart step-ca 358$ sudo systemctl status step-ca 359 360â step-ca.service - step-ca service 361 Loaded: loaded (/etc/systemd/system/step-ca.service; enabled; preset: enabled) 362 Active: active (running) since Sun 2024-09-29 14:36:05 EDT; 16s ago 363 Docs: https://smallstep.com/docs/step-ca 364 https://smallstep.com/docs/step-ca/certificate-authority-server-production 365 Main PID: 3086 (step-ca) 366 Tasks: 9 (limit: 4643) 367 Memory: 17.3M 368 CPU: 156ms 369 CGroup: /system.slice/step-ca.service 370 ââ3086 /usr/bin/step-ca config/ca.json --password-file password.txt 371 372Sep 29 14:36:05 deb-step-01 systemd[1]: Started step-ca.service - step-ca service.</code></pre><h2 id="creating-a-leaf-template">Creating a leaf template</h2><p>Next, let's create a <em>leaf</em> template. The content should look something like this:</p><pre><code class="language-json">{ 373 "subject": {{ toJson .Subject }}, 374 "sans": {{ toJson .SANs }}, 375 {{- if typeIs "*rsa.PublicKey" .Insecure.CR.PublicKey }} 376 "keyUsage": ["keyEncipherment", "digitalSignature"], 377 {{- else }} 378 "keyUsage": ["digitalSignature"], 379 {{- end }} 380 "extKeyUsage": ["serverAuth", "clientAuth"], 381 "crlDistributionPoints": ["http://ca.demo.networktechguy.com/1.0/crl"] 382}</code></pre><p>I've placed in a newly created <em>subdirectory</em> (<code>x509</code>) of the <em>templates</em> <em>directory</em>, so the full path of the file is <code>/etc/step-ca/templates/x509/leaf.tpl</code>. </p><h2 id="modify-provisioners-to-use-new-template-file">Modify provisioners to use new template file</h2><p>There are two ways to do it - one way is to do it via <code>step ca provisioner</code> command, like this:</p><pre><code class="language-bash">step ca provisioner update NTG --x509-template /etc/step-ca/templates/x509/leaf.tpl</code></pre><p>Please keep in mind that if you want <em>ACME</em> certificates to use the new template file, you have to do it for that <em>provisioner</em> as well:</p><pre><code class="language-bash">step ca provisioner update acme --x509-template /etc/step-ca/templates/x509/leaf.tpl</code></pre><p>Now, with that said, this will modify your <code>ca.json</code> file and add whatever was in the <code>leaf.tpl</code> file into the <code>ca.json</code> file, in-line:</p><pre><code class="language-json"> { 383 "type": "JWK", 384 "name": "NTG", 385 "key": { 386 "use": "sig", 387 "kty": "EC", 388 "kid": "---OUTPUT OMITTED---", 389 "crv": "P-256", 390 "alg": "ES256", 391 "x": "---OUTPUT OMITTED---", 392 "y": "---OUTPUT OMITTED---" 393 }, 394 "encryptedKey": "---OUTPUT OMITTED---", 395 "claims": { 396 "minTLSCertDuration": "5m0s", 397 "maxTLSCertDuration": "43830h0m0s", 398 "defaultTLSCertDuration": "17532h0m0s", 399 "enableSSHCA": true, 400 "disableRenewal": false, 401 "allowRenewalAfterExpiry": false, 402 "disableSmallstepExtensions": false 403 }, 404 "options": { 405 "x509": { 406 "template": "{\n \"subject\": {{ toJson .Subject }},\n \"sans\": {{ toJson .SANs }},\n {{- if typeIs \"*rsa.PublicKey\" .Insecure.CR.PublicKey }}
406\n \"keyUsage\": [\"keyEncipherment\", \"digitalSignature\"],\n {{- else }}\n \"keyUsage\": [\"digitalSignature\"],\n {{- end }}\n \"extKeyUsage\": [\"serverAuth\", \"clientAuth\"],\n \"crlDistributionPoints\": [\"http://ca.demo.networktechguy.com/1.0/crl\"]\n}\n" 407 }, 408 "ssh": {} 409 } 410 }</code></pre><p>I don't like that, so after I did it via these commands, I modified the file to look like this instead:</p><pre><code class="language-json"> { 411 "type": "JWK", 412 "name": "NTG", 413 "key": { 414 "use": "sig", 415 "kty": "EC", 416 "kid": "---OUTPUT OMITTED---", 417 "crv": "P-256", 418 "alg": "ES256", 419 "x": "---OUTPUT OMITTED---", 420 "y": "---OUTPUT OMITTED---" 421 }, 422 "encryptedKey": "---OUTPUT OMITTED---", 423 "claims": { 424 "minTLSCertDuration": "5m0s", 425 "maxTLSCertDuration": "43830h0m0s", 426 "defaultTLSCertDuration": "17532h0m0s", 427 "enableSSHCA": true, 428 "disableRenewal": false, 429 "allowRenewalAfterExpiry": false, 430 "disableSmallstepExtensions": false 431 }, 432 "options": { 433 "x509": { 434 "templateFile": "/etc/step-ca/templates/x509/leaf.tpl" 435 }, 436 "ssh": {} 437 } 438 },</code></pre><p>This is an output for <em>JWK</em> <em>provisioner</em> only, if you added the new <em>leaf</em> template to <em>ACME</em> <em>provisioner</em>, you will have to fix it there as well.</p><p>For this to work, make sure that your template file has correct ownership and permissions:</p><pre><code class="language-bash">$ ls -alh /etc/step-ca/templates/x509/leaf.tpl 439 440-rw-r--r-- 1 step step 367 Sep 29 13:39 templates/x509/leaf.tpl</code></pre><p>Finally, restart the service and check the status:</p><pre><code class="language-bash">sudo systemctl restart step-ca 441sudo systemctl status step-ca</code></pre><p>If everything is working after all these changes, you can check the status of your <em>CRL</em> server - I'm doing this now on the workstation, as all the changes on the server are complete:</p><pre><code class="language-bash">$ step crl inspect http://ca.demo.networktechguy.com/1.0/crl --insecure</code></pre><p>Results should be something like this:</p><pre><code class="language-bash">$ step crl inspect http://ca.demo.networktechguy.com/1.0/crl --insecure 442 443Certificate Revocation List (CRL): 444 Data: 445 Valid: false 446 Version: 17 (0x11) 447 Signature algorithm: ECDSA-SHA256 448 Issuer: 449 Last Update: 2024-09-29 20:57:38 +0000 UTC 450 Next Update: 2024-09-30 04:57:38 +0000 UTC 451 CRL Extensions: 452 X509v3 Authority Key Identifier: 453 keyid:1B:20:FA:72:A8:A4:26:10:D9:B2:8D:AC:29:88:DB:13:B9:1D:7E:7F 454 X509v3 CRL Number: 455 17 456 X509v3 Issuing Distribution Point: critical 457 Full Name: 458 URI:http://ca.demo.networktechguy.com/1.0/crl 459 Only User Certificates 460 Revoked Certificates: 461 Serial Number: 14901852086807387906094692013751768567 (0x0B35FE086D3BF2E8D33BB60BED8595F7) 462 Revocation Date: 2024-09-29 19:59:04 +0000 UTC
463 Serial Number: 165745321111098419965161888279534387093 (0x7CB16340C3FCA91B5F07181E28C63F95) 464 Revocation Date: 2024-09-29 19:45:44 +0000 UTC 465 Serial Number: 265544075792166084197075778072633340760 (0xC7C5EDC016778C94A2B743E32F86F358) 466 Revocation Date: 2024-09-29 18:56:15 +0000 UTC 467 Serial Number: 287599246715617662997638596379242195474 (0xD85D99A1ADEDF37E0FDDB0A31EC8EA12) 468 Revocation Date: 2024-09-29 19:32:29 +0000 UTC 469 Signature Algorithm: ECDSA-SHA256 470 30:45:02:20:0b:c8:a8:4a:8a:0e:08:5d:83:cb:54:d9: 471 15:7a:c7:4d:24:17:f6:62:18:36:5b:d7:55:e0:b8:75: 472 83:8f:3e:e1:02:21:00:99:7c:06:0d:95:7b:2f:ba:d2: 473 31:63:71:b1:88:75:89:67:a1:24:ed:4e:5a:e3:6c:b1: 474 d7:a0:3c:d2:b3:b4:66</code></pre><p>You will notice that I already have a few revoked certificates in my list. Also, notice that updates are done in 8-hour intervals, as configured here:</p><pre><code class="language-bash"> "cacheDuration": "8h0m0s",</code></pre><p>If you don't want to wait this long, you can always change the value to something that fits your needs better. Also, when you issue a <em>service restart</em> command, it will also clear the <em>cache</em>.</p><p>So let's try and create a new certificate with this new setup. One thing to note is that I changed the minimum <em>TLS</em> certificate duration parameter from the time I posted previous article, so it is now set to 5 minutes:</p><pre><code class="language-json"> "minTLSCertDuration": "5m0s",</code></pre><p>New certificate request:</p><pre><code class="language-bash">$ step ca certificate test-06.demo.networktechguy.com test-06.demo.networktechguy.com.crt test-06.demo.networktechguy.com.key --not-after=60m 475 476â Provisioner: NTG (JWK) [kid: 6zkvMKLGZxf0qa4n-cleOyn2seI04fweoAuOjBlcr4A] 477Please enter the password to decrypt the provisioner key: �������� 478â CA: https://ca.demo.networktechguy.com 479â Certificate: test-06.demo.networktechguy.com.crt 480â Private Key: test-06.demo.networktechguy.com.key</code></pre><p>Let's inspect the new certificate:</p><pre><code class="language-bash">step certificate inspect test-06.demo.networktechguy.com.crt 481Certificate: 482---OUTPUT OMITTED--- 483 Issuer: CN=NetworkTechGuy.com CA Intermediate CA 484 Validity 485 Not Before: Sep 29 21:40:32 2024 UTC 486 Not After : Sep 29 22:41:32 2024 UTC 487 Subject: CN=test-06.demo.networktechguy.com 488---OUTPUT OMITTED--- 489 X509v3 Subject Alternative Name: 490 DNS:test-06.demo.networktechguy.com 491 X509v3 CRL Distribution Points: 492 Full Name: 493 URI:http://ca.demo.networktechguy.com/1.0/crl 494---OUTPUT OMITTED---</code></pre><p>What we can see from the output is that the new certificate has a one hour validity and that the <em>CRL</em> distribution point is included in the extensions. From this point on, any service that requires <em>CRL</em> extension to be included in the certificate, should be happy!</p><p>As for the revocation, it's quite easy to do. When you inspect the certificate, you will notice that there is a serial number of the certificate at the beginning:</p><pre><code class="language-bash">$ step certificate inspect test-06.demo.networktechguy.com.crt 495 496Certificate: 497 Data: 498 Version: 3 (0x2) 499 Serial Number: 65623237680889282882253127865884846522 (0x315e936ae33eec9d05dca6a17c99a9ba)</code></pre><p>We will use this serial number to revoke the certificate:</p><pre><code class="language-bash">$ step ca revoke 65623237680889282882253127865884846522 --reason="No longer needed" 500 501â Provisioner: NTG (JWK) [kid: 6zkvMKLGZxf0qa4n-cleOyn2seI04fweoAuOjBlcr4A] 502Please enter the password to decrypt the provisioner key: �������� 503â CA: https://ca.demo.networktechguy.com 504Certificate with Serial Number 65623237680889282882253127865884846522 has been revoked.</code></pre><p>If we were to check the status of the <em>CRL</em> right now, it would not reflect the change as it's reading the list from the cache:</p><pre><code class="language-bash">$ step crl inspect http://ca.demo.networktechguy.com/1.0/crl --insecure 505---OUTPUT OMITTED--- 506 Revoked Certificates:
507 Serial Number: 14901852086807387906094692013751768567 (0x0B35FE086D3BF2E8D33BB60BED8595F7) 508 Revocation Date: 2024-09-29 19:59:04 +0000 UTC 509 Serial Number: 165745321111098419965161888279534387093 (0x7CB16340C3FCA91B5F07181E28C63F95) 510 Revocation Date: 2024-09-29 19:45:44 +0000 UTC 511 Serial Number: 265544075792166084197075778072633340760 (0xC7C5EDC016778C94A2B743E32F86F358) 512 Revocation Date: 2024-09-29 18:56:15 +0000 UTC 513 Serial Number: 287599246715617662997638596379242195474 (0xD85D99A1ADEDF37E0FDDB0A31EC8EA12) 514 Revocation Date: 2024-09-29 19:32:29 +0000 UTC</code></pre><p>As you can see, our certificate is not on the list of revoked certificates (yet). To manually refresh the <em>CRL</em>, restart the service on the server and then try again:</p><pre><code class="language-bash">step crl inspect http://ca.demo.networktechguy.com/1.0/crl --insecure 515---OUTPUT OMITTED--- 516 Serial Number: 65623237680889282882253127865884846522 (0x315E936AE33EEC9D05DCA6A17C99A9BA) 517 Revocation Date: 2024-09-29 21:50:41 +0000 UTC 518---OUTPUT OMITTED---</code></pre><p>As you can see, this certificate is now successfully revoked and any service that utilises CRLs will see that it's been revoked.</p><h2 id="conclusion">Conclusion</h2><p>Unfortunately, status of browser <em>CRL</em> checks is not that great at the moment. Even though certificate has been revoked, and it is so stated in the inspection, I have yet to figure out how to get my browsers to actually check the <em>CRL</em> stated in the certificate itself. That's why consider this blog post a half-done - if a <strong>service</strong> requires a <em>CRL</em> extension to be present in the certificate - this will do. If <strong>you</strong> require <em>CRL</em> checks to be performed against issued certificates, this does not (yet) work. I will continue looking into this to see how (and <strong>if</strong>) I can make it work, but for now, consider passive revocation - issue personal certificates with validity that you are comfortable with. If you want someone to temporarily access your service, issue them a certificate with validity of one day for example and that will work without an issue. Hopefully there's a solution for this that I'm just not aware of.</p> 519 </div> 520 521 <div class="gh-canvas"> 522 <footer class="single-footer"> 523 524 <div class="single-footer-left"> 525 <div class="navigation navigation-previous"> 526 <a class="navigation-link" href="/traefik-with-mtls/" aria-label="Previous post"> 527 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon navigation-icon"> 528 <path d="M26.667 14.667v2.667h-16L18 24.667l-1.893 1.893L5.547 16l10.56-10.56L18 7.333l-7.333 7.333h16z"></path> 529</svg> </a> 530 </div> 531 </div> 532 533 <div class="single-footer-middle"> 534 <div class="single-footer-top"> 535 <h3 class="single-footer-title">Published by:</h3> 536 <div class="author-list"> 537 <div class="author-image-placeholder u-placeholder square"> 538 <a href="/author/nex/" title="Nenad Karlovcec"> 539 <img class="author-image u-object-fit" src="/content/images/size/w150/2022/06/profilna.jpg" alt="Nenad Karlovcec" loading="lazy"> 540 </a> 541 </div> 542 </div> 543 </div> 544 </div> 545 546 <div class="single-footer-right"> 547 <div class="navigation navigation-next"> 548 <a class="navigation-link" href="/proxmox-changing-windows-10-bios-from-seabios-to-ovmf-uefi/" aria-label="Next post"> 549 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon navigation-icon"> 550 <path d="M5.333 14.667v2.667h16L14 24.667l1.893 1.893L26.453 16 15.893 5.44 14 7.333l7.333 7.333h-16z"></path> 551</svg> </a> 552 </div> 553 </div> 554 555 </footer> 556 </div> 557 558</article> 559 <section class="related-wrapper gh-canvas"> 560 <h3 class="related-title">You might also like...</h3> 561 <div class="related-feed"> 562 <article class="feed public post featured"> 563 564 <div class="feed-calendar"> 565 <div class="feed-calendar-month"> 566 Sep 567 </div> 568 <div class="feed-calendar-day"> 569 28 570 </div> 571 </div> 572 573 <h2 class="feed-title">Traefik with mTLS</h2> 574 575 <div class="feed-right"> 576 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon icon-star"> 577 <path d="M16 23.027L24.24 28l-2.187-9.373 7.28-6.307-9.587-.827-3.747-8.827-3.747 8.827-9.587.827 7.267 6.307L7.759 28l8.24-4.973z"></path> 578</svg> <div class="feed-length"> 579 11 min read 580 </div> 581 </div> 582 583 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon feed-icon"> 584 <path d="M11.453 22.107L17.56 16l-6.107-6.12L13.333 8l8 8-8 8-1.88-1.893z"></path> 585</svg> 586 <a class="u-permalink" href="/traefik-with-mtls/" aria-label="Traefik with mTLS"></a> 587 588</article> <article class="feed public post featured"> 589 590 <div class="feed-calendar"> 591 <div class="feed-calendar-month"> 592 Sep 593 </div> 594 <div class="feed-calendar-day"> 595 28 596 </div> 597 </div> 598 599 <h2 class="feed-title">Using traefik with local CA with ACME support</h2> 600 601 <div class="feed-right"> 602 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon icon-star"> 603 <path d="M16 23.027L24.24 28l-2.187-9.373 7.28-6.307-9.587-.827-3.747-8.827-3.747 8.827-9.587.827 7.267 6.307L7.759 28l8.24-4.973z"></path> 604</svg> <div class="feed-length"> 605 10 min read 606 </div> 607 </div> 608 609 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon feed-icon"> 610 <path d="M11.453 22.107L17.56 16l-6.107-6.12L13.333 8l8 8-8 8-1.88-1.893z"></path> 611</svg> 612 <a class="u-permalink" href="/using-traefik-with-local-ca-with-acme-support/" aria-label="Using traefik with local CA with ACME support"></a> 613 614</article> <article class="feed public post featured"> 615 616 <div class="feed-calendar"> 617 <div class="feed-calendar-month"> 618 Sep 619 </div> 620 <div class="feed-calendar-day"> 621 28 622 </div> 623 </div> 624 625 <h2 class="feed-title">Smallstep's step-ca as CA with ACME support</h2> 626 627 <div class="feed-right"> 628 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon icon-star"> 629 <path d="M16 23.027L24.24 28l-2.187-9.373 7.28-6.307-9.587-.827-3.747-8.827-3.747 8.827-9.587.827 7.267 6.307L7.759 28l8.24-4.973z"></path> 630</svg> <div class="feed-length"> 631 29 min read 632 </div> 633 </div> 634 635 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon feed-icon"> 636 <path d="M11.453 22.107L17.56 16l-6.107-6.12L13.333 8l8 8-8 8-1.88-1.893z"></path> 637</svg> 638 <a class="u-permalink" href="/smallsteps-step-ca-as-ca-with-acme-support/" aria-label="Smallstep's step-ca as CA with ACME support"></a> 639 640</article> </div> 641 </section> 642 643 <section class="gh-comments gh-canvas"> 644 <header class="gh-comments-header"> 645 <h3 class="gh-comments-title related-title">Member discussion</h3> 646
646<script 647 data-ghost-comment-count="66f9b308104ad400011e7442" 648 data-ghost-comment-count-empty="" 649 data-ghost-comment-count-singular="comment" 650 data-ghost-comment-count-plural="comments" 651 data-ghost-comment-count-tag="span" 652 data-ghost-comment-count-class-name="gh-comments-count" 653 data-ghost-comment-count-autowrap="true" 654> 655</script>
655 656 </header> 657 658
658<script defer src="https://cdn.jsdelivr.net/ghost/comments-ui@~1.0/umd/comments-ui.min.js" data-locale="en" data-ghost-comments="https://www.networktechguy.com/" data-api="https://www.networktechguy.com/ghost/api/content/" data-admin="https://www.networktechguy.com/ghost/" data-key="53622933082ad9942fbcd6911f" data-title="" data-count="false" data-post-id="66f9b308104ad400011e7442" data-color-scheme="auto" data-avatar-saturation="60" data-accent-color="#3daa9b" data-comments-enabled="all" data-publication="NetworkTechGuy.com" crossorigin="anonymous"></script>
658 659 660 </section> 661 662</main> 663 </div> 664 665 <footer class="gh-foot gh-outer"> 666 <div class="gh-foot-inner gh-inner"> 667 <div class="gh-copyright"> 668 NetworkTechGuy.com © 2026 669 </div> 670 <nav class="gh-foot-menu"> 671 <ul class="nav"> 672 <li class="nav-sign-up"><a href="#/portal/">Sign up</a></li> 673</ul> 674 675 </nav> 676 <div class="gh-powered-by"> 677 <a href="https://ghost.org/" target="_blank" rel="noopener">Powered by Ghost</a> 678 </div> 679 </div> 680 </footer> 681 682</div> 683 684 <div class="pswp" tabindex="-1" role="dialog" aria-hidden="true"> 685 <div class="pswp__bg"></div> 686 687 <div class="pswp__scroll-wrap"> 688 <div class="pswp__container"> 689 <div class="pswp__item"></div> 690 <div class="pswp__item"></div> 691 <div class="pswp__item"></div> 692 </div> 693 694 <div class="pswp__ui pswp__ui--hidden"> 695 <div class="pswp__top-bar"> 696 <div class="pswp__counter"></div> 697 698 <button class="pswp__button pswp__button--close" title="Close (Esc)"></button> 699 <button class="pswp__button pswp__button--share" title="Share"></button> 700 <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button> 701 <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button> 702 703 <div class="pswp__preloader"> 704 <div class="pswp__preloader__icn"> 705 <div class="pswp__preloader__cut"> 706 <div class="pswp__preloader__donut"></div> 707 </div> 708 </div> 709 </div> 710 </div> 711 712 <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap"> 713 <div class="pswp__share-tooltip"></div> 714 </div> 715 716 <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)"></button> 717 <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)"></button> 718 719 <div class="pswp__caption"> 720 <div class="pswp__caption__center"></div> 721 </div> 722 </div> 723 </div> 724</div>
725<script 726 src="https://code.jquery.com/jquery-3.5.1.min.js" 727 integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" 728 crossorigin="anonymous"> 729</script>
vendor: 1 bytes, line 729
729
730<script src='/assets/built/main.min.js?v=fbe86d181e'></script>
730 731 732 733
734<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v4bc70e2c01a94c73b74392e4234840661791215815920" integrity="sha512-L0ha0OXavK/8okipN9F8BtP84dg9DUhPERbBXzwI6dgTA55d2+yweo3pn5CSFYs45/r8md2+xvUPtTdvTNRfjA==" data-cf-beacon='{"version":"2024.11.0","token":"58e5ad7d6f7d4cc494aec957319e6801","r":1,"spa":2}' crossorigin="anonymous"></script>
vendor: 1 bytes, line 734
734
735<script>(function(){function c(){var b=a.contentDocument||(a.contentWindow&&a.contentWindow.document);if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'a47247f8e9f3e178',t:'MTc5MTQzMjQ3Mg=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>
735</body> 736</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.