migrates ghost blog to hugo
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
<!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>UFW VPN Kill Switch | dvdt.dev</title>
|
||||
<meta name="keywords" content="">
|
||||
<meta name="description" content="NetworkManager unfortunately doesn’t have a kill switch in case your VPN connection drops but you can achieve the same effect through firewall rules. I’m using ufw here but you can achieve the same using iptables or firewall-cmd. I haven’t looked into automating this when VPN connects yet but opening Gufw and switching the profile hasn’t become annoying yet either. If I ever get around to that I’ll post an update.">
|
||||
<meta name="author" content="David Lick">
|
||||
<link rel="canonical" href="https://new.dvdt.dev/2020/10/ufw-vpn-kill-switch/">
|
||||
<link crossorigin="anonymous" href="/assets/css/stylesheet.5cfc680b1eeaeef9efbced92d46c2a9e876b72ee14fba85846afc4cff9e6e6f8.css" integrity="sha256-XPxoCx7q7vnvvO2S1Gwqnodrcu4U+6hYRq/Ez/nm5vg=" rel="preload stylesheet" as="style">
|
||||
<script defer crossorigin="anonymous" src="/assets/js/highlight.f413e19d0714851f6474e7ee9632408e58ac146fbdbe62747134bea2fa3415e0.js" integrity="sha256-9BPhnQcUhR9kdOfuljJAjlisFG+9vmJ0cTS+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">
|
||||
UFW VPN Kill Switch
|
||||
</h1>
|
||||
<div class="post-meta"><span title='2020-10-11 00:00:00 +0000 UTC'>October 11, 2020</span> · David Lick
|
||||
|
||||
</div>
|
||||
</header>
|
||||
<div class="post-content"><p><img loading="lazy" src="/img/old-switch.jpg" alt="Old wall switch" />
|
||||
</p>
|
||||
<p>NetworkManager unfortunately doesn’t have a kill switch in case your VPN connection drops but you can achieve the same effect through firewall rules. I’m using <a href="https://wiki.archlinux.org/index.php/Uncomplicated_Firewall">ufw</a> here but you can achieve the same using iptables or firewall-cmd. I haven’t looked into automating this when VPN connects yet but opening <a href="https://gufw.org/">Gufw</a> and switching the profile hasn’t become annoying yet either. If I ever get around to that I’ll post an update.</p>
|
||||
<p>Gufw’s UI is very good and the advanced tab in it’s rules creator has everything I need: interface, direction, to/from IP and port ranges so I use that over setting rules from the command line.</p>
|
||||
<ul>
|
||||
<li>First, set up the kill switch profile to easily turn rules on and off as needed. You’ll want to set incoming and outgoing to deny:</li>
|
||||
</ul>
|
||||
<p><img loading="lazy" src="/img/gufw-kill-switch.png" alt="Gufw Kill Switch Profile" />
|
||||
</p>
|
||||
<ul>
|
||||
<li>Optionally, create rules to allow traffic out (and in from if you like) to the local network. You can use CIDR notation here to add your whole subnet:</li>
|
||||
</ul>
|
||||
<p><img loading="lazy" src="/img/firewall-rule-wizard-local-out.png" alt="Firewall Rule Wizard" />
|
||||
</p>
|
||||
<ul>
|
||||
<li>If you would like to allow local traffic into your machine be sure to switch your from to be your local CIDR and your <code>to</code> to be <code>any</code>:</li>
|
||||
</ul>
|
||||
<p><img loading="lazy" src="/img/firewall-rule-wizard-local-in.png" alt="Firewall Rule Wizard" />
|
||||
</p>
|
||||
<ul>
|
||||
<li>In order for your VPN to be able to reconnect if the connection drops, <code>allow</code> any connections out to your VPN servers:</li>
|
||||
</ul>
|
||||
<p><img loading="lazy" src="/img/firewall-rule-wizard-reconnect.png" alt="Firewall Rule Wizard" />
|
||||
</p>
|
||||
<ul>
|
||||
<li>Finally, <code>allow</code> any traffic out (and in if you like) on the <code>tun0</code> interface. Since we’re blocking all traffic by default this rule is the magic that makes sure that only VPN traffic makes it out (or in):</li>
|
||||
</ul>
|
||||
<p><img loading="lazy" src="/img/firewall-rule-wizard-allow.png" alt="Firewall rule wizard" />
|
||||
</p>
|
||||
<p>That’s it! If you’ve used a VPN client with a kill switch before, ultimately this is how it works under the hood. They’ll have some automation on top to only apply these rules when the VPN is active but the concepts are the same.</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="post-footer">
|
||||
<ul class="post-tags">
|
||||
</ul>
|
||||
</footer>
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<span>© 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>
|
||||
Reference in New Issue
Block a user