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
where:
- 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` me@myserver.net
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.
top