, ,

Linux Server Hardening After Installation: Complete Security Guide

👁 1 vizualizare


Installing a Linux server is only the first step. Before exposing applications to users or to the Internet, the operating system should be reviewed and hardened so that unnecessary services, weak authentication methods and excessive privileges do not become easy attack paths.

This guide presents a practical post-installation hardening process for Linux servers running distributions such as Ubuntu Server, Debian, AlmaLinux and Rocky Linux.

The goal is not to turn a server into an unusable fortress. Good hardening reduces unnecessary exposure while keeping the system maintainable and recoverable.

Start with a fully updated system

Security hardening on top of an outdated operating system makes little sense. Apply available updates before changing security policy.

Ubuntu and Debian

apt update
apt full-upgrade

AlmaLinux and Rocky Linux

dnf update

If the kernel, OpenSSL, systemd or other critical components were updated, reboot before continuing.

reboot

Check the current operating system state

uname -r
cat /etc/os-release
uptime
systemctl --failed

A new server should not already contain unexplained failed services or configuration errors.

Inventory listening ports

One of the first questions during hardening should be simple: what is currently listening on the network?

ss -lntup

Every listening socket should correspond to a service that the server genuinely needs.

For example:

22/tcp    SSH
80/tcp    HTTP
443/tcp   HTTPS

If an unexpected database, RPC or development service is listening on all interfaces, investigate before exposing the server to an untrusted network.

Disable unnecessary services

systemctl list-unit-files \
  --type=service \
  --state=enabled

If a service is confirmed unnecessary:

systemctl disable --now SERVICE

Do not blindly disable services because their names are unfamiliar. Understand dependencies first.

Create a dedicated administrative account

Routine administration should not require direct root login.

Ubuntu / Debian

adduser adminuser
usermod -aG sudo adminuser

AlmaLinux / Rocky Linux

useradd -m adminuser
passwd adminuser
usermod -aG wheel adminuser

Test privilege escalation before closing the current root session:

su - adminuser
sudo whoami

Use SSH public-key authentication

SSH keys are preferable to relying exclusively on reusable passwords.

Generate an Ed25519 key on the administrator workstation:

ssh-keygen -t ed25519

Copy it to the server:

ssh-copy-id adminuser@server-ip

Open a second session and verify key authentication before disabling passwords.

Harden sshd

OpenSSH configuration is commonly stored in:

/etc/ssh/sshd_config
/etc/ssh/sshd_config.d/

A reasonable baseline can include:

PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no

Only disable password authentication after public-key access has been tested.

Validate the configuration:

sshd -t

If the command produces no output, the configuration syntax is valid.

Changing the SSH port is not a primary security control

Moving SSH away from TCP port 22 can reduce automated scanning noise, but it does not provide meaningful protection against a determined attacker.

Use strong authentication, firewall restrictions and monitoring as the real controls.

Configure a host firewall

A secure default is to deny unsolicited inbound connections and explicitly allow required services.

UFW on Ubuntu

ufw default deny incoming
ufw default allow outgoing

ufw allow OpenSSH

ufw enable
ufw status verbose

firewalld on AlmaLinux / Rocky Linux

systemctl enable --now firewalld

firewall-cmd --permanent \
  --add-service=ssh

firewall-cmd --reload

firewall-cmd --list-all

Restrict SSH by source network when possible

If administration is performed through a VPN or a known management network, there is often no reason to expose SSH to every address on the Internet.

Restricting management access is one of the simplest ways to reduce exposure.

Install Fail2ban where appropriate

Fail2ban can monitor authentication logs and temporarily block addresses generating repeated failures.

Ubuntu / Debian

apt install fail2ban

systemctl enable --now fail2ban

Check status:

fail2ban-client status

For SSH:

fail2ban-client status sshd

Fail2ban is a useful secondary control, but it does not replace proper SSH authentication or firewall policy.

Keep SELinux enabled

AlmaLinux and Rocky Linux normally use SELinux.

getenforce
sestatus

The expected production state is typically:

Enforcing

If an application is blocked, investigate the policy violation rather than automatically disabling SELinux.

ausearch -m AVC -ts recent

Keep AppArmor enabled

Ubuntu commonly relies on AppArmor for mandatory access control.

aa-status

Applications should not automatically be placed into unrestricted mode simply because a profile needs adjustment.

Automatic security updates

Security updates need an explicit operational policy.

On Ubuntu and Debian:

apt install unattended-upgrades

Check the relevant configuration under:

/etc/apt/apt.conf.d/

Automation is useful, but important production servers still require monitoring, maintenance windows and recovery planning.

Audit user accounts

getent passwd

Review interactive users:

awk -F: '$7 !~ /(nologin|false)$/ {print $1,$7}' /etc/passwd

Remove old accounts only after verifying ownership of files, scheduled jobs and application dependencies.

Audit privileged groups

Ubuntu / Debian

getent group sudo

AlmaLinux / Rocky Linux

getent group wheel

Administrative access should be granted deliberately, not accumulated indefinitely.

Review sudo configuration

visudo

Additional rules may exist in:

/etc/sudoers.d/

Avoid unrestricted NOPASSWD: ALL rules unless there is a well-understood automation requirement.

Find SUID and SGID files

Setuid binaries execute with the privileges of their owner and deserve periodic review.

find / -xdev -type f \
  \( -perm -4000 -o -perm -2000 \) \
  -print 2>/dev/null

Many legitimate system utilities use these bits, so the purpose is inventory and anomaly detection, not blindly removing them.

Look for world-writable files

find / -xdev -type f \
  -perm -0002 \
  -print 2>/dev/null

Investigate unexpected results, especially in application and configuration directories.

Protect application secrets

Database passwords, API credentials, private keys and tokens should not be stored in files readable by every local user.

chmod 600 application.env
chown appuser:appuser application.env

Never solve permission problems with chmod 777

A recursive 777 permission change usually creates a security problem instead of solving an application design problem.

Use:

ls -la
stat FILE
namei -l /path/to/file

and determine the correct owner, group and required permission set.

Database exposure

A database should generally not listen on every network interface unless remote access is explicitly required.

ss -lntup | grep -E '3306|5432'

For an application and database running on the same machine, loopback-only access can be preferable.

127.0.0.1

Audit scheduled tasks

crontab -l
ls -la /etc/cron.d/
ls -la /etc/cron.daily/

Also review systemd timers:

systemctl list-timers --all

Unexpected scheduled execution is important during both hardening and incident response.

Install auditd where detailed audit trails are required

Ubuntu / Debian

apt install auditd

AlmaLinux / Rocky Linux

dnf install audit

Enable it:

systemctl enable --now auditd

Audit rules should be designed around what actually matters in the environment rather than collecting unlimited noise.

Review authentication logs

SSH activity can be inspected with systemd:

journalctl -u ssh
journalctl -u sshd

Traditional files may include:

/var/log/auth.log
/var/log/secure

Check recent login activity

last
lastlog

Unexpected login sources should be investigated.

Kernel network hardening

Some servers benefit from explicit sysctl hardening, but values should be chosen based on server role rather than copied blindly.

Inspect current settings:

sysctl -a

Persistent local configuration can be placed under:

/etc/sysctl.d/

Do not enable IP forwarding unless required

sysctl net.ipv4.ip_forward

A normal application server usually does not need to act as a router.

VPN gateways, container hosts and routers are obvious exceptions.

Backups are part of security

Hardening reduces risk, but it cannot eliminate compromise, operator mistakes or storage failure.

A secure server still needs reliable backups.

  • keep multiple backup generations;
  • store at least one copy away from the server;
  • protect backup credentials;
  • monitor backup jobs;
  • test restore procedures.

Monitor the server

Security controls that nobody monitors provide limited value.

Useful signals include:

  • failed authentication attempts;
  • unexpected listening ports;
  • disk usage;
  • filesystem inode usage;
  • service failures;
  • package update status;
  • certificate expiration;
  • backup failures;
  • CPU and memory anomalies.

Useful periodic checks

systemctl --failed

ss -lntup

df -h
df -i

free -h

journalctl -p warning -b

last

fail2ban-client status

Do not expose management panels directly if you do not need to

Hypervisors, storage management interfaces and application control panels should preferably be reachable through trusted management networks or VPN access rather than being universally exposed.

Use a VPN for administrative access

A private management VPN can significantly reduce the number of administrative services exposed publicly.

WireGuard is a particularly useful option because of its simple configuration and small attack surface.

Server hardening checklist

  1. Install all available security updates.
  2. Reboot after critical kernel updates.
  3. Review all listening ports.
  4. Disable unnecessary services.
  5. Create a dedicated administrator account.
  6. Configure SSH public-key authentication.
  7. Disable direct root SSH access.
  8. Disable SSH passwords after testing keys.
  9. Enable a host firewall.
  10. Restrict SSH source networks where practical.
  11. Install Fail2ban where useful.
  12. Keep SELinux or AppArmor enabled.
  13. Configure a security-update policy.
  14. Review local users.
  15. Review sudo/wheel membership.
  16. Review SUID and SGID binaries.
  17. Investigate world-writable files.
  18. Protect application secrets.
  19. Avoid chmod 777.
  20. Restrict database listeners.
  21. Review cron jobs and systemd timers.
  22. Configure audit logging where needed.
  23. Review login history.
  24. Monitor logs and service health.
  25. Configure off-host backups.
  26. Test recovery.

Hardening without breaking the server

The biggest mistake in server hardening is applying large lists of configuration changes without understanding what they affect.

Make changes incrementally.

  • change one control;
  • validate configuration;
  • test application functionality;
  • keep an existing administrative session open;
  • document the change;
  • only then continue.

Final thoughts

Linux server security is not a one-time script. Hardening establishes a baseline, but security depends on continuing maintenance.

Patch regularly, keep administrative access restricted, understand every exposed service, monitor authentication activity, protect backups and periodically review the server against its intended role.

A server with fewer services, clear permissions, strong authentication and a tested recovery plan is easier to defend and easier to operate.

The best security baseline is one that administrators understand well enough to maintain consistently.