quail-howto(8) FreeBSD System Manager’s Manual quail-howto(8)


qjail-howto — Details explaining how to use qjail to build a NON-VIMAGE jail system.


This howto will strive to explain how the qjail utility is used in a real world application Utilizing a documentation approach that fills in the blanks of how all the separate network functions fit together.


Please keep in mind that all this is fictitious, completely fake. For the purpose of this discussion, this host is typical of a home user or a Small Business. There is an officially registered domain name that points to the hosts IP address assigned by the ISP. The user has purchased a Home Class type of Internet service which gets assigned a Dynamic IP address. A business may purchase Business Class type of Internet service which gets assigned a static IP address. In both cases the host jails get configured the same way. All this is predicated on the jail being configured correctly first. This can be tested by logging into the running jail from the host console using this qjail command qjail console jail-name then issuing whois command, you will receive a reply if jail is configured correctly.


There is a big difference between the two in how they get configured on the host system and the yearly fee the ISP charges.

Static IP addresses are only assigned by the ISP for Business Class Internet service. The IP addresses assigned are public routable and permanent. The ISP does not provide any auto configuration services for Static IP address. The host configuration files have to be manually configured. The ISP will convey the following information;

The one or more assigned static IP addresses. These will need ifconfig statements added to the hosts /etc/rc.conf file to enable their usage. The fully qualified domain names of the ISP’s two DNS servers plus their IP addresses. This info is used to populate the hosts /etc/resolv.conf file.

Dynamic IP addresses are only assigned by the ISP for Home Class Internet service. A single assigned IP address is public routable. The ISP provides auto configuration services through DHCP. Dynamic means the ISP can change the assigned IP address on you while in use or change the DSN IP addresses and their domain names or reconfigure their network on the fly to use a different block of network IP address.   The /etc/rc.conf ifconfig_rl0="DHCP" statement will automatically handle this change on the fly transparently. This class of service is far cheaper than Business Class. Don’t be fooled by who uses Home Class internet service. Many small to medium sized businesses have this type of service.

While were talking about IP addresses, per RFC 1918, there are groups of IP address ranges reserved for private networks that will never be connected to the public internet. These are intended for Local Area Networks. They are not routable on the public Internet without first being NATed. - - -


Domain names have to be registered in the country where they are located and a yearly fee is charged. The domain name is linked to your IP address and this information is distributed to public Internet DNS servers so users on the internet can put your fully qualified domain name in the URL field of their web browser and find it’s way to the IP address of your host.

If you used a dynamic IP address to link to your domain name then when the dynamic IP address changes the linked domain name no longer points to your host and all Internet traffic stops. Now there are solutions to address this problem. Some domain name registers, and companies that host domain names, offer services where a program is run on the host that watches for dynamic IP changes and then updates the linked IP address of the domain name with the new dynamic IP address when a change occurs. Using this technique will keep your domain name pointing at your host.


The users domain name register hosts the domain name and points it to your hosts ip address. The ISP assigned one dynamic IP address to the host. The host is running RELEASE 11.0 and its already connected to the public internet and working correctly. All firewall rules are keep state and only inbound ports 53, 67, 22 are allowed in and only outbound ports 43, 53, 3690 are allowed out. All other inbound/outbound ports are blocked by default. Issuing whois command from the hosts console should work as the test to verify the host is functional. It’s assumed that all host commands are issued from the host’s local console keyboard.

The host only has 2 services running on it, SSH and IPFILTER firewall. The firewall allows remote public Internet access to SSH. SSH login authentication method is not important here as what ever method you want to use can be setup. The Host has two jails one for apache web server and the other one with ssh access.


1. NON-VIMAGE jails which we are talking about here do not have their
own firewalls. All jail traffic passes through the hosts firewall.
Security of what you want allowed in/out of the jail is controlled by
the hosts firewall based on the port numbers being used.

2. For jails to receive unsolicited inbound public access, each jail
needs a unique port number assigned to each separate jail for each
service you are going to run in that jail.

3. A firewall keep state rule to allow that unique port number in has to
be added to your hosts firewall rule set.

4. A NAT forward rule forwarding that unique port number to the IP
address assigned to the jail is required to be added to the hosts
firewall rule set. Different firewalls code this in different ways.
Read your firewall manual for details.

5. You can NOT run the same service on the host and in a jail or in
other jails without using a unique inbound port number to forward the
selected traffic to the desired jail.

6. Your domain name hoster plays a big part here. They have online
administrator functions where you can configure all port 80 traffic to
be forwarded to what ever port number you have used to point to the
desired jail. You can do this same thing for what ever other standard
port numbers you want forwarded to a jails unique port numbers. This
is how you drive different public domain name traffic to a single host
with jails serving services for just that domain name.


Step 1. Enter pkg install qjail to Install the qjail software.

Step 2. Enter qjail install to install the qjail environment.

Step 3. Enter qjail create -4 -c ssh To create a
directory tree type jail with ssh enabled.

Step 4. Enter qjail create -4 www To create a
directory tree type jail.

Step 5. Enter qjail start ssh Start this jail.

Step 6. Enter qjail restart ssh to stop and start the jail so
SSH will start running in the jail.

Step 7. Enter qjail start www Start this jail.

Step 8. Enter qjail console www Auto login to this jails console.
Enter pkg install apache24 Install web server software.
Enter echo "apache24_enable="YES"" >> /etc/rc.conf
Enter exit to leave jail console.

Step 9. Enter qjail restart www to stop and start the jail so
apache web server will start running.

Config host firewall for jail traffic

For the purpose of this discussion the host system is using the ipfilter firewall which is based on a IPF rules file and IPF NAT rules file. The actual IPF rules will be shown to illustrate their syntax.

To drive public traffic to a jail and have that same service run on the host means the same default port numbers can not be used in both the host and the jails. So port numbers 22 & 80 are used for the host. To target traffic to a jail we must assign the jails unique port numbers, 6122 for the ssh jail and 6180 for the www jail. These unique port numbers are arbitrarily chosen. You can chose whatever number fits your fancy.

These 2 unique port numbers must be allowed to pass through the IPF firewall. To do so add these 2 rules to the IPF rule set.

# Allow in www function for apache in qjail jail www pass in quick rl0 tcp from any to any port = 6188 flags S keep state

# Allow in ssh function in qjail jail ssh pass in quick rl0 tcp from any to any port = 6122 flags S keep state

In the NAT rules file is where the real action takes place. First of all, the MAP command must cover the compete range of IP addresses you plan to use on the host system for assignment to jails or LAN machines. In this case that’s this command.

map rl0 -> 0/32 # for normal lan + all jails

Now we have to code forward commands to point the inbound port numbers 6122 & 6188 to the jails IP addresses like this.

# Forward inbound unique port to jail ssh rdr rl0 port 6122 -> port 22 tcp

# Forward inbound unique port to jail www rdr rl0 port 6188 -> port 80 tcp

Load the NAT file to the system.

#This command loads the ipnat rules ipnat -FC -f /etc/ipnat.rules

#This command will resync ipnat with current host ip address ipf -y

Now we have to return to the IPF rules file and add rules to allow traffic outputted by the NAT forward rules to pass through the firewall by adding these two rules.

pass in quick rl0 tcp from any to port = 22 flags S keep state pass in quick rl0 tcp from any to port = 80 flags S keep state

Load the IPF rules file. ipf -FS -Fa -f /etc/ipf.rules

Testing remote jail traffic

From any device with a browser, as long as its IP address is not associated with the hosts IP address. Enter this URL format hosts_domain_name:8010/ or hosts_ip_address:8010/ Your browser will get this message It worked meaning you now have remote access to your www apache web server.

From any device with a ssh client, as long as its IP address is not associated with the hosts IP address. Use "hosts_domain_name" and port 8010 for ssh login or "hosts_ip_address" and port 8010. Use login name of "ssh" and first time password of ssh. You will be prompted to change the password. You now have remote SSH access to your ssh jail.

Some host debug commands

sockstat -j jid jib=jail running number sockstat -4 display all the in use host ip address and port number
being listened on. sockstat -4 | grep display only info for that ip number ipnat -lhd display nat info with count of times rule was hit ipfstat -hni list inbound firewall rules with hit count. Note: Any rule that is allowing in a unique port number that gets
forwarded does not show a hit count. Look for the rule that
allows in the jails ip address port number for the count.

You can add the tcpdump function to a jail be changing the devfs_ruleset number in the jails jail.conf definition from 4 to 50. There is a customized ruleset number 50 that adds the "bfp" device that tcpdump requires to work. The first time you use the "qjail config -b 50" command it will be created automatically.

From inside running jail issue tcpdump -v ip host jail-ip-address tcpdump -v tcp port 6122


qjail(8), qjail-intro(8), qjail-vnet-howto(8), qjail-ipv6-testing


Joe Barbish

FreeBSD 11.0 February 16, 2017 FreeBSD 11.0