A freshly installed server should not be considered ready immediately after the operating system is deployed. Before installing application services, it is useful to perform a short baseline configuration: update the system, check network and time settings, create a regular administrative user, restrict remote access, enable a firewall and add basic protection against repeated login attempts.
This checklist is written for Debian-based and RPM-based Linux systems. Commands that are identical are shown once. Separate blocks are used only where package managers, service names or firewall tools differ.
1. Confirm the installed system
Start by checking the current user, operating system, kernel and hostname.
whoami
id
cat /etc/os-release
uname -a
hostnamectl
2. Check network configuration
Verify addresses, routing and DNS resolver configuration before installing additional services.
ip -br addr
ip route
cat /etc/resolv.conf
Optional connectivity checks:
ping -c 4 1.1.1.1
ping -c 4 example.org
3. Update the system
Debian / Ubuntu
apt update
apt full-upgrade -y
RHEL / Rocky / AlmaLinux / Fedora
dnf check-update || true
dnf upgrade -y
On older RPM-based systems, yum may be used instead:
yum check-update || true
yum update -y
If the kernel or important system libraries were updated, reboot and verify the result:
reboot
After reconnecting:
cat /etc/os-release
uname -a
uptime
4. Install basic administration tools
A minimal installation often lacks useful troubleshooting utilities.
Debian / Ubuntu
apt install -y \
sudo curl wget ca-certificates gnupg lsb-release \
nano vim less htop tmux unzip zip tar jq \
dnsutils iproute2 iputils-ping traceroute tcpdump \
chrony fail2ban
RHEL / Rocky / AlmaLinux / Fedora
dnf install -y \
sudo curl wget ca-certificates gnupg2 \
nano vim less htop tmux unzip zip tar jq \
bind-utils iproute iputils traceroute tcpdump \
chrony fail2ban
5. Set hostname
Choose a clear hostname that identifies the server role.
hostnamectl set-hostname example-host
hostnamectl
Update /etc/hosts if necessary:
nano /etc/hosts
Basic example:
127.0.0.1 localhost
127.0.1.1 example-host
::1 localhost ip6-localhost ip6-loopback
Check the result:
hostname
hostnamectl
cat /etc/hosts
6. Check time synchronization
Correct time is important for logs, scheduled jobs and certificates.
Debian / Ubuntu
systemctl enable --now chrony
timedatectl
systemctl status chrony --no-pager -l
RHEL / Rocky / AlmaLinux / Fedora
systemctl enable --now chronyd
timedatectl
systemctl status chronyd --no-pager -l
Optional timezone example:
timedatectl set-timezone UTC
timedatectl
7. Create a regular administrative user
A regular administrative user should be used for routine access instead of direct root login.
Debian / Ubuntu
adduser example-admin
usermod -aG sudo example-admin
id example-admin
groups example-admin
RHEL / Rocky / AlmaLinux / Fedora
useradd -m example-admin
passwd example-admin
usermod -aG wheel example-admin
id example-admin
groups example-admin
Check sudo access:
su - example-admin
sudo whoami
Expected result:
root
8. Add SSH key authentication
Generate a key on the administrator workstation:
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/example-server-admin
Copy the public key to the server:
ssh-copy-id -i ~/.ssh/example-server-admin.pub example-admin@SERVER_IP
If ssh-copy-id is not available, add the public key manually on the server:
mkdir -p /home/example-admin/.ssh
nano /home/example-admin/.ssh/authorized_keys
chown -R example-admin:example-admin /home/example-admin/.ssh
chmod 700 /home/example-admin/.ssh
chmod 600 /home/example-admin/.ssh/authorized_keys
Test login from a new terminal session:
ssh -i ~/.ssh/example-server-admin example-admin@SERVER_IP
9. Move SSH to a non-default port
This does not replace proper authentication, but it reduces noise from automated scans.
cat > /etc/ssh/sshd_config.d/10-custom-port.conf <<'EOF'
Port 2222
EOF
sshd -t
Debian / Ubuntu
systemctl reload ssh
RHEL / Rocky / AlmaLinux / Fedora
If SELinux is enforcing, allow the new SSH port first:
dnf install -y policycoreutils-python-utils
semanage port -a -t ssh_port_t -p tcp 2222
systemctl reload sshd
Check listening ports:
ss -tulpn | grep sshd
Test the new port from a separate terminal:
ssh -p 2222 -i ~/.ssh/example-server-admin example-admin@SERVER_IP
10. Harden SSH access
After key-based access on the new port is confirmed, disable direct root login and password authentication.
cat > /etc/ssh/sshd_config.d/20-basic-hardening.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
AllowUsers example-admin
X11Forwarding no
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
EOF
sshd -t
Debian / Ubuntu
systemctl reload ssh
RHEL / Rocky / AlmaLinux / Fedora
systemctl reload sshd
Verify effective SSH settings:
sshd -T | egrep '^(port|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|authenticationmethods|allowusers|maxauthtries|x11forwarding)'
11. Configure firewall
Only required ports should be open. A simple baseline may allow SSH, HTTP and HTTPS.
Debian / Ubuntu with UFW
apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 2222/tcp comment 'ssh'
ufw allow 80/tcp comment 'http'
ufw allow 443/tcp comment 'https'
ufw --force enable
ufw status verbose
If the old SSH port was temporarily allowed, remove it only after confirming that the new port works:
ufw delete allow 22/tcp
ufw status numbered
RHEL / Rocky / AlmaLinux / Fedora with firewalld
dnf install -y firewalld
systemctl enable --now firewalld
firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
firewall-cmd --list-all
If the default SSH service should not remain open, remove it only after confirming the new SSH port:
firewall-cmd --permanent --remove-service=ssh
firewall-cmd --reload
firewall-cmd --list-all
12. Enable fail2ban
Fail2ban helps reduce repeated authentication attempts against SSH.
Debian / Ubuntu
apt install -y fail2ban
RHEL / Rocky / AlmaLinux / Fedora
dnf install -y fail2ban fail2ban-systemd
Create the SSH jail:
cat > /etc/fail2ban/jail.d/sshd.local <<'EOF'
[sshd]
enabled = true
port = 2222
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
ignoreip = 127.0.0.1/8 ::1
EOF
systemctl enable --now fail2ban
systemctl restart fail2ban
fail2ban-client status
fail2ban-client status sshd
13. Final baseline verification
Save the final state in server notes.
echo "=== OS ==="
cat /etc/os-release
echo
echo "=== HOSTNAME ==="
hostnamectl
echo
echo "=== TIME ==="
timedatectl
echo
echo "=== NETWORK ==="
ip -br addr
ip route
echo
echo "=== LISTEN PORTS ==="
ss -tulpn
echo
echo "=== SSH EFFECTIVE CONFIG ==="
sshd -T | egrep '^(port|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|authenticationmethods|allowusers|maxauthtries|x11forwarding)'
echo
echo "=== FAIL2BAN ==="
fail2ban-client status
fail2ban-client status sshd
Debian / Ubuntu firewall check
ufw status verbose
RHEL / Rocky / AlmaLinux / Fedora firewall check
firewall-cmd --list-all
14. Maintenance record template
Date:
Server:
OS:
Kernel:
Hostname:
Administrative user:
SSH port:
Firewall status:
Time synchronization:
Fail2ban status:
Open ports:
Changes made:
Verification commands:
Notes:
The purpose of the checklist is not to make the server complex. It is to create a known-good baseline: updated system, correct time, limited remote access, active firewall and basic protection against repeated login attempts.
← Back to notes