How To Make A Linux Server

How To Make A Linux Server

Reading time1 min
#Linux#Server#Security#Minimalism#Debian#SSH

Building a Lean, Secure Linux Server from Scratch: The Minimalist Approach

Default Linux server installations are notorious for surplus packages—miscellaneous libraries, services, and tools you’ll never use. In production environments, unnecessary components introduce risk: for example, any unused daemon is another potential CVE vector. Lean provisioning offers improved security, predictable patching, and simpler troubleshooting.

Below: assembling a minimal Debian server, using real-world-tested techniques. The goal is an environment suitable for critical workloads—where every running process is deliberate.


Distribution Selection

Minimalism requires a distribution that doesn't fight you. Four stand out:

DistributionProsNotes
Debian NetinstallStable, minimal, predictableUsed below
Ubuntu Server Min.Up-to-date kernel availableMore frequent changes
Arch LinuxTotal control, rollingManual upkeep
Alpine LinuxTiny, musl-libcSome software quirks

Debian Netinstall (e.g. version 12, “Bookworm”) balances dependency clarity and long-term maintainability. For reproducible infrastructure, avoid distributions that hide package complexity or mandate “batteries-included” policies.


Minimal Installation

Start with a clean install. Skip virtualization details here; either bare metal or KVM/Xen/VMware is fine.

  • Download the latest Debian Netinstall ISO.
  • Boot and proceed through the installer.
    • Set your locale, hostname, users, and partitioning (LVM or simple ext4, your call).
  • Software selection:
    Un-tick everything except “standard system utilities”.
    Don’t install “SSH server” yet. (Better to audit configs before the service is available.)

# Sample output at end of install:

Installation complete. Remove the installation medium, then press ENTER.

First Steps: Updates and Access

When the system first boots, log in on the console.

Update the entire base:

sudo apt update && sudo apt full-upgrade -y

# full-upgrade ensures dependency changes (e.g., kernel updates).

Install OpenSSH explicitly:

sudo apt install openssh-server

Check status:

sudo systemctl status ssh

Potential gotcha:
If you misspell openssh-server, only the client is installed—common issue on rushed setups.


SSH: Harden Before Exposure

Vanilla SSH configuration is too permissive. Harden /etc/ssh/sshd_config before exposing any port externally.

Typical recommended edits:

# /etc/ssh/sshd_config

Port 2222                   # If moving from 22 helps reduce random scans
PermitRootLogin no
PasswordAuthentication no   # Require public key authentication
AllowUsers adminuser         # Restrict to a specific login

After changes:

sudo systemctl restart ssh

On your workstation, prepare keypair and deploy:

ssh-keygen -t ed25519 -a 100 -C "ops@example.com"
ssh-copy-id -p 2222 adminuser@your.server.ip

-a 100 increases key derivation rounds—slows brute-force attempts.

Known issue:
If you lock out password auth before copying keys, you’ll need to use the local console to revert.


Audit and Prune Unneeded Services

Check service list:

systemctl list-unit-files --state=enabled | grep enabled

Disable anything unexpected—examples (exim4, cups, avahi sometimes sneak in):

sudo systemctl disable exim4
sudo systemctl stop exim4
sudo apt purge exim4 -y

For small servers, also inspect active sockets:

ss -lpntu

Look for surprises (e.g., open RPC ports, or avahi-daemon still running).


Firewall: UFW Baseline

Strict firewalling is simplest with UFW. (For more granular control, use iptables, but UFW fits most basic web/app servers.)

sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2222/tcp
sudo ufw enable

Verify:

sudo ufw status verbose

Note:
If you’re provisioning on public cloud, double-check upstream (“cloud firewall”) security groups. UFW only manages the server’s host stack.


Package and Dependency Hygiene

After initial setup: always use --no-install-recommends to avoid extra packages.

Example—installing only the essential barebones NGINX:

sudo apt install --no-install-recommends nginx -y

Compare:
A standard install adds helpers like nginx-common and documentation (/usr/share/doc), which, if you’re truly lean, may be purged as well.

Side note:
For logging, rsyslog may be pre-installed. If you shift logs to journald + external shipper, apt purge rsyslog is an easy win.


Monitoring and Ongoing Maintenance

Install minimal tools for diagnostics as needed:

  • htop — process monitoring (sudo apt install htop)
  • bmon — simple bandwidth visualization
  • ncdu — interactive disk usage

For scheduled upgrades, avoid unattended-upgrades unless you need fully automatic patching; manual review is more predictable.


Next Level: Application Isolation with Containers

Avoid polluting the OS with multiple app runtimes. Use containers (Docker, Podman).

Example: Clean Docker Install on Debian 12

sudo apt install --no-install-recommends \
    ca-certificates curl gnupg -y

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg

echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list

sudo apt update
sudo apt install --no-install-recommends docker-ce docker-ce-cli containerd.io -y

This avoids package bloat and GPG key warnings.

Practical tip:
Pin your app images to exact tags or SHA256 digests, not latest, to guarantee reproducibility.


Closing Notes

Minimal Linux server builds save administration time in the long run. Fewer components mean less risk, shorter patch cycles, and top-to-bottom visibility—especially under incident response conditions. Don’t chase “minimal” for its own sake; instead, deliberate inclusion and ruthless exclusion are what keep environments robust.

There’s always an argument for automation (e.g., Ansible, Packer)—script these procedures as infrastructure-as-code for repeatable results.

Final non-obvious tip:
If you want a truly clean / on Debian, run apt autoremove --purge post-setup and check /var/log/installer/—often forgotten space hog.