What Is a Firewall
A firewall is a input and output filter of your server. Every connection trying to reach it passes through this filter first. The firewall checks where the connection wants to go (which port) and decides whether to let it through or block it. Without a firewall, every open port on your server is accessible to the whole world.
🧠 Analogy: The Building’s Doorman
Imagine a building with a doorman at the entrance. Everyone who wants to come in stops at the front desk. The doorman has a list: anyone on the list gets in; anyone who isn’t stays outside, no matter how much they insist. The firewall is your server’s doorman.
- •Visitor on the list (port 443): goes in to view the site
- •You, the owner (port 22): goes in to manage
- •Strange without permission: blocked at the gate
💡 By default, the attack has already started
As soon as you put a server online, automated bots start scanning its ports within minutes, looking for an open one to break into. This is normal and happens to every server. The firewall is the first and most important line of defense against this constant noise.
UFW: Allow and Deny Ports
On Linux, the simplest way to set up a firewall is UFW (Uncomplicated Firewall, or "easy-to-use firewall"). It’s a user-friendly layer on top of the system firewall. With short commands in clear English, you tell it which ports to open and which to close.
ufw allow e ufw deny
The commands are almost like sentences: "ufw allow 22" = "firewall, allow port 22".
# Allow a port (let traffic through)
$ sudo ufw allow 22
Rules updated
Rules updated (v6)
# Allow by service name
$ sudo ufw allow OpenSSH
# Deny a port (block it)
$ sudo ufw deny 3306
Rules updated
ufw enable e ufw status
Defining the rules isn’t enough: you need to turn on the firewall. And always check the status to see what’s in effect.
# Enable the firewall
$ sudo ufw enable
Firewall is active and enabled on system startup
# View the active rules
$ sudo ufw status
Status: active
To Action From
-- ------ ----
22 ALLOW Anywhere
80 ALLOW Anywhere
443 ALLOW Anywhere
# Turn it off (if needed)
$ sudo ufw disable
⚠️ Common Error
Problem: I ran sudo ufw enable and I was disconnected from the server forever.
Solution: This happens when you enable the firewall WITHOUT allowing port 22 (SSH) first. Since the firewall blocks everything that hasn't been allowed, it cuts off your own connection. Always run sudo ufw allow 22 BEFORE enable. If you’ve locked yourself out, use your provider’s web console (VPS) to log in and open the port.
✓ What TO DO
- ✓Open Port 22 (SSH) BEFORE running
enable - ✓Check with
ufw statusafter each change - ✓Open only the ports you actually use
✗ What NOT to do
- ✗Run
enablewithout enabling SSH first - ✗Open the database port (3306) to the internet
- ✗Leave everything open “to deal with later”
Essential Ports: 22, 80, and 443
A port is like a a building's numbered entrance: each service lives behind a specific door. For a simple web server, you only need three open ports. Knowing what each one does keeps you from opening too many ports (dangerous) or too few (website down).
Your administration door. This is how you access the server through the terminal.
The gateway to sites without a lock. It usually just redirects visitors to HTTPS.
The gateway to sites with a green lock. This is where your truly secure site will respond.
Opening All Three at Once
# SSH first (so you don't lock yourself out)
$ sudo ufw allow 22
# Site without a lock (redirects to the secure one)
$ sudo ufw allow 80
# Secure site (HTTPS)
$ sudo ufw allow 443
# Now turn on the firewall
$ sudo ufw enable
Firewall is active and enabled on system startup
👁 What you’ll see on the screen
After allowing it and turning it on, the ufw status numbered shows the numbered list of your rules. Each line is an open port:
$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 22 ALLOW IN Anywhere
[ 2] 80 ALLOW IN Anywhere
[ 3] 443 ALLOW IN Anywhere
The numbers in brackets let you remove a rule later: sudo ufw delete 2 delete rule number 2.
💡 Tip: don't open ports "just in case"
Every open port is one more port an attacker can probe. If you don't know what a port is for, DO NOT open it. Databases (3306, 5432), for example, should stay closed to the internet and be accessed only from within the server itself.
Fail2ban: Blocking Intrusion Attempts
The firewall opens port 22 so you can administer the server, but it’s also visible to attackers who try to guess your password thousands of times. The Fail2ban solves this: it watches failed attempts and, after a few in a row, ban the attacker's IP for a while.
🧠 Analogy: The Guard Who Memorizes Faces
Imagine a bouncer at a club’s door. If the same person tries to get in with a fake ID five times in a row, he writes down their face and bans them from coming near for an hour. Fail2ban does this with IPs: get the password wrong too many times, and you’re temporarily banned.
Installing and Enabling
# Install
$ sudo apt install fail2ban -y
# Enable it to start with the server
$ sudo systemctl enable fail2ban
$ sudo systemctl start fail2ban
# View the currently banned IPs
$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Currently failed: 2
|- Total failed: 148
`- Banned IP list: 203.0.113.45 198.51.100.7
Attacker tries to break in
A bot tries to log in to SSH using random passwords: admin, 123456, root...
Fail2ban counts the failed attempts
Every incorrect password is recorded in the log. Fail2ban monitors that log.
Exceed the limit and get banned
After 5 failures (default), the IP is blocked by the firewall for 10 minutes. Try again? The ban lasts longer.
👁 Where to adjust the limits
The configuration is in the file /etc/fail2ban/jail.local. The three most common settings:
# how long the IP stays banned (10 min)
bantime = 10m
# window in which failures are counted
findtime = 10m
# how many failures before the ban
maxretry = 5
⚠️ Common Error
Problem: "I entered my own password incorrectly a few times, and now I’m banned from my server!"
Solution: Fail2ban can't tell you apart from an intruder. If that happens, log in through your provider's web console (VPS) and run sudo fail2ban-client unban SEU_IP. To avoid this, use SSH keys (module 3.2) instead of a password: that way, you never get it wrong.
SSL Certificate with Let's Encrypt
The green lock in the browser (HTTPS) means the connection between the visitor and your site is encrypted: no one in between can read the data. To get this lock, you need an SSL certificate. The Let's Encrypt issues these certificates for free, and certbot does all the work for you.
🧠 Analogy: The Sealed Envelope
HTTP is a postcard: any mail carrier along the way can read what's written. HTTPS is a letter inside a sealed envelope: only the recipient can open it. The SSL certificate is what ensures the seal, and the green padlock is proof that the seal is intact.
Installing certbot and Issuing the Certificate
# Install certbot (example with Nginx)
$ sudo apt install certbot python3-certbot-nginx -y
# Issue the certificate for your domain
$ sudo certbot --nginx -d meusite.com -d www.meusite.com
Requesting a certificate for meusite.com
Successfully received certificate.
Deploying certificate
Congratulations! You have successfully enabled HTTPS
Certbot edits the Nginx configuration automatically and enables the redirect from HTTP to HTTPS.
👁 The certificate expires in 90 days (and renews itself automatically)
Let's Encrypt certificates are valid for 90 days. But certbot already schedules automatic renewal. You can test whether renewal works without waiting:
$ sudo certbot renew --dry-run
Processing /etc/letsencrypt/renewal/meusite.com.conf
Congratulations, all simulated renewals succeeded
⚠️ Common Error
Problem: Certbot fails with "Could not bind to port 80" or "connection refused".
Solution: Let's Encrypt needs to access your server through ports 80 and 443 to verify that the domain is yours. Confirm that sudo ufw allow 80 e sudo ufw allow 443 have already been run, and that the domain points (DNS) to the server's IP address.
Server Security Checklist
Putting it all together: a well-protected server follows a few basic steps that cover 90% of automated attacks. Use this checklist every time you bring up a new server. There are only a few commands, and they make a huge difference.
1.Update the system
$ sudo apt update && sudo apt upgrade -y
Outdated packages are the most common way in.
2.Use an SSH key and disable password login
# in /etc/ssh/sshd_config
PasswordAuthentication no
PermitRootLogin no
With no password to guess, the brute-force attack dies.
3.Enable the Firewall with Only the Essentials
$ sudo ufw allow 22
$ sudo ufw allow 80
$ sudo ufw allow 443
$ sudo ufw enable
4.Install Fail2ban
$ sudo apt install fail2ban -y
$ sudo systemctl enable fail2ban
5.Enable HTTPS
$ sudo certbot --nginx -d meusite.com
✓ Safe Habits
- ✓Update the system regularly
- ✓Log in only with an SSH key, never a password
- ✓Check
ufw statusand check the logs from time to time - ✓Create a regular user and don't use root day to day
✗ Risks to avoid
- ✗Log in as root directly over the internet
- ✗Use short or repeated passwords
- ✗Leave ports open “for testing and forget about them”
- ✗Serve the site over HTTP only, without the padlock
🏆 Your server now has a doorman
With a firewall, Fail2ban, and HTTPS, you're already ahead of most servers on the internet. Security isn't a single button: it's a set of layers. In the next module, you'll learn how to manage tokens and access securely, so your keys and secrets never leak.
📚 Module Summary
Next Module:
3.4 - Tokens and Access (managing keys and secrets without ever letting them leak)