Your sovereign SIEM's foundation, a hardened VPS outside the CLOUD Act

A European VPS, Cloud Act-proof, hardened SSH, reduced attack surface via Tailscale, off-site encrypted backups.

Your sovereign SIEM's foundation, a hardened VPS outside the CLOUD Act

Before detecting anything, you need a place to install your SIEM. A machine. Not just any machine, not configured any way.

In the opening episode, we established why. GDPR already requires you to detect and notify a breach within 72 hours, NIS2 has widened the net, and it won’t stop there. American SaaS does the job but hands over your most sensitive logs on demand to the US government. It’s all very unfavorable to your interests, you’ll agree.

So, how to resolve this dilemma? The simple answer is, you build your own SIEM, GDPR and NIS2 compliant, on infrastructure you control entirely.

This article is the first brick. The foundation.

The rest of the series will stack on top of it. Wazuh in episode 2, agents in episode 3, network defense, email filter, execution control. If the foundation is shaky, the whole stack is shaky. A SIEM that monitors your park but runs on a machine itself compromised, it’s like a surveillance camera plugged into an open door.

The stack I recommend, I use daily. I’ll show you how to build your foundation, in order, with real commands. You can reproduce it today.


Choose the hoster, jurisdiction first

The first decision, and the most structuring one. Where your machine will live.

The temptation is to go for the cheapest or most well-known. AWS, Google Cloud, Azure. They’re excellent technically. But they’re all American nationality, and thus subject to the CLOUD Act, that wonderful 2018 law that allows US authorities to seize data from an American provider, wherever it’s stored in the world, including European datacenters.

Storing your security logs there is exactly the problem we’re trying to solve. So, what we’re looking for is a hoster whose headquarters, servers, and capital are not subject to this US exception.

Three criteria to really consider.

  • The jurisdiction of the headquarters. An European company without an American parent company is not subject to the CLOUD Act. Switzerland, Germany, France, etc. The nuance is, a hoster with an entity in the US exposes resources hosted in that entity to the CLOUD Act. The headquarters alone isn’t enough, you need to look where your data physically lives.

  • The location of the datacenters. Your logs need to stay on European servers, period. No transatlantic replication “for your availability”.

  • Price, last. A VPS to start a SIEM for an SME costs between 5 and 25 euros per month. At this level, the price difference between sovereign operators is marginal. You don’t choose your security hoster based on cents.

In practice, two names come up when crossing these criteria.

Infomaniak, Swiss hoster based in Geneva, owned 100% by its founders and employees, without external investment funds. Servers exclusively in Switzerland, under nLPD, the Swiss federal law on data protection entered into force in September 2023, aligned with GDPR and recognized by the European Commission’s adequacy decision.

No US subsidiary, not subject to the CLOUD Act by design, not part of the 5-eyes, therefore no extended cooperation with US intelligence. In Switzerland, all communication requests must go through justice, one of the most protective jurisdictions in the world.

Their datacenters are certified ISO 27001 and ISO 50001. It’s the operator I use, on their VPS Cloud range, but the entry-level VPS Lite can suffice to start.

Hetzner, German family-owned hoster founded in 1997, unbeatable performance/price ratio in Europe, with an ARM cloud range at 4.49 euros HT per month, around 5.40 euros TTC, at the time of writing. Excellent choice, with one condition. Hetzner opened datacenters in the US in 2021, then in Singapore in 2023. You need to provision your machine exclusively on their European sites, Falkenstein, Nuremberg, or Helsinki, to stay outside the CLOUD Act.

Two honest caveats in addition. Hetzner’s interface and support are only in English and German, and Hetzner sometimes suspends accounts deemed risky, without warning. Nothing blocking for a legitimate SIEM use, but good to know.

For this guide, I’m going with Infomaniak. The logic is the same at Hetzner, just the interface names change.

Read soon: Choosing your sovereign hoster, the complete comparison


Size the machine, not too much, not too little

Wazuh, which we’ll install in episode 2, isn’t lightweight. It comes with a manager, an indexer, and a dashboard. The indexer, in particular, loves RAM.

For an SME with up to fifty machines to monitor, the right starting point is three numbers.

  • 4 vCPU, to absorb indexing and rule correlations without saturation.
  • 8 Go of RAM, the bare minimum for the Wazuh indexer. Below that, it struggles or stops. I recommend 12 Go.
  • 100 to 250 Go of SSD, depending on the log retention you want. The more months of history you keep, the more space you’ll need. NIS2 and GDPR think in months, plan ahead.

A VPS of this caliber runs around 15 to 30 euros per month with a sovereign operator. You can start smaller to test, but don’t go below 8 Go of RAM if you plan to run Wazuh on it for real.

For the system, choose a Linux distribution with long-term support. Ubuntu Server LTS or Debian stable. Both are well-documented, supported for years, and are what the Wazuh community tests first. I use Ubuntu Server LTS, that’s what I’ll use in the following commands.


The first contact, and the first hardening

You’ve just ordered your machine. The hoster sends you an IP address, a root ID, and a password. This is the most exposed moment in the entire life of the server, a root accessible via password on a public IP is exactly what bots scan all the time.

A precision before diving in. A server is administered via the command line, no graphical interface or mouse, the Terminal is your only cockpit. Each command in this guide is short and explained line by line.

The first connection session serves to close this door. In order.

Create a non-root user

Working as root daily is like driving without a seatbelt. The slightest command error executes with full privileges. We create a dedicated user, who can elevate their privileges when necessary via sudo.

adduser mack
usermod -aG sudo mack

The first adduser creates the account and asks for a password. The second adds the user to the sudo group, allowing them to execute admin commands by prefixing them with sudo. From now on, log in with this account, never as root directly.

Switch to key-based authentication

A password can be guessed, forced with a dictionary, stolen. A cryptographic key, no. We generate a key pair on your local machine, install the public part on the server, and disable password-based authentication completely.

On your Mac, in the Terminal:

ssh-keygen -t ed25519 -C "your-comment"
ssh-copy-id mack@IP_OF_THE_SERVER

The first command generates the key pair, in Ed25519, the modern, short, and solid algorithm. The second copies your public key to the server. Then test that you can log in without a password, ssh mack@IP_OF_THE_SERVER. If it works, we can cut off the rest.

Lock down SSH

This is where the attack surface really closes. We edit the SSH daemon’s configuration.

sudo nano /etc/ssh/sshd_config

Three lines to set, these are the three that matter.

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

PermitRootLogin no forbids direct root logins. PasswordAuthentication no disables passwords, only your key opens the door now. PubkeyAuthentication yes confirms that we accept keys.

Keep your current session open, restart the service, then test a new connection in a second window. An SSH config error, and you’re locked out of your own machine.

sudo systemctl restart ssh

A known trap with cloud images, Ubuntu often leaves a file /etc/ssh/sshd_config.d/50-cloud-init.conf containing PasswordAuthentication yes, which overrides your configuration. Check the actual applied value with sudo sshd -T | grep -i passwordauthentication, and if it comes back as yes, fix this file too.

Three commands, three config lines. You’ve just eliminated almost all automated attacks that target SSH. The bots that try root via password are now hitting a wall.

Enable automatic security updates

A server that hasn’t been patched is a vulnerable server, and no one connects every morning to launch updates manually. We automate security patches.

sudo apt update && sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

The unattended-upgrades package automatically installs security updates published for your distribution, without touching the rest. Your known vulnerabilities close automatically, while you sleep.


The minimal attack surface, the real sovereign goal

The SSH hardening, that’s the basics. The level jump is here.

The guiding principle is one sentence. A port that doesn’t listen can’t be attacked. Each service exposed on a public IP is a door, and each door is a target. Maximum security isn’t the best lock on each door, it’s not having a door at all.

That’s exactly the logic we saw for the Secure Enclave. The most secure component is the one that refuses access, not the one that defends it well.

The firewall, closed by default

On Ubuntu, the firewall is managed with ufw. The right posture is the inverse, we block everything, then open only what’s necessary.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw enable

default deny incoming refuses all incoming connections. default allow outgoing lets your machine join the outside world, for updates, for example. We only open port 22, SSH, the bare minimum to administer the machine. And we enable.

At this point, your server presents only one SSH door per key. That’s already a profile radically more discreet than 90% of production VPS.

Tailscale, and the public IP disappears

We can do better. Instead of opening SSH on the public IP, even via key, we remove it entirely from internet view and expose it only on a private, encrypted network.

That’s the role of Tailscale. Tailscale creates a private mesh between your devices, over WireGuard, the modern tunneling protocol. Your machines see each other via private addresses, like they’re on the same local network, even if they’re scattered between a Swiss datacenter, your office, and your home. The rest of the internet, meanwhile, sees nothing.

Here’s the concrete flow. You install Tailscale on the server and on your Mac. Both join your private network. Your Mac gets a Tailscale address, the server does too. You log in to the server via its Tailscale address, not its public IP. And you close port 22 on the public IP. To reach SSH, you have to already be a member of your private network. An attacker on the internet can’t even see that the port exists.

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

The command displays a link, you open it in your browser, authenticate the machine, it joins your network. Repeat on your Mac. Retrieve the server’s Tailscale address:

tailscale ip -4

Test the SSH connection via this private address. Once it works, we close port 22 on the public IP:

sudo ufw delete allow 22/tcp
sudo ufw allow in on tailscale0 to any port 22 proto tcp

The first line removes the SSH opening on all interfaces. The second reopens it only on the tailscale0 interface, your private network. SSH only listens on the encrypted mesh.

The result is a machine with only one admin door, invisible from the internet. Not locked, invisible. A port scan on your public IP reveals nothing exploitable.

For the rest of the series, that’s also how your Wazuh agents will send their logs to the server, never through the open internet. The network foundation we’re putting in place today serves the whole stack.

And the services that must remain public?

Not everything can live behind the private network. If your server hosts a website or a service that needs to be reachable by anyone, that service has to listen on the public IP. It’s inevitable.

The rule, then, isn’t “zero public ports” but “zero unnecessary public ports”. You open exactly what the service requires, nothing more. A website, that’s port 443 in HTTPS, and port 80 while renewing certificates. Nothing else. Everything else, administration, databases, internal dashboards, stays on Tailscale.

For our SIEM foundation, at this point, the simple answer is no public services. The server exposes nothing to the world. Wazuh, which we’ll install later, lives entirely behind Tailscale, accessible only to you.


The backups, encrypted off-site

A hardened server isn’t an immortal server. A datacenter can burn down, as we saw with OVH Strasbourg in March 2021, clients without backups lost everything. A ransomware can still pass on one of your production machines. A finger slip on a wrong command can erase a database.

The rule is non-negotiable. Your backups live elsewhere than on the machine they protect, and they’re encrypted before they leave. Encrypted by you, on your machine, before sending. Not encrypted by the storage provider, by you. That way, even the storage provider can’t read what it’s storing.

The tool I use is Kopia. Open source, fast, and it does exactly what we want, client-side encryption before transfer, deduplication to not explode your storage volume, and sending to an S3-compatible storage.

And the off-site storage, I take it with Swiss Backup, Infomaniak’s backup service. Same logic of sovereignty as for the VPS, Swiss servers, not subject to the CLOUD Act, and an S3 endpoint that Kopia consumes directly.

The concrete flow. Kopia runs on your server. Once a day, or several times, it takes a snapshot of the folders that matter, your system configuration, your Wazuh data, your logs.

It encrypts this snapshot locally, with a key that only you hold. Then it sends it to Swiss Backup. The day the server dies, you provision a new machine, reinstall Kopia, point it to the remote repository with your key, and restore.

curl -s https://kopia.io/signing-key | sudo gpg --dearmor -o /usr/share/keyrings/kopia-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/kopia-keyring.gpg] http://packages.kopia.io/apt/ stable main" | sudo tee /etc/apt/sources.list.d/kopia.list
sudo apt update && sudo apt install kopia
kopia repository create s3 \
  --bucket=YOUR_BUCKET \
  --endpoint=s3.swiss-backup.infomaniak.com \
  --access-key=YOUR_KEY \
  --secret-access-key=YOUR_SECRET

The first three lines install Kopia from its official repository. The last command creates the encrypted repository on the remote storage, using the exact endpoint displayed in your Swiss Backup console, it varies depending on the cluster you’re assigned. Kopia asks for a passphrase when creating the repository, that’s the key to encrypt all your backups. Note it down somewhere other than on the server. If you lose it, your backups are permanently unreadable, including to you. That’s the price of client-side encryption, and that’s exactly what we want.

Then automate. We create a daily snapshot of the critical folders, then schedule it with a cron job.

kopia snapshot create /etc /home /var/log

This command captures the current state of the three folders. You schedule it to run every night, and occasionally check that your snapshots are there with kopia snapshot list. A backup you don’t test is not a backup, it’s a hope. So we’ll need to plan a test restore of your data every quarter.

This SIEM foundation will serve the rest of the series. Every brick we add, Wazuh and its data, the rules you calibrate, will be captured in the same encrypted snapshot, off-site, ready for the day you need it.


In summary

The foundation is four gestures that build on each other.

You’ve chosen a hoster whose jurisdiction protects you, not just whose datacenter is in Europe. You’ve hardened access, non-root user, key-based authentication, root forbidden, automatic updates. You’ve reduced the attack surface to nothing, closed firewall by default, admin behind a private encrypted network, no unnecessary public ports. And you’ve put encrypted backups off-site, unreadable to anyone without your key, ready for the day when.

None of these steps are complicated. Together, they turn a rented machine into a fortress you control. It’s the exact opposite of what you sign up for with an American SaaS, where the data is yours but the infrastructure and jurisdiction aren’t.

An afternoon’s work. Not a weekend.

The foundation is in place. In episode 2, we fill the vault. Wazuh all-in-one, manager, indexer, and dashboard on this single node. The functional equivalent of a Splunk, for the price of the VPS you’ve just built. Your SIEM starts to exist.


Series recap

Seven episodes to build your sovereign security plumbing, brick by brick.

Technical terms? Check the glossary.