Skip to content

Ports and firewalls

Practical 3.8 ports-and-firewalls-annex.pdf · PDF

Your PC has one IP address. Right now it may have a browser with ten tabs open, a chat app, a music stream and an update downloading. Thirty conversations arrive at the same address at the same time. How does each byte reach the right program, and not the wrong tab?

And a more uncomfortable question. On the previous page you opened one door in your router, port 8080, on purpose. How many other doors of your router are open that you never opened? By the end of this page you will know, and you will be able to close them.

What you will learn

  • Explain what a port is and why one address can offer many services
  • Compare TCP and UDP, and name the well-known ports of SSH, DNS, DHCP, HTTP and HTTPS
  • List the listening ports of a Linux machine with ss and test one with nc
  • Build a stateful firewall on RouterOS with the input and forward chains
  • Close a single machine with its own host firewall (ufw), leaving one service open
  • Why "connection refused" and "timed out" are not the same thing, and why rule order matters

One address, 65,536 doors

We keep one analogy for the whole page: a building.

An IP address is the street address of a building. Inside, there are numbered doors. A program that offers a service stands behind one door and waits for visitors: it listens.

A port is a 16-bit number inside every TCP or UDP packet that says which program, inside the machine, the packet is for.

16 bits gives 2¹⁶ = 65,536 doors, numbered 0 to 65535. A conversation is identified by address and port on both ends: 10.3.0.199:51000 talking to 1.1.1.1:443.

Careful: port has two meanings

ether2 is a physical port: a socket where you plug a cable. Port 443 is a number inside a packet, at the transport layer (layer 4). On this page, "port" always means the number.

Which door? Well-known ports

A visitor must know the door before knocking, so common services always use the same number:

Port Protocol Service
22 TCP SSH (a remote terminal)
53 UDP, TCP DNS
67, 68 UDP DHCP (67 server, 68 client)
80 TCP HTTP (web)
443 TCP HTTPS (secure web)
8291 TCP WinBox (MikroTik's management tool)

Port numbers are split into three ranges:

Range Name Used for
0–1023 Well-known ports System services: SSH, DNS, HTTP...
1024–49151 Registered ports Applications. Your 8080 lives here
49152–65535 Dynamic ports Temporary ports for the client side

When your browser opens a connection, your system picks a temporary high port for its own side, like the 51000 you saw in the NAT notebook. Only the server side needs a fixed, known number.

Two ways to deliver: TCP and UDP

Ports live in the transport layer, and it comes in two flavours:

TCP UDP
Defined in RFC 793, September 1981 RFC 768, August 1980, only three pages long
Before sending Sets up a connection: SYN → SYN-ACK → ACK, the three-way handshake Nothing: it just sends
If a piece is lost Notices, and sends it again, in order Nobody notices
Like A phone call A postcard
Used by Web, SSH, e-mail, file transfers DNS questions, DHCP, video calls, online games

TCP (Transmission Control Protocol) delivers reliably and in order, at the cost of setting up a connection first. UDP (User Datagram Protocol) just sends, fast and without guarantees.

Why would anyone choose the unreliable one? Imagine a video call loses half a second of sound. Do you want that half-second played again, two seconds later, in the middle of the next sentence? No. In live voice, video and games, late is worse than lost. That is why UDP exists.

sequenceDiagram
    participant C as Client
    participant S as Server :443
    Note over C,S: TCP: the three-way handshake
    C->>S: SYN (can we talk?)
    S->>C: SYN-ACK (yes, can you hear me?)
    C->>S: ACK (yes: connection open)
    C->>S: data...

Who is listening on my PC? ss and nc

Linux tells you which doors are open with ss (socket statistics):

ss -tuln
Option Means
-t TCP
-u UDP
-l Only listening sockets (doors with someone waiting behind)
-n Show numbers, not names

The column Local Address:Port is the door. The address in front of the port matters a lot:

You see Means Who can knock
0.0.0.0:8080 Listening on every address of the machine Anyone who can reach the PC
127.0.0.1:631 Listening on localhost only Only programs on the same machine

Localhost (127.0.0.1) is the address a machine uses to talk to itself: a door that only opens towards the inside of the building. On a typical Ubuntu PC you will see 127.0.0.53%lo:53 (a local DNS helper) and 127.0.0.1:631 (the printing service).

Now open a door yourself and knock on it:

python3 -m http.server 8080 &
ss -tlnp | grep 8080
nc -zv 127.0.0.1 8080
nc -zv 127.0.0.1 8081
grep -E "^(ssh|domain|https)\s" /etc/services
kill %1
  • python3 -m http.server 8080 & starts a small web server in the background.
  • ss -tlnp adds the -p option: it shows the program behind the door, like users:(("python3",pid=...)).
  • nc -zv (netcat) only knocks: -z connects without sending data, -v tells you what happened. Port 8080 says Connection to 127.0.0.1 8080 port [tcp/http-alt] succeeded!. Port 8081 says Connection refused.
  • /etc/services is the system's list of service names and their port numbers.
  • kill %1 stops the background web server.

Refused or timed out?

These two results look like the same failure. They are not.

Result What happened In the building
Connection refused The machine is there and answers: "nobody behind that door" You knock and someone shouts "nobody lives here"
Timed out No answer at all: something on the way threw the knock away You knock and a guard at the entrance silently turns you away

Refused is an answer. Timed out is silence, and the usual cause of silence is a firewall.

The guard and the list: how a firewall decides

A firewall is a guard at the entrance with a list of rules. It decides, for every packet, whether it may pass (accept) or is thrown away (drop).

How the guard reads the list:

  1. Start at the top.
  2. The first rule that matches decides. The rest is not read.
  3. If no rule matches, RouterOS accepts the packet.

That third point is important: a RouterOS firewall with no rules lets everything through. That is the state of every group router so far. Try it: from your PC, knock on your partner group's router with nc -zv -w 2 172.16.0.4 8291, then ports 22 and 80. All three succeed. WinBox, SSH and the router's web page are open to the whole backbone. On a real WAN, to the whole Internet, with only the password as protection.

Two lists: input and forward

RouterOS sorts packets into chains, each with its own list:

Chain Packets... Protects
input Addressed to the router itself: WinBox, SSH, DNS, a ping to it The router
forward Going through the router, from one network to another The PCs behind it
flowchart LR
    WAN["<b>WAN</b><br>outside"] -->|"to the router itself"| IN["<b>input chain</b><br>guards the router"]
    IN --> ROS["<b>RouterOS</b><br>WinBox, SSH, DNS"]
    WAN -->|"passing through"| FW["<b>forward chain</b><br>guards the LAN"]
    FW --> LAN["<b>LAN PCs</b>"]

The guard needs a memory

The naive rule "drop everything that comes from the WAN" kills your Internet: the answers to your own requests also come from the WAN.

The guard needs to remember which conversations you started. It uses the same notebook as NAT, connection tracking, which gives each packet a state:

State Means
new The first packet of a conversation
established Belongs to a conversation already seen
related Linked to an existing conversation (for example an error message about it)
invalid Makes no sense: does not belong to anything

A firewall that uses these states is a stateful firewall.

So every rule list begins with the same line:

/ip firewall filter
add chain=input action=accept connection-state=established,related,untracked

"Whatever answers something we started: come in." After this line, the rest of the rules only have to decide about new conversations.

A firewall for the group router

Before the first rule, press Safe Mode in WinBox (in the CLI: Ctrl+X). If a rule cuts your own session, the router undoes everything you did since. Leave Safe Mode only when the tests pass.

First, two interface lists to keep the rules readable: WAN and LAN.

/interface list add name=WAN
/interface list add name=LAN
/interface list member add list=WAN interface=ether1
/interface list member add list=LAN interface=bridge-lan
/interface list member add list=LAN interface=vlan10
/interface list member add list=LAN interface=vlan20

Then the rules, in this exact order (group 3 shown):

/ip firewall filter
add chain=input action=accept connection-state=established,related,untracked
add chain=input action=drop connection-state=invalid
add chain=input action=accept protocol=icmp
add chain=input action=drop in-interface-list=!LAN
add chain=forward action=accept connection-state=established,related,untracked
add chain=forward action=drop connection-state=invalid
add chain=forward action=drop connection-state=new connection-nat-state=!dstnat \
    in-interface-list=WAN
add chain=forward action=drop src-address=10.3.20.0/24 dst-address=10.3.10.0/24
# Chain What it does
1 input Accept answers to what the router started
2 input Drop nonsense packets
3 input Accept ping (ICMP), so the router stays easy to diagnose
4 input Drop everything else that does not come from the LAN (! means "not")
5 forward Accept answers to conversations started from inside
6 forward Drop nonsense packets
7 forward Drop new conversations from the WAN, unless they came through a port-forwarding rule
8 forward Tramuntana's policy: design may not start conversations with dev

Rule 7 is why your door on port 8080 still works: connection-nat-state=!dstnat means "except what was port-forwarded".

After. Your partner group knocks again: now WinBox, SSH and the web page time out. Not refused: the guard gives no answer at all. ping 172.16.0.3 still answers (rule 3), and curl http://172.16.0.3:8080 still shows your Hello page (rule 7).

Inside the group, the dev PC pings the design PC and it works. The other way round, it does not. Same two PCs, same cables. The answers from design pass because of rule 5; a new conversation from design dies at rule 8.

If WinBox drops when you add rule 4

Your LAN list is empty or misses bridge-lan, so rule 4 blocks you too. Safe Mode restores everything. If you were not in Safe Mode, reconnect by MAC address: the IP firewall does not see layer 2, so WinBox by MAC still gets in.

The order trap

The same rules in a different order are a different firewall. In the lab you will fall into this trap on purpose.

You add the policy drop rule first:

add chain=forward action=drop src-address=10.3.20.0/24 dst-address=10.3.10.0/24 \
    comment="design-to-dev"

Design to dev fails: wanted. But dev to design fails too: the answers from design to dev hit the same rule. So you add the "accept established, related" line... and it still fails. Why? It was added below the drop, and the first match decides. The fix is to remove the drop rule and add it again, so that it lands under the accept rule:

remove [find where comment="design-to-dev"]
add chain=forward action=drop src-address=10.3.20.0/24 dst-address=10.3.10.0/24 \
    comment="design-to-dev"

Now dev reaches design, and design cannot start anything towards dev. Answers must be accepted before the drop rule.

A host firewall: ufw

A router firewall protects a whole network. But a server should not trust the network around it: it closes its own doors too.

A host firewall runs on one machine and filters the packets that reach that machine only.

On Ubuntu and Debian the simple tool is ufw (uncomplicated firewall), a front end for the packet filter built into the Linux kernel:

ufw default deny incoming
ufw allow 80/tcp
ufw --force enable
ufw status verbose
  1. By default, refuse every incoming connection.
  2. Except TCP port 80, the web server.
  3. Turn it on (--force skips the "are you sure?" question).
  4. Show the policy and the rules.

In the lab, a machine with web servers on ports 80 and 9090 answers curl on port 80, but nc -zv -w 2 203.0.113.1 9090 times out although a program is listening there. You will meet ufw again in Unit 6, on the office server.

Router firewall Host firewall
Runs on The router Each machine
Protects Every device behind it Only that machine
Example RouterOS /ip firewall filter ufw on Linux
Default with no rules RouterOS accepts everything ufw is off until you enable it

The Practical 3.8 sheet takes you through all of it: your own PC with ss and nc, the group router, then the order trap and ufw in the lab.

Key takeaways

  • A port is a 16-bit number (0–65535) that picks the program inside a machine; well-known ports: SSH 22, DNS 53, DHCP 67–68, HTTP 80, HTTPS 443.
  • TCP sets up a connection (the three-way handshake) and resends what is lost; UDP just sends, for when late is worse than lost.
  • ss -tuln lists listening sockets; 0.0.0.0 means anyone can reach it, 127.0.0.1 (localhost) only the same machine.
  • Refused = the machine answers "nobody here"; timed out = silence, usually a firewall.
  • A firewall reads its rules from the top and the first match decides; RouterOS uses the input chain (the router) and forward chain (through it).
  • A stateful firewall starts by accepting established,related, so answers come back; a host firewall like ufw protects a single machine.

Quick check

1. Which port and protocol does HTTPS normally use?
  • Port 443, TCP
  • Port 22, TCP
  • Port 53, UDP
  • Port 8291, UDP

HTTPS listens on TCP 443. Port 22 is SSH, 53 is DNS, and 8291 is WinBox, which runs over TCP.

2. ss -tln shows a socket listening on 127.0.0.1:631. Who can reach that service?
  • Only programs on the same machine
  • Every device in the LAN
  • Anyone on the Internet
  • Nobody, because the service is off

127.0.0.1 is localhost, the address a machine uses to talk to itself. A door on it opens only towards the inside of the building. 0.0.0.0 would mean every address of the machine.

3. How is TCP different from UDP?
  • TCP sets up a connection and resends lost pieces
  • TCP is always faster than UDP
  • TCP has no port numbers
  • TCP is used only for video calls

TCP opens a connection with the three-way handshake and makes sure everything arrives, in order. UDP just sends, which suits live video, voice and games where late data is useless.

4. Why does a RouterOS firewall start with a rule that accepts established and related connections?
  • So that answers to conversations started from inside can come back
  • So that new connections from the WAN can enter
  • So that pings to the router are blocked
  • So that the router forwards packets faster

A stateful firewall remembers the conversations you started. Accepting established,related first lets their answers in; the remaining rules only judge new conversations.

5. You run nc against a port and it says timed out instead of refused. What is the most likely reason?
  • A firewall dropped the packet without answering
  • Nobody is listening on that port
  • The port is a UDP port
  • The DNS server failed

Refused is an answer: the machine is there but nobody listens. Timed out is silence: something on the way threw the packet away, typically a firewall rule with action=drop.

6. A RouterOS firewall has no rules at all. What happens to a packet that reaches the router?
  • It is accepted
  • It is dropped
  • It is sent back to the sender
  • It waits until a rule is added

In RouterOS, a packet that matches no rule is accepted. So a firewall with an empty list lets everything through, including WinBox and SSH from the WAN.

7. A forward list has a drop rule for design-to-dev, and below it an accept rule for established and related. Dev cannot get answers from design. Pick the two that are true.
  • The first rule that matches decides, so the drop rule wins
  • Moving the accept rule above the drop rule fixes it
  • The order of firewall rules does not matter
  • Dev and design must be on the same VLAN for answers to pass

The answers from design to dev match the drop rule first, and the list stops there. The accept rule below is never read. Put the accept for established,related above the drop, and answers pass while new conversations from design are still blocked.

8. Which chain of a RouterOS firewall protects WinBox and SSH on the router itself?
  • input
  • forward
  • srcnat
  • dstnat

The input chain judges packets addressed to the router itself. The forward chain judges packets passing through it towards the LAN, and srcnat/dstnat are NAT chains, not filter chains.

Next: all this time you have used 32-bit addresses that ran out in 2011. Meet their successor — IPv6 in 55 minutes.