<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Kirsten's Dev Notes]]></title><description><![CDATA[Kirsten's Dev Notes]]></description><link>https://notes.kirstyconsole.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/65d4f75666ff1e0436cda476/f646d84e-f3f5-439a-a2f3-e47136d1e5c1.png</url><title>Kirsten&apos;s Dev Notes</title><link>https://notes.kirstyconsole.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Wed, 20 May 2026 12:56:47 GMT</lastBuildDate><atom:link href="https://notes.kirstyconsole.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Setting Up Contabo's Built-In Firewall on Your VPS (No Terminal Required)]]></title><description><![CDATA[So you've got a VPS on Contabo. You may be running something like Jellyfin behind a Caddy reverse proxy, a web app, or you're just experimenting. Either way, someone (probably a tutorial, probably me ]]></description><link>https://notes.kirstyconsole.dev/setting-up-contabo-s-built-in-firewall-on-your-vps-no-terminal-required</link><guid isPermaLink="true">https://notes.kirstyconsole.dev/setting-up-contabo-s-built-in-firewall-on-your-vps-no-terminal-required</guid><dc:creator><![CDATA[Kirsty]]></dc:creator><pubDate>Tue, 14 Apr 2026 13:29:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/65d4f75666ff1e0436cda476/9bc1a3d0-cc14-4896-80cd-ed40e82b9d5f.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>So you've got a VPS on Contabo. You may be running something like Jellyfin behind a Caddy reverse proxy, a web app, or you're just experimenting. Either way, someone (probably a tutorial, probably me in a future article) is going to tell you: set up a firewall.</p>
<p>And yeah, you should. But the good news is that Contabo recently rolled out a free, built-in firewall with a GUI right in the control panel. No iptables commands, no memorizing syntax, no accidentally locking yourself out and crying. Just point, click, and your server is protected.</p>
<p>This is how I set mine up, and how you can too.</p>
<hr />
<h2>What Even Is a Firewall?</h2>
<p>Quick explanation: your server is connected to the internet. Without a firewall, any traffic can knock on any port, and your server will answer. That's not great. That is nightmarish <em>there are lots of smart people with bad intentions.</em></p>
<p>A firewall sits in front of all that and says, "Only these specific things are allowed in. Everything else? Thank you, next."</p>
<p>Contabo's firewall works at the network level, meaning traffic gets filtered before it even touches your server. Your VPS doesn't even see the blocked stuff. That's cleaner and safer than a software firewall you install on the OS itself.</p>
<p>And it's free. Included with every VPS and VDS. No excuses to not set it up and <em>not have nightmares about ports being hammered while you sleep!</em></p>
<hr />
<h2>Before You Touch the Firewall: Do This First</h2>
<p>Here's something that tripped me up mentally at first: how do you know what to allow if you don't know what's running?</p>
<p>SSH into your server and run:</p>
<pre><code class="language-bash">ss -tlnp
</code></pre>
<p>This lists every service that's currently listening for connections and the port it's listening on. Here's what mine looked like:</p>
<pre><code class="language-plaintext">State   Port    Process
LISTEN  53      systemd-resolve   (127.0.0.1 only)
LISTEN  8096    jellyfin
LISTEN  2019    caddy             (127.0.0.1 only)
LISTEN  22      sshd
LISTEN  443     caddy
LISTEN  80      caddy
</code></pre>
<p>Now you read it like this:</p>
<ul>
<li><p>If the Local Address shows <code>127.0.0.1</code> or <code>127.0.0.53</code>, it's an internal-only address. The internet can't reach it anyway. You don't need a firewall rule for it.</p>
</li>
<li><p>If it shows <code>0.0.0.0</code> or <code>*</code>, it's publicly reachable. You need to decide: should it be?</p>
</li>
</ul>
<p>In my case, the services that actually needed to be reachable from the outside were:</p>
<table>
<thead>
<tr>
<th>Port</th>
<th>Service</th>
<th>Why</th>
</tr>
</thead>
<tbody><tr>
<td>22</td>
<td>SSH</td>
<td>So I can connect to my server</td>
</tr>
<tr>
<td>80</td>
<td>Caddy</td>
<td>HTTP, redirects to HTTPS</td>
</tr>
<tr>
<td>443</td>
<td>Caddy</td>
<td>HTTPS, actual web traffic</td>
</tr>
</tbody></table>
<p><strong>What about Jellyfin on port 8096?</strong></p>
<p>Good question. I access Jellyfin through a subdomain (<code>jellyfin.mydomain.com</code>), which Caddy proxies. So traffic comes in on port 443, Caddy handles it, and forwards it internally to port 8096. Port 8096 never needs to be public. I leave it closed.</p>
<p>If you're accessing Jellyfin directly via <code>yourip:8096</code> in the browser, then you'd need to open 8096. But I'd recommend setting up a reverse proxy instead, it's cleaner and more secure. (That's a separate article, though.)</p>
<hr />
<h2>Setting Up the Contabo Firewall</h2>
<h3>Step 1: Log In to the Firewall Section</h3>
<p>Log in to your <a href="https://my.contabo.com">Contabo Customer Control Panel</a>. In the navigation, go to:</p>
<p><strong>Network Services → Firewall</strong></p>
<p>You'll land on a page where you can create and manage firewall rule sets.</p>
<h3>Step 2: Understand the Default</h3>
<p>When you first enable the firewall, Contabo creates one rule:</p>
<table>
<thead>
<tr>
<th>Status</th>
<th>Display Name</th>
<th>Action</th>
<th>Protocol</th>
<th>Port(s)</th>
<th>Source(s)</th>
</tr>
</thead>
<tbody><tr>
<td>ACTIVE</td>
<td>Block all traffic</td>
<td>DROP</td>
<td>Any</td>
<td>Any</td>
<td>Any</td>
</tr>
</tbody></table>
<p>This is your safety net. It means: if nothing else matches, drop the packet. You want this rule to exist. You want it to stay at the bottom. Every rule you add will be an exception to this. Do not worry too much about this caveat Contabo knows this and every new rule you add, is added above your default DROP all rule, but if you mess with one just be mindful of this.</p>
<h3>Step 3: Add Your Allow Rules</h3>
<p>Now add a rule for each port you identified earlier. For each one, you'll specify:</p>
<ul>
<li><p><strong>Action</strong>: ACCEPT</p>
</li>
<li><p><strong>Protocol</strong>: TCP</p>
</li>
<li><p><strong>Port</strong>: the port number</p>
</li>
<li><p><strong>Source</strong>: Any (or a specific IP if you want to lock SSH down to just your home IP, more on that below)</p>
</li>
</ul>
<p>Add these three rules:</p>
<p><strong>Rule 1: SSH</strong></p>
<ul>
<li><p>Display Name: <code>Allow SSH</code></p>
</li>
<li><p>Action: ACCEPT</p>
</li>
<li><p>Protocol: TCP</p>
</li>
<li><p>Port: 22</p>
</li>
<li><p>Source: Any</p>
</li>
</ul>
<p><strong>Rule 2: HTTP</strong></p>
<ul>
<li><p>Display Name: <code>Allow HTTP</code></p>
</li>
<li><p>Action: ACCEPT</p>
</li>
<li><p>Protocol: TCP</p>
</li>
<li><p>Port: 80</p>
</li>
<li><p>Source: Any</p>
</li>
</ul>
<p><strong>Rule 3: HTTPS</strong></p>
<ul>
<li><p>Display Name: <code>Allow HTTPS</code></p>
</li>
<li><p>Action: ACCEPT</p>
</li>
<li><p>Protocol: TCP</p>
</li>
<li><p>Port: 443</p>
</li>
<li><p>Source: Any</p>
</li>
</ul>
<h3>Step 4: Check Your Rule Order</h3>
<p>Your final rule list should look something like this:</p>
<table>
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th>Action</th>
<th>Protocol</th>
<th>Port(s)</th>
<th>Source(s)</th>
</tr>
</thead>
<tbody><tr>
<td>ACTIVE</td>
<td>Allow SSH</td>
<td>ACCEPT</td>
<td>TCP</td>
<td>22</td>
<td>Any</td>
</tr>
<tr>
<td>ACTIVE</td>
<td>Allow HTTP</td>
<td>ACCEPT</td>
<td>TCP</td>
<td>80</td>
<td>Any</td>
</tr>
<tr>
<td>ACTIVE</td>
<td>Allow HTTPS</td>
<td>ACCEPT</td>
<td>TCP</td>
<td>443</td>
<td>Any</td>
</tr>
<tr>
<td>ACTIVE</td>
<td>Block all traffic</td>
<td>DROP</td>
<td>Any</td>
<td>Any</td>
<td>Any</td>
</tr>
</tbody></table>
<p>The DROP rule should always be last. Rules are evaluated top to bottom, first match wins. So ACCEPT rules go above, DROP catches everything that didn't match.</p>
<h3>Step 5: Attach the Firewall to Your VPS</h3>
<p>Creating rules isn't enough, you have to attach the rule set to your actual VPS instance. In the Contabo panel, go to the <strong>Active VPS/VDS</strong> tab and assign your firewall there.</p>
<p>Once attached, it's live immediately. No restart is needed.</p>
<hr />
<h2>Optional, but Recommended: Lock Down SSH</h2>
<p>Allowing SSH from any source works, but if you have a static home IP or office IP, you can restrict SSH to just that address. This means even if someone finds port 22, they can't connect unless they're you.</p>
<p>In your SSH rule, instead of Source: Any, put your IP address (you can find it by Googling "what is my IP").</p>
<p>Just make sure you remember to update this if your IP changes, or you'll lock yourself out. If that happens, Contabo has a VNC console in the control panel you can use as a backup.</p>
<hr />
<h2>Testing It</h2>
<p>After your rules are active, test from your local machine:</p>
<pre><code class="language-bash"># Test HTTP
curl http://your-server-ip

# Test SSH
ssh root@your-server-ip
</code></pre>
<p>If HTTP returns a response and SSH connects, you're good. Everything else is blocked.</p>
<p>Want to be thorough? You can use <code>nmap</code> to scan your server from outside and see exactly what's visible:</p>
<pre><code class="language-bash">nmap -Pn your-server-ip
</code></pre>
<p>Only ports 22, 80, and 443 should show as open.</p>
<hr />
<h2>Quick Reference</h2>
<p>Condensed version of everything for quick reference.</p>
<ol>
<li><p><code>ss -tlnp</code> on your server to see what's running and on which port</p>
</li>
<li><p>Identify which ports need to be public (ignore <code>127.0.0.1</code> entries, this just means local.)</p>
</li>
<li><p><strong>Contabo Panel</strong> → <strong>Network Services</strong> → <strong>Firewall</strong></p>
</li>
<li><p>Add ACCEPT rules for your ports (22, 80, 443 at minimum)</p>
</li>
<li><p>Keep the Block all traffic <strong>DROP</strong> rule at the bottom</p>
</li>
<li><p>Attach the firewall to your VPS instance</p>
</li>
<li><p>Test with <code>curl</code> and <code>ssh</code></p>
</li>
</ol>
<hr />
<h2>Wrapping Up</h2>
<p>Contabo's built-in firewall is one of the nicer things they've added recently. No need to mess with a command line and worry about <code>iptables-persistent</code>, no scary moments thinking to yourself "did I save that rule before rebooting?". Its all sorted very cleanly from the site.</p>
<p>The key habit to build here is: always check what's running before you build your rules. Don't just copy someone else's firewall setup, your server is yours, and your services are different. Running <code>ss -tlnp</code> takes two seconds and tells you exactly what you're working with.</p>
<p>If you're running a Jellyfin + Caddy setup like me, the three rules above are all you need. Keep 8096 closed, let Caddy handle the routing, and you're good to go.</p>
<hr />
<p><em>Have questions, or something didn't work the way you expected? Drop a comment. I'm learning too, and we can figure it out together.</em></p>
]]></content:encoded></item></channel></rss>