migrates ghost blog to hugo

This commit is contained in:
2023-11-19 22:12:39 -05:00
commit dbd645375f
93 changed files with 5371 additions and 0 deletions
@@ -0,0 +1,223 @@
<!DOCTYPE html>
<html lang="en" dir="auto">
<head><meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="robots" content="noindex, nofollow">
<title>Decrypting a Headless Server on Boot... Remotely | dvdt.dev</title>
<meta name="keywords" content="">
<meta name="description" content="Like the title says, how do you decrypt a headless server at boot time that has it&rsquo;s root partition LUKS encrypted.. while not on site? I&rsquo;ve been running my server for almost two years and I knew this problem would come up eventually so it&rsquo;s been at the back of my mind for a while. And you know it had to come up at the most inopportune time&hellip; 15 minutes before I leave town for a weekend away.">
<meta name="author" content="David Lick">
<link rel="canonical" href="https://new.dvdt.dev/2020/11/decrypting-a-headless-server-on-boot...-remotely/">
<link crossorigin="anonymous" href="/assets/css/stylesheet.5cfc680b1eeaeef9efbced92d46c2a9e876b72ee14fba85846afc4cff9e6e6f8.css" integrity="sha256-XPxoCx7q7vnvvO2S1Gwqnodrcu4U&#43;6hYRq/Ez/nm5vg=" rel="preload stylesheet" as="style">
<script defer crossorigin="anonymous" src="/assets/js/highlight.f413e19d0714851f6474e7ee9632408e58ac146fbdbe62747134bea2fa3415e0.js" integrity="sha256-9BPhnQcUhR9kdOfuljJAjlisFG&#43;9vmJ0cTS&#43;ovo0FeA="
onload="hljs.initHighlightingOnLoad();"></script>
<link rel="icon" href="https://new.dvdt.dev/favicon.ico">
<link rel="icon" type="image/png" sizes="16x16" href="https://new.dvdt.dev/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://new.dvdt.dev/favicon-32x32.png">
<link rel="apple-touch-icon" href="https://new.dvdt.dev/apple-touch-icon.png">
<link rel="mask-icon" href="https://new.dvdt.dev/safari-pinned-tab.svg">
<meta name="theme-color" content="#2e2e33">
<meta name="msapplication-TileColor" content="#2e2e33">
<noscript>
<style>
#theme-toggle,
.top-link {
display: none;
}
</style>
<style>
@media (prefers-color-scheme: dark) {
:root {
--theme: rgb(29, 30, 32);
--entry: rgb(46, 46, 51);
--primary: rgb(218, 218, 219);
--secondary: rgb(155, 156, 157);
--tertiary: rgb(65, 66, 68);
--content: rgb(196, 196, 197);
--hljs-bg: rgb(46, 46, 51);
--code-bg: rgb(55, 56, 62);
--border: rgb(51, 51, 51);
}
.list {
background: var(--theme);
}
.list:not(.dark)::-webkit-scrollbar-track {
background: 0 0;
}
.list:not(.dark)::-webkit-scrollbar-thumb {
border-color: var(--theme);
}
}
</style>
</noscript>
</head>
<body class="" id="top">
<script>
if (localStorage.getItem("pref-theme") === "dark") {
document.body.classList.add('dark');
} else if (localStorage.getItem("pref-theme") === "light") {
document.body.classList.remove('dark')
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.body.classList.add('dark');
}
</script>
<header class="header">
<nav class="nav">
<div class="logo">
<a href="https://new.dvdt.dev/" accesskey="h" title="dvdt.dev (Alt + H)">dvdt.dev</a>
<div class="logo-switches">
<button id="theme-toggle" accesskey="t" title="(Alt + T)">
<svg id="moon" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
</svg>
<svg id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</button>
</div>
</div>
<ul id="menu">
<li>
<a href="https://new.dvdt.dev/about-me/" title="about me">
<span>about me</span>
</a>
</li>
<li>
<a href="https://new.dvdt.dev/support" title="support">
<span>support</span>
</a>
</li>
</ul>
</nav>
</header>
<main class="main">
<article class="post-single">
<header class="post-header">
<h1 class="post-title">
Decrypting a Headless Server on Boot... Remotely
</h1>
<div class="post-meta"><span title='2020-11-21 00:00:00 +0000 UTC'>November 21, 2020</span>&nbsp;·&nbsp;David Lick
</div>
</header>
<div class="post-content"><p><img loading="lazy" src="/img/server-room.jpg" alt="" />
</p>
<p>Like the title says, how do you decrypt a headless server at boot time that has it&rsquo;s root partition LUKS encrypted.. while not on site? I&rsquo;ve been running my server for almost two years and I knew this problem would come up eventually so it&rsquo;s been at the back of my mind for a while. And you know it had to come up at the most inopportune time&hellip; 15 minutes before I leave town for a weekend away. After a weekend without access to my network or any of the services I host I finally started working on solving this.</p>
<p>Quick primer on the typical Linux boot process: when you start your computer it loads a minimal OS called <code>initramfs</code> that knows how to decrypt your root and data partitions and start the boot process. <code>initramfs</code> is configured a few different ways, I&rsquo;m on a RHEL based distro so I used dracut to configure it. Arch based distros use <code>mkinitramfs</code>. Unsure about Ubuntu since I prefer real operating systems ;)</p>
<p>There&rsquo;s really two routes to take to solving this problem: fully automatic (bad security posture) and manual intervention (good security but inconvenient). The automatic path means writing the keys in plain text in the <code>initramfs</code> and the thought of plain text keys makes me full body cringe. It&rsquo;s like having a safe with your combination on a Sticky Note next to the dial: why even have a safe? So I knew I needed to find a way to reach my box remotely during the initial boot process.</p>
<p>Luckily, this was fairly easy to implement. I found a very good Github repo <a href="https://github.com/gsauthof/dracut-sshd">https://github.com/gsauthof/dracut-sshd</a> with full instructions. It does have a couple different options so here&rsquo;s what I did:</p>
<p>I initially tried to go the systemd-networkd path but was not able to get it working. I instead had to add a network module to <code>initramfs</code>:</p>
<pre tabindex="0"><code>~$ echo &#39;add_dracutmodules+=&#34; network &#34;&#39; &gt;&gt; /etc/dracut.conf.d/90-networkd.conf
</code></pre><p>Next you&rsquo;ll want to put your public key in <code>/root/.ssh/authorized_keys</code>. You should generally generate a new public/private keypair for each new user/service:</p>
<pre tabindex="0"><code>~$ ssh-keygen -t ed25519 &amp;&amp; cat ~/.ssh/id_ed25519.pub &gt;&gt; /root/.ssh/authorized_keys
</code></pre><p>Then it was as simple as adding the <code>46sshd</code> folder from the <code>dracut-sshd</code> repo to <code>/usr/lib/dracut/modules.d/</code> and rebuilding <code>initramfs</code>:</p>
<pre tabindex="0"><code>~$ git clone https://github.com/gsauthof/dracut-sshd.git ~/dracut-sshd
~$ mv ~/dracut-sshd/46sshd /usr/lib/dracut/modules.d
~$ dracut -v -f
</code></pre><p>The <code>Permission denied (public key)</code> issue described in the FAQ happened to me. Fixed by:</p>
<pre tabindex="0"><code>~$ usermod -p &#39;*&#39; root
</code></pre><p>That&rsquo;s it! Restart your server and SSH in, run the Systemd ask password agent:</p>
<pre tabindex="0"><code>~$ systemd-tty-ask-password-agent
</code></pre><p>I hope this helps someone. If I would&rsquo;ve known it was this easy I would&rsquo;ve done it two years ago and never worried about how to reach home after the power goes out!</p>
</div>
<footer class="post-footer">
<ul class="post-tags">
</ul>
</footer>
</article>
</main>
<footer class="footer">
<span>&copy; 2023 <a href="https://new.dvdt.dev/">dvdt.dev</a></span>
</footer>
<a href="#top" aria-label="go to top" title="Go to Top (Alt + G)" class="top-link" id="top-link" accesskey="g">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 6" fill="currentColor">
<path d="M12 6H0l6-6z" />
</svg>
</a><footer class="footer">PGP: 6FF9 2943 B795 21DC 51D2 4734 715C 88E0 E239 7C72</footer>
<script>
let menu = document.getElementById('menu')
if (menu) {
menu.scrollLeft = localStorage.getItem("menu-scroll-position");
menu.onscroll = function () {
localStorage.setItem("menu-scroll-position", menu.scrollLeft);
}
}
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener("click", function (e) {
e.preventDefault();
var id = this.getAttribute("href").substr(1);
if (!window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView({
behavior: "smooth"
});
} else {
document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView();
}
if (id === "top") {
history.replaceState(null, null, " ");
} else {
history.pushState(null, null, `#${id}`);
}
});
});
</script>
<script>
var mybutton = document.getElementById("top-link");
window.onscroll = function () {
if (document.body.scrollTop > 800 || document.documentElement.scrollTop > 800) {
mybutton.style.visibility = "visible";
mybutton.style.opacity = "1";
} else {
mybutton.style.visibility = "hidden";
mybutton.style.opacity = "0";
}
};
</script>
<script>
document.getElementById("theme-toggle").addEventListener("click", () => {
if (document.body.className.includes("dark")) {
document.body.classList.remove('dark');
localStorage.setItem("pref-theme", 'light');
} else {
document.body.classList.add('dark');
localStorage.setItem("pref-theme", 'dark');
}
})
</script>
</body>
</html>