01Professional services

Linux servers that are boring on purpose.

Provisioning, hardening, and the day to day administration that keeps a fleet predictable. We measure every host against one written baseline, show you the diff before anything changes, and leave you able to run the same checks without us.

0
Checks in the standard hardening baseline
0%
Changes shipped as a diff you approve
0/7
On-call cover on retained fleets
0 min
Response target on a production outage
The problem

Most Linux estates are not misconfigured. They are undocumented.

Servers rarely fail because someone made a bad decision. They fail because six good decisions were made over four years by three people who have since left, none of them written down, and nobody now knows which of them the application depends on.

So the estate calcifies. Patches get skipped because nobody is confident about what a reboot will take with it. Firewall rules accumulate because removing one is riskier than leaving it. The box that has been up for 900 days is the one everybody is most afraid of.

We start by measuring, not by changing. A first pass produces a report of what each host actually is: kernel, packages, users with shell access, listening ports, sudo rules, cron, mounts, and where each of those sits against the baseline. That report is the thing you were missing, and it is yours whether or not the engagement goes further.

The baseline

One standard, applied the same way to every host.

A hardening run is a dry run first. You see every proposed change with the current value and the target value, and nothing is written until you say so.

root@web-03: ~
$ pulseguard harden --profile cis-l2 --dry-run
scanning host web-03.vantagerail.internal
kernel 6.8.0-51-generic · ubuntu 24.04.1 LTS
[ ok ] ssh PermitRootLogin no
[ ok ] ssh PasswordAuthentication no
[fail] ssh MaxAuthTries 6 → 3
[ ok ] ufw default deny incoming
[warn] ufw 22/tcp open to 0.0.0.0/0 → restrict to bastion
[ ok ] sysctl net.ipv4.conf.all.rp_filter = 1
[fail] sysctl kernel.dmesg_restrict = 0 → 1
[ ok ] auditd running, rules loaded (74)
[warn] fs /tmp mounted without noexec
[ ok ] pkg unattended-upgrades enabled
18 checks · 13 pass · 3 warn · 2 fail
no changes written (dry run)
Baseline

Every host we take on gets measured against one written baseline, then brought to it. The report is the same one you can run yourself afterwards.

SSH and access100
Firewall and exposure82
Kernel and sysctl91
Audit and logging100
Filesystem and mounts76
Change policy

Nothing is applied on a first pass. You get the diff, you approve it, and the same run applies it with a recorded rollback.

Scope

What we take on

01

Provisioning and base images

One golden path from bare metal or a cloud image to a host that is ready for work.

A single base image and a single provisioning run, so a server built today is identical to one built in six months. Cloud-init or Kickstart for the first boot, then configuration management for everything after it. No host reaches production through a sequence of remembered commands.

cloud-initPackerAnsibleKickstart
02

Hardening to a written baseline

CIS-derived, adjusted to what your applications actually need, and kept in version control.

SSH and sudo policy, kernel and sysctl parameters, firewall defaults, audit rules, mount options, and package hygiene. The baseline is a document before it is code, because the exceptions matter: a control your application genuinely cannot live with is recorded as an accepted risk with a reason, not silently dropped.

CISsysctlauditdSELinuxAppArmor
03

Patching and update policy

A schedule with a maintenance window, a rollback, and evidence that it ran.

Security updates applied automatically where that is safe, everything else batched into a window with a tested rollback. Kernel updates and reboots are planned rather than avoided, which is the only way to stop a fleet drifting years behind and turning every reboot into a gamble.

unattended-upgradesdnf-automatickexeclivepatch
04

Access and identity

Named accounts, keys with owners, and a bastion instead of a shared password.

Root logins disabled, password authentication off, keys issued per person and revocable per person, sudo rights scoped to what the role needs, and every session logged. Where you have a directory already, hosts join it rather than keeping a parallel list of local users that nobody prunes.

OpenSSHsudoSSSDbastionMFA
05

Backups and restore testing

A backup nobody has restored from is a plan, not a backup.

Encrypted, offsite, versioned, and monitored, with a restore performed on a schedule and timed so your recovery objective is a measured number rather than an aspiration. The restore test is part of the retainer, not a line item you have to remember to ask for.

resticBorgsnapshotsRPO / RTO
06

Observability and log shipping

Metrics and logs off the box, so a dead host still tells you why it died.

Node metrics, journald shipping, and alerting that fires on symptoms rather than on every threshold. Where you run PulseGuard, the agent already carries the host metrics and the findings, so this is usually a matter of connecting what exists rather than standing up another stack.

PrometheusLokijournaldPulseGuard agent
How it runs

Audit first, and you can stop after it.

Week 1

Audit

Read-only access, one pass across the fleet, and a written report of what every host is and where it sits against the baseline.

Week 2

Baseline

We agree the standard and the exceptions, in a document. Anything your applications cannot tolerate is recorded as an accepted risk.

Weeks 3 to 4

Apply

Changes go out in waves, staging first, each as a reviewed diff with a rollback. Nothing is applied on a first pass.

Ongoing

Operate

Patching, changes, capacity, and on-call, with drift from the baseline reported monthly rather than discovered later.

Tools we work in
UbuntuDebianRHELRocky LinuxAnsibleTerraformsystemdnftablesufwauditdSELinuxAppArmorOpenSSHPrometheusLokiresticBorgLVMZFSPodman

Start with the audit.

One pass across the fleet, a written report of what you actually have, and no obligation to continue past it.