I now place all external ssh access behind knockd. I allow no-knock access with ssh over wireguard and tend to do all normal ssh operations that way. It is true that ssh with key access and passwords disabled has a similar security level to wireguard, what I like is that to an external observer, the pressence of wireguard and what port it's on is impossible to determine, since it's UDP. It also gives me access to the proxmox UI over wireguard which lets me disable access to Proxmox over open internet.
My initial knock rule setting script is:
Bash:
#!/bin/sh
# VA1DER - qst.va1der.ca knocklock, lock the door for the knock daemon
#
RULEPREFIX="QST_KNOCK_"
IPTABLES=/usr/sbin/iptables
# First delete all the tagged old rules, just in case this is rerun, clean up your mess first...
for CHAIN in INPUT; do
while $IPTABLES -t filter -L $CHAIN --line-number | grep $RULEPREFIX > /dev/null; do
$IPTABLES -t filter -D $CHAIN $($IPTABLES -t filter -L $CHAIN --line-number | grep $RULEPREFIX | head -1 | awk '{print $1}');
done
done
# Close ssh port
$IPTABLES -A INPUT -i eth0 -p tcp --syn --dport 22 -j REJECT --reject-with tcp-reset -m comment --comment $RULEPREFIX"SSH"
My knockd configuration is:
Code:
#----------------------------------------------------------------------------
# VA1DER - qst.va1der.ca Port Knock Daemon Config
#
[options]
UseSyslog
[opencloseSSH]
sequence = 2000:udp,3000:udp,4000:tcp
seq_timeout = 5
tcpflags = syn
start_command = iptables -D INPUT $(iptables -L INPUT --line-number | grep QST_KNOCK_SSH | head -1 | awk '{print $1}')
cmd_timeout = 5
stop_command = iptables -A INPUT -i eth0 -p tcp --syn --dport 22 -m comment -j REJECT --reject-with tcp-reset --comment QST_KNOCK_SSH
On a Proxmox (and thus Debian) server, also edit /etc/defaults/knockd and set the ethenet device to listen to. If you happen (like me) to employ IPv4 alias adapters, then knockd needs the alias adapter name to listen to (ie: eth0:1, eth0:2). I mention this because most applications (and firewall rules) work on the adapter base name which includes all aliases. In the very likely event you don't employ adapter aliases, just ignore what I said about them.
And lastly I have ssh configured to automatically knock before connecting via external to this by editing ~user/.ssh/config
Code:
Match host qstx exec "knock -v -d 250 qst.va1der.ca 2000:udp 3000:udp 4000:tcp"
Host qstx
Hostname qst.va1der.ca
Port 22
user kfitzner
Identityfile ~/.ssh/id_rsa16k_delilah
IdentitiesOnly yes
KexAlgorithms sntrup761x25519-sha512@openssh.com
Ciphers chacha20-poly1305@openssh.com
MACs hmac-sha2-512-etm@openssh.com
HostKeyAlgorithms rsa-sha2-512
With the above, when I "ssh qstx" it will automatically knock then connect.
Those, of course, are not the actual ports or order of UDP vs TCP that I use, but you get the picture.
Regarding what settings for ssh, I recommend using only large-key RSA host keys, sntrup761x25519 key exchange, and chacha20-poly1305 cipher. The MAC won't actually matter if you do that since that cipher has its own MAC. This requires a realatively modern ssh. If you have to use an older ssh, then diffie-hellman-group18-sha512 is the best (most quantum resistant classical KEX) to use. Under no circumstance use the variable-key-length diffie-hellman-group-exchange KEX.