
Most port knocking or
Single Packet Authorization
implementations offer the ability to passively authenticate clients for access only
to a locally running server (such as SSHD). That is, the daemon that monitors a
firewall log or that sniffs the wire for port knock sequences or SPA
packets can only reconfigure a local firewall to allow the client to access a local
socket. This is usually accomplished by allowing the client to connect to the
server port by putting an
ACCEPT rule in the
INPUT chain for
iptables firewalls, or adding a
pass rule for
ipfw firewalls
for the client source IP address. For local servers, this works well enough, but
suppose that you ultimately want to access an SSH daemon that is running on an
internal system? If the SPA software is deployed on a Linux gateway that is
protecting a non-routable internal network and has a routable external IP address,
it is inconvenient to first have to login to the gateway and then login to the
internal system.
Since the 1.9.2 release,
fwknop has supported the creation
of inbound port forwarding rules for iptables firewalls via the
DNAT
target in the
PREROUTING chain after receiving a valid SPA packet. This
allows direct access to internal systems on non-routable address space from the
open Internet. Here is an example - suppose that you are running
fwknop on Linux gateway system that is protecting an internal network
192.168.10.0/24 and has an external routable address of
11.1.1.1.
Now, suppose that you are on travel somewhere (so your source IP address is not
predictable), and you would like to access an SSH server that is running on the
internal system
192.168.10.23. Finally, because fwknop is deployed, iptables
is configured in a default-DROP stance against all attempts to connect with any SSH
daemon;
nmap cannot even tell that there is any SSH server listening. Access is
granted only after a valid SPA packet is passively sniffed by the fwknopd daemon.
With inbound NAT support configured in fwknop (the config is mentioned below), here
is an illustration of fwknop usage in order to gain direct access to SSHD on the
192.168.10.23 from an external network (note that the -R argument instructs
the fwknop client to automatically resolve the current IP address - 12.2.2.2 in
this case):
[externalhost]$ fwknop -A tcp/22 --Forward-access 192.168.10.23,5001 \
-R -D 11.1.1.1
[+] Starting fwknop client (SPA mode)...
Resolving external IP via: http://www.whatismyip.org/
Got external address: 12.2.2.2
[+] Enter an encryption key. This key must match a key in the file
/etc/fwknop/access.conf on the remote system.
Encryption Key:
[+] Building encrypted Single Packet Authorization (SPA) message...
[+] Packet fields:
Random data: 6862733471944039
Username: root
Timestamp: 1207404612
Version: 1.9.3
Type: 2 (FORWARD access mode)
Access: 12.2.2.2,tcp/22
Forward access: 192.168.10.23,5001
SHA256 digest: hE4zGafLtQiQiFrep+cSq/wVO7SQhwh65hmLr+ehtrw
[+] Sending 206 byte message to 11.1.1.1 over udp/62201...
Now, port 5001 on the external IP address is forwarded through to the SSH server
on the internal 192.168.10.23 system, but only for the client IP 12.2.2.2:
[externalhost]$ ssh -p 5001 mbr@11.1.1.1
Password:
[internalhost]$
Graphically, this scenario is illustrated by the following picture. The dotted
lines represent the SPA packet from the fwknop client (which only needs to be
sniffed by the fwknopd daemon running on the Linux gateway), and the solid
arrows represent the SSH connection from the external client through to the
internal SSH server.
On the Linux gateway system that is running the fwknop daemon, executing the
following command illustrates the additions to the iptables policy to allow the
SSH connection to be forwarded to the internal system. These firewall rules
are automatically deleted after a 30 second timeout (this is tunable), but any
existing SSH connection remains open through the use of the iptables connection
tracking capability.
[gateway]# fwknopd --fw-list
[+] Listing rules in fwknop chains...
Chain FWKNOP_INPUT (1 references)
pkts bytes target prot opt in out source destination
Chain FWKNOP_FORWARD (1 references)
pkts bytes target prot opt in out source destination
19 2740 ACCEPT tcp -- * * 12.2.2.2 0.0.0.0/0 tcp dpt:22
Chain FWKNOP_PREROUTING (1 references)
pkts bytes target prot opt in out source destination
1 60 DNAT tcp -- * * 12.2.2.2 0.0.0.0/0 tcp \
dpt:5001 to:192.168.10.23:22
Finally, the
/etc/fwknop/access.conf is configured like so to facilitate
this example, and the ENABLE_IPT_FORWARDING variable is also enabled in the
/etc/fwknop/fwknop.conf file:
SOURCE: ANY;
OPEN_PORTS: tcp/22;
PERMIT_CLIENT_PORTS: N;
ENABLE_FORWARD_ACCESS: Y;
FW_ACCESS_TIMEOUT: 30;
KEY: aesdemokey;
In addition to explaining the inbound NAT support offered by fwknop, this blog
post also announces the
1.9.3 release
of fwknop. Here is the complete
ChangeLog:
- Added MASQUERADE and SNAT support to complement inbound DNAT connections
for SPA packets that request --Forward-access to internal systems. This
functionality is only enabled when both ENABLE_IPT_FORWARDING and
ENABLE_IPT_SNAT are set, and is configured by two new variables
IPT_MASQUERADE_ACCESS and IPT_SNAT_ACCESS which define the iptables
interface to creating SNAT rules. The SNAT supplements of DNAT rules
are not usually necessary because internal systems usually have a route
back out to the Internet, but this feature accommodates those systems
that do not have such a route. By default, the MASQUERADE target is
used if ENABLE_IPT_SNAT is enabled because this means that the external
IP does not have to be manually defined. However, the external IP can
be defined by the SNAT_TRANSLATE_IP variable.
- Added hex_dump() feature for fwknop client so that raw encrypted SPA
packet data can be displayed in --verbose mode.
- When ENABLE_IPT_FORWARDING is set, added a check for the value of the
/proc/sys/net/ipv4/ip_forward file to ensure that the local system
allows packets to be forwarded. Unless ENABLE_PROC_IP_FORWARD is
disabled, then fwknopd will automatically set the ip_forward file to "1"
if it is set to "0" (again, only if ENABLE_IPT_FORWARDING is enabled).
- Minor bugfix to remove sys_log() call in legacy port knocking mode.
- Minor bugfix to expand both the Id and Revision tags via the
svn:keywords directive.