Over the past month, our development team has been hard at work delivering a host…
Security best practices, part 3.
Welcome to our 3rd installment of security best practices. Today we’ll take a look at port knocking and service ports. If you missed part 1 and 2, you can find them here:
Port knocking
If you’ve ever thought about a secret knock that only you and your friends would know about to get into the clubhouse as a kid, then you know the premise behind port knocking. With this mechanism, a client sends some data to a server in a specified way, and the server checks that method against some rules to determine if they knocked correctly. If they do, they gain entrance – and if not? Keep on walking, buddy – move along.
Time for another example, I think. Let’s take a MikroTik router as the port knocking server and my client is just a plain old Windows 10 PC, using a browser, although you could just as easily use a linux shell, telnet, a port knocking client, etc.
First, you decide how many knocks it’s going to take, in what order and in what time frame to consider that the client connecting is trusted. In the following example, I’ll show 3 knocks that have to be done in under 60 seconds per step, and then I’ll explain the logic.
MikroTik example:
- /ip firewall filter add comment=defconf chain=input action=accept connection-state=established,related
- /ip firewall filter add comment=”Allow TRUSTED” chain=input action=accept src-address-list=trusted
- /ip firewall filter add comment=”Knock1” chain=input action=add-src-to-address-list protocol=tcp address-list=port_knock_1 address-list-timeout=1m dst-port=33333
- /ip firewall filter add comment=”Knock2”chain=input action=add-src-to-address-list protocol=tcp src-address-list=port_knock_1 address-list=port_knock_2 address-list-timeout=1m dst-port=22222
- /ip firewall filter add comment=”Knock3” chain=input action=add-src-to-address-list protocol=tcp src-address-list=port_knock_2 address-list=trusted address-list-timeout=7d dst-port=11111
Explanation:
- This rule may have been previously added (pretty likely) – if so go ahead and skip it. What it does is allow for traffic that originated from this router to return without getting blocked. For example, if our router asks for NTP (Network Time Protocol) and the return packet comes in on the random port assigned by this router (which it should), we’ll accept the packet.
- This firewall rule will check the source IP and allow access from locations that are listed as “trusted” – an empty address list at the start. Make sure to allow administration early in the filters to ensure that it’s below any drop rules.
- Our first port knock. If I open my browser and go to router_ip_address:33333 in the address bar, I’ll trigger step 1. The IP address of my PC will be added to a temporary address list called “port_knock_1”, which expires after 1 minute.
- Second port knock. This time I send my browser to router_ip_address:22222. If my PC has already recently knocked on the first port knock (TCP/33333) in the last 60 seconds, it’ll now get added to step 2. Another temporary address list that expires in 1 minute, “port_knock_2”. Otherwise, any other traffic to 22222 is ignored.
- Final port knock. I go to router_ip_address:11111 in my browser. My PC must have knocked on step 1 and step 2 to make it this far, and it must’ve done so in under 60 seconds per step. If we succeed, our client’s IP address will be added to the “trusted” address list for a week before it’ll disappear and we’ll have to do the port knock procedure again.
Port knocking can be tweaked to your liking, and here are a few hints on further hardening for this method:
- Make it fast – rather than allowing 60 seconds between steps, tune it down to just a few seconds
- Add more knocks – every additional knock is like adding another character to a password. It increases the security exponentially
- Keep knocks random, or at least not sequential – Don’t choose a sequence like 1111, 1112, 1113 because a simple port scanning tool is likely to trigger all 3 in just a few seconds. The order matters, so something like 55555,11111,3333 is TONS stronger than something sequential
- Use other protocols – if you mix and match protocols – for example, some TCP, some UDP, maybe an ICMP, you can increase the complexity of the knock. It’s just like adding special symbols to your password.
- Add a VPN – rather than simply allowing rule #2 as specified above, you can make a VPN tunnel blocked to all sources that aren’t in your “trusted” list. This way, you can’t VPN until you’ve also successfully port-knocked!
Non-standard ports
This one is more of a best practice than an actual security mechanism because it doesn’t technically improve the security of a server or service – it just makes it more difficult to find with automated tools. It doesn’t encrypt or block traffic, but it does make it harder to gain access, which should be the goal of any good security strategy. This is commonly called “security through obscurity”.
Consider the following example:
A hacker tool scans for servers out there and attempts to connect to their SSH port and run arbitrary commands after trying several login attempts. In addition, servers responding to SSH attempts are marked for later brute force attempts. If we’ve moved the SSH port from the well-known port of 22 to something else, say 12345, it’s highly unlikely that hacker tools will waste the effort of trying every port on every IP to connect to SSH. By obfuscating the attack surface, you’re not any less vulnerable, but you have made it so that it’s just a little bit more effort to get to the goods.
At RWB, we’ve moved any service ports that aren’t globally exposed off of their standard values to decrease the ease of discovery.
And don’t forget to disable services that aren’t used! For example, on our web-server we don’t run the database service and on our database-server we don’t run the web service. And on our routers, we never run telnet, ftp, or www, because they are all insecure and send data in the clear, or unencrypted.
MikroTik Example:
- /ip service set telnet disabled=yes
- /ip service set www disabled=yes
- /ip service set ftp disabled=yes
Thanks!
If you’ve just read all that, I hope you enjoyed it and learned something useful. We all need to be vigilant with security because even though it makes doing work more difficult and cumbersome, it also prevents hacks, exploits, and data breaches. Best of luck keeping your servers, services and kit secure!