3 minutes, 29 seconds
Host Your Own Services With FreeBSD: Prepare Jail Host

Now that we have secured our FreeBSD system, as well as our data partitions - both UFS and ZFS - from unavailability caused by disk failures, we will prepare it for its role of jail host. This requires reconfiguration of services that bind to all available interfaces to bind to specific interfaces instead. Jail manpage's section about setting up the host environment gives general guidelines, but it mentions services which are usually not enabled by default on contemporary FreeBSD versions (sendmail, inetd and rpcbind), while it does not mention services which are (ssh, ntp and syslog). This article gives instruction on how to bind sshd, ntpd and syslogd to specific interfaces, as well on how to create additional loopback interface. Finally we will modify hosts file.

Setting up the Host Environment section of jail manpage states that:

Since jails are implemented using IP aliases, one of the first things to do is to disable IP services on the host system that listen on all local IP addresses for a service. If a network service is present in the host environment that binds all available IP addresses rather than specific IP addresses, it may service requests sent to jail IP addresses if the jail did not bind the port.

This article assumes IP address of our jailhost has been set to 192.0.2.10

Let's check which network services are active:

root@jailhost:~ # sockstat -P tcp,udp
USER     COMMAND    PID   FD  PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
root     sshd         749 3   tcp6   *:22                  *:*
root     sshd         749 4   tcp4   *:22                  *:*
ntpd     ntpd         695 20  udp6   *:123                 *:*
ntpd     ntpd         695 21  udp4   *:123                 *:*
ntpd     ntpd         695 22  udp4   192.0.2.10:123        *:*
ntpd     ntpd         695 23  udp6   ::1:123               *:*
ntpd     ntpd         695 24  udp6   fe80::1%lo0:123       *:*
ntpd     ntpd         695 25  udp4   127.0.0.1:123         *:*
root     syslogd      643 6   udp6   *:514                 *:*
root     syslogd      643 7   udp4   *:514                 *:*

Services which have asterisk before port number in LOCAL ADDRESS column are the ones we want to bind. COMMAND column inform us those are sshd, ntpd and syslogd.

Let's set sshd_config:

# jailhost.example.org:/etc/ssh/sshd_config
ListenAddress      192.0.2.10
AuthorizedKeysFile .ssh/authorized_keys
Subsystem sftp     /usr/libexec/sftp-server

sshd_config manpage has more information about ssh server configuration options

Let's set ntp.conf:

# jailhost.example.org:/etc/ntp.conf
tos minclock 3 maxclock 6
pool 0.freebsd.pool.ntp.org iburst
pool 2.freebsd.pool.ntp.org iburst
restrict default limited kod nomodify notrap noquery nopeer
restrict source  limited kod nomodify notrap noquery
restrict 127.0.0.1
restrict 192.0.2.0 mask 255.255.255.0 nomodify notrap noquery nopeer
leapfile "/var/db/ntpd.leap-seconds.list"
interface ignore wildcard
interface listen 192.0.2.10

ntp.conf manpage has more information about ntp server configuration options

In order to keep jails' loopback traffic off the host's loopback network interface lo0, we will configure and create additional loopback interface lo1. Later on, when creating jails, we will assign jails' primary IP addresses to be from 127.0.1.0/24 address space bound to lo1 interface, whereas secondary IP address is going to be "real" IP address from 192.0.2.0/24 address space bound to physical interface. This will prevent jails' communication over host's loopback interface, requiring all the jails to communicate with each other as though they were separate physical machines.

Let's set rc.conf:

# jailhost.example.org:/etc/rc.conf
hostname="jailhost.example.org"
keymap="hr.kbd"
ifconfig_em0="inet 192.0.2.10 netmask 255.255.255.0"
defaultrouter="192.0.2.254"
cloned_interfaces="lo1" # CREATES ADDITIONAL LOOPBACK INTERFACE
ntpd_flags="-4" # SETS NTPD IPv4 ONLY
ntpd_enable="YES" # ENABLES NTPD
sshd_enable="YES" # ENABLES SSHD
syslogd_flags="-ss" # DISABLES NETWORK SOCKET FOR SYSLOGD
moused_nondefault_enable="NO"
zfs_enable="YES"

ntpd and syslogd manpages have more information about ntp and syslogd daemon flags

rc.conf manpage has more information about setting stuff at system startup

Let's set hosts file:

# jailhost.example.org:/etc/hosts
::1        localhost localhost.example.org
127.0.0.1  localhost localhost.example.org
192.0.2.10  jailhost  jailhost.example.org

Now that we prepared all the config files, let's apply changes:

root@jailhost:~ # service sshd restart
root@jailhost:~ # service ntpd restart
root@jailhost:~ # service syslogd restart
root@jailhost:~ # service netif cloneup

Confirm there are no services that bind to all interfaces:

root@jailhost:~ # sockstat -P tcp,udp
USER     COMMAND    PID   FD  PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
ntpd     ntpd         883 20  udp4   192.0.2.10:123        *:*
ntpd     ntpd         883 21  udp4   127.0.0.1:123         *:*
root     sshd         857 3   tcp4   192.0.2.10:22         *:*

Confirm existence of lo1 interface:

root@jailhost:~ # ifconfig lo1
lo1: flags=8008<LOOPBACK,MULTICAST> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        groups: lo
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>

Here's transcript of terminal session: