There are safeguards to prevent the packet from being spoofed, and until the packet is received my SSH port stays safely blocked by the firewall - preventing the use of clever undiscovered exploits.
This is pretty cool because it means that my ssh port can be safely closed behind a firewall, yet still accessible to me (and only me) on the internet.
There are a whole bunch of moving pieces here (firewall, ports, services, client, keys), so I'll talk a lot of detail about the installation and configuration, the some options, then try an example or two. I haven't even touched the options for using my GPG-key for knocking!
Planning: Ahead of time, fill in this list:
- I want the knock to occur on UDP port #: (default 62201)
- I want be able to open ports for the following services: (example: sshd)
- Those services run on ports: (example: tcp/22)
- I want my knock password (key) to be: (8 characters min -or- GPG)
- I want to be notified of a successful knock by: (log/email/none)
- The interface I want to protect is: (only one, usually the same internet-facing interface described in your firewall)
- Server Install:
apt-get install fwknop-server # Debian
- Enable fwknopd to autostart upon boot. Edit /etc/default/fwknop-server
START_DAEMON="no" #From START_DAEMON="yes" #To
- Customize the server setup by editing /etc/fwknop/fwknop.conf:
EMAIL_ADDRESSES root@localhost; # From EMAIL_ADDRESSES MyLoginAccountName@localhost; #to PCAP_INTF eth0; # From PCAP_INTF ppp0; # To PCAP_FILTER udp port 62201; # From PCAP_FILTER udp port <some other port number>; # To
PCAP_INTF should be the same internet-facing interface used in your firewall (for example, ppp0). You can only choose ONE interface. In this case, ppp0 protects the internet-facing interface only so it does not protect against, say, hackers on the LAN wifi.
PCAP_FILTER is the udp port to listen for the knock on. Remember that PCAP_FILTER port number - you'll need that again on the client.
- Set the server access controls and keys by editing /etc/fwknop/access.conf:
# Change all three of the following, if needed. OPEN_PORTS: tcp/22,tcp/23,tcp/24,udp/85; KEY: <Your-8-digit-key>; FW_ACCESS_TIMEOUT: 30;
OPEN_PORTS is the list of ports fwknopd is permitted to open. The client will request a specific port on the list. Remember that 8-digit key, you'll need it again on the client.
- Edit the firewall to close all fwknop-protected ports. The fwknopd daemon will tell iptables to open the port as needed.
iptables -A INPUT -i lan0 -p tcp -dport 22 -j ACCEPT iptables -A INPUT -i ppp0 -p tcp -dport 22 -j REJECT
The first line opens the firewall for ssh from the LAN (not protected by fwknopd). The second line closes the firewall for ssh from the internet-facing ppp0. If the default policy is already DROP or REJECT, you don't need a separate entry at all and the second line can be deleted. fwknopd can open a port regardless of the default policy or any explicit closure rule.
- Restart fwknopd (and optionally the firewall) to load the new config(s):
fwknopd -Restart
- E-mail spamming of successful knocks: I got tired of that pretty fast, so I moved the notifications to a log:
- In /etc/fwknop/fwknop.conf, change
ALERTING_METHODS
fromALL;
tonoemail;
- Create a new file /etc/rsyslog.d/fwknop.conf:
# Log fwknopd actions to syslog, auth.log, and iptables.log :msg, contains, "fwkno" -/var/log/auth.log :msg, contains, "fwkno" -/var/log/iptables.log #my own custom iptables-related log
- Restart rsyslogd to reload the new config:
service rsyslog restart
- In /etc/fwknop/fwknop.conf, change
- Server Testing Tip: To prevent locking yourself out of the server (and feeling like a chump), here's a way to test fwknop without erroneously locking yourself out:
- Edit /etc/ssh/sshd.conf to add a second ssh port (let's say port 2233)
- Restart sshd to load the new config:
service ssh restart
- Use
netstat -tulpn
to ensure sshd is really listening on both ports - Edit your firewall so the new port (2233) is either explicitly closed or closed by the default policy (it doesn't matter which as long as it's closed). If necessary, reload your firewall to apply the changes.
- Configure fwknopd to listen on your LAN interface, and only to control the ssh test port.
- Do your testing and experimenting. Your original ssh port is unaffected.
- When testing is complete, edit /etc/ssh/sshd.conf to remove the testing port, remove any testing-port related lines in your firewall, and edit /etc/fwknopd/access.conf to remove the test port.
- Client Install:
sudo apt-get install fwknop-client # Ubuntu
- Usage with manually-entered key:
$fwknop --Server-port 12345 --Access 'tcp/22' -R --Destination myserver.dyndns.org Enter your key: <Your 8-digit key> $ssh -p 22 myserver.dyndns.org
Server-port is the PCAP_FILTER, the UDP port to send the knock on.
Access is the firewall port to open. It must be on the server's OPEN_PORTS list.
The 8-digit key must be the same, of course, as on the server.
The followup ssh command to connect on the briefly-open port is just an example. - Create a keyfile for automatic use (optional): Use the format servername: key
echo "myserver.dyndns.org: <Your 8-digit-key> > .knock-keyfile
- Usage with keyfile key (optional - handy for scripting):
$fwknop --Server-port 12345 --Access 'tcp/22' -R --Destination myserver.dyndns.org --get-key .knock-keyfile $ssh -p 22 myserver.dyndns.org