pf nat and rdr from host to jail

dvl@

Developer
I'm using FreeBSD 9.1. The host system gets a DHCP address on em0.

My goal is several jails, each of which you can ssh from the outside. I'll do this by redirecting port 100 to port 22 for the first jail, port 101 to 22 on the second jail, etc.

I'm using pf(4) to redirect and nat. But I'm doing it wrong. I'm missing something...

I've created a cloned interface, lo1. This has all the jail IP addresses. From /etc/rc.conf:

Code:
ifconfig_em0="DHCP"

cloned_interfaces="lo1"

ifconfig_lo1_alias0="inet  10.99.0.100/32"
ifconfig_lo1_alias1="inet  10.99.0.101/32"
ifconfig_lo1_alias2="inet  10.99.0.102/32"
etc

From the host system, I can ssh to the jail:

Code:
ssh -A dan@10.99.0.100

From my laptop, I can ssh to the host:

Code:
ssh -A 192.168.2.17

I cannot ssh to the jail from my laptop:

Code:
$ ssh -p 100 -A 192.168.2.17
ssh: connect to host 192.168.2.17 port 100: Connection refused

Here is /etc/pf.conf from the host system

Code:
ext_if="em0"
int_if="lo1"

internal_net="10.99.0.0/24"

set skip on lo0
set skip on lo1
set skip on em0

scrub in all

nat on $ext_if from $internal_net to any -> ($ext_if)

rdr on $ext_if proto tcp from any to ($ext_if) port 100 -> 10.99.0.100 port 22

pass  in all
pass out all

Here is some pfctl -sa output:

Code:
# pfctl -s a                  
No ALTQ support in kernel
ALTQ related functions disabled
TRANSLATION RULES:
nat on em0 inet from 10.99.0.0/24 to any -> (em0) round-robin
rdr on em0 inet proto tcp from any to (em0) port = newacct -> 10.99.0.100 port 22

FILTER RULES:
scrub in all fragment reassemble
pass in all flags S/SA keep state
pass out all flags S/SA keep state

INFO:
Status: Enabled for 0 days 01:12:29           Debug: Urgent
... rest snipped
 
FYI, I checked, and didn't have this in /etc/rc.conf, but it's there now. Problem persist.

Code:
gateway_enable="YES"
 
Hmmm, let me brain dump as I go along..

Code:
# tcpdump -ni em0 port 100
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on em0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:09:48.567632 IP 192.168.2.14.52042 > 192.168.2.17.100: Flags [S], seq 2374899772, win 65535, options [mss 1460,nop,wscale 1,nop,nop,TS val 2162829001 ecr 0,sackOK,eol], length 0
15:09:48.567643 IP 192.168.2.17.100 > 192.168.2.14.52042: Flags [R.], seq 0, ack 2374899773, win 0, length 0

So, clearly the incoming ssh connection is getting to the host system. But tcpdump -ni lo1 shows no output at all when the request comes in.
 
Oh wait, even an ssh 10.99.0.100 issued on the host system shows nil output from tcpdump -ni lo1.

If that's the case, then that's maybe why the existing rule set has no effect. The traffic isn't going through lo(4).
 
I have a better solution for this situation. I'm going to use my own WAP. That gets everyone onto the same network, 10.0.44/24. I'll hardcode the IP address of the jail server. Everyone else joins my WAP in the .0-.90 range. The jails sit in the .100-.140 range. Everyone is happy.
 
Here's my pf.conf:
Code:
ext_if = "fxp0"
int_if = "lo1"

nat on $ext_if from ($int_if:network) to any -> ($ext_if:0)
rdr pass on $ext_if inet proto tcp from any to ($ext_if:0) port 100 -> 10.0.0.2 port 22

Have you tried removing all the "skip on .." rules?
 
Toast said:
Have you tried removing all the "skip on .." rules?


Damn! That's probably what it was. Thank you.

FYI, I've set up the box for now, but I'll keep this in mind for future tutorial sessions.
 
Back
Top