<?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>S3 – Serverküche</title><link>https://serverkueche.de/en/tags/s3/</link><description>S3 – 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>Wed, 21 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://serverkueche.de/en/tags/s3/index.xml" rel="self" type="application/rss+xml"/><item><title>netcup eos hands-on: the new cloud in preview</title><link>https://serverkueche.de/en/tutorials/netcup-eos-preview/</link><pubDate>Wed, 21 Oct 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/en/tutorials/netcup-eos-preview/</guid><description>netcup's new cloud platform eos in preview: VM, network, ACLs and S3 tried out, with benchmarks against the VPS 1000 and every stumbling block.</description><content:encoded><![CDATA[<p>netcup is building its own cloud: eos, aimed at people who manage servers via API, Terraform or
an AI agent rather than by clicking. We were in the closed preview and tried out what already
works – and where it still catches.</p>
<p>Up front: this is the state of a test phase. eos goes public in 2027; netcup customers are to get
access earlier through a friends &amp; family launch. Prices, sizes and many details will change until
then.</p>
<h2 id="what-are-we-building">What are we building?</h2>
<p>We set up a Debian VM in eos, make it reachable via SSH, back up data with restic into the
platform&rsquo;s S3 storage and measure the VM with the same benchmarks as our
<a href="/en/tutorials/netcup-vps-1000-benchmark/">VPS 1000</a>. Along the way we show the stumbling blocks
you hit the first time – two of them cost half an hour without warning.</p>
<p>eos stands for &ldquo;European Orchestrated Sovereignty&rdquo; and launched as a preview in August 2026. So
far the platform runs in <strong>one region, Klagenfurt</strong>, and bills by the minute. Everything the web
interface does is also available through a REST API with a public OpenAPI description, the
command-line tool <code>eosctl</code>, a Terraform provider and an MCP server for AI agents. That part –
infrastructure as code – is covered in
netcup eos with eosctl and OpenTofu <span class="text-sm text-slate-500 dark:text-slate-400">(Tutorial expected in October)</span>; here we
look at the platform itself.</p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li><strong>Access to the eos preview</strong>. Sign-up ran through the netcup forum and was open to netcup
customers only; according to netcup, the test phase ran until 17 October. Next comes a
friends &amp; family launch for netcup customers, with the public launch planned for 2027.</li>
<li>An SSH key on your machine (<code>ssh-keygen -t ed25519</code>) – how and why is covered in
<a href="/en/tutorials/harden-ssh/">Harden SSH</a>.</li>
<li>Basic Linux server knowledge, as taught in
<a href="/en/tutorials/first-steps-netcup-vps/">First steps with your netcup VPS</a>.</li>
</ul>
<p>Whatever you create in the preview is explicitly not meant for production: no SLAs, no
redundancy guarantee, and all data is deleted after the test phase.</p>
<h2 id="step-by-step">Step by step</h2>
<h3 id="1-the-console-organisation-realm-permissions">1. The console: organisation, realm, permissions</h3>
<p>After logging in (password plus TOTP, or directly with a security key) you land on the dashboard
of an <strong>organisation</strong>. Below it sit <strong>realms</strong> – workspaces, for example one per project or
environment. Permissions are granted through teams; for automation there are client credentials
at organisation or realm level.</p>
<p><figure class="my-6"><img src="/en/tutorials/netcup-eos-preview/eos-dashboard_hu_92f0b0bdb1a6c47b.webp" srcset="/en/tutorials/netcup-eos-preview/eos-dashboard_hu_b196a81dd274070c.webp 480w, /en/tutorials/netcup-eos-preview/eos-dashboard_hu_92f0b0bdb1a6c47b.webp 768w, /en/tutorials/netcup-eos-preview/eos-dashboard_hu_c6d791d3aa3df3d6.webp 1200w, /en/tutorials/netcup-eos-preview/eos-dashboard_hu_e9b70828a9d2f26c.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-eos-preview/eos-dashboard_hu_3a1ff0e3ea96be7f.webp"
    alt="The eos dashboard of an organisation with tiles for access, realms, useful links and recent activity" title="The dashboard: organisation top left, the realm with all resources below"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The dashboard: organisation top left, the realm with all resources below</figcaption></figure></p>
<p>The realm&rsquo;s left-hand menu lists the building blocks: Virtual Machines, Networking, ACL, Public IP,
Volume Storage and Object Storage. Kubernetes, managed databases, load balancers and a container
registry are still missing. There are no automatic backups either – you create snapshots by hand.</p>
<h3 id="2-creating-the-first-vm">2. Creating the first VM</h3>
<p>Under <strong>Virtual Machines → Create new</strong> you pick the size, image and root disk. The preview offered
three sizes, all with a 1 Gbit/s network card:</p>
<table>
	<thead>
			<tr>
					<th>Type</th>
					<th>vCores</th>
					<th>RAM</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>vServer Mini</td>
					<td>1</td>
					<td>2 GB</td>
			</tr>
			<tr>
					<td>vServer Small</td>
					<td>2</td>
					<td>4 GB</td>
			</tr>
			<tr>
					<td>vServer Medium</td>
					<td>4</td>
					<td>8 GB</td>
			</tr>
	</tbody>
</table>
<p>Images available: Alpine Edge, Arch Linux, Debian 13 and Ubuntu 26.04, each also as a <strong>cloud
variant</strong> with cloud-init. The root disk size is free, starting at 10 GB.</p>
<p><figure class="my-6"><img src="/en/tutorials/netcup-eos-preview/eos-vm-erstellen_hu_3ada93e6ee46e2ca.webp" srcset="/en/tutorials/netcup-eos-preview/eos-vm-erstellen_hu_b0f2be38c2eaee10.webp 480w, /en/tutorials/netcup-eos-preview/eos-vm-erstellen_hu_3ada93e6ee46e2ca.webp 768w, /en/tutorials/netcup-eos-preview/eos-vm-erstellen_hu_d298e0a99ae00c74.webp 1200w, /en/tutorials/netcup-eos-preview/eos-vm-erstellen_hu_83ebec34270a3b9f.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-eos-preview/eos-vm-erstellen_hu_50a1dca8ec7542c8.webp"
    alt="The eos VM wizard with the three sizes, an uploaded cloud-init file, the Debian 13 Cloud image and a 20 GB root disk" title="The VM wizard – all three sizes at the same placeholder price"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The VM wizard – all three sizes at the same placeholder price</figcaption></figure></p>
<p>Prices in the preview are play money (&ldquo;credits&rdquo;) and clearly placeholders: all three sizes cost
the same, 10 GB of disk is supposed to cost ten times as much as the VM, and the console regularly
reports <code>Price conversion error</code> in the top right. Nothing about later prices can be read from it.</p>
<p>A new VM reached <code>ready / started</code> in about half a minute.</p>
<h3 id="3-cloud-init-the-ssh-server-is-missing">3. Cloud-init: the SSH server is missing</h3>
<p>The most important stumbling block first: <strong>even the cloud images ship without an SSH server.</strong>
Cloud-init dutifully creates your user and key, but <code>openssh-server</code> is not installed. Pass only a
user with a key and you get a VM that accepts nothing on port 22.</p>
<p>The console only takes cloud-init as a <strong>file upload</strong>, not as a text field. So create a file
<code>user-data.yaml</code> locally:</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c">#cloud-config</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">users</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">koch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">groups</span><span class="p">:</span><span class="w"> </span><span class="l">sudo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">shell</span><span class="p">:</span><span class="w"> </span><span class="l">/bin/bash</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">sudo</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;ALL=(ALL) NOPASSWD:ALL&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ssh_authorized_keys</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">ssh-ed25519 AAAA… YOUR_KEY</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">package_update</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">packages</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">openssh-server</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">write_files</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/ssh/sshd_config.d/10-nur-schluessel.conf</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">content</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">      PasswordAuthentication no
</span></span></span><span class="line"><span class="cl"><span class="sd">      PermitRootLogin no</span></span></span></code></pre></div>
</div>
<p>Replace <code>YOUR_KEY</code> with the contents of your <code>~/.ssh/id_ed25519.pub</code>. The file creates a user
<code>koch</code> with sudo rights, installs the SSH server and disables password and root login through a
drop-in file.</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 use ssh_pwauth
  </p>
  <div class="prose-kitchen text-sm">The obvious key <code>ssh_pwauth: false</code> locks you out. To apply it, cloud-init writes an
<code>/etc/ssh/sshd_config</code> – at a point when the package isn&rsquo;t installed yet. The result is a file with
exactly one line, <code>PasswordAuthentication no</code>, and the <code>openssh-server</code> installed afterwards keeps
it. Without Debian&rsquo;s default configuration <code>UsePAM yes</code> is missing, and the account whose password
cloud-init locked is then refused even with a key. The log says
<code>User koch not allowed because account is locked</code>. The drop-in file above avoids this.</div>
</div>
<p>eos&rsquo;s official SSH guide, by the way, takes a different route: set a root password and allow
<code>PermitRootLogin yes</code>. That may do for a test, not for a server on the internet.</p>
<h3 id="4-the-web-console-root-without-logging-in">4. The web console: root without logging in</h3>
<p>Without SSH you&rsquo;re still not locked out. In a VM&rsquo;s three-dot menu, <strong>Open Console</strong> opens a root
shell in the browser – no password, straight in as root.</p>
<p><figure class="my-6"><img src="/en/tutorials/netcup-eos-preview/eos-konsole_hu_48266a4c1d0ceaa6.webp" srcset="/en/tutorials/netcup-eos-preview/eos-konsole_hu_b897d0fa0f2cdf75.webp 480w, /en/tutorials/netcup-eos-preview/eos-konsole_hu_48266a4c1d0ceaa6.webp 768w, /en/tutorials/netcup-eos-preview/eos-konsole_hu_6f3661edb57917a8.webp 1200w, /en/tutorials/netcup-eos-preview/eos-konsole_hu_e49f329f92fc2af2.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-eos-preview/eos-konsole_hu_6daeff6e5c1b351f.webp"
    alt="The eos web console shows a root shell with cloud-init finished, the SSH service active and the created user" title="Open Console: a root shell in the browser, no login"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Open Console: a root shell in the browser, no login</figcaption></figure></p>
<p>That&rsquo;s handy for repairs and at the same time the reason your eos account needs a second factor:
whoever reaches the console has root on every VM. After the first boot, check there:</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">cloud-init status
</span></span><span class="line"><span class="cl">systemctl is-active ssh</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">status: done
</span></span><span class="line"><span class="cl">active</span></span></code></pre></div>
</div>
<h3 id="5-public-ip-and-acl-two-steps-not-one">5. Public IP and ACL: two steps, not one</h3>
<p>A new VM only has private addresses. Every network does get a public IPv4 and IPv6, but those are
for outbound traffic and port forwards only – they can&rsquo;t be attached to a VM. For direct access,
create your own address under <strong>Public IP → Create new</strong> and attach it to the VM with <strong>Attach
Public IP</strong> (always 1:1).</p>
<p><figure class="my-6"><img src="/en/tutorials/netcup-eos-preview/eos-vm-detail_hu_a52c343441ab60a9.webp" srcset="/en/tutorials/netcup-eos-preview/eos-vm-detail_hu_da9d221fcafe79f7.webp 480w, /en/tutorials/netcup-eos-preview/eos-vm-detail_hu_a52c343441ab60a9.webp 768w, /en/tutorials/netcup-eos-preview/eos-vm-detail_hu_f44d550495c231.webp 1200w, /en/tutorials/netcup-eos-preview/eos-vm-detail_hu_bd24b05164c422a.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-eos-preview/eos-vm-detail_hu_2c85209946340947.webp"
    alt="The detail page of a VM with root volume, attached public IP and the open action menu" title="The VM detail page: volumes, public IP and every action in the three-dot menu"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The VM detail page: volumes, public IP and every action in the three-dot menu</figcaption></figure></p>
<p>The VM still isn&rsquo;t reachable after that. eos works &ldquo;secure by default&rdquo;: every network has a
default ACL, and it is empty. Inbound everything is rejected, outbound everything is allowed. For
SSH you need a rule under <strong>ACL → Add New Rule</strong>:</p>
<ul>
<li>Action <code>Allow</code>, Protocol <code>TCP</code></li>
<li>Sources: your own IP – or empty for &ldquo;from anywhere&rdquo;</li>
<li>Destinations: the VM&rsquo;s <strong>internal</strong> IP, e.g. <code>172.19.144.3</code></li>
<li>Destination Ports: <code>22</code></li>
</ul>
<p><figure class="my-6"><img src="/en/tutorials/netcup-eos-preview/eos-acl_hu_1904ddb0ebe84059.webp" srcset="/en/tutorials/netcup-eos-preview/eos-acl_hu_cb81a5b0a9e65f4.webp 480w, /en/tutorials/netcup-eos-preview/eos-acl_hu_1904ddb0ebe84059.webp 768w, /en/tutorials/netcup-eos-preview/eos-acl_hu_6b7393633c8d9ea7.webp 1200w, /en/tutorials/netcup-eos-preview/eos-acl_hu_723bc886d7970a8f.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-eos-preview/eos-acl_hu_279e9c13c294a504.webp"
    alt="The default ACL of an eos network with one rule allowing TCP port 22 from a source IP to the VM&rsquo;s internal IP" title="One rule is enough: TCP 22 from a source to the VM&#39;s internal address"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">One rule is enough: TCP 22 from a source to the VM&#39;s internal address</figcaption></figure></p>
<p>In the destination field the console also offers to pick a VM via <code>@name</code>. In the preview exactly
that failed: the API accepted the rule, and shortly afterwards the console reported
<code>Failed to create ACL Rule</code>. With the internal IP as destination the rule was active immediately.</p>
<p>The cross-check shows whether the ACL works: from the allowed address you get in via SSH, from any
other the connection attempt times out. VMs in the same network need no rule – they reach each
other privately at around 1 ms.</p>
<h3 id="6-performance-cpu-strong-disk-and-network-halved">6. Performance: CPU strong, disk and network halved</h3>
<p>We measured a Medium VM (4 vCores, 8 GB) with the same commands as the
<a href="/en/tutorials/netcup-vps-1000-benchmark/">VPS 1000 G12</a>, which also has 4 cores and 8 GB. These
are single runs on preview infrastructure – a snapshot, not a verdict on the later product.</p>
<table>
	<thead>
			<tr>
					<th></th>
					<th>eos Medium</th>
					<th>VPS 1000 G12</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>sysbench CPU, 1 / 4 threads</td>
					<td>1,509 / 5,831</td>
					<td>1,495 / 5,974</td>
			</tr>
			<tr>
					<td>7-Zip (total MIPS)</td>
					<td>29,100</td>
					<td>27,400</td>
			</tr>
			<tr>
					<td>AES-256-GCM</td>
					<td>12.5 GB/s</td>
					<td>7.7 GB/s</td>
			</tr>
			<tr>
					<td>RAM (sysbench, 4 threads)</td>
					<td>28,200 MiB/s</td>
					<td>28,700 MiB/s</td>
			</tr>
			<tr>
					<td>4K read / write (IOPS)</td>
					<td>45,700 / 36,700</td>
					<td>101,000 / 67,000</td>
			</tr>
			<tr>
					<td>sequential read / write</td>
					<td>2,100 / 1,650 MiB/s</td>
					<td>4,300 / 3,100 MiB/s</td>
			</tr>
			<tr>
					<td>Download (Hetzner Falkenstein)</td>
					<td>118 MB/s</td>
					<td>246 MB/s</td>
			</tr>
	</tbody>
</table>
<p>Compute and RAM are on par, AES is clearly faster on eos – the VM reports AVX-512 and AES-NI, the
CPU model itself is hidden behind &ldquo;Common KVM processor&rdquo;. Disk and network deliver about half. For
the network that&rsquo;s simply the 1 Gbit/s card: 118 MB/s is the full line. The disk figures match
what netcup itself states: the preview runs on limited infrastructure with reduced performance.</p>
<p>One detail if you measure yourself: on Debian 13 <code>/tmp</code> is a tmpfs in RAM. A fio run there measures
memory, not the disk – put the test files in your home directory.</p>
<h3 id="7-object-storage-s3-with-restic">7. Object storage: S3 with restic</h3>
<p>eos comes with S3-compatible storage; Ceph works in the background (users carry an IAM handle
<code>RGW…</code>). A program gets access through an <strong>S3 user</strong>, which you create under <strong>Object Storage →
Users</strong>. Two things to note:</p>
<ul>
<li>The secret key is shown <strong>exactly once</strong>. Copy it into your password manager right away.</li>
<li>The user is a root user with access to all buckets of the organisation. Bucket policies exist
for separate permissions.</li>
</ul>
<p>The endpoint is <code>at-preview1.object-storage.eoscloud.io</code>, addressed path-style. With
<a href="/en/tutorials/restic-backups/">restic</a> it looks like this:</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"><span class="nb">export</span> <span class="nv">AWS_ACCESS_KEY_ID</span><span class="o">=</span>YOUR_ACCESS_KEY
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">AWS_SECRET_ACCESS_KEY</span><span class="o">=</span>YOUR_SECRET_KEY
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">RESTIC_REPOSITORY</span><span class="o">=</span>s3:https://at-preview1.object-storage.eoscloud.io/YOUR_BUCKET/restic
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">RESTIC_PASSWORD</span><span class="o">=</span>A_LONG_PASSWORD
</span></span><span class="line"><span class="cl">restic init</span></span></code></pre></div>
</div>
<p>The console shows a bucket URL with a long internal identifier in front of the name; restic doesn&rsquo;t
care – the bucket name is enough. One gigabyte of random data went in in just over 9 seconds and
came back out in about 7, bit-identical. Here too the network card is the limit.</p>
<p>We couldn&rsquo;t create a second bucket. The console greys out the district selection without giving a
reason; only the API says it plainly:</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">Bucket creation is currently unavailable in this district.</span></span></code></pre></div>
</div>
<p><figure class="my-6"><img src="/en/tutorials/netcup-eos-preview/eos-bucket-district_hu_702088ad6ddbb705.webp" srcset="/en/tutorials/netcup-eos-preview/eos-bucket-district_hu_7d280c6ad58629c8.webp 480w, /en/tutorials/netcup-eos-preview/eos-bucket-district_hu_702088ad6ddbb705.webp 768w, /en/tutorials/netcup-eos-preview/eos-bucket-district_hu_3cb8ad308ba3b021.webp 1200w, /en/tutorials/netcup-eos-preview/eos-bucket-district_hu_d301a7c9619f0641.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-eos-preview/eos-bucket-district_hu_37f3e325f8b49437.webp"
    alt="The dialog for a new bucket with the greyed-out district at-preview1 and the price conversion error" title="New buckets: the only district is greyed out, without explanation"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">New buckets: the only district is greyed out, without explanation</figcaption></figure></p>
<p>As far as we know, the preview allowed one bucket per organisation. The existing bucket&rsquo;s usage
display also stayed at 0 GB – the statistics hadn&rsquo;t been updated for days, while the data sat in
the bucket correctly.</p>
<h3 id="8-audit-log-who-did-what">8. Audit log: who did what</h3>
<p>A clear plus: every action lands in the organisation&rsquo;s <strong>audit log</strong> with time, person, realm and
resource – VM created, IP attached, rule created, console opened.</p>
<p><figure class="my-6"><img src="/en/tutorials/netcup-eos-preview/eos-auditlog_hu_52b335984d67d946.webp" srcset="/en/tutorials/netcup-eos-preview/eos-auditlog_hu_16dd014d3b3535b1.webp 480w, /en/tutorials/netcup-eos-preview/eos-auditlog_hu_52b335984d67d946.webp 768w, /en/tutorials/netcup-eos-preview/eos-auditlog_hu_f8cb23e49ac0f1cb.webp 1200w, /en/tutorials/netcup-eos-preview/eos-auditlog_hu_e77acdc34195b45d.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/netcup-eos-preview/eos-auditlog_hu_ecf29e7d8ada9865.webp"
    alt="The organisation&rsquo;s audit log lists the sign-in, created VM, volume, public IP, ACL rule and console commands with timestamps" title="The audit log: every action with time, person and resource"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The audit log: every action with time, person and resource</figcaption></figure></p>
<p>Failed operations such as the rejected ACL rules don&rsquo;t show up there, though.</p>
<h2 id="when-it-doesnt-work">When it doesn&rsquo;t work</h2>
<div class="troubleshoot not-prose">
<p><strong>SSH reports <code>Connection refused</code> although IP and ACL are right.</strong> No SSH server is running on
the VM – the cloud images don&rsquo;t ship one either. Open the web console, install it with
<code>apt install openssh-server</code> and add the package to your cloud-init file for future VMs (step 3).</p>
<p><strong>The key is refused, the log says <code>account is locked</code>.</strong> Your cloud-init file contains
<code>ssh_pwauth</code>. That produces a one-line <code>sshd_config</code> without <code>UsePAM yes</code>. Check with
<code>wc -l /etc/ssh/sshd_config</code> – if it says 1, delete the file in the web console, reinstall the
package with <code>apt install --reinstall -o Dpkg::Options::=--force-confmiss openssh-server</code> and
restart the service with <code>systemctl restart ssh</code>. Debian&rsquo;s full configuration is then back on disk.</p>
<p><strong>The VM has a public IP but isn&rsquo;t reachable.</strong> The ACL rule is missing. Without a rule, all inbound
traffic is blocked; create an allow rule for the port with the VM&rsquo;s internal IP as destination.</p>
<p><strong><code>Failed to create ACL Rule</code> right after saving.</strong> The destination is entered as <code>@vm-name</code>. Enter
the VM&rsquo;s internal IP instead, shown on its detail page.</p>
<p><strong>A default IP can&rsquo;t be attached to the VM.</strong> The two public addresses every network brings along
are reserved for outbound traffic and port forwards. Create a separate public IP in the same network
and attach that one.</p>

</div>
<p class="mt-3 text-sm text-slate-500 dark:text-slate-400">
  Your problem is not listed?
  <a href="/en/errors/" class="font-medium text-paprika-700 hover:underline dark:text-paprika-400">Search all error messages →</a>
</p>

<h2 id="maintenance--backups">Maintenance &amp; backups</h2>
<p>In the preview there&rsquo;s one simple rule: <strong>don&rsquo;t store anything important there.</strong> netcup may
delete resources at any time for maintenance, and after the test phase everything is gone anyway.</p>
<p>For later, once eos is ready for production:</p>
<ul>
<li><strong>Organise backups yourself.</strong> There are no automatic backups (yet). You create snapshots by hand
through the VM menu; for data, a restic backup into a bucket – ideally at a second location – is
the more robust route.</li>
<li><strong>Secure the account.</strong> The web console grants root on every VM. A security key or TOTP for every
member of the organisation is a must, and client credentials belong in a vault like passwords.</li>
<li><strong>Maintain your ACLs.</strong> Every rule is a hole in the default block. Keep sources as narrow as
possible and delete rules when a service goes away.</li>
<li><strong>Clean up public IPs.</strong> An additional public IP costs as long as it exists. Detach it from the VM
before deleting, otherwise eos refuses.</li>
</ul>
<p>Our impression after the days in the preview: the foundation is right – secure defaults, a clean
API, a complete audit log and CPU performance at VPS level. What&rsquo;s missing is what makes a preview a
preview: real prices, more regions, backups and a few rough edges in the interface. If you need
compute for production today, take a classic netcup VPS or root server; if you want to manage your
infrastructure as code and are a netcup customer, keep the friends &amp; family launch in mind.</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"
     data-track-content data-content-name="Affiliate-Box · /en/tutorials/netcup-eos-preview/" data-content-piece="VPS 1000 G12.5">
  <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.5</p>
      <p class="mt-1 text-sm text-slate-600 dark:text-slate-300">4 vCores · 8 GB RAM · 128 GB SSD</p>
      <p class="mt-1 text-sm font-semibold text-paprika-700 dark:text-paprika-400">from €14.50/month</p>
      <p class="mt-2 text-sm text-slate-600 dark:text-slate-400">The classic netcup VPS we measured eos against – today the safe choice for production.</p>
    </div>
    <a href="https://www.netcup.com/en/server/vps/vps-1000-g12.5-iv-24m-eu?ref=44083#vps-1000-g12.5-iv-12m-eu" rel="sponsored noopener" target="_blank"
   data-track-event="Affiliate|netcup: Affiliate-Box|VPS 1000 G12.5 · {page}"
   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"><div class="not-prose my-3 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"
     data-voucher-api="vps-1000" data-voucher-msg-empty="No code is available for this plan right now – use the €5.95 code." data-voucher-msg-limit="No more codes today – use the €5.95 code or try again tomorrow." data-voucher-msg-error="The code couldn&#39;t be fetched right now – use the €5.95 code."
     data-voucher-hint="Empty the cart first – the code adds the server itself.">
  <p class="flex flex-wrap items-center gap-x-2 gap-y-1"><span>💶 <span class="font-semibold">1 month free</span>:</span>
    <button type="button" data-voucher-reveal data-copy-title="Click to copy"
            class="cursor-pointer rounded bg-white px-2 py-0.5 font-mono text-sm font-semibold text-herb-800 hover:ring-2 hover:ring-herb-500/40 dark:bg-slate-800 dark:text-herb-400">Show code</button>
    <button type="button" data-voucher-next hidden
            class="rounded border border-herb-500/40 px-2 py-0.5 text-xs text-herb-800 hover:bg-white dark:text-herb-400 dark:hover:bg-slate-800">another code</button>
  </p><p class="mt-1 text-xs text-slate-500 dark:text-slate-400" data-voucher-hint-target>
    Single use, valid for VPS 1000 G12.5.
    <a href="https://www.netcup.com/en/checkout/cart?ref=44083" rel="sponsored noopener" target="_blank"
       data-track-event="Affiliate|netcup: Gutschein einlösen|VPS 1000 G12.5 · {page}"
       class="font-medium text-herb-800 underline underline-offset-2 hover:text-herb-900 dark:text-herb-400">Redeem in the cart →</a>
  </p><p class="mt-2 flex flex-wrap items-center gap-x-2 gap-y-1 border-t border-herb-500/30 pt-2">
    <span>💶 <span class="font-semibold">€5.95 voucher</span> for new netcup customers:</span>
    <button type="button" data-voucher-code data-track-voucher="36nc17844976032"
            title="Click to copy" class="cursor-pointer rounded bg-white px-2 py-0.5 font-mono text-sm font-semibold text-herb-800 hover:ring-2 hover:ring-herb-500/40 dark:bg-slate-800 dark:text-herb-400">36nc17844976032</button>
    <span class="text-xs text-slate-500 dark:text-slate-400">always valid · not for domains or VPS Lite</span>
  </p><p class="mt-1 text-xs"><a href="/en/netcup-voucher/" class="font-medium text-herb-800 underline underline-offset-2 hover:text-herb-900 dark:text-herb-400">All netcup vouchers →</a></p>
</div></div>
</div>

]]></content:encoded></item></channel></rss>