Installing Fedora Server and Initial Configuration: Steps You Cannot Skip

Fedora tutorial - IT technology blog
Fedora tutorial - IT technology blog

The Real Problem: A Freshly Installed Server That Isn’t Ready to Use

The first time I set up a VPS running Fedora Server, my feeling after the install finished was “done, let’s go”. But just three days later, the logs showed hundreds of brute-force attempts on port 22, continuous root login attempts, and a firewall that was barely blocking anything significant because I hadn’t configured a single rule.

Fedora Server is not a “secure out of the box” distro. It gives you a clean foundation, but everything else — security, user management, network services — is on you. I’ve been using Fedora as my main development machine for 2 years and I’m quite happy with its package update cadence, but the server side needs a few extra configuration steps before it’s truly production-ready.

Understanding the Problem: Why Fedora Server Defaults Aren’t Enough

Fedora prioritizes flexibility over opinionated hardened defaults. After a minimal install, here’s what you’re working with:

  • SSH daemon is running and allows password-based login by default — making it easy to brute-force.
  • firewalld is enabled but the default public zone still exposes many unnecessary services.
  • SELinux is in Enforcing mode — good for security, but many people disable it when they hit errors without understanding why.
  • No fail2ban — brute-force attempts can keep going indefinitely without being blocked.
  • Root SSH login isn’t disabled in some install configurations.

The issue isn’t Fedora itself — it’s that many people skip the initial hardening steps, assuming it can be done later.

Your Options

Option 1: Automate with Ansible

If you manage multiple servers, Ansible is a solid choice. Write a playbook once and you’re done. The downside: it’s overkill for beginners, and you’ll need to understand YAML and module syntax first.

Option 2: A One-Time Shell Script

Write a bash script that handles everything, run it after provisioning. Faster than Ansible but harder to maintain, and prone to bugs if not thoroughly tested.

Option 3: Manual Step-by-Step Configuration (Recommended for Beginners)

Takes more time, but you understand what each step does. When something breaks later, you know exactly where to look. This is how I started, and I still use this approach when I need to debug.

The Best Approach: Step-by-Step Initial Configuration

Step 1: Install Fedora Server

Download the ISO from the official Fedora website. During installation, choose Fedora Server Edition with a minimal configuration to avoid installing unnecessary packages. During setup, create a root password and also create a non-root user.

After the first boot, update the system immediately:

sudo dnf update -y
sudo reboot

Why reboot: if the kernel was updated, you need to restart to run the new kernel.

Step 2: Create a User and Grant Sudo Privileges

The root account still exists after installation, but using it directly is bad practice — one wrong command can wipe the entire server with no checkpoint. Create a dedicated user and grant sudo access:

# Create a new user
useradd -m -s /bin/bash sysadmin
passwd sysadmin

# Add to the wheel group (sudo on Fedora)
usermod -aG wheel sysadmin

# Verify
id sysadmin

From now on, log in as this user — never use root directly.

Step 3: Properly Lock Down SSH

SSH is your only entry point to the server — and also the most frequently attacked service. I once skipped this step and paid for it with thousands of brute-force log entries every day, plus unusual CPU spikes in the middle of the night.

First, copy your SSH public key to the server (run this from your local machine):

# On your local machine
ssh-keygen -t ed25519 -C "[email protected]"
ssh-copy-id sysadmin@your_server_ip

Then, edit the SSH configuration file on the server:

sudo nano /etc/ssh/sshd_config

Find and update the following lines:

Port 2222                    # Change the default port (optional but reduces noise)
PermitRootLogin no           # Disable root login via SSH
PasswordAuthentication no    # Use SSH keys only
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
# Restart SSH (DO NOT close your current session)
sudo systemctl restart sshd

# Open a new terminal and test the connection before closing your current session
ssh -p 2222 sysadmin@your_server_ip

Important: if you change the SSH port, you must open that port in the firewall before restarting sshd. Skipping this step means locking yourself out of the server.

Step 4: Configure firewalld

Fedora uses firewalld with a zone-based approach. I find this quite convenient once you’re familiar with it.

# Check current active zones
sudo firewall-cmd --get-active-zones

# View existing rules
sudo firewall-cmd --list-all

# If you changed SSH port to 2222
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --remove-service=ssh  # Remove the old port 22 rule

# Only open what you actually need (e.g., for a web server)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

# Reload to apply changes
sudo firewall-cmd --reload

# Verify
sudo firewall-cmd --list-all

Step 5: Keep SELinux — Don’t Disable It

Dozens of guides on Stack Overflow and Linux forums will tell you to “just disable SELinux to avoid the hassle”. I disagree with that advice. SELinux is your second layer of defense — it stops attackers even after they’ve bypassed the first layer, for example through a web application with an RCE vulnerability.

# Check SELinux status
sudo sestatus

# Ensure it's in Enforcing mode
sudo getenforce

If you encounter SELinux-related errors, use audit2allow to analyze them instead of disabling SELinux:

# View recent SELinux denials
sudo ausearch -m avc -ts recent

# Or use sealert if setroubleshoot is installed
sudo sealert -a /var/log/audit/audit.log

Step 6: Install fail2ban

fail2ban automatically blocks IPs after N failed login attempts. On my server, this tool blocks an average of 80–150 IPs per day — almost all of them are automated bots scanning from various botnets.

# Install
sudo dnf install fail2ban -y

# Create a local config file (don't modify the original)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Add or update the [sshd] section. Fedora uses systemd-journald, so you need to specify the backend explicitly:

[sshd]
enabled = true
port = 2222
filter = sshd
backend = systemd
maxretry = 3
bantime = 3600
findtime = 600
# Enable and start the service
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# Check status
sudo fail2ban-client status sshd

Step 7: Set Up Automatic Security Updates

Fedora includes dnf-automatic for automatically installing security updates:

sudo dnf install dnf-automatic -y

# Edit the config: only download security updates
sudo nano /etc/dnf/automatic.conf
[commands]
upgrade_type = security
apply_updates = yes
# Enable the timer
sudo systemctl enable --now dnf-automatic.timer
sudo systemctl status dnf-automatic.timer

Full System Check After Configuration

# Currently running services
sudo systemctl list-units --type=service --state=running

# Check which ports are listening
sudo ss -tlnp

# View recent login attempts
sudo journalctl -u sshd --since "1 hour ago"

# Verify fail2ban is working
sudo fail2ban-client status

After completing these 7 steps, your server is solid enough for basic production use. It typically takes me around 30–45 minutes to complete this process on a new server, and every step can be scripted for future use.

One lesson I’ve learned: don’t wait for an incident before hardening your server. Do it right after installation — it saves a tremendous amount of headache down the road.

Share: