ctx->guides->proxy
Accessing firewalled services using PF on OpenBSD
Consider a scenario where all hosts in a network have public IP
addresses, but only one subnet is accessible from the Internet because
of a corporate firewall. Internal hosts communicate with each other
normally. In order to access the SSH port of a firewalled machine, say
with the hostname hidden
, you may use another host, say middle
,
belonging in the accessible subnet, at a different port, and redirect
traffic to and from hidden
. Most of this is described in
PF User's Guide, but the
manual assumes a public and a private interface with NAT between the two.
This guide is about using the same interface to do the forwarding.
It can be done using a user-level proxy or completely in-kernel with PF.
The configuration of the middle
host is found below.
User-level proxy with inetd and netcat
/etc/pf.conf:
# Proxy SSH to other machines with inetd
pass in quick on egress proto tcp from any to any port 1337 rdr-to (lo)
/etc/inetd.conf:
# SSH proxy using nc
127.0.0.1:1337 stream tcp nowait proxy /usr/bin/nc nc hidden 22
/etc/rc.conf.local:
inetd_flags=
Kernel-level proxy only with PF rules
/etc/pf.conf:
# Proxy SSH to other machines
pass in quick on egress proto tcp to port 1337 rdr-to hidden port ssh
pass out quick on egress proto tcp to hidden port ssh nat-to (egress)
/etc/sysctl.conf:
net.inet.ip.forwarding=1
Tips for SSH access
For seamless SSH access to the hidden
host you can alias it to the
middle
host, and use the appropriate port like this.
~/.ssh/config:
Host hidden
HostName middle
Port 1337
The aliasing can also be done at the /etc/hosts
or DNS level using a
CNAME record for hidden.example.org
that points to
middle.example.org
and use:
~/.ssh/config:
Host hidden.example.org
Port 1337
Performance evaluation
A rough benchmarking of the two methods shows that the PF-only setup
performs slightly better probably because it generates less local traffic
and context switches. Throughput and latency was measured over ssh as
shown below. The tests are a single large file transfer and the timing
of login and logout. The load on the middle
host is also displayed
broken down as interrupts and system time.
# large file transfer
$ time scp install54.iso hidden:
# login operation
$ time ssh hidden echo
And the results:
# throughput latency ints system
user-level: 3.9MB/s 0.6461s 35% 5%
kernel-only: 3.9MB/s 0.6220s 23% 0%
Choose your destiny!
Cheers!
lostd@