Networking is a complicated subject. The internet is made up of lots on interconnected parts that all share the same limitation. At the end of the day everything has to get converted back into something the computer understands, binary. Little electrical pulses moving across the motherboard when a 1 gets passed and not moving when there’s a 0.
In order to make this all work we usually deal with things as numbers; IP addresses, permission variables, data, and port numbers. Ports are as integral to our use of the internet as the IP addresses they’re ties to, and they about as misunderstood.
For the average user they’ll never see the ports their using, or have any reason to. For gamers ports are frequently a cause of headaches as they can prevent voice chat from working properly, or stop matchmaking. For the Home Labers ports are an obstacle which stops them from accessing their services. For the networking security professionals ports are a necessary evil. But what actually are ports, and are they really a security concern?
The controversial reality is that ports aren’t actually a real thing, but we’ve been using the term for so long that it’s become a real thing. Servers and services need a way to listen for and receive connections from other people on the internet and then send those connections to a specific service. To do this we use a system called ports. Think about this website you’re on right now. This website is a service, and this service hosted on one IP address. Along with this website there are other services also running on this one IP. How does my server know what service to load when you visit? It uses ports. Right now you’re using port 443 (HTTPS) to view the website, but if you were to go to port 8000 you would reach my MITRE TRAM instance where I go through cyber reporting. Port 2342 would reach my Photoprism instance, port 8080 would reach my mail server, etc. The ports are what tells my server what service to load up and display.
The above was a simplified version of how all this works, in reality things are a bit more complicated. I have a reverse proxy which takes a single port 443 and maps it to different ports based on the Subject Name Identifier (SNI), but this is a lesson for a different day.
At this point you might be saying ‘Okay, I understand you’re saying but I didn’t type anything like 443 when I came to this webpage.’ and you’d be right. In the industry we have a series of documents called requests for comments (RFC) which is when someone comes up with a standard and puts it out for others to comment on. If enough of the community agrees then RFC becomes the new standard and everyone should follow it; they don’t have to, but they should.
When it comes to ports there are actually a lot of RFCs which cover ports and define what’s known as “the well known” port numbers. These well known port numbers commonly accepted standards for different services. RFC 2616 and RFC 2818 cover ports 80 (HTTP) and 443 (HTTPS) respectively. These RFCs in, in a nutshell version, say that when someone wants to go to an HTTP website the web browser should default to port 80 and when they want to go to an HTTPS website the browser should default to port 443. So if you look up at the URL bar you should notice that it says https:// in front of the blog.gravitywall.net part. That HTTPS section tells your web browser to send it’s connection request over port 443 to my webserver. My webserver receives that request on port 443 and knows to reply by sending this web page.
I stated earlier that there are a number of RFCs that define well known ports and that’s true. The first 1023 (out of 65535) ports are considered the well known ports. This range includes things are usually critical for computers to work and the internet to function. This range includes things like DNS (53), HTTP (80), HTTPS (443), DHCP (67, 68), NetBIOS (135-139), SMB (445), etc.
All of these are considered the standard used by the industry but they can be changed by individuals, at dire costs. You can change your DNS to something other than port 53 but if every DNS server is expecting port 53 then nothing will receive your requests and you won’t be able to use the internet.
In addition to the well known port we also have RFCs for “registered ports”. Registered ports are for ports numbered between 1024 and 49151. These ports are usually decided on by the vendors of products and software. There is no established standard for registered ports and anyone is free to use any one for anything. Some brands are known to use specific ports for their products but the port is not exclusively used for that product or service like it is with the well known ports. For instance port 2343, where I host Photoprism, is also used by
- Seagate Manage Exec
- Age of Empires II multiplayer
- Chessmaster 8000 Multiplayer
- Flight Simulator 2000 and 2002
- MSN Game Zone DX,
- and more
Registered ports aren’t as important as the well known ports but since I’m doing a full overview of ports it’s worth mentioning them.
Also known as dynamic ports, tertiary ports are the ports ranging from 49152 through 65535. Dynamic ports are any port not assigned to a specific service. While dynamic ports can be used for inbound connections to a service they are more frequently used by a computer initiating the connection as a means of mapping where the reply should go on the way back through a process known as port address translation (PAT). While again somewhat outside the scope of this post PAT works by linking a session to a port number so that the computer can differentiate which service made the request.
When you connect to a service on the internet, like this blog, the process usually goes like this. Your computer will check itself and see which of tertiary port range is not being used and randomly pick a number out of that range. It will link that port to the session it’s creating (ie the web browser). It will then look at the service you’re trying to go to, in this case HTTPS, and send the connection to that port. When my website receives that connection it will load the content you requested and rend the reply back on the tertiary port your computer picked initially. Your computer will then receive that reply on the tertiary port and know that port XYZ is linked to this specific browser window.
Port forwarding is by far the most common time people will intentionally interact with ports. We’ve established that ports are a server’s way of listening for connections and then sending that connection to the appropriate service but we may not want to let just anyone send connections to our servers. Firewalls, also outside the scope of this, are our way of blocking unwanted connections to our servers and services, but firewalls also block the connections that we do want. By default a firewall should block any connection that we don’t explicitly allow.
To maximize protection while enabling availability we use a system called port forwarding. Port forwarding is actually a two part process that most routers pair together into one action. The first action is telling the router to allow a specific port (ie. stop blocking it), the second action to redirect that connection to the specified location.
Port forwarding usually requires three things:
- A port forward on the router firewall
- An open port on the server
- A listening service
Any one of those three things missing and your port forward will fail.
Forgetting one of these three things causes significant issues frequently. A quick trip over to any networking, router, or gaming subreddit and you’ll be greeted with tons of posts from people trying, and failing, to set up port forwarding. These users generally set up the port forward on the router correctly but they forget to allow the port on their server firewall or they don’t have the service running at the time they test.
This results in the test showing the port as closed and often causes the users to assume the issue is with the router when in reality the router is doing it’s job properly.
Ever since Vista in 2001 Windows has had a host firewall enabled by default. Microsoft also went back to XP and added the firewall feature to that OS with service pack 3. This built in, enabled by default, firewall is the cause of many issues I see when discussing port forwarding on Reddit. I want to be clear about this next part.
The Windows firewall is GOOD and you should leave it enabled.
The correct answer when trying to host something on Windows is not to disable the firewall like you sometimes see as advice. What you need to do is specifically allow the port(s) you need.
Linux on the other hand, generally does not have a firewall enabled by default. Most Linux distributions have a powerful firewall built into the system (IPTables) but it’s generally not enabled.
I’ve recently noticed this strange trend of people on networking sub-Reddits saying to ‘never ever ever port forward’. They’ll tell you about how every port is a security risk and proclaim tunnel services like Cloudflare Tunnel, ZeroTier, and Tailscale as the safer alternative. The questions now become; ‘are open ports dangerous’ and ‘are tunnel services safer’?
The answer is it’s complicated and I’ll explain it all more in a minute.
First up, are open ports dangerous? No, not by themselves. Simply having an open port on the router does not pose a major security risk. Remember the three things you need for port forwarding to work? The real risk comes from the third thing, the listening service.
Computers today are smart enough to know when they should and should not be receiving data. When the computer receives data, it’s not expecting it should simply drop the packets. So where is the risk? While it’s true that the risk is with the services the calculus comes into play when you consider the knowledge of the average user. This is certainly not a dig at the intelligence of the average user, but I feel confident saying that the average user doesn’t understand what background services are running on their computer and what ports they use. The average user certainly isn’t equipped to tell if a service has a vulnerability or now. I’ve been in their field for 10 years and I still can’t fully do vulnerability discovery in services.
That’s where the risk comes into play. Ports by themselves aren’t dangerous, but when you open ports and you’re not sure what’s on the other side and how susceptible it is; then you’re asking for trouble.
Tunnels work almost like port forwarding, but in reverse. Instead of you opening a port in your routers and having your server wait for a connection you have a server actively reach out to a controller. That controller then handles sending the packets through the tunnel to your servers. When you want to connect to your server you use a URL, provided to you by the service, and connect that way.
Tunnels provide some benefits and some disadvantages.
The immediate benefit of a tunnel service is that you don’t have any visibly exposed services. I intentionally didn’t say open ports because again the risk is not the open port. There are bots on the internet that are scanning the entire internet every day. Some of them are well known services like Google or Shodan, and others are lesser known services that haven’t proven themselves trust worthy like reCyber. These bots are always scanning and indexing everything including the ports you have open. Using a tunnel service will prevent these bots from seeing your services because there won’t be any publicly visible services.
So what are the downsides of tunnel services you might ask? Just like there are bots scanning IPs for exposed services there are also bots scanning these tunnel services for exposed tunnels. Since these services are designed mainly for people unable to port forward they usually follow a pattern in their URL. An example of this is ngrok. With a free ngrok account every tunnel follows the pattern of [uniquename].ngrok.io. That means bots could, and do, index these sites. A simple google search for site:ngrok.io shows over 4.5K results.
While tunnels don’t reveal exposed services when your IP is scanned they also don’t provide security as the urls are frequently scanned an indexed.
The second downside to tunnel services is that free usually means limited. Some free tunnels like ZeroTier limit the amount of IPs you can reach through the tunnel (eg. you can’t have 1 free tunnel reach 255 servers). Other services like Ngrok don’t allow you to change the URL thus making them easier to index.
Now that’s the big question that companies pay network security engineers big money to figure out. The unfortunate answer that there is no perfect way to secure this. In the CIA triad one of the legs is availability. As someone hosting servers you need to decide how available you want those servers and services. Should they be available to everyone? Should they only be available to you?
The best way to make sure you are port forwarding safely is to only port forward what is absolutely necessary for only the people who absolutely need access. With some of my services I specifically have the port forward set to only allow my IP address. I decided that this service specifically (my Photoprism service) should not be accessible by the entire world. Other services like the SQL database that powers this website is also not accessible to the world even though the front end of the website is.
Port forwarding can be done safely if you can control availability and limit access to absolute minimum required.
As video games became more and more online users started experiencing issues figuring out how to get all the features to work properly. One of the most common issues dealt with voice chat. You may have heard of the concept of NAT type OPEN, MODERATE, or STRICT on Xbox while PlayStation referred to these as NAT type 1, 2, and 3. Users with NAT type 3 or Strict are generally unable to use voice chat and in some cases are unable to matchmake properly.
When you look up guides on how to fix this issue the common answer is to port forward in the router, or place the console in the DMZ. While these work, albeit placing the console in the DMZ is still a bad idea, let’s break down why these issues are happening.
Online games have largely moved to dedicated servers but voice chat still largely happens in a peer to peer (P2P) context. One person in the lobby will usually be the host for voice chat and all players will connect to that individual. Unfortunately if the chat host’s router does not allow all the ports. This is why you’ll frequently see the guides recommending that users port forward.
Different games will sometimes list specific ports to allow for the connections, occasionally they differentiate which ports are for different services (eg. chat vs matchmaking.)
What about outbound ports?
Sometimes services, like Steam, will document what ports their services need to work. In cases like this the post listing are for outbound connections to the server. Firewalls work in both directions, they block outbound connections the same way they block inbound connections. Most firewalls are set to allow all outbound connections but that’s not always true. Some network security professionals will block outbound ports that aren’t common. In cases like this where enabling outbound ports is necessary.
This was a very shallow introduction to a wide variety of topic involving ports and port security. I hope this answered some of the more common questions I see in networking sub-Reddits regularly.