
Port knocking - simonpure
https://en.wikipedia.org/wiki/Port_knocking
======
rsync
I've been in this business for a long, long time and have come across all
manner of innovations regarding network security.

Port knocking (which I think I learned about first at defcon ... perhaps 18
years ago ?) _stands out_ as one of the very few things that made my
network(s) substantially safer at nearly zero cost. I love, and continue to
love, both the idea and the implementation.

Pay no attention to the nay-sayers and their comical straw-man argument
against deploying port knocking _by itself_. Of course it's not deployed by
itself - it is the last layer of _defense-in-depth_ on top of all the other
authentication methods you may be doing.

The _substantive critique_ is that you add some amount of complication to your
network and introduce a point of failure with knockd - and that is correct. I
am happy to report that 15+ years of knockd in production use, all over the
world, has produced exactly zero lock-outs or unintentional self-DoS.

~~~
acl777
any tips or where one would get best practice for configuring/setting up/using
knockd?

I wrote up how having a server on the internet is scary now
([http://redgreenrepeat.com/2020/03/20/why-you-should-
secure-y...](http://redgreenrepeat.com/2020/03/20/why-you-should-secure-your-
server-1/)) and how to protect it ([http://redgreenrepeat.com/2020/04/10/how-
to-secure-your-serv...](http://redgreenrepeat.com/2020/04/10/how-to-secure-
your-server-2/))

One thing I didn't get into more was port knocking/knockd as there were not
many resources for it.

I'd love to learn more about how you have used knockd.

~~~
rmrfstar
Moxie actually published a nice lighweight port knocking daemon that:

* Does not bind to sockets

* Is not written in C

* Prevents replay attacks

* The only code that runs as root is just tailing kern.log and is like 15 lines

It probably needs to roll from SHA1 to SHA256 and Python2 to Python3, but
otherwise seems sound.

[1]
[https://moxie.org/software/knockknock/](https://moxie.org/software/knockknock/)

~~~
Forbo
Looks like there is a pull request to change it from authenticate-then-encrypt
to encrypt-then-authenticate that hasn't been merged for over five years.
Thinking this project might be abandoned, unfortunately. :-(

Edit: It appears there may be an active fork here:
[https://github.com/indyprime/knockknock](https://github.com/indyprime/knockknock)

Still digging through to see if the encrypt-then-authenticate change made it
into this version.

Edit 2: It looks like it still uses authenticate-then-encrypt. I sent an email
to the maintainer of that fork, we'll see what happens. ^__^

------
taliesinb
I implemented a physical port-knocking daemon, once. I lived in a block of
flats — you needed an expensive fob to open the outer gate, and it didn’t even
work reliably.

I lost my fob. So I took my intercom apart and wired a band pass filter
circuit between the buzzer input and actuator output. If you pressed my buzzer
with the right steady pattern, it would automatically let you in.

It worked great and I didn’t buy a replacement fob.

A few months later I started getting woken up by someone buzzing my buzzer.
They would always scurry in before I could open my door to see who it was.

Turns out my upstairs neighbor saw my shenanigans a few times and started
freeloading off my invention. Honestly amazed he/she reverse engineered what
was going on!

Needless to say, I bought a new fob.

~~~
LordOfWolves
I enjoyed your story, but can you please elaborate on what your intercom is /
was for?

I understand the key fob/card concept for access purposes, but have never
heard of an “intercom” in the context of home/apartment/etc security.

~~~
jmchuster
An intercom that lets someone at the gate talk to the apartment in question to
try to convince them to buzz them in?

~~~
mike_d
Yes. They press an apartment number which dials your phone. "Hey your pizza is
here", then you press a button on your phone which opens the outer gate or the
front door to the building. You then meet them at your front door.

------
tptacek
Port knocking was somewhat silly when it was introduced ~20 years ago --- at
most, on a reasonably designed network, it was saving you from your own
misconfigurations, but at least in 2005 it was reasonable to imagine a highly
diverse network of machines that people logged into using multiple protocols,
where those misconfigurations were likely.

In 2020, it's gone past "silly" and is now a design smell, in the same way
that actually relying on fail2ban would be. Whatever port knocking is doing to
help you is a a description of something you're doing wrong with your
architecture.

We're not even comfortable with long-lived _keys_ anymore; modern networks are
built with short-lived certificates issued off 2FA from an IdP. We have good
VPNs right now for the other weird cases. Our networks default to all-ports
all-hosts closed. Arguably, port knocking is literally setting your security
back, by making it harder for automated tooling to scream bloody murder if
you've managed to expose a dev instance unexpectedly to the Internet.

Don't bother. If you've got a single system you're managing outside of a cloud
provider with its own decent network firewall, just set up WireGuard and
filter everything but that. If it helps, think of WireGuard as the evolution
of SPA port knocking.

~~~
nominated1
I use port knocking and I don’t take it seriously. Anyone using it in a
serious setup is batshit. However, for fun home projects where users install
that giant php based file sharing program, or that IoT camera, why not? They
don’t have automated intrusion prevention, etc. They can’t understand the code
to determine it’s quality, etc.

When the next 0day hits… will it be enough to protect them, yes. After all,
they’re not a target and the automated attacks won’t affect them.

~~~
okamiueru
I don't understand how knocking in if itself is bad. It's just a technique to
add a layer of protection.

In my case, all internal services in a kubernetes cluster have no path that
allow it to be accessed from the outside. Occasionally, developers might want
to do so, say to access a database or prometheus server.

The way to properly do this, imo, is to use a hardened service that functions
as a networking proxy. Use proper encryption keys for access, and it should be
quite hard to bust open.

Where does port knocking come in? That service should need to be exposed at
all times. So, use port knocking to configure the infrastructure to
temporarily allow access from your IP, to that proxy servers IP, on that
particular port.

I'm more inclined to _not_ take it serious, if such a simple mechanism isn't
in place to protect infrastructure.

~~~
okamiueru
*should not need to

------
orev
If you’re a fan or not of port knocking, single packet authorization is along
the same lines, and has a much more robust mechanism that addresses most of
the criticisms of port knocking. Your packet is cryptographically signed.

Take a look at fwknop for the implementation. The only issue with it is
there’s no easy install for pfsense.

------
x3blah
One can use "port knocking" for more than remotely opening ports. It is a
crude form of messaging in its own right, that can be based on some pre-
determined code, like Morse code. The "secret knock" need not open any ports.
It can be simply a message to the person (or program) reading the logs, to be
translated according to the pre-determined code. Actions might be taken in
response to the message, or not.

It is possible to do similar things with haproxy. Configured to listen for TLS
connections on a large number of ports, look for a secret combination of
custom headers and values, then, if found and matching, forward to a localhost
ucspi tcpserver on the backend. The tcpserver may then execute some program,
for example sshd or pfctl.

[http://cr.yp.to/ucspi-tcp.html](http://cr.yp.to/ucspi-tcp.html)

~~~
rogerdonut
Good idea. You can also do it based on a sequence of ports accessed as well
without headers/values which would allow you to forward directly to a tcp
based service. You can track which ports are accessed and verify the sequence
using stick-tables.

Here's an example of what that would look like:

[https://gist.github.com/dcorbett-
haproxy/ec7059cbfccf12c8f41...](https://gist.github.com/dcorbett-
haproxy/ec7059cbfccf12c8f41d060ac25403a5)

------
marcrosoft
Port knocking is great. Also look into honey ports which would be somewhat
opposite where you automatically block/log hosts that touch the wrong ports.

~~~
acl777
interesting - would this be an effective way to block portscanners?

~~~
marcrosoft
Yes.

------
nimish
A fun exercise is to integrate this with TOTP by reloading knockd with a new
config every 30 sec based on the secret.

~~~
MertsA
Doesn't TOTP usually allow for clock drift in either direction? This might be
problematic, especially if there's some IO issue causing it to hang. What
happens if the rootfs gets stuck read only?

------
nominated1
I too am a fan of port knocking. I don’t use knockd, just iptables. I found
the Arch Wiki most helpful. You’ll need to figure out which chain works for
your setup but it’s pretty straightforward.

[https://wiki.archlinux.org/index.php/Port_knocking#Port_knoc...](https://wiki.archlinux.org/index.php/Port_knocking#Port_knocking_with_iptables_only)

Here’s my example for a VPN running on OpenWrt. If you experience any race
conditions with iptables you can pepper each rule with something like “-w 5”

This opens Wireguard port 666 for 15 seconds. I have a script that creates my
ipset allowing connections from the USA only.

    
    
       # The correct port sequence is  1111 -> 2222 -> 3333 -> 4444; any other sequence will drop the traffic 
       iptables -N WG-INONE
       iptables -N WG-INTWO
       iptables -N WG-INTHREE
       #
       iptables -A input_wan_rule -m conntrack --ctstate NEW -m udp -p udp --dport 666 -m set --match-set usa src -m recent --mask 255.255.255.0 --rcheck --name WG3 --seconds 15 -j ACCEPT
       iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp -m recent --mask 255.255.255.0 --name WG3 --remove -j DROP
       iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp --dport 4444 -m recent --mask 255.255.255.0 --rcheck --name WG2 -j WG-INTHREE
       iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp -m recent --mask 255.255.255.0 --name WG2 --remove -j DROP
       iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp --dport 3333 -m recent --mask 255.255.255.0 --rcheck --name WG1 -j WG-INTWO
       iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp -m recent --mask 255.255.255.0 --name WG1 --remove -j DROP
       iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp --dport 2222 -m recent --mask 255.255.255.0 --rcheck --name WG0 -j WG-INONE
       iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp -m recent --mask 255.255.255.0 --name WG0 --remove -j DROP
       iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp --dport 1111 -m recent --mask 255.255.255.0 --name WG0 --set -j DROP
       iptables -A WG-INONE -m recent --mask 255.255.255.0 --name WG1 --set -j DROP
       iptables -A WG-INTWO -m recent --mask 255.255.255.0 --name WG2 --set -j DROP
       iptables -A WG-INTHREE -m recent --mask 255.255.255.0 --name WG3 --set -j DROP
    

EDIT - For those wondering about the Netmask, it's for mobile connections.

~~~
thaumaturgy
FWIW I worked with a guy who insisted on doing it this way and it was
extremely twitchy.

Problems included various operating systems and network tools knocking in ways
that iptables hates but a knock daemon will handle (e.g. sending two requests
per port); making iptables rules unnecessarily complex and hard to audit and
eventually conflicting with other things that interacted with iptables; and,
once, accidentally getting the knock-related rules nuked by some other
software and turning a simple login into a fun little puzzle at exactly the
wrong time to be solving more puzzles.

We tested both approaches early on. A working knockd implementation cost less
than an hour, including getting other users set up to interact with it. The
iptables implementation he switched to shortly after ended up costing dozens
of hours.

~~~
nominated1
Interesting. The only issue I’ve had was ensuring knocks were received in
order. DDNS being the worst culprit. Ensuring an adequate delay between knocks
solved my problems. However, I use this for home (friends and family only)
nothing serious.

If I were to use a daemon I’d go with an SPA, like fwknop. The lack of an iOS
client is the only reason I still use port knocking.

------
thomashabets2
I agree with other comments that portknocking is stupid.

It's not stupid to have a tiny tiny service to unlock your bigger attack
surfaces. It _IS_ stupid to implement "IP-over-SYNpackets" (actually "password
over SYN packets") when we already have a perfectly good way to send packets
of information that doesn't expose even the complexities of TCP (e.g.
slowlaris, SYN flood, etc…). And it's called UDP. Just send your plaintext
password in a UDP packet.

It's not exactly hard to safely receive a UDP packet. In fact it's orders of
magnitude easier to make a UDP server secure than a raw packet sniffer.

But also I would argue that TCP MD5 (RFC 2385) is vastly underused. It doesn't
work through NAT, so maybe now that IPv6 is becoming more and more common
it'll gain more traction. It's been used in production with BGP since forever
(at least since the 90s), but there's nothing stopping it being used for SSH
too. (in fact I run a patched OpenSSH that uses TCP MD5, see my blog post)

TCP MD5 also prevents your connection from being reset on a TCP level, once
it's up and running, even by someone who can inject spoofed packets and sniff
your encrypted connection.

More on this: [https://blog.habets.se/2019/11/TCP-
MD5.html](https://blog.habets.se/2019/11/TCP-MD5.html)

------
bkanber
What does port knocking look like on the client side? Does ssh have some
option that makes it easy? Does everyone just write a custom bash script that
wraps ssh client?

~~~
bkanber
If anyone else was curious like I was, it looks like yes, most people do write
a custom bash script to wrap (or use before) SSH. The makers of knockd also
make a `knock` util that serves as a client, but other people also do
something like:

``` for x in 9000 8000 7000; do nmap -Pn --host_timeout 201 --max-retries 0 -p
$x server_ip_address; done ```

------
crawshaw
A recent version of single-packet port knocking is the handshake in the Noise
protocol: [https://noiseprotocol.org/](https://noiseprotocol.org/)

------
gurustave
Classic! I remember using Port Knocking during the Louisiana Tech CyberStorm
Hacking Competition in 2015 to completely lock down open ports on our VM Host
Server since trying to use the glitchy Server KVM directly on the Rack was a
test in futility. Between Port Knocking, Xpra, and knowing to disconnect the
VMs from the network until after I had patched them, no one stood a chance
hacking our VMs. Their VMs on the other hand often didn't withstand my scripts
just constantly trying to get in with the VM default passwords, change the
flags to give us credit, lockdown and take over root, leaving us a way back in
after, and continuously using the root account to reclaim the flag if they
noticed.

------
kitteh
Couldn't someone (in the dataplane path) just sniff the knock and observe
comms after and replay it later?

~~~
barbegal
Yes but you can defend it against replay attacks if you use a rolling code
[https://en.wikipedia.org/wiki/Rolling_code](https://en.wikipedia.org/wiki/Rolling_code)

------
Pxtl
This seems brittle as hell, and is security-through-obscurity. It breaks when
packets come out of order. It breaks when packets are dropped. It breaks when
it gets carried away and shuts down all inbound traffic, effectively DDOSing
yourself.

It seems like you would get the same benefits by moving all major at-risk
services (eg SSH) to non-standard ports, and set up exponential IP bans on
attempts to communicate on any other port.

------
aaronky
I use port knocking as an emergency backup measure on my bastion host (OpenBSD
w/pf). The regular sshd runs on a non standard port with key authentication
only. The backup sshd needs to be knocked and allows password authentication.
I only use it in emergencies when I don't have my key handy.

I have used it in the past and has saved me a few times. This is only on the
bastion.

------
vulkd
One-time knocking via changing the ports for every connection / every X
seconds with a OTP is something else you can do to further contribute to the
_defense-in-depth_ idea. Port knocking is great on it's own, but curious to
hear from those who have set it up this way. Love the 'honey port' idea
mentioned elsewhere in the thread.

------
knorker
Port knocking is pointless. Just use a password over UDP and stop feeling
yourself with your cloak and dagger pretend spy nonsense.

------
emiunet
We like fwknop a lot for its cryptography implementation which can prevent
MITM attacks. However, we don't like it for relatively complex client setup.
(For example, there is no official iOS client). So we built our own cheap
version of port-knocking and called it "doormand". It's just a HTTP server
(behind nginx) listening for a POST request from clients. If the request is
valid, a new iptables rule is added for the knocking IP for 30 seconds. It
supports users with secret key (think API token) so we can knock from our
workstation easily. It also supports Timebased-OTP (we can even setup so user
is required to enter 2 different TOTP's when knocking) so we can knock from
mobile devices. All messages are hash'ed with timestamp making it harder to
re-play attack. It works great for us (a small team) because now we can knock
over HTTPS on our phone/ipad and then SSH-connect to servers.

------
teddyh
Port knocking is stupid. The only possible real reason anyone should have for
actually using it is if they really don’t want their logs to be flooded with
the normal internet attacks. Logs which the SSH daemon really shouldn’t (by
default) be creating in the first place, since what’s the use? It’s like
having a weather station on your roof which always says “it’s raining”, since
you _live on the ocean floor_. It’s the internet, SSH will be attacked;
there’s (by default) no purpose to logging this.

For _actual security_ , though, it’s also woefully inadequate:

1\. It adds _very little_ security. How many bits are in a “secret knock”?

2\. The security it _does_ add is _bad_ : It’s sent in cleartext, and easily
brute-forced.

3\. It complicates access, since it’s non-standard.

~~~
blauditore
I agree with 1. and 3., but not 2.: It's basically like a password where ports
are your alphabet.

Assuming you use most of the 2^16 ports, and a typical text password is based
on an alphabet of ~70 characters, each knocking step is roughly equivalent to
log_70(2^16) ≃ 2.61 traditional password characters.

For example, 5 steps of knocking already entail (2^16)^5 ≃ 1.2*10^24 steps to
check. With 1000 attempts per second, that still means trying > 10^13 years
until all combinations have been tried.

~~~
teddyh
I’m unconvinced that most people use such complicated knocking schemes to
contain that many bits.

It’s still trivially sniffed, since it’s sent in the clear.

And it’s hard to change, since you have to change all the places which needs
it.

------
jftuga
I have created a different approach to accomplish the (somewhat) same goal as
port knocking here:

[https://github.com/jftuga/gofwd](https://github.com/jftuga/gofwd)

gofwd is a cross-platform TCP port forwarder with Duo 2FA and Geographic IP
integration. Its use case is to help protect services when using a VPN is not
possible. Before a connection is forwarded, the remote IP address is
geographically checked against city, region (state), and/or country. Distance
(in miles) can also be used. If this condition is satisfied, a Duo 2FA request
can then be sent to a mobile device. The connection is only forwarded after
Duo has verified the user.

Thoughts?

------
michaelaiello
Many Many Moons ago I implemented an OS version of this for windows. It was
taken over a few years back and is released as KnockKnock.
[https://sourceforge.net/projects/knockknock/](https://sourceforge.net/projects/knockknock/)

We are now using the same technique in a network security product at AppGate
which is used to protect highly sensitive workloads around the world.
[https://www.appgate.com/blog/dont-be-fooled-by-lowercase-
sdp...](https://www.appgate.com/blog/dont-be-fooled-by-lowercase-sdp-
imitators)

Port Knocking is great, another layer of defense.

------
ubercow13
How convoluted. Why not just send the password in a plaintext UDP packet?

~~~
knorker
Correct.

------
rubyn00bie
And to save other folks a search, this is pretty awesome:

[https://linux.die.net/man/1/knockd](https://linux.die.net/man/1/knockd)

~~~
geoffeg
If someone intercepts the traffic to my server, they could see the knock
sequence and re-use it. Is there any way to get knockd to use a google
authenticator-like sequence of port knocks?

~~~
thedanbob
I use fwknop[0] on my servers. It does single-packet authorization rather than
straight port knocking, which solves the replay issue.

[0] [https://www.cipherdyne.org/fwknop/](https://www.cipherdyne.org/fwknop/)

------
brobinson
Alternatively, check out "single packet authorization"

------
101404
TIL. Basically you type in a password. But instead of fingers, you use HTTP
requests. And instead of a keyboard, you use server ports.

------
infogulch
What if the correct port knock sequence rotates every 15s based on the time
and some PSK material, kinda like TOTP.

------
vijaybritto
This was one of the coolest tech that I have implemented!! We used it for
authenticating public facing services in a voip application. It worked really
well! I was a beginner and I barely understood the benefits. It was the tech
leads who guided me to the finish. Such a rewarding experience!

------
Zenst
it's a great technique, one I used a lot in the late 90's, had a port sequence
would ping and that was S/KEY and could run on an nokia or anything that could
run java to get the key from the seed. then dydns and could get ssh open and
connect. Probably a bit para, but hey, with security it's only paranoid in
hindsight if nothing bad happened. Also added extra layer against any zero day
upon ssh.

Had it on a openbsd box, firewall script deamon would monitor the firewall
logs, pick up the sequence and open ssh for that ip if matched and as sequence
was S/KEY, it was always changing. Still cool effective solution.

[https://en.wikipedia.org/wiki/S/KEY](https://en.wikipedia.org/wiki/S/KEY)

------
tnash
knockd is pretty easy to setup and use. I used it in a security lab class in
college in the late 2000s and nobody could figure out why we didn't have any
open ports!

------
nwsm
Why is this better than an application taking open requests on one of the
ports and accepting a password used to open the other port?

------
Animats
It's not really very secure, but it's used so little that low-end attackers
don't bother to attack it.

------
peterwwillis
Port knocking is literally the computer security equivalent of an ADT home
security sticker in your front window.

------
ChrisSD
Port knocking is great theatre but not much good for anything else. I guess it
can keep logs clear feom some drive by script kiddies.

~~~
BenjiWiebe
If your ssh sever had a 0day, port knocking would protect you.

~~~
c22
What if your port knocking monitor has a zero day?

~~~
flemhans
Then ssh would protect you. The two having zero days at the same time is
unlikely.

~~~
barbegal
Not necessarily, imagine a port knocking monitor that stores each port attempt
it sees in a large buffer. Imagine you make many attempted connections
allowing you to overflow the buffer and write arbitrary data onto the heap.

~~~
cutemonster
Or the monitor being written in c and analyzing text in the knock messages,
e.g. looks and interprets a hash

