Versão em Português

Not-So-Well-Known Port Numbers

Rec 05-jan-2008 14:48

Not-So-Well-Known Port Numbers (NSWKPNs) is a simple yet reasonably effective way to reduce your network perimeter's exposure to Internet threats.

Recall that a cornerstone of the TCP/IP suite is the concept of well-known port numbers: by convention, some programs and protocols use certain port numbers. The standard port for HTTP is 80/tcp, HTTPS is 443/tcp, SSH is 22/tcp, syslog is 514/udp.

This makes easy for you to reach your SSH server that allows you to remotely administer your site. But it also makes easy for an attacker to try and exploit/bruteforce/abuse your SSH server.

Sure, you can set up your firewall to drop connections coming from untrusted sources, but that hampers your ability to connect from anywhere.

Now, what if the port number changed every five seconds in a way that it's easily predictable to you but looked random to an attacker? More precisely, what if your SSH daemon port number was computed from a strong cryptographic hash function using the current time and a secret key?

Even more precisely, let's suppose your SSH server port number is computed from the following function:

    port = HOTP( (T/G) || K,4)+O


  • T is the current time in seconds
  • G is the granularity, say, 5 seconds
  • K is a 128-bit secret key
  • / means 32-bit integer division
  • || is the concatenation operator, so the result of the first parameter is 160-bit long
  • HOTP(k,d) is the One Time Password generator function defined in RFC 4226, with its result truncated to d digits
  • O is an offset from the set { 10000, 20000, 30000, 40000, 50000 }

Suppose there is a simple userland utility called pn (for "port number") that does that computation, taking the key from its command-line argments and sending the result to the standard output. Then, on the client side, we could do:

ssh -p `pn somepassword 1 5`

The string somepassword is, obviously, the password. The 1 is shorthand for a O value of 10000, meaning that the resulting port will be in the 10000-19999 range. The 5 is the granularity.

Now suppose there is a netfilter match module called nswkpn that matches destination port numbers using the exact same calculation. So we could have iptable rules somewhat like that:

iptables -t nat -A PREROUTING -d ssh_servers_external_ip \  
    -m nswkpn -p tcp --offset 1 -j DNAT --to-destination=ssh_servers_internal_ip:22
iptables -A INPUT -d ssh_servers_internal_ip \  
    -m nswkpn -p tcp --offset 1 -j ACCEPT # Change INPUT to FORWARD if dest in other host

For this to work, the server and the client's clock must be synchronized with accuracy better than G.

Using this method, we reduce the chance that an attacker finds our SSH server from 1 (100%) to 1/10000 (0.01%). It's not as stealthy as many port knocking schemes, but it is simpler. The port number generation program may also run in your cellphone or PDA.

We could achieve even stealthier operation by computing/matching the source ports via a similar algorithm, but source NAT may mangle the source port numbers, causing the system to fail.

I was tempted to call this system "one-time port numbers" in analogy with one-time password schemes, but realized it would be imprecise: the numbers are not used only once, they are reused over and over at different times.

Kiko > PostsInEnglish > EnBlogEntry2008Jan05A
Creative Commons License   The content of this site is made available under the terms of a Creative Commons License, except where otherwise noted.
  O conteúdo deste site está disponibilizado nos termos de uma Licença Creative Commons, exceto onde dito em contrário.