<?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>Netcup – Serverküche</title><link>https://serverkueche.de/en/tags/netcup/</link><description>Netcup – Neueste Beiträge von Serverküche</description><generator>Hugo</generator><language>en-US</language><managingEditor>feedback@serverkueche.de (Serverküche)</managingEditor><webMaster>feedback@serverkueche.de (Serverküche)</webMaster><copyright>2026 Serverküche</copyright><lastBuildDate>Fri, 17 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://serverkueche.de/en/tags/netcup/index.xml" rel="self" type="application/rss+xml"/><item><title>Connecting a domain to your server (DNS basics)</title><link>https://serverkueche.de/en/tutorials/connect-domain-to-server/</link><pubDate>Fri, 17 Jul 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/en/tutorials/connect-domain-to-server/</guid><description>A and AAAA records, TTL and propagation explained clearly: how your own domain points to your server – the prerequisite for HTTPS with Traefik.</description><content:encoded><![CDATA[<p>So far you only reach your server via its IP address. For real services you need a
<strong>domain</strong> – and not just for looks: without a publicly resolving domain,
<a href="/en/tutorials/traefik-reverse-proxy/">Traefik</a> can&rsquo;t fetch a <strong>TLS certificate</strong>
from Let&rsquo;s Encrypt later. This tutorial connects your domain to the server and
explains the three terms beginners get stuck on: A record, TTL and propagation.</p>
<h2 id="what-are-we-building">What are we building?</h2>
<p>By the end, your domain (<code>YOUR_DOMAIN</code>) points to your server IP via an <strong>A record</strong>
(IPv4) and – if your server has IPv6 – an <strong>AAAA record</strong>, including <code>www</code>. You can
verify this yourself with <code>dig</code> and understand why a change isn&rsquo;t always visible
immediately. Optionally you also set up <strong>reverse DNS (PTR)</strong> – important as soon as
your server sends emails. This lays the foundation for all publicly reachable
services.</p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>A <a href="/en/tutorials/first-steps-netcup-vps/">set-up server</a> with a known public IP
address</li>
<li>A <strong>registered domain</strong> (at netcup, another registrar, or included in your hosting
package)</li>
<li>Access to the <strong>DNS management</strong> of your domain (at netcup: the customer account
CCP)</li>
</ul>
<h2 id="step-by-step">Step by step</h2>
<h3 id="step-1-find-the-server-ip">Step 1: Find the server IP</h3>
<p>Connect via SSH and display the public IP addresses:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ip -4 addr show scope global
</span></span><span class="line"><span class="cl">ip -6 addr show scope global</span></span></code></pre></div>
</div>
<p>The IPv4 address is after <code>inet</code> (e.g. <code>203.0.113.10</code>), any IPv6 address after
<code>inet6</code> (does not start with <code>fe80::</code>, that would only be link-local). Alternatively
you&rsquo;ll find both in the netcup <strong>Server Control Panel (SCP)</strong> in the server overview.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Tip
  </p>
  <div class="prose-kitchen text-sm">Note down both addresses. If your server has <strong>no</strong> global IPv6 address, you simply
don&rsquo;t create an AAAA record later – that&rsquo;s perfectly fine.</div>
</div>
<h3 id="step-2-create-a-and-aaaa-records">Step 2: Create A and AAAA records</h3>
<p>Open the DNS management of your domain. There you enter <strong>resource records</strong> – the
mapping of names to addresses. Create:</p>
<table>
	<thead>
			<tr>
					<th>Type</th>
					<th>Host / Name</th>
					<th>Value</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>A</code></td>
					<td><code>@</code></td>
					<td><code>YOUR_SERVER_IPV4</code></td>
			</tr>
			<tr>
					<td><code>A</code></td>
					<td><code>www</code></td>
					<td><code>YOUR_SERVER_IPV4</code></td>
			</tr>
			<tr>
					<td><code>AAAA</code></td>
					<td><code>@</code></td>
					<td><code>YOUR_SERVER_IPV6</code> <em>(only if available)</em></td>
			</tr>
			<tr>
					<td><code>AAAA</code></td>
					<td><code>www</code></td>
					<td><code>YOUR_SERVER_IPV6</code> <em>(only if available)</em></td>
			</tr>
	</tbody>
</table>
<ul>
<li><strong><code>@</code></strong> stands for the domain itself (<code>YOUR_DOMAIN</code>), <code>www</code> for the subdomain
<code>www.YOUR_DOMAIN</code>.</li>
<li><strong>A</strong> points to an IPv4 address, <strong>AAAA</strong> to an IPv6 address. The name &ldquo;AAAA&rdquo; comes
from an IPv6 address being four times as long as an IPv4 address.</li>
<li>For individual services you can later create specific subdomains (e.g. <code>cloud</code>,
<code>git</code>) – following the same pattern.</li>
</ul>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>Warning
  </p>
  <div class="prose-kitchen text-sm">For A/AAAA enter <strong>only the bare IP</strong> – no <code>http://</code>, no slash, no port. For
redirects to other names there would be <code>CNAME</code>, but for &ldquo;domain → own server&rdquo; the
A/AAAA record is the right and most robust way.</div>
</div>
<h3 id="step-3-understand-ttl-and-propagation">Step 3: Understand TTL and propagation</h3>
<p>Every record has a <strong>TTL</strong> (Time To Live) in seconds – e.g. <code>3600</code> (one hour). It
tells resolvers worldwide <strong>how long</strong> they may cache the answer before asking again.</p>
<p>From this follows the notorious <strong>propagation</strong>: if you change a record, some
resolvers see the new value immediately, others only after the old TTL expires. &ldquo;DNS
propagating&rdquo; means nothing more than these caches expiring one by one. In everyday
use, reckon with <strong>minutes up to an hour</strong>, occasionally longer.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Before planned migrations
  </p>
  <div class="prose-kitchen text-sm">If you want to change an IP soon, lower the TTL <strong>one or two days beforehand</strong> to
e.g. <code>300</code> (5 minutes). Then the actual switch takes effect almost immediately later.
Raise it again after the migration.</div>
</div>
<h3 id="step-4-verify-with-dig">Step 4: Verify with dig</h3>
<p>Wait a few minutes, then check from your own machine where the domain points. <code>dig</code>
is the standard tool for that:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dig +noall +answer YOUR_DOMAIN A</span></span></code></pre></div>
</div>
<p>This is what a correct answer looks like (example for this site&rsquo;s real domain):</p>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">serverkueche.de.	600	IN	A	46.38.243.234</span></span></code></pre></div>
</div>
<p>The number <code>600</code> is the remaining TTL, followed by the target IP. For IPv6, do the
same with <code>AAAA</code>. If you only want it very brief:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dig +short YOUR_DOMAIN</span></span></code></pre></div>
</div>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">46.38.243.234</span></span></code></pre></div>
</div>
<p>If your correct server IP appears, the domain is connected. Also check <code>www</code>:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dig +short www.YOUR_DOMAIN</span></span></code></pre></div>
</div>
<p>Here too, the <strong>same</strong> server IP as for the apex should come back as a plain line:</p>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">46.38.243.234</span></span></code></pre></div>
</div>
<h3 id="step-5-set-reverse-dns-ptr--optional-but-recommended">Step 5: Set reverse DNS (PTR) – optional but recommended</h3>
<p>The A record answers the question &ldquo;Which IP belongs to this name?&rdquo;. <strong>Reverse DNS</strong> –
the PTR record – answers the opposite direction: &ldquo;Which name belongs to this IP?&rdquo;.
For a plain website you don&rsquo;t need this. But as soon as your server <strong>sends emails</strong> –
even if only notifications from Nextcloud, Gitea &amp; co. – it&rsquo;s practically mandatory:
the receiving mail servers reject mail from IPs <strong>without</strong> a matching PTR or treat it
as spam.</p>
<p>The crucial difference from the previous records: you enter the PTR <strong>not</strong> at your
DNS provider, but where the <strong>IP address is managed</strong> – i.e. at your <strong>VPS provider</strong>.
At netcup you&rsquo;ll find it in the <strong>Server Control Panel (SCP)</strong> in the <strong>Netzwerk
(Network)</strong> tab – there&rsquo;s a <strong>Reverse DNS</strong> field per address (IPv4 and IPv6). Enter a
hostname there that points to the same server via an A record – either directly
<code>YOUR_DOMAIN</code> or your own name like <code>server.YOUR_DOMAIN</code> (shown as an example in the
screenshot) – and click <strong>Save</strong>.</p>
<p><figure class="my-6"><img src="/en/tutorials/connect-domain-to-server/netcup-reverse-dns_hu_d24e02b203a775be.webp" srcset="/en/tutorials/connect-domain-to-server/netcup-reverse-dns_hu_888311629ed75749.webp 480w, /en/tutorials/connect-domain-to-server/netcup-reverse-dns_hu_d24e02b203a775be.webp 768w, /en/tutorials/connect-domain-to-server/netcup-reverse-dns_hu_1a64247f0e364cec.webp 1200w, /en/tutorials/connect-domain-to-server/netcup-reverse-dns_hu_ce3761572748486e.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/connect-domain-to-server/netcup-reverse-dns_hu_aff7b021b12d562c.webp"
    alt="netcup Server Control Panel in the Network tab: the reverse-DNS fields for the IPv4 and IPv6 address, each with an example hostname entered and a Save button" title="Reverse DNS in the netcup SCP under Network – one field per IP address"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Reverse DNS in the netcup SCP under Network – one field per IP address</figcaption></figure></p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Forward and reverse must match
  </p>
  <div class="prose-kitchen text-sm">For the PTR to count as &ldquo;clean&rdquo; (forward-confirmed rDNS, FCrDNS), the name entered
there must <strong>point back to the same IP</strong> via an A/AAAA record. For <code>YOUR_DOMAIN</code> and
<code>www</code> this is already satisfied by step 2. If you use your own name like
<code>server.YOUR_DOMAIN</code>, first create an A/AAAA record for it as in step 2 – otherwise
the reverse direction doesn&rsquo;t match.</div>
</div>
<p>If you have <strong>IPv6</strong>, set the PTR <strong>for both</strong> addresses – IPv4 <em>and</em> IPv6. The IPv6
PTR is easily forgotten, and that&rsquo;s exactly what some mail servers trip over after all.</p>
<p>You can check the result with <code>dig</code> and the <code>-x</code> option (reverse lookup) – for IPv6
do the same with <code>YOUR_SERVER_IPV6</code>:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dig +short -x YOUR_SERVER_IPV4</span></span></code></pre></div>
</div>
<p>Your hostname with a trailing dot should come back:</p>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">serverkueche.de.</span></span></code></pre></div>
</div>
<p>If nothing comes back, or still the provider&rsquo;s default name (at netcup something like
<code>v220….bestsrv.de</code>), the PTR is not (correctly) set yet – or, as with every DNS entry,
the change still needs some time.</p>
<h2 id="when-things-go-wrong">When things go wrong</h2>
<div class="troubleshoot not-prose">
<p><strong><code>dig</code> returns no IP or a wrong (old) one.</strong> Usually still propagation. Query a
public resolver specifically to bypass your local cache: <code>dig +short YOUR_DOMAIN @1.1.1.1</code>. If it already shows the correct value, only your local/provider cache
hasn&rsquo;t expired yet – wait.</p>
<p><strong>The domain resolves, but to the wrong IP – e.g. a registrar&rsquo;s parking page.</strong> Often
an old A record or a redirect/parking setting still exists. Remove contradictory
entries; per name and type there should be exactly <strong>one</strong> value (deliberate
exceptions aside).</p>
<p><strong>IPv4 works, IPv6 (AAAA) leads to timeouts.</strong> You entered an AAAA record even though
the server has no working IPv6 address. Browsers then prefer IPv6 and run into a
timeout. remove the AAAA record until the server really supports IPv6.</p>
<p><strong>In some interfaces the value is stored with a trailing dot (<code>YOUR_DOMAIN.</code>) and
you&rsquo;re unsure.</strong> The trailing dot (root of the DNS hierarchy) is normal and correct –
many DNS managers add it automatically. No reason to worry.</p>
<p><strong>Emails sent from the server land in spam or are rejected (the mail log shows e.g.
<code>does not resolve to address</code> or <code>no PTR record</code>).</strong> The reverse-DNS entry (PTR) is
missing or doesn&rsquo;t match the sender hostname. Set the PTR as described in step 5 at
the VPS provider and make sure it points to the same name that also resolves via the
A/AAAA record.</p>

</div>

<h2 id="maintenance--backups">Maintenance &amp; backups</h2>
<ul>
<li><strong>DNS is low-maintenance.</strong> Once set correctly, the A/AAAA record rarely changes.
Exception: a <strong>server migration</strong> – then the TTL trick from step 3 applies.</li>
<li><strong>Document your records.</strong> Keep track somewhere of which names (<code>@</code>, <code>www</code>,
<code>cloud</code>, …) point to which IP. With several services you otherwise lose the
overview.</li>
<li><strong>No classic backup needed</strong>, but a screenshot or export of your DNS zone doesn&rsquo;t
hurt in case you switch providers.</li>
<li><strong>Carry reverse DNS along on an IP change.</strong> If the server gets a new IP (migration,
new product), you have to reset the PTR at the VPS provider – it&rsquo;s tied to the IP,
not the domain.</li>
</ul>
<p>Your domain now points to the server – with that, the last prerequisite is met for
serving services <strong>publicly with automatic HTTPS</strong> via the <a href="/en/tutorials/traefik-reverse-proxy/">reverse proxy
Traefik</a>.</p>
]]></content:encoded></item><item><title>netcup snapshots &amp; the Server Control Panel (SCP)</title><link>https://serverkueche.de/en/tutorials/netcup-snapshots-scp/</link><pubDate>Fri, 17 Jul 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/en/tutorials/netcup-snapshots-scp/</guid><description>Use the netcup Server Control Panel &amp; snapshots properly: a safety net before risky changes – and why it's no substitute for a real backup.</description><content:encoded><![CDATA[<p>Before you do something risky on the server – a big update, a delicate config change –
you want a point you can return to in minutes. That&rsquo;s exactly what <strong>netcup snapshots</strong>
are for. This tutorial shows you the <strong>Server Control Panel (SCP)</strong> and how to use
snapshots properly – and where their limit lies.</p>
<h2 id="what-are-we-building">What are we building?</h2>
<p>You get to know the <strong>netcup Server Control Panel (SCP)</strong> – the web interface to your
server – and create a <strong>snapshot</strong> there: a complete image of your server disk, to which
you return in a few minutes if a mishap happens. By the end you know when a snapshot is
your rescue – and why it&rsquo;s still <strong>no substitute for a real backup</strong>.</p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>A netcup server, e.g. your <a href="/en/tutorials/first-steps-netcup-vps/">first VPS</a>.</li>
<li>Your <strong>SCP credentials</strong> – they are in the netcup welcome email and are <strong>different</strong>
from your SSH login.</li>
</ul>
<div class="not-prose my-6 overflow-hidden rounded-xl border border-paprika-200 bg-paprika-50 dark:border-paprika-800 dark:bg-paprika-900/20">
  <div class="flex items-center justify-between border-b border-paprika-200 bg-paprika-100 px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-paprika-700 dark:border-paprika-800 dark:bg-paprika-900/40 dark:text-paprika-300">
    <span>🍳 Recommendation</span>
    <span title="Links marked with * are affiliate links.">Ad</span>
  </div>
  <div class="flex flex-col gap-4 p-4 sm:flex-row sm:items-center sm:justify-between">
    <div>
      <p class="text-lg font-bold text-slate-900 dark:text-white">VPS 1000 G12</p>
      <p class="mt-1 text-sm text-slate-600 dark:text-slate-300">4 vCores · 8 GB RAM · 256 GB NVMe</p>
      <p class="mt-1 text-sm font-semibold text-paprika-700 dark:text-paprika-400">from €10.36/month</p>
      <p class="mt-2 text-sm text-slate-600 dark:text-slate-400">All netcup servers include the SCP with its snapshot function.</p>
    </div>
    <a href="https://www.netcup.com/en/server/vps/vps-1000-g12-iv-12m?ref=44083" rel="sponsored noopener" target="_blank"
   class="inline-flex shrink-0 items-center justify-center rounded-lg bg-paprika-600 px-5 py-2.5 font-semibold text-white transition-colors hover:bg-paprika-700">
  Go to netcup →
</a>

  </div><div class="px-4 pb-4"><p class="not-prose my-3 flex flex-wrap items-center gap-x-2 gap-y-1 rounded-lg border border-herb-500/40 bg-herb-50 px-3 py-2 text-sm text-slate-700 dark:bg-herb-900/20 dark:text-slate-200">
  <span>💶 <strong>5 € voucher</strong> for new netcup customers:</span>
  <code class="rounded bg-white px-2 py-0.5 font-mono text-sm font-semibold text-herb-800 dark:bg-slate-800 dark:text-herb-400">36nc17844976032</code>
  <span class="text-xs text-slate-500 dark:text-slate-400">(new customers only, no domains)</span>
</p></div>
</div>

<h2 id="step-by-step">Step by step</h2>
<h3 id="step-1-log-into-the-scp-and-find-the-server">Step 1: Log into the SCP and find the server</h3>
<p>Open <a href="https://www.servercontrolpanel.de/">servercontrolpanel.de</a> and log in with your
SCP credentials. You land in the server list; a click on your server opens the
<strong>overview</strong> with product, status and hardware. At the top you see the tabs through which
you control everything – <strong>snapshots are under &ldquo;Media&rdquo;</strong>.</p>
<p><figure class="my-6"><img src="/en/tutorials/netcup-snapshots-scp/netcup-scp-uebersicht_hu_f14d52af6d3ebf4e.webp" srcset="/en/tutorials/netcup-snapshots-scp/netcup-scp-uebersicht_hu_bbfd35db587d3122.webp 480w, /en/tutorials/netcup-snapshots-scp/netcup-scp-uebersicht_hu_f14d52af6d3ebf4e.webp 768w, /en/tutorials/netcup-snapshots-scp/netcup-scp-uebersicht_hu_bd0829934b1aaf36.webp 1200w, /en/tutorials/netcup-snapshots-scp/netcup-scp-uebersicht_hu_a72f85ba080e7afb.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-snapshots-scp/netcup-scp-uebersicht_hu_4eaae45f34f5fc19.webp"
    alt="The server overview in the netcup SCP with the tabs; snapshots are under &ldquo;Media&rdquo;" title="The server overview in the SCP – the tabs lead to all functions"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The server overview in the SCP – the tabs lead to all functions</figcaption></figure></p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Different login than SSH
  </p>
  <div class="prose-kitchen text-sm">The SCP has <strong>its own</strong> credentials (customer number + SCP password), independent of your
SSH access. Keep them in your password manager – via the SCP you can reach the server
even when SSH is stuck (e.g. via the VNC console under &ldquo;Display&rdquo;).</div>
</div>
<h3 id="step-2-create-a-snapshot">Step 2: Create a snapshot</h3>
<p>Go to <strong>Media → Snapshots</strong>. Under <strong>Create snapshot</strong> you fill in:</p>
<ul>
<li><strong>Name:</strong> name it after the <strong>why</strong>, not the date alone – e.g. <code>before-update-2026-07</code>.
That way you later know what it was for.</li>
<li><strong>Description:</strong> one sentence of context (optional, but helpful).</li>
<li><strong>Disk:</strong> usually <code>vda</code> (your system disk).</li>
<li><strong>Type:</strong> here lies the most important decision – see below.</li>
</ul>
<p><figure class="my-6"><img src="/en/tutorials/netcup-snapshots-scp/netcup-snapshot-erstellen_hu_ee0d5e35a238c588.webp" srcset="/en/tutorials/netcup-snapshots-scp/netcup-snapshot-erstellen_hu_6604a6e69c643091.webp 480w, /en/tutorials/netcup-snapshots-scp/netcup-snapshot-erstellen_hu_ee0d5e35a238c588.webp 768w, /en/tutorials/netcup-snapshots-scp/netcup-snapshot-erstellen_hu_a6d49e30eda0f52f.webp 1200w, /en/tutorials/netcup-snapshots-scp/netcup-snapshot-erstellen_hu_e1e85c70dd2d985b.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-snapshots-scp/netcup-snapshot-erstellen_hu_f5c77f2441eb89a8.webp"
    alt="The snapshot form in the SCP with name, description, disk and type" title="\&#34;Create snapshot\&#34; – give a name after the purpose, choose the type deliberately"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">\&#34;Create snapshot\&#34; – give a name after the purpose, choose the type deliberately</figcaption></figure></p>
<p><strong>Offline or online snapshot?</strong></p>
<ul>
<li><strong>Offline snapshot:</strong> the server is briefly <strong>shut down</strong> for the capture. This
guarantees a <strong>consistent</strong> state – the right choice when databases are running, and
when you can afford the brief downtime.</li>
<li><strong>Online snapshot:</strong> capture <strong>while running</strong>, without downtime. Convenient, but with
active writes (e.g. a database mid-write) the image can be <strong>inconsistent</strong>.</li>
</ul>
<p>A click on <strong>Create</strong> starts the process; depending on the amount of data it takes a few
minutes. It runs in the background – the creation date and type then appear in the list
above once it&rsquo;s done. Best schedule the brief downtime of an offline snapshot for a quiet
time; after that your return point is set and you can tackle the planned change.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>Only one snapshot slot
  </p>
  <div class="prose-kitchen text-sm">A VPS usually has <strong>one</strong> snapshot slot. If you create a new one, it <strong>overwrites</strong> the
previous one. A snapshot is thus a <em>single</em> restore point, not a history – for multiple
version states you need real backups (see section &ldquo;Maintenance &amp; backups&rdquo;).</div>
</div>
<h3 id="step-3-restore-a-snapshot">Step 3: Restore a snapshot</h3>
<p>If something went wrong, you find the snapshot in the list under <strong>Snapshots</strong>; in the
<strong>Actions</strong> column there&rsquo;s <strong>Restore</strong>.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-paprika-400 bg-paprika-50 dark:border-paprika-700 dark:bg-paprika-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🔥</span>Restoring overwrites everything
  </p>
  <div class="prose-kitchen text-sm">A restore resets the disk <strong>completely</strong> to the snapshot state. <strong>Everything that has
happened since is lost</strong> – new data, changes, uploads. Use this only deliberately in an
emergency, not as a &ldquo;quick undo&rdquo;.</div>
</div>
<h3 id="step-4-the-other-safety-lines-in-the-scp">Step 4: The other safety lines in the SCP</h3>
<p>The SCP has more than snapshots – good to know for an emergency:</p>
<ul>
<li><strong>Display (VNC console):</strong> direct screen access to the server, even when SSH refuses –
the safety line from the <a href="/en/tutorials/harden-ssh/">SSH tutorial</a>.</li>
<li><strong>Rescue system:</strong> boots the server into an emergency Linux to repair a broken
installation.</li>
<li><strong>Media → Images / DVD drive:</strong> install a different operating system.</li>
</ul>
<h2 id="when-things-go-wrong">When things go wrong</h2>
<div class="troubleshoot not-prose">
<p><strong>The new snapshot overwrote the old one.</strong> That&rsquo;s expected behavior – a VPS only has one
snapshot slot. If you want to keep a particular state, restore it or back up the data
separately <strong>before</strong> you create a new snapshot.</p>
<p><strong>After an online snapshot restore, the database is corrupted.</strong> An online snapshot may
catch a running write mid-way. For servers with a database, take an <strong>offline snapshot</strong>
or create a database dump beforehand.</p>
<p><strong>You can&rsquo;t get into the SCP.</strong> The SCP uses <strong>its own</strong> credentials (not SSH). They are
in the welcome email; a forgotten SCP password you reset in the netcup customer account
(CCP).</p>

</div>

<h2 id="maintenance--backups">Maintenance &amp; backups</h2>
<ul>
<li><strong>Snapshot ≠ backup – the most important point.</strong> A snapshot lives at <strong>netcup</strong>, under
<strong>your</strong> account, in <strong>one</strong> slot and is meant as a momentary snapshot. If the account,
the data center or your access fails, it&rsquo;s gone too. It&rsquo;s a <strong>quick safety net</strong>, not
an off-site backup.</li>
<li><strong>Snapshot before every risky action.</strong> Before big updates, migrations or delicate
config changes: snapshot first, then start. Afterwards you can calmly replace it with
the next one.</li>
<li><strong>Snapshots age.</strong> A months-old snapshot brings you back to a long-outdated state – when
in doubt, worse than no snapshot. Renew it specifically before every larger action; a
fresh return point is worth more than an old one.</li>
<li><strong>For real safety you need both.</strong> Complement the snapshot with <strong>encrypted off-site
backups</strong> – how that works is shown in the tutorial on <a href="/en/tutorials/restic-backups/">backups with
Restic</a>. Rule of thumb: snapshot for the quick return,
Restic for &ldquo;my server is gone&rdquo;.</li>
</ul>
]]></content:encoded></item><item><title>Setting up the netcup firewall in the SCP (with the stateless-UDP trick)</title><link>https://serverkueche.de/en/tutorials/netcup-firewall-setup/</link><pubDate>Fri, 17 Jul 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/en/tutorials/netcup-firewall-setup/</guid><description>Set up the netcup firewall as network protection in front of the server: composable policy templates in the SCP – with the trick for stateless UDP (DNS &amp; NTP).</description><content:encoded><![CDATA[<p>netcup comes with a <strong>firewall in front of your server</strong> – in the Server Control Panel,
before a packet even reaches the operating system. Built correctly, it&rsquo;s a strong shield.
But there&rsquo;s a trick many people fail at: the netcup firewall is <strong>stateless for UDP</strong>. This
tutorial shows you a clean, reusable firewall – and why DNS and NTP otherwise suddenly get
stuck.</p>
<h2 id="what-are-we-building">What are we building?</h2>
<p>In the <strong>netcup SCP</strong> we build a network firewall from <strong>composable policy templates</strong>: a
<strong>base</strong> template (that every server needs), one for <strong>SSH</strong>, and one for <strong>web
(HTTP/HTTPS)</strong>. You assign these building blocks to your server as needed – a web server
gets base + SSH + web, a server without a website only base + SSH. By the end, everything
inbound is blocked except what you deliberately allow.</p>
<p>A netcup-specific detail makes the difference: for <strong>UDP the firewall works statelessly</strong> –
which is why services like DNS and NTP need their own inbound rule, otherwise they suddenly
get stuck. Why that is and how the base template solves it is shown in step 2.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-sky-300 bg-sky-50 dark:border-sky-800 dark:bg-sky-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">ℹ️</span>Network firewall ≠ host firewall
  </p>
  <div class="prose-kitchen text-sm">The netcup firewall works in the <strong>network in front of the server</strong> and does <strong>not</strong>
replace the firewall on the server itself (<a href="/en/tutorials/firewall-ufw-setup/">UFW</a>). Both
together are &ldquo;defense in depth&rdquo;: if one layer fails or is misconfigured, the other kicks
in. Feel free to set up both.</div>
</div>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>A netcup server, e.g. your <a href="/en/tutorials/first-steps-netcup-vps/">first VPS</a>.</li>
<li>Your <strong>SCP credentials</strong> (customer number + SCP password from the netcup welcome email –
different from your SSH login).</li>
<li>Clarity about your <strong>SSH port</strong>: the default is <code>22</code>, and it stays that way when
<a href="/en/tutorials/harden-ssh/">hardening SSH</a>. If you changed it elsewhere, use your real
port – otherwise you lock yourself out when activating.</li>
</ul>
<div class="not-prose my-6 overflow-hidden rounded-xl border border-paprika-200 bg-paprika-50 dark:border-paprika-800 dark:bg-paprika-900/20">
  <div class="flex items-center justify-between border-b border-paprika-200 bg-paprika-100 px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-paprika-700 dark:border-paprika-800 dark:bg-paprika-900/40 dark:text-paprika-300">
    <span>🍳 Recommendation</span>
    <span title="Links marked with * are affiliate links.">Ad</span>
  </div>
  <div class="flex flex-col gap-4 p-4 sm:flex-row sm:items-center sm:justify-between">
    <div>
      <p class="text-lg font-bold text-slate-900 dark:text-white">VPS 1000 G12</p>
      <p class="mt-1 text-sm text-slate-600 dark:text-slate-300">4 vCores · 8 GB RAM · 256 GB NVMe</p>
      <p class="mt-1 text-sm font-semibold text-paprika-700 dark:text-paprika-400">from €10.36/month</p>
      <p class="mt-2 text-sm text-slate-600 dark:text-slate-400">The firewall is included in the SCP with every netcup server.</p>
    </div>
    <a href="https://www.netcup.com/en/server/vps/vps-1000-g12-iv-12m?ref=44083" rel="sponsored noopener" target="_blank"
   class="inline-flex shrink-0 items-center justify-center rounded-lg bg-paprika-600 px-5 py-2.5 font-semibold text-white transition-colors hover:bg-paprika-700">
  Go to netcup →
</a>

  </div><div class="px-4 pb-4"><p class="not-prose my-3 flex flex-wrap items-center gap-x-2 gap-y-1 rounded-lg border border-herb-500/40 bg-herb-50 px-3 py-2 text-sm text-slate-700 dark:bg-herb-900/20 dark:text-slate-200">
  <span>💶 <strong>5 € voucher</strong> for new netcup customers:</span>
  <code class="rounded bg-white px-2 py-0.5 font-mono text-sm font-semibold text-herb-800 dark:bg-slate-800 dark:text-herb-400">36nc17844976032</code>
  <span class="text-xs text-slate-500 dark:text-slate-400">(new customers only, no domains)</span>
</p></div>
</div>

<h2 id="step-by-step">Step by step</h2>
<h3 id="step-1-open-firewall-policies-in-the-scp">Step 1: Open Firewall Policies in the SCP</h3>
<p>Log into the <a href="https://www.servercontrolpanel.de/">Server Control Panel</a> and open the
<strong>Firewall Policies</strong> menu item at the top. Here you create reusable rule sets
(&ldquo;policies&rdquo;) – independent of the individual server. You only assign them later.</p>
<h3 id="step-2-build-the-base-template">Step 2: Build the base template</h3>
<p>Click <strong>Create firewall policy</strong>, give it the name <code>Serverküche Base</code> and, via <strong>Add
rule</strong>, create these four rules – all <strong>INBOUND</strong> and <strong>ACCEPT</strong>:</p>
<table>
	<thead>
			<tr>
					<th>Description</th>
					<th>Protocol</th>
					<th>Source port (Src)</th>
					<th>Destination port (Dst)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>DNS replies (stateless)</td>
					<td>UDP</td>
					<td><strong>53</strong></td>
					<td>any</td>
			</tr>
			<tr>
					<td>NTP replies (stateless)</td>
					<td>UDP</td>
					<td><strong>123</strong></td>
					<td>any</td>
			</tr>
			<tr>
					<td>ICMP (ping/PMTU)</td>
					<td>ICMP</td>
					<td>–</td>
					<td>–</td>
			</tr>
			<tr>
					<td>ICMPv6 (Neighbor Discovery)</td>
					<td>ICMPv6</td>
					<td>–</td>
					<td>–</td>
			</tr>
	</tbody>
</table>
<p><figure class="my-6"><img src="/en/tutorials/netcup-firewall-setup/netcup-fw-basis-regeln_hu_9e99585f9ae8a8a2.webp" srcset="/en/tutorials/netcup-firewall-setup/netcup-fw-basis-regeln_hu_940a2c430e5ad078.webp 480w, /en/tutorials/netcup-firewall-setup/netcup-fw-basis-regeln_hu_9e99585f9ae8a8a2.webp 768w, /en/tutorials/netcup-firewall-setup/netcup-fw-basis-regeln_hu_9b56e056028b7396.webp 1200w, /en/tutorials/netcup-firewall-setup/netcup-fw-basis-regeln_hu_a4a5b78ddd1de01e.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-firewall-setup/netcup-fw-basis-regeln_hu_191c700aae76cc67.webp"
    alt="The base template in the netcup SCP with four inbound ACCEPT rules: DNS and NTP via the source port, plus ICMP and ICMPv6" title="The base template: DNS/NTP replies come in via source port 53/123"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The base template: DNS/NTP replies come in via source port 53/123</figcaption></figure></p>
<p>Two things that make the difference here:</p>
<ul>
<li><strong>DNS/NTP via the <code>Src Port</code>, not the destination port.</strong> Your server <em>queries</em> DNS/NTP
(outbound); the <strong>reply</strong> comes back from port 53 or 123. Because UDP is stateless, you
need this inbound rule – otherwise there&rsquo;s no name resolution and no time
synchronization, even though &ldquo;everything else&rdquo; seems to work.</li>
<li><strong>Never forget ICMPv6.</strong> Without Neighbor Discovery, IPv6 breaks completely. ICMP (v4) on
top is useful for ping and path MTU discovery. netcup&rsquo;s default policy &ldquo;Ping allow&rdquo; does
already cover ICMP – it&rsquo;s deliberately in the base template again so your foundation stays
complete even if you ever remove the netcup defaults.</li>
</ul>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-sky-300 bg-sky-50 dark:border-sky-800 dark:bg-sky-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">ℹ️</span>As soon as one rule exists, netcup blocks the rest automatically
  </p>
  <div class="prose-kitchen text-sm">You do <strong>not</strong> need to create a final &ldquo;block everything&rdquo;. <strong>Without</strong> an assigned policy,
everything inbound is allowed. <strong>But as soon as you assign the server at least one of your
own policies, netcup switches the default to &ldquo;block all&rdquo;</strong> – from then on everything
inbound is blocked that none of your rules explicitly allows. So the whitelist arises on
its own; outbound stays open.</div>
</div>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Does your server use DHCP?
  </p>
  <div class="prose-kitchen text-sm">netcup VPS are usually configured <strong>statically</strong> (<code>iface … inet static</code>) – then there&rsquo;s
nothing to do here. netcup&rsquo;s network does run a DHCP server, but because UDP is stateless,
the DHCP <strong>reply</strong> (source port <strong>67</strong>) is discarded by the whitelist. If your server is
exceptionally configured via DHCP, add <code>INBOUND · UDP · ACCEPT · Src 67</code> to the base
template (for DHCPv6 additionally <code>Src 547</code>) – otherwise it loses its IP at the next lease
renewal.</div>
</div>
<h3 id="step-3-small-building-blocks-for-ssh-and-web">Step 3: Small building blocks for SSH and web</h3>
<p>Instead of one big rule monolith, you create <strong>atomic templates</strong> that you freely combine.
Create two more policies following the same pattern:</p>
<ul>
<li><strong><code>Serverküche SSH</code></strong> – one rule: INBOUND, TCP, ACCEPT, destination port <strong>22</strong>.</li>
<li><strong><code>Serverküche Web</code></strong> – two rules: INBOUND, TCP, ACCEPT, destination port <strong>80</strong> and
<strong>443</strong>.</li>
</ul>
<p><figure class="my-6"><img src="/en/tutorials/netcup-firewall-setup/netcup-fw-policys_hu_8300974e73f572e.webp" srcset="/en/tutorials/netcup-firewall-setup/netcup-fw-policys_hu_37f1808047787952.webp 480w, /en/tutorials/netcup-firewall-setup/netcup-fw-policys_hu_8300974e73f572e.webp 768w, /en/tutorials/netcup-firewall-setup/netcup-fw-policys_hu_4fba52dd0cbe8f8e.webp 1200w, /en/tutorials/netcup-firewall-setup/netcup-fw-policys_hu_490c02b761af2a0d.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-firewall-setup/netcup-fw-policys_hu_113b718980b0626c.webp"
    alt="The three composable firewall templates in the netcup SCP overview: base, SSH and web" title="Three small, reusable building blocks instead of one monolith"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Three small, reusable building blocks instead of one monolith</figcaption></figure></p>
<p>The gain: the base rules appear only <strong>once</strong>, not duplicated in every policy. If a service
is added later (e.g. a mail server or WireGuard), you build another small template for it
and plug it in – without touching the existing ones.</p>
<h3 id="step-4-assign-templates-to-the-server">Step 4: Assign templates to the server</h3>
<p>Switch to <strong>Server → your server → &ldquo;Firewall&rdquo; tab</strong> and click <strong>Edit firewall policies</strong>.
Move the appropriate ones from <strong>Available firewall policies</strong> to <strong>Selected</strong>: for a web
server <code>Serverküche Base</code> + <code>Serverküche SSH</code> + <code>Serverküche Web</code>.</p>
<p><figure class="my-6"><img src="/en/tutorials/netcup-firewall-setup/netcup-fw-zuweisen_hu_b5de2471022cffb5.webp" srcset="/en/tutorials/netcup-firewall-setup/netcup-fw-zuweisen_hu_916fa5dee97d09.webp 480w, /en/tutorials/netcup-firewall-setup/netcup-fw-zuweisen_hu_b5de2471022cffb5.webp 768w, /en/tutorials/netcup-firewall-setup/netcup-fw-zuweisen_hu_2f19ef31e0b0bfcc.webp 1200w, /en/tutorials/netcup-firewall-setup/netcup-fw-zuweisen_hu_1ec7e51f2b6aaab8.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-firewall-setup/netcup-fw-zuweisen_hu_d021fbd03a3210d1.webp"
    alt="The assignment dialog in the netcup SCP: on the left the available templates, on the right the ones selected for this server" title="Assign = plug together: base &#43; SSH &#43; web on a web server"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Assign = plug together: base &#43; SSH &#43; web on a web server</figcaption></figure></p>
<p>Confirm with <strong>Apply</strong> and then <strong>Save</strong>. Check that the <strong>&ldquo;Firewall active&rdquo;</strong> switch is
turned on. The assigned rules now appear in the list – together with netcup&rsquo;s <strong>default
policies</strong> (more on those below).</p>
<p><figure class="my-6"><img src="/en/tutorials/netcup-firewall-setup/netcup-fw-server_hu_1b203778eff9dee8.webp" srcset="/en/tutorials/netcup-firewall-setup/netcup-fw-server_hu_8c4daef82bf14989.webp 480w, /en/tutorials/netcup-firewall-setup/netcup-fw-server_hu_1b203778eff9dee8.webp 768w, /en/tutorials/netcup-firewall-setup/netcup-fw-server_hu_aec528535f9a750b.webp 1200w, /en/tutorials/netcup-firewall-setup/netcup-fw-server_hu_dbeac9995b0b9626.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-firewall-setup/netcup-fw-server_hu_d32ec044e4959b65.webp"
    alt="The server&rsquo;s firewall tab with an active firewall and the assigned rules" title="Firewall active – rules are evaluated top to bottom, the first match wins"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Firewall active – rules are evaluated top to bottom, the first match wins</figcaption></figure></p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>Don&#39;t lock yourself out
  </p>
  <div class="prose-kitchen text-sm">Only activate the firewall if the <strong>SSH rule</strong> (port 22 or your real port) is in it. During
the switch, keep a <strong>second SSH session open</strong> and open a new connection in parallel to test
access – only once that works do you close the old session. If you can&rsquo;t get in at all, the
VNC console under <strong>Display</strong> in the SCP helps.</div>
</div>
<h3 id="step-5-ready-made-templates-for-common-services">Step 5: Ready-made templates for common services</h3>
<p>Exactly following the pattern from step 3, here are ready-made templates for the most
common self-hosting services. Each is its <strong>own small template</strong>, all rules are <strong>INBOUND</strong>
and <strong>ACCEPT</strong>. Build only the ones you really need and plug them, as in step 4, into
<code>Serverküche Base</code> + <code>Serverküche SSH</code>.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-sky-300 bg-sky-50 dark:border-sky-800 dark:bg-sky-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">ℹ️</span>For UDP services: destination port, not source port
  </p>
  <div class="prose-kitchen text-sm">For UDP services you <strong>offer yourself</strong> (VPN, TURN, your own DNS server), the port is in the
<strong>destination port (Dst)</strong> – because here clients connect <em>to your server</em>. That&rsquo;s the
<strong>opposite</strong> of the DNS/NTP rules from the base template: there the port is in the <strong>source
port (Src)</strong>, because your server is the <em>querying client</em> whose reply comes back. TCP
replies aren&rsquo;t affected by this (the firewall state only matters for UDP); outbound is
allowed anyway.</div>
</div>
<h4 id="mail-server-mailcow--co">Mail server (mailcow &amp; co.)</h4>
<table>
	<thead>
			<tr>
					<th>Description</th>
					<th>Protocol</th>
					<th>Source port (Src)</th>
					<th>Destination port (Dst)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>SMTP (mail acceptance from others)</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>25</strong></td>
			</tr>
			<tr>
					<td>Submission (STARTTLS)</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>587</strong></td>
			</tr>
			<tr>
					<td>Submission (implicit TLS)</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>465</strong></td>
			</tr>
			<tr>
					<td>IMAP (STARTTLS)</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>143</strong></td>
			</tr>
			<tr>
					<td>IMAPS</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>993</strong></td>
			</tr>
			<tr>
					<td>POP3 (STARTTLS)</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>110</strong></td>
			</tr>
			<tr>
					<td>POP3S</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>995</strong></td>
			</tr>
			<tr>
					<td>ManageSieve (filter rules)</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>4190</strong></td>
			</tr>
	</tbody>
</table>
<p>Two things that <strong>additionally</strong> belong to a mail server:</p>
<ul>
<li><strong>Web UI and certificates:</strong> mailcow needs <code>80</code>/<code>443</code> for the web interface and the
Let&rsquo;s Encrypt retrieval – just assign the <code>Serverküche Web</code> template along with it.</li>
<li><strong>Enable outbound SMTP:</strong> a mail server must be able to deliver on <strong>port 25 outbound</strong>.
netcup blocks that with the default policy &ldquo;netcup Mail block&rdquo; – you have to <strong>remove</strong> it
on the server (see &ldquo;When things go wrong&rdquo;). And without a correct
<a href="/en/tutorials/connect-domain-to-server/">PTR/reverse-DNS entry</a> your mails land in spam.</li>
</ul>
<h4 id="wireguard-vpn">WireGuard VPN</h4>
<table>
	<thead>
			<tr>
					<th>Description</th>
					<th>Protocol</th>
					<th>Source port (Src)</th>
					<th>Destination port (Dst)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>WireGuard</td>
					<td>UDP</td>
					<td>–</td>
					<td><strong>51820</strong></td>
			</tr>
	</tbody>
</table>
<p><code>51820</code> is the usual default – use the value from your <code>ListenPort</code>. Only this one inbound
rule is needed; the replies to the clients go out outbound.</p>
<h4 id="openvpn">OpenVPN</h4>
<table>
	<thead>
			<tr>
					<th>Description</th>
					<th>Protocol</th>
					<th>Source port (Src)</th>
					<th>Destination port (Dst)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>OpenVPN (UDP, default)</td>
					<td>UDP</td>
					<td>–</td>
					<td><strong>1194</strong></td>
			</tr>
			<tr>
					<td>OpenVPN (TCP fallback)</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>1194</strong></td>
			</tr>
	</tbody>
</table>
<p>The default is <strong>UDP 1194</strong>. The TCP rule only if you deliberately run OpenVPN over TCP
(some additionally put it on <code>TCP 443</code> to get through restrictive foreign networks) –
otherwise leave it out.</p>
<h4 id="zabbix-monitoring">Zabbix monitoring</h4>
<p>Here it depends on the server&rsquo;s role:</p>
<table>
	<thead>
			<tr>
					<th>Role</th>
					<th>Description</th>
					<th>Protocol</th>
					<th>Destination port (Dst)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>Monitored host</strong> (Zabbix agent)</td>
					<td>passive checks from the server</td>
					<td>TCP</td>
					<td><strong>10050</strong></td>
			</tr>
			<tr>
					<td><strong>Zabbix server</strong></td>
					<td>trapper (active agents/proxies)</td>
					<td>TCP</td>
					<td><strong>10051</strong></td>
			</tr>
	</tbody>
</table>
<p>The Zabbix server additionally needs <code>80</code>/<code>443</code> for the web frontend (<code>Serverküche Web</code>). If
you run <strong>active</strong> checks, the agent connects outbound to the server on <code>10051</code> – for that,
<strong>no</strong> inbound rule is needed on the agent host.</p>
<h4 id="checkmk">Checkmk</h4>
<table>
	<thead>
			<tr>
					<th>Role</th>
					<th>Description</th>
					<th>Protocol</th>
					<th>Destination port (Dst)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>Monitored host</strong> (agent)</td>
					<td>agent controller, pull mode</td>
					<td>TCP</td>
					<td><strong>6556</strong></td>
			</tr>
			<tr>
					<td><strong>Checkmk server</strong> (optional)</td>
					<td>agent receiver (push/registration)</td>
					<td>TCP</td>
					<td><strong>8000</strong></td>
			</tr>
			<tr>
					<td><strong>Checkmk server</strong> (optional)</td>
					<td>Livestatus (distributed monitoring)</td>
					<td>TCP</td>
					<td><strong>6557</strong></td>
			</tr>
	</tbody>
</table>
<p>In the <strong>default pull mode</strong>, the Checkmk server fetches the data actively – so it connects
outbound to <code>6556</code> of the agents. Inbound, therefore, only the <strong>monitored host</strong> needs port
<code>6556</code>. The Checkmk server itself gets by with <code>80</code>/<code>443</code> (<code>Serverküche Web</code>); <code>8000</code> and
<code>6557</code> only if you use push mode or distributed monitoring.</p>
<h4 id="coturn--turn-server-nextcloud-talk-matrix">Coturn / TURN server (Nextcloud Talk, Matrix)</h4>
<table>
	<thead>
			<tr>
					<th>Description</th>
					<th>Protocol</th>
					<th>Source port (Src)</th>
					<th>Destination port (Dst)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>STUN/TURN</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>3478</strong></td>
			</tr>
			<tr>
					<td>STUN/TURN</td>
					<td>UDP</td>
					<td>–</td>
					<td><strong>3478</strong></td>
			</tr>
			<tr>
					<td>STUN/TURN over TLS</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>5349</strong></td>
			</tr>
			<tr>
					<td>STUN/TURN over TLS</td>
					<td>UDP</td>
					<td>–</td>
					<td><strong>5349</strong></td>
			</tr>
			<tr>
					<td>Media relay (audio/video)</td>
					<td>UDP</td>
					<td>–</td>
					<td><strong>49152–65535</strong></td>
			</tr>
	</tbody>
</table>
<p>The large UDP relay range is the default – the actual audio/video streams run over it. You
can narrow it in the coturn configuration (<code>min-port</code>/<code>max-port</code>) and then set the firewall
rule to the same, smaller range.</p>
<h4 id="your-own-dns-server-adguard-home-pi-hole-unbound">Your own DNS server (AdGuard Home, Pi-hole, Unbound)</h4>
<table>
	<thead>
			<tr>
					<th>Description</th>
					<th>Protocol</th>
					<th>Source port (Src)</th>
					<th>Destination port (Dst)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>DNS queries</td>
					<td>UDP</td>
					<td>–</td>
					<td><strong>53</strong></td>
			</tr>
			<tr>
					<td>DNS queries (large replies/TCP)</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>53</strong></td>
			</tr>
			<tr>
					<td>DNS-over-TLS (DoT)</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>853</strong></td>
			</tr>
	</tbody>
</table>
<p>Careful, this is exactly the <strong>opposite direction</strong> to the base template: there <code>Src 53</code>
allows the <em>replies</em> to your own DNS queries; here <code>Dst 53</code> allows the <em>queries of foreign
clients</em> to your DNS server. Both exist side by side without problems.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>No open resolver
  </p>
  <div class="prose-kitchen text-sm">A globally open recursive DNS server is abused for <strong>DNS amplification attacks</strong>. Restrict
access to your own networks (set the source address in the rule) or offer DNS exclusively
encrypted (DoT/DoH) for registered clients – never open <code>53</code> &ldquo;just quickly&rdquo; for the whole
world.</div>
</div>
<h4 id="remote-database-access-emergency-only">Remote database access (emergency only)</h4>
<table>
	<thead>
			<tr>
					<th>Description</th>
					<th>Protocol</th>
					<th>Source port (Src)</th>
					<th>Destination port (Dst)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>PostgreSQL</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>5432</strong></td>
			</tr>
			<tr>
					<td>MySQL / MariaDB</td>
					<td>TCP</td>
					<td>–</td>
					<td><strong>3306</strong></td>
			</tr>
	</tbody>
</table>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-paprika-400 bg-paprika-50 dark:border-paprika-700 dark:bg-paprika-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🔥</span>Databases don&#39;t belong on the open internet
  </p>
  <div class="prose-kitchen text-sm">A directly reachable database is a preferred attack target. The <strong>right</strong> way is to <strong>not</strong>
open the port at all and instead access it via a <a href="/en/#wireguard-vpn">WireGuard tunnel</a> or an
SSH tunnel (<code>ssh -L 5432:localhost:5432 …</code>). If you must open the port anyway, then <strong>only</strong>
with a source address restricted to your fixed admin IP in the netcup rule – never for
everyone.</div>
</div>
<h2 id="when-things-go-wrong">When things go wrong</h2>
<div class="troubleshoot not-prose">
<p><strong>After activating, name resolution stops working (<code>apt update</code> hangs, <code>ping domain.de</code>
fails, but <code>ping 1.1.1.1</code> works).</strong> The DNS <strong>replies</strong> are being blocked. Check the rule in
the base template <em>INBOUND UDP ACCEPT, Src port 53</em>. Important: <strong>source</strong> port, not
destination port.</p>
<p><strong>The clock drifts, or TLS certificates are rejected due to the wrong time.</strong> The NTP
replies are missing. Add <em>INBOUND UDP ACCEPT, Src port 123</em>.</p>
<p><strong>IPv6 no longer works (v4 does).</strong> The <strong>ICMPv6</strong> rule is missing. Without Neighbor
Discovery, the server can&rsquo;t even find its neighbor (router) over IPv6.</p>
<p><strong>After activating, you can no longer get in via SSH.</strong> The SSH rule is missing or names the
wrong port. Via the <strong>VNC console</strong> (SCP → Display) you can still reach the server; correct
the policy and save again. That&rsquo;s exactly what the &ldquo;keep a second session open&rdquo; rule above
helps against.</p>
<p><strong>The server can&rsquo;t send emails (outbound port 25 doesn&rsquo;t work).</strong> That&rsquo;s <strong>not</strong> an error in
your policy, but netcup&rsquo;s <strong>default policy &ldquo;netcup Mail block&rdquo;</strong> – it blocks outbound SMTP
(ports 25/465/587) as spam protection. For real mail sending you have to disable this netcup
template on the server.</p>
<p><strong>The server initially runs normally and is suddenly offline after one or two weeks.</strong> If
the server uses DHCP, the <strong>lease renewal</strong> is blocked by the whitelist – the DHCP reply
comes from UDP source port <strong>67</strong>, which no rule allows, and UDP is stateless. Add <code>INBOUND · UDP · ACCEPT · Src 67</code> to the base template. Statically configured netcup VPS (the
default) aren&rsquo;t affected.</p>

</div>

<h2 id="maintenance--backups">Maintenance &amp; backups</h2>
<ul>
<li><strong>Test access after every change.</strong> Firewall rules are the classic way to lock yourself
out. Keep a second session open, check a new connection, only then finish.</li>
<li><strong>New services = new template.</strong> If you later need another port (game server, WireGuard
VPN over UDP, database), create a small template of your own and assign it additionally.
The existing building blocks stay untouched.</li>
<li><strong>Mind the order.</strong> netcup evaluates the rules <strong>top to bottom</strong>; the <strong>first</strong> matching
rule wins. For pure ACCEPT rules that doesn&rsquo;t matter – but as soon as you use your own DROP
rules, watch the order relative to the ACCEPTs.</li>
<li><strong>Know netcup&rsquo;s default policies.</strong> &ldquo;netcup Mail block&rdquo; (outbound SMTP on ports 25/465/587
blocked) and &ldquo;netcup Ping allow&rdquo; are predefined. Via <strong>Restore default policies</strong> you can,
in an emergency, get back to a known, working baseline if you locked yourself out with your
own rules – together with the VNC console, your second safety net.</li>
</ul>
]]></content:encoded></item><item><title>Hardening SSH access</title><link>https://serverkueche.de/en/tutorials/harden-ssh/</link><pubDate>Tue, 14 Jul 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/en/tutorials/harden-ssh/</guid><description>Key-based login instead of passwords and no root login: the most important moves to harden the front door to your server.</description><content:encoded><![CDATA[<p>After the <a href="/en/tutorials/first-steps-netcup-vps/">initial setup</a> we harden the SSH
access – the most important door to your server.</p>
<h2 id="what-are-we-building">What are we building?</h2>
<p>By the end you log in with an <strong>SSH key</strong> instead of a password, and neither root
login nor password login is possible from outside. This makes the automated
password-guessing attacks that hit every publicly reachable server around the
clock run completely into the void. Tested with <strong>OpenSSH on Debian 13</strong>.</p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>A <a href="/en/tutorials/first-steps-netcup-vps/">set-up server</a> with a sudo user</li>
<li>Access to the VNC console in the netcup SCP as a safety line in case you lock yourself out</li>
</ul>
<h2 id="step-by-step">Step by step</h2>
<h3 id="step-1-generate-an-ssh-key-pair">Step 1: Generate an SSH key pair</h3>
<p>If you don&rsquo;t have a key yet, generate an Ed25519 key pair <strong>on your own machine</strong>
(not on the server!):</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ssh-keygen -t ed25519</span></span></code></pre></div>
</div>
<p>You can accept the suggested storage location with Enter. Set a <strong>passphrase</strong> –
it protects the key if your machine falls into the wrong hands. Two files are
created: <code>~/.ssh/id_ed25519</code> (private, stays with you) and
<code>~/.ssh/id_ed25519.pub</code> (public, goes on the server).</p>
<h3 id="step-2-transfer-the-public-key">Step 2: Transfer the public key</h3>
<p><code>ssh-copy-id</code> appends your public key to the <code>~/.ssh/authorized_keys</code> file of your
server user – with the correct file permissions:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ssh-copy-id koch@YOUR_SERVER_IP</span></span></code></pre></div>
</div>
<p>Test right afterwards that key login works:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ssh koch@YOUR_SERVER_IP</span></span></code></pre></div>
</div>
<p>You should now be logged in <strong>without</strong> a server password (only the passphrase of
your key may be requested). Only once that works do we continue – in the next step
we disable password login.</p>
<h3 id="step-3-disable-password-login-and-root-login">Step 3: Disable password login and root login</h3>
<p>Open the SSH server configuration:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo nano /etc/ssh/sshd_config</span></span></code></pre></div>
</div>
<p>Set (or uncomment) these two lines:</p>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">PermitRootLogin no
</span></span><span class="line"><span class="cl">PasswordAuthentication no</span></span></code></pre></div>
</div>
<p><code>PermitRootLogin no</code> blocks direct root login completely,
<code>PasswordAuthentication no</code> allows only key logins.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>Warning
  </p>
  <div class="prose-kitchen text-sm">On cloud images there are often extra files under <code>/etc/ssh/sshd_config.d/</code> that
<strong>override</strong> these settings. Check with
<code>grep -r PasswordAuthentication /etc/ssh/sshd_config.d/</code> and adjust any matches as
well.</div>
</div>
<h3 id="step-4-test-the-configuration-and-restart-ssh">Step 4: Test the configuration and restart SSH</h3>
<p>Check the configuration for syntax errors <strong>before</strong> you restart – a typo would
otherwise take the SSH service down:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo sshd -t</span></span></code></pre></div>
</div>
<p>No output means: all good. Then apply it:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo systemctl restart ssh</span></span></code></pre></div>
</div>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-paprika-400 bg-paprika-50 dark:border-paprika-700 dark:bg-paprika-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🔥</span>Caution
  </p>
  <div class="prose-kitchen text-sm">Test key login now in a <strong>second</strong> terminal session before you close the first –
otherwise you might lock yourself out.</div>
</div>
<p>To verify: <code>sudo systemctl status ssh</code> should show <code>active (running)</code>, and a login
attempt as root must now be rejected with <code>Permission denied (publickey)</code>.</p>
<h2 id="when-things-go-wrong">When things go wrong</h2>
<div class="troubleshoot not-prose">
<p><strong>SSH keeps asking for the password despite <code>ssh-copy-id</code>.</strong> Usually the file
permissions on the server are wrong. SSH ignores <code>authorized_keys</code> if the
permissions are too open: <code>chmod 700 ~/.ssh &amp;&amp; chmod 600 ~/.ssh/authorized_keys</code>.
Also check that you&rsquo;re connecting with the right user (<code>koch@…</code>, not <code>root@…</code>).</p>
<p><strong><code>Permission denied (publickey)</code> – and you can&rsquo;t get in at all anymore.</strong>
Password login was disabled before the key worked. No drama: open the <strong>VNC
console in the netcup SCP</strong>, log in locally there, set <code>PasswordAuthentication yes</code>, restart SSH and start again at step 2.</p>
<p><strong>After the restart the SSH service no longer starts.</strong> Syntax error in the
<code>sshd_config</code> (that&rsquo;s why you always run <code>sshd -t</code> before restarting). Log in via
the VNC console; <code>sudo sshd -t</code> shows you the file and line number of the error.</p>
<p><strong>The settings seem to take effect, but password login still works.</strong> A file under
<code>/etc/ssh/sshd_config.d/</code> (often <code>50-cloud-init.conf</code>) overrides your values.
<code>sudo sshd -T | grep -i passwordauthentication</code> shows the actually effective
setting – adjust matches in the extra files and restart SSH.</p>

</div>

<h2 id="maintenance--backups">Maintenance &amp; backups</h2>
<ul>
<li><strong>Back up the private key:</strong> Without <code>~/.ssh/id_ed25519</code> you can only reach the
server via the VNC console. Back up the key encrypted (e.g. in a password
manager) or add a second key from another device to <code>authorized_keys</code>.</li>
<li><strong>Keep an eye on logins:</strong> <code>sudo journalctl -u ssh --since today</code> shows you all
login attempts. Failed attempts on port 22 are normal and, thanks to the
key requirement, harmless – you can automatically ban such bots later with
<a href="/en/tutorials/fail2ban-setup/">Fail2ban</a>.</li>
<li><strong>Updates:</strong> OpenSSH gets its security updates through the normal <code>apt upgrade</code> –
so keep the server up to date, ideally
<a href="/en/tutorials/unattended-upgrades-automatic-updates/">automated</a>.</li>
</ul>
]]></content:encoded></item><item><title>First steps with a netcup VPS</title><link>https://serverkueche.de/en/tutorials/first-steps-netcup-vps/</link><pubDate>Mon, 13 Jul 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/en/tutorials/first-steps-netcup-vps/</guid><description>From a freshly ordered netcup server to a ready-to-use system: SSH login, system updates, a sudo user and the most important first steps.</description><content:encoded><![CDATA[<p>You&rsquo;ve ordered your first netcup server – congratulations! Before we fire up the
kitchen, let&rsquo;s set the system up cleanly.</p>
<h2 id="what-are-we-building">What are we building?</h2>
<p>By the end of this tutorial, your VPS runs a current <strong>Debian 13</strong> with all
security updates, and you work with your own user with sudo rights instead of
permanently as <code>root</code>. That&rsquo;s the foundation for all the other recipes in the
Serverküche – from hardening SSH to your first application.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Tip
  </p>
  <div class="prose-kitchen text-sm">All commands are written for <strong>Debian 13</strong>. On Ubuntu they work almost
identically.</div>
</div>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>An ordered netcup server with the credentials from your customer account</li>
<li>A terminal on your machine (Linux/macOS) or an SSH client like PuTTY (Windows)</li>
</ul>
<p>Not sure which server size you even need? The
<a href="/en/server-calculator/">server calculator</a> estimates the RAM and CPU you&rsquo;ll need for your
planned services and suggests a matching netcup plan.</p>
<div class="not-prose my-6 overflow-hidden rounded-xl border border-paprika-200 bg-paprika-50 dark:border-paprika-800 dark:bg-paprika-900/20">
  <div class="flex items-center justify-between border-b border-paprika-200 bg-paprika-100 px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-paprika-700 dark:border-paprika-800 dark:bg-paprika-900/40 dark:text-paprika-300">
    <span>🍳 Recommendation</span>
    <span title="Links marked with * are affiliate links.">Ad</span>
  </div>
  <div class="flex flex-col gap-4 p-4 sm:flex-row sm:items-center sm:justify-between">
    <div>
      <p class="text-lg font-bold text-slate-900 dark:text-white">VPS 1000 G12</p>
      <p class="mt-1 text-sm text-slate-600 dark:text-slate-300">4 vCores · 8 GB RAM · 256 GB NVMe</p>
      <p class="mt-1 text-sm font-semibold text-paprika-700 dark:text-paprika-400">from €10.36/month</p>
      <p class="mt-2 text-sm text-slate-600 dark:text-slate-400">A good start for most self-hosting projects.</p>
    </div>
    <a href="https://www.netcup.com/en/server/vps/vps-1000-g12-iv-12m?ref=44083" rel="sponsored noopener" target="_blank"
   class="inline-flex shrink-0 items-center justify-center rounded-lg bg-paprika-600 px-5 py-2.5 font-semibold text-white transition-colors hover:bg-paprika-700">
  Go to netcup →
</a>

  </div><div class="px-4 pb-4"><p class="not-prose my-3 flex flex-wrap items-center gap-x-2 gap-y-1 rounded-lg border border-herb-500/40 bg-herb-50 px-3 py-2 text-sm text-slate-700 dark:bg-herb-900/20 dark:text-slate-200">
  <span>💶 <strong>5 € voucher</strong> for new netcup customers:</span>
  <code class="rounded bg-white px-2 py-0.5 font-mono text-sm font-semibold text-herb-800 dark:bg-slate-800 dark:text-herb-400">36nc17844976032</code>
  <span class="text-xs text-slate-500 dark:text-slate-400">(new customers only, no domains)</span>
</p></div>
</div>

<h2 id="step-by-step">Step by step</h2>
<h3 id="step-1-log-in-via-ssh">Step 1: Log in via SSH</h3>
<p>Log in with your server&rsquo;s IP address as <code>root</code>. You&rsquo;ll find the IP and the
password in the credentials from your customer account:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ssh root@YOUR_SERVER_IP</span></span></code></pre></div>
</div>
<p>On the very first login, SSH asks whether you want to trust the server:</p>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">The authenticity of host &#39;YOUR_SERVER_IP&#39; can&#39;t be established.
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">Are you sure you want to continue connecting (yes/no/[fingerprint])?</span></span></code></pre></div>
</div>
<p>Answer <code>yes</code> – your machine remembers the server from now on. After that you land
on a prompt like <code>root@v12345:~#</code>.</p>
<h3 id="step-2-update-the-system">Step 2: Update the system</h3>
<p>Freshly delivered images are rarely up to date. So the first thing to do is fetch
all updates – security updates in particular should never wait:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">apt update <span class="o">&amp;&amp;</span> apt upgrade -y</span></span></code></pre></div>
</div>
<p><code>apt update</code> fetches the current package lists, <code>apt upgrade -y</code> installs all
available updates without prompting.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>Warning
  </p>
  <div class="prose-kitchen text-sm">Reboot the server after a kernel update (<code>reboot</code>) so the changes take effect. On
a fresh Debian there&rsquo;s no automation for this yet – the safest bet is a reboot
right after the first big update. Debian does <strong>not</strong> create the marker file
<code>/var/run/reboot-required</code> (which indicates a pending reboot) on kernel updates by
default – you&rsquo;ll set up the matching hook later together with
<a href="/en/tutorials/unattended-upgrades-automatic-updates/">automatic updates</a>.</div>
</div>
<h3 id="step-3-create-a-sudo-user">Step 3: Create a sudo user</h3>
<p>Don&rsquo;t work as <code>root</code> permanently: a typo with full rights can wreck the entire
system, and having your own user is the prerequisite for
<a href="/en/tutorials/harden-ssh/">disabling root login completely</a> later. Create a
user – we&rsquo;ll call it <code>koch</code> (&ldquo;cook&rdquo;) here, but you can pick any name:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">adduser koch</span></span></code></pre></div>
</div>
<p>You&rsquo;ll be asked for a password and a few optional details (you can skip the
details with Enter). After that, give the user sudo rights:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">usermod -aG sudo koch</span></span></code></pre></div>
</div>
<h3 id="step-4-test-the-new-user">Step 4: Test the new user</h3>
<p>Check <strong>in a new terminal session</strong> (keep the root session open!) that login and
sudo work:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ssh koch@YOUR_SERVER_IP
</span></span><span class="line"><span class="cl">sudo whoami</span></span></code></pre></div>
</div>
<p>After entering your password, <code>sudo whoami</code> should return <code>root</code>. From now on you
continue working with this user.</p>
<h2 id="when-things-go-wrong">When things go wrong</h2>
<div class="troubleshoot not-prose">
<p><strong><code>ssh: connect to host … port 22: Connection timed out</code>.</strong> Usually the IP was
mistyped or the server isn&rsquo;t fully provisioned yet. Check the IP in your customer
account and whether the server is shown as &ldquo;online&rdquo; there. Wait a few minutes
after ordering.</p>
<p><strong><code>Permission denied, please try again</code> on root login.</strong> Wrong password – often a
copy-paste issue with invisible trailing spaces, or a different keyboard layout.
Copy the password without surrounding spaces directly from the credentials.</p>
<p><strong><code>WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!</code>.</strong> The server was reinstalled
and has a new host key – SSH rightly raises the alarm. If <strong>you</strong> reinstalled it,
remove the old entry with <code>ssh-keygen -R YOUR_SERVER_IP</code> and reconnect. If you
didn&rsquo;t reinstall, investigate before you connect.</p>
<p><strong><code>sudo: command not found</code> as the new user.</strong> On minimal images the package is
sometimes missing. Install it as <code>root</code>: <code>apt install sudo</code>. Then check that the
user is in the group: <code>groups koch</code> must contain <code>sudo</code> – otherwise repeat step 3
and log out and back in once.</p>

</div>

<h2 id="maintenance--backups">Maintenance &amp; backups</h2>
<ul>
<li><strong>Updates:</strong> You should schedule <code>sudo apt update &amp;&amp; sudo apt upgrade</code> at least
<strong>weekly</strong> – or
<a href="/en/tutorials/unattended-upgrades-automatic-updates/">automate security updates</a>
with <code>unattended-upgrades</code>.</li>
<li><strong>Snapshots:</strong> Create a snapshot in the
<a href="/en/tutorials/netcup-snapshots-scp/">netcup Server Control Panel (SCP)</a> before
bigger changes. It&rsquo;s your safety line while you don&rsquo;t have a proper backup
strategy yet – but a snapshot does <strong>not replace</strong> a backup outside the server.</li>
<li><strong>Credentials:</strong> Keep the root password safe (password manager). Via the VNC
console in the SCP you can still reach the server even when SSH is stuck.</li>
</ul>
<p>You&rsquo;ll find both in the server overview of the SCP: the <strong>VNC console</strong> is under
the <strong>&ldquo;Bildschirm&rdquo; (Display)</strong> tab, and the remaining <strong>snapshot quota</strong> is shown
in the status block.</p>
<p><figure class="my-6"><img src="/en/tutorials/first-steps-netcup-vps/netcup-scp-server_hu_8973a5aa80175a41.webp" srcset="/en/tutorials/first-steps-netcup-vps/netcup-scp-server_hu_ddb4950e5055f484.webp 480w, /en/tutorials/first-steps-netcup-vps/netcup-scp-server_hu_8973a5aa80175a41.webp 768w, /en/tutorials/first-steps-netcup-vps/netcup-scp-server_hu_18e42b31ae963ce5.webp 1200w, /en/tutorials/first-steps-netcup-vps/netcup-scp-server_hu_47fe22d828e0f3e5.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/first-steps-netcup-vps/netcup-scp-server_hu_7cd6ca3ca4c57df9.webp"
    alt="The server overview in the netcup Server Control Panel: tabs including &ldquo;Display&rdquo; (VNC console), status with snapshot quota, and the hardware specs" title="Server overview in the netcup SCP – the Display tab is the VNC console"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Server overview in the netcup SCP – the Display tab is the VNC console</figcaption></figure></p>
]]></content:encoded></item></channel></rss>