Scan your own lab with nmap
In lesson 1 you looked at the server from the inside with ss. But attackers don't get an inside view. They stand on the network and knock on doors. nmap lets you do the same to your own machines, so you can see exactly what the outside world sees, and fix it before someone else finds it.
You will learn
- What a port scan is, and what open, closed and filtered mean
- Finding the machines on your own network, then their open ports and versions
- Why the inside view (
ss) and the outside view (nmap) can disagree - Closing a database that was left open to the network, at two layers
Your lab, and nobody else's
A port scan is not a break-in, but it can still get you in trouble. Scanning a network you don't own can break the rules of your school, your internet provider or the law, and a heavy scan can even crash fragile devices like old printers. So the rule from lesson 1 still stands: only scan machines you own or have written permission to test. In this lesson that's your home lab: the laptop, the server, the router and the printer on 192.168.1.0/24.
Build one: a VM on your own computer is perfect. The Nmap project also runs scanme.nmap.org, a machine whose owners invite a few gentle scans a day. Nothing else on the internet has said yes.
Knocking on doors: open, closed, filtered
Each network service waits on a numbered port: SSH on 22, websites on 80 and 443, MySQL/MariaDB on 3306. nmap tries to connect to each port and writes down what happened:
| State | What happened | What it means for you |
|---|---|---|
| open | A program answered | Something is listening and the firewall lets people reach it. Is that on purpose? |
| closed | The machine answered "nothing here" | No program on that port, but the firewall let the knock through |
| filtered | No answer, or a firewall's "not allowed" | A firewall is in the way. A silent drop also makes scans slow |
The commands
nmap works the same way on both families. Only the install differs:
| Task | Rocky / RHEL | Ubuntu / Debian |
|---|---|---|
| Install | sudo dnf install nmap | sudo apt install nmap |
| Which machines are up? | nmap -sn 192.168.1.0/24 same on both | |
| The 1000 most common ports | nmap 192.168.1.50 same on both | |
| Every port (all 65535) | nmap -p- 192.168.1.50 same on both | |
| What program and version answers? | nmap -sV -p 22,80,3306 192.168.1.50 same on both | |
| Guess the operating system | sudo nmap -O 192.168.1.50 same on both, needs root | |
-sV is worth a close look: services happily tell anyone their name and version number. Anyone can then look up which known bugs that version has. That's one more reason to keep up with updates (Linux Basics 2, lesson 6).
Inside view vs outside view
sudo ss -tlnp on the server tells you what is listening. nmap from another machine tells you what is reachable. The firewall sits in between, so the two lists can be different, and both matter:
- A service listening on
127.0.0.1only shows up inside. That's what you want for a database that only the website on the same server uses. - A service on
0.0.0.0that the firewall blocks shows up as filtered outside. It's safe for now, but only one layer thick: one wrong firewall command and it's open. - Scan from another machine. Scanning a server from itself skips its own firewall, so it tells you nothing about what the network sees.
Fix it at both layers
A database almost never needs to be reachable from the network. The web app talks to it on the same server. So do two things: tell MariaDB to listen only on 127.0.0.1, and remove the firewall hole. Here the two families start differently:
| Rocky / RHEL | Ubuntu / Debian | |
|---|---|---|
| Listens on, out of the box | every address (0.0.0.0); the firewall is what protects it | 127.0.0.1 only |
| Server config files | /etc/my.cnf.d/*.cnf | /etc/mysql/mariadb.conf.d/*.cnf |
| Your own settings file | /etc/my.cnf.d/99-bind.cnf | /etc/mysql/mariadb.conf.d/99-bind.cnf |
| Close the firewall hole | sudo firewall-cmd --permanent --remove-service=mysqlsudo firewall-cmd --reload | sudo ufw delete allow 3306/tcp |
The setting itself is two lines, the same on both:
[mysqld]
bind-address = 127.0.0.1
MariaDB reads its .cnf files in alphabetical order, and when a setting appears twice, the last value wins. That's why a file called 99-… overrides the ones before it. In lesson 2 it was the other way round: sshd keeps the first value. Every program has its own rule, so check: my_print_defaults --mysqld lists what MariaDB will read, in order.
An open port 22 with keys-only SSH is fine. An open port 3306 is a database waiting for password guesses. nmap gives you the list; deciding what belongs on it is your job.
Try it: what does the network see? 📡
You're on your laptop, on your home network. The club server (192.168.1.50) runs a website and a MariaDB database. Scan your lab, compare with the inside view, and close what shouldn't be open.
Quick check
1. nmap says 3306/tcp closed. What's going on?
✓ Closed = the machine itself answered "nothing here". Blocked by a firewall shows as filtered.
2. You run nmap on the server against its own address and see port 3306 open. Your firewall blocks 3306. Why?
✓ Always scan from outside to see what the network sees.
3. The database only serves the website on the same server. What's the best setup?
✓ Two layers. And moving the port is security through obscurity: nmap -p- finds it in seconds.