In a FreeBSD 10 setup, I have a jail running the publicly accessible nginx web server and another jail for the Java backend server based on Jetty. Each jail has its own internal IP address 127.0.1.x attached to the lo1 loopback interface. All this is configured to run with the pf firewall, which redirects incoming traffic to the nginx jail and from there to the Jetty jail. Basic pf configuration is shown below.

Now I would like to have a Git repository accessible externally via https. This is already set up and works well, but only by accessing it externally. From the Jetty jail, no connect is possible. However, I would like to access the Git repository from my Jetty backend jail via the public IP address.

I tried something like the following line to enable this in pf without success:

rdr pass proto tcp from $ip_jetty to $ip_public port https -> $ip_nginx

My pf firewall configuration looks as follows:

ip_public = ""
if_external = "igb0"
net_jails = ""
ip_nginx = ""
ip_jetty = ""

# Allow traffic from jails to outside world, enabled by network address translation
nat pass on $if_external from $net_jails to any -> $ip_public

# Redirect incoming web traffic to nginx jail
rdr pass on $if_external proto tcp from any to $ip_public port { http, https } -> $ip_nginx

# Allow outgoing connections
pass out all

# Allow nginx access to Jetty backend
pass in on lo1 proto tcp from $ip_nginx to $ip_jetty port 8080

To answer my own question, I got it to work using the following firewall configuration:

# Allow dynaserv jail to access git on https port of web jail
pass in on lo1 proto tcp from $ip_jetty to $ip_nginx port https

Also, in the /etc/hosts file of the Jetty jail, I added the internal IP address of the Nginx Jail:               git.mycompany.com

This way, the traffic is routed through the internal lo1 loopback interface instead of the external network device. This is not quite what I wanted to have in my original post, but this also works well once configured.

If someone still has an idea how to solve the question in the way it was intended (using the external network device), I am still interested in an answer.


I know it's been a while since this was asked, but here goes:

What you're describing in the OP is known as "Hairpin NAT." Instead of adding needless load on your gateway however, what you want to do is let PF handle all the translation. I believe the answer you seek is listed in the first comment on the top answer here: https://serverfault.com/questions/55611/loopback-to-forwarded-public-ip-address-from-local-network-hairpin-nat .

Basically, PF doesn't do this out of the box, but you can make it do so as follows (where, I believe, $hairpin_int is a new vNIC. Your /etc/rc.conf would have something like cloned_interfaces="lo1 hp1"):

no nat on $int_if proto tcp from $int_if to $int_net
nat on $int_if proto tcp from $int_net to $hairpin_int port $hairpin_ports -> $int_if
rdr on $int_if proto tcp from $int_net to $ext_if port $hairpin_ports -> $hairpin_int

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.