# Jail natting on one interface



## razixx (Aug 26, 2012)

I've got FreeBSD-9.0 amd64 running on a VM what I'm trying to do is set it up jails so that the host acts as a gateway and all the jails run within a private network.

/etc/rc.conf

```
hostname="bsdbox"
ifconfig_em0=" inet 192.168.1.51 netmask 255.255.255.0"
defaultrouter="192.168.1.1"
gateway_enable="YES"

# IP for jail apache
cloned_interfaces="lo1"
ifconfig_lo1=" inet 192.168.2.1 netmask 255.255.255.255"
ifconfig_lo1_alias0=" inet 192.168.2.254 netmask 255.255.255.0"

pf_enable="YES"
pflog_enable="YES"

sshd_enable="YES"
syslogd_flags="-ss"

# Jails
jail_set_hostname_allow="YES"
jail_enable="YES"
jail_devfs_enable="YES"
jail_procfs_enable="YES"
#jail_sysvipc_allow="YES"
jail_socket_unixiproute_only="YES"

ezjail_enable="YES"

# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="NO"
```


```
bsdbox# jls
   JID  IP Address      Hostname                      Path
     1  192.168.2.1     apache.home.local             /usr/jails/apache
```

 /etc/pf.conf 

```
ext_if="em0"
int_if="lo1"
localnet=$int_if:network

set skip on lo0

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

block all
#pass in proto tcp to port ssh
#pass from $localnet to any keep state
[color="Red"]pass all[/color]
```

With the way that /etc/pf.conf is currently setup, I'm able to ping and resolve addresses from within the jail, however, if I remove the two hashes and the "pass all" line.  I am unable to do anything within the jail.  Syntastically it looks like it should work, and was pulled almost word for word from "The Book of PF".

Does anyone have any ideas what I may be doing wrong?

Eventually I want to scale this to a purchased vm once I can get a working setup.


----------



## razixx (Aug 26, 2012)

I probably should have posted this in the firewall forum, however if anyone knows of a better way of trying to accomplish the same thing, please feel free to share.  

I've already spent a couple of days on this and have made great progress and even learned a thing or two.  I have found many examples but most are incomplete showing only partial firewall configs or network configs or are trying to accomplish something similar but not the same(multiple nics whereas I only have one)


----------



## _martin (Aug 26, 2012)

I'm doing post in hurry but I'm sure the book you mentioned have this covered. Anyway either try 


```
nat pass .. (rest of the syntax)
```

if you want to allow all NATed traffic or make more specific rules.


----------



## plamaiziere (Aug 27, 2012)

razixx said:
			
		

> ```
> nat on $ext_if from $localnet to any -> ($ext_if)
> 
> block all
> ...



NAT occurs before filtering. It means that after NAT your outgoing packets (on em0) don't have anymore the source address $localnet but the address of ($ext_if). So your rule "pass from $localnet" doesn't match.

Regards.


----------



## kpa (Aug 27, 2012)

Nope, NAT is the last in the chain for outgoing packets. For incoming traffic it's the other way around, NAT (rdr rules) first then filtering. I would turn on logging for the block all -rule and see what kind of traffic is blocked.


----------



## fbsd1 (Aug 29, 2012)

You said 
"set it up jails so that the host acts as a gateway and all the jails run within a private network."

To me this means you have a host system without LAN behind it. On this host system you have a single ezjail setup jail that is running a apache web server that will serve public internet requests, port 80. The host is not running it's own web server. 

Your rc.conf is very simple
ezjail_enable="YES"   # so jail starts at boot
ipconfig_xl0="DHCP"   # interface connected to the public internet
# no firewall or any of that other network stuff you posted

Change the ip address of ezjail apache.home.local to what ever your public routable ip address your ISP asigned you. You dont need firewall to do NAT. Remote public internet user's browser makes request to your jailed apache web server FQDN, public dns converts FQDN to your public IP address, request packet arrives at host NIC, host presents port 80 for service and since no port 80 service is running on host them jail sees it and processes it. Back and forth traffic proceeds. Be sure jails /etc/resolv.conf is populated with the content of the hosts /etc/resolv.conf. 

This simple approach will verify that your jail is configured correctly and that your public FQDN is also configured correctly. You should be able to login to the jail using ezjail console command and issue "whois" cmd to see if you have outbound public internet access. Have remote user browse your FQDN. If that dont work have remote user browse your public routable IP address.


----------



## razixx (Aug 30, 2012)

> Change the ip address of ezjail apache.home.local to what ever your public routable ip address your ISP asigned you. You dont need firewall to do NAT. Remote public internet user's browser makes request to your jailed apache web server FQDN, public dns converts FQDN to your public IP address, request packet arrives at host NIC, host presents port 80 for service and since no port 80 service is running on host them jail sees it and processes it. Back and forth traffic proceeds. Be sure jails /etc/resolv.conf is populated with the content of the hosts /etc/resolv.conf.



I'm not sure this would work in my case,
<internet>  -->  <pfsense> --> <windows host><virtualbox><vm +freebsd +jails>
I was just trying to run this stuff in a test environment until I could move to a production environment but am finding I still have quite a bit to learn before I can do this.

I think I'm just going to abondon this setup for now, it's posing to be more dificult than I originally thought it would be.  I don't even know how to read /var/log/pflog (tcpdump I've recently discovered) thank you all for the suggestions.

*runs away with tail between legs*


----------



## _martin (Aug 31, 2012)

@razixx

Hi. In your example I would use the following skeleton of the pf.conf:


```
ext_if="em0"
jail_if="lo1"

IP_PUB="192.168.1.51"
IP_JAIL_WWW="192.168.2.1"

NET_JAIL="192.168.2.0/24"

PORT_WWW="{80,443}"

scrub in all

# nat+pass for www jail (use NET_JAIL to allow the whole subnet) 
nat pass on $ext_if from $IP_JAIL_WWW to any -> $IP_PUB

# redirect WWW ports to jail
rdr pass on $ext_if proto tcp from any to $IP_PUB port $PORT_WWW -> $IP_JAIL_WWW

# your wish
block all

# allow host SSH
pass in proto tcp from any to $IP_PUB port 22 label ssh-in
```


----------

