IPFW Help required for IPFW, IPv6 and Jails

Hi all,

I think I need some hints and tipps from you firewall and network experts here.

Currently I have the following working scenario for IPv4:
My server has one external IPv4 address.
I'm running several jails hosting different services, each having an own 192.168.0.x IP on an internal cloned network interface.
(A jail running PostgreSQL and slapd as databases, a Jail with Prosody as chat server, a Jail with Apache + Nextcloud, a Jail with Apache + Subversion and a jail running pound as proxy to dispatch HTTP traffic between the two Apaches, since I have multiple domains.)

I'm using IPFW with in-kernel NAT to isolate the jails against each other and routing incoming traffic to the right jail.
Incoming traffic to port 5222 (prosody) is routed to the 'chat server jail', incoming traffic to port 80,443 is routed to the 'pound proxy jail' which itself forwards than to either the 'nextcloud jail' or 'subversion jail'.

The jails are isolated against each other, for example each jail can reach the postgres and slapd ports on the database jail (because the services there need a database or LDAP for authentication), but the database jail itself is not reachable from the outside.
The database jail cannot reach the nextcloud jail by itself, because there is no need for that and so on and so on...

As I said: This scenario is working fine for some years now, see my IPFW rules posted below. Pretty sure that some of the rules could be optimized, but it works and I think (/hope) I have no severy security issues with that rules. (Any hints for improvements are welcome.)

Now I (finally) want to use IPv6 in parallel.
For IPv6 I've got a whole subnet from my ISP, not only a single IPv4.
So, I think it should be possible to assign each jail an own IPv6 and set my DNS records accordingly (chat.mydomain.com to the chat jail's own IPv6, nextcloud.mydomain.com to the nextcloud jail's own IPv6 etc.).
No need to NAT and/or the pound proxy anymore.

My first question: Can I use my existing IPv4 scenario in parallel with that new IPv6 scenario? So, stick to the single external IPv4 and each jail uses an internal 192.168.0.x IPv4 on a cloned interface and using IPFW NAT + a pound proxy? And in parallel assign each jail a own IPv6 from my subnet so that I can make port 80,443 of my nextcloud jail directly accessible with its own IPv6 and also port 80,443 of my svn jail with its own IPv6?
Or is a combination of IPv6 and IPv4+NAT not possible with IPFW and I need to NAT everthing (IPv4 and IPv6) or get completely rid of IPv4?

My second question: I just started with IPv6 and tried to make as a first step the ssh server (directly running on my server, not in a jail) reachable via IPv6. THerefore I added some IPv6 statements to my IPFW rules, but must have an error here.
When I've disabled IPFW I can reach my sshd with IPv6, but if it is enabled its blocked. From that I know that the IPv6 network configuration seems to be ok and the issue must be an IPFW issue.

I really would appreciate if someone can tell me a) the right rules to open sshd for IPFW+IPv6 and b) tell me if my whole IPv4+IPv6 scenario is possible (or how it is possible).

Thanks & kind regards,
Fool

Here my current network configuration in rc.conf:

Code:
# Private IPv4 assigned by ISP                                                                                                                                                                                                             
ifconfig_em0="inet A.B.C.D netmask 255.255.252.0"
# Gateway IPv4 assigned by ISP                                                                                                                                                                                                             
defaultrouter="E.F.G.H"
 # First IPv6 from assigned subnet by ISP
ifconfig_em0_ipv6="inet6 aaaa:bbbb:cccc:dddd::1/64"                                                                                                                                                                                             
# Additional IPv6s from assigned subnet by ISP (for jails)
ifconfig_em0_alias0="inet6 aaaa:bbbb:cccc:dddd::2/64"                                                                                                                                                                                           
ifconfig_em0_alias1="inet6 aaaa:bbbb:cccc:dddd::3/64"
[...]                                                                                                                                                                                       
# Gateway IPv6 assigned by ISP                                                                                                                                                                                                             
ipv6_defaultrouter="xxxx::1%em0"
 # internal local interface for jail communication                                                                                                                                                                                             
cloned_interfaces="lo1"                                                                                                                                                                                                                       
ifconfig_lo1="inet 192.168.0.1 netmask 255.255.255.0 mtu 1500"                                                                                                                                                                               
icmp_drop_redirect="YES"                                                                                                                                                                                                                     
icmp_log_redirect="YES"
[...]
gateway_enable="YES"                                                                                                                                                                                                                         
firewall_enable="YES"                                                                                                                                                                                                                         
firewall_nat_enable="YES"                                                                                                                                                                                                                     
firewall_quiet="YES"                                                                                                                                                                                                                         
firewall_logging="YES"                                                                                                                                                                                                                       
firewall_script="/etc/ipfw.rules"

Here is my current ipfw.rules including some IPv6 attemts:
Code:
#!/bin/sh

#################################################
# configuration 
################################################
fwcmd="/sbin/ipfw -q add"        # ipfw command
wan="em0"                # the external interface (public internet)
wan_ip4="a.b.c.d"            # the externally assigned IPv4 address
loop="lo0"                # loopback interface (local network for host only)
lan="lo1"                # internal interface (local network for jails)
jumpNAT="skipto 65100"            # jump to NAT rule
jail_host="192.168.0.1"            # jail aliases
database_jail="192.168.0.2"
proxy_jail="192.168.0.3"
chat_jail="192.168.0.4"
nextcloud_jail="192.168.0.5"
svn_jail="192.168.0.6"



################################################
# Initialization
################################################

# flush out the list before we add any rules
/sbin/ipfw -q -f flush



################################################
# Initialization for IPv4 NAT 
################################################

# permit reinsertion of translated packets for further processing
/sbin/ipfw disable one_pass
# activate in-kernel NAT and define rules
/sbin/ipfw -q nat 1 config if ${wan} same_ports unreg_only reset \
    redirect_port tcp ${proxy_jail}:80 80 \
    redirect_port tcp ${proxy_jail}:443 443 \
    redirect_port tcp ${chat_jail}:5222 5222



################################################
# LOCAL traffic (rules 0-499)
################################################

# ALLOW anything within the loopback interface
${fwcmd} 00001 allow all from any to any via ${loop}

# ALLOW each jail to reach itself without restriction
${fwcmd} 00010 allow all from ${jail_host} to ${jail_host} via ${lan} 
${fwcmd} 00011 allow all from ${database_jail} to ${database_jail} via ${lan} 
${fwcmd} 00012 allow all from ${proxy_jail} to ${proxy_jail} via ${lan}
${fwcmd} 00013 allow all from ${chat_jail} to ${chat_jail} via ${lan}
${fwcmd} 00014 allow all from ${nextcloud_jail} to ${nextcloud_jail} via ${lan}
${fwcmd} 00015 allow all from ${svn_jail} to ${svn_jail} via ${lan}



################################################
# NAT and existing entries in dynamic rules table
# (rules 500-999)
################################################

# reassemble inbound packets
${fwcmd} 00500 reass all from any to any in 
# NAT any inbound packets
${fwcmd} 00501 nat 1 ip from any to any in via ${wan}
# allow packets having an existing entry in the dynamic rules table
${fwcmd} 00502 check-state



################################################
# OUTBOUND traffic (rules 1000-9999)
################################################

# ALLOW access to public DNS (see /etc/resolve.conf)
${fwcmd} 01000 ${jumpNAT} tcp from any to a.b.c.d 53 out via ${wan} setup keep-state
${fwcmd} 01001 ${jumpNAT} udp from any to a.b.c.d 53 out via ${wan} keep-state
${fwcmd} 01002 ${jumpNAT} tcp from any to a.b.c.d 53 out via ${wan} setup keep-state
${fwcmd} 01003 ${jumpNAT} udp from any to a.b.c.d 53 out via ${wan} keep-state
${fwcmd} 01004 ${jumpNAT} tcp from any to ${wan_ip4} 443 out via ${wan} setup keep-state
${fwcmd} 01005 ${jumpNAT} udp from any to ${wan_ip4} 443 out via ${wan} keep-state

# ALLOW access to OpenNTP (see /usr/local/etc/ntpd.conf)
${fwcmd} 01010 ${jumpNAT} udp from any to any 123 out via ${wan} keep-state

# ALLOW nextcloud jail some outbound traffic
# send mail
${fwcmd} 01050 ${jumpNAT} tcp from ${nextcloud_jail} to A.B.C.D 465,993 out via ${wan} setup keep-state
# use HTTP / HTTPS connections
${fwcmd} 01051 ${jumpNAT} tcp from ${nextcloud_jail} to any 80,443 out via ${wan} setup keep-state

# ALLOW svn jail some outbound traffic
# send mail
${fwcmd} 01080 ${jumpNAT} tcp from ${svn_jail} to A.B.C.D 465,993 out via ${wan} setup keep-state

# ALLOW traffic to services between jails (note: no NAT required)
# to database jail
${fwcmd} 01100 allow tcp from ${jail_host} to ${database_jail} 389,636,5432 out via ${lan} setup keep-state
${fwcmd} 01101 allow tcp from ${chat_jail} to ${database_jail} 389 out via ${lan} setup keep-state
${fwcmd} 01102 allow tcp from ${nextcloud_jail} to ${database_jail} 636,5432 out via ${lan} setup keep-state
${fwcmd} 01103 allow tcp from ${svn_jail} to ${database_jail} 636 out via ${lan} setup keep-state
# to proxy jail
${fwcmd} 01110 allow tcp from ${jail_host} to ${proxy_jail} 80,443 out via ${lan} setup keep-state
# to chat jail
${fwcmd} 01120 allow tcp from ${jail_host} to ${chat_jail} 5222 out via ${lan} setup keep-state
${fwcmd} 01121 allow tcp from ${svn_jail} to ${chat_jail} 5222 out via ${lan} setup keep-state
# to nextcloud jail
${fwcmd} 01130 allow tcp from ${jail_host} to ${nextcloud_jail} 80,443 out via ${lan} setup keep-state
${fwcmd} 01131 allow tcp from ${proxy_jail} to ${nextcloud_jail} 80,443 out via ${lan} setup keep-state
# to svn jail 
${fwcmd} 01140 allow tcp from ${jail_host} to ${svn_jail} 80,443 out via ${lan} setup keep-state
${fwcmd} 01141 allow tcp from ${proxy_jail} to ${svn_jail} 80,443 out via ${lan} setup keep-state

# ALLOW each jail to reach the host's syslogd and exim (note: no NAT required)
${fwcmd} 01200 allow udp from 192.168.0.0/24 to ${jail_host} 514 out via ${lan} keep-state
${fwcmd} 01201 allow tcp from 192.168.0.0/24 to ${jail_host} 25 out via ${lan} setup keep-state

# ALLOW root user to reach anything - this applies also for jails!
# (important for updates etc.)
${fwcmd} 01300 ${jumpNAT} tcp from me to any out via ${wan} setup keep-state uid root
${fwcmd} 01301 ${jumpNAT} udp from me to any out via ${wan} keep-state uid root
${fwcmd} 01302 ${jumpNAT} icmp from me to any out via ${wan} keep-state
# same for ipv6
${fwcmd} 01310 allow tcp from me6 to any out via ${wan} setup keep-state uid root
${fwcmd} 01311 allow udp from me6 to any out via ${wan} keep-state uid root
${fwcmd} 01312 allow ipv6-icmp from me6 to any out via ${wan} keep-state

# DENY and log all other outbound connections
${fwcmd} 09999 deny log all from any to any out via ${wan}



################################################
# INBOUND traffic (rules 10000-19999)
################################################

# DENY all inbound traffic from non-routable reserved address spaces
${fwcmd} 10001 deny all from 192.168.0.0/16 to any in via ${wan}     #RFC 1918 private IP
${fwcmd} 10002 deny all from 172.16.0.0/12 to any in via ${wan}      #RFC 1918 private IP
${fwcmd} 10003 deny all from 10.0.0.0/8 to any in via ${wan}         #RFC 1918 private IP
${fwcmd} 10004 deny all from 127.0.0.0/8 to any in via ${wan}        #loopback
${fwcmd} 10005 deny all from 0.0.0.0/8 to any in via ${wan}          #loopback
${fwcmd} 10006 deny all from 169.254.0.0/16 to any in via ${wan}     #DHCP auto-config
${fwcmd} 10007 deny all from 192.0.2.0/24 to any in via ${wan}       #reserved for docs
${fwcmd} 10008 deny all from 204.152.64.0/23 to any in via ${wan}    #Sun cluster interconnect
${fwcmd} 10009 deny all from 224.0.0.0/3 to any in via ${wan}        #Class D & E multicast

# DENY public pings (only allow icmptype 0 if we ping stuff ourself)
${fwcmd} 10010 deny icmp from any to any in via ${wan} not icmptypes 0
${fwcmd} 10011 deny ipv6-icmp from any to any in via ${wan} not icmp6types 0

# DENY ident/ noise from routers
${fwcmd} 10020 deny tcp from any to any 113 in via ${wan}
${fwcmd} 10021 deny udp from any to any 520 in via ${wan}

# DENY all Netbios services
${fwcmd} 10030 deny tcp from any to any 137 in via ${wan}
${fwcmd} 10031 deny tcp from any to any 138 in via ${wan}
${fwcmd} 10032 deny tcp from any to any 139 in via ${wan}
${fwcmd} 10033 deny tcp from any to any 81 in via ${wan}

# DENY fragments
${fwcmd} 10040 deny all from any to any frag in via ${wan}

# DENY ACK packets that didn't match the dynamic rule table
${fwcmd} 10041 deny tcp from any to any established in via ${wan}

# DENY broadcasts and multicasts
${fwcmd} 10050 deny ip from any to 255.255.255.255
${fwcmd} 10051 deny ip from any to 224.0.0.0/24 in    

# DENY spoofing from outside
${fwcmd} 10060 deny ip from any to any not antispoof in via ${wan}
${fwcmd} 10061 deny all from any to 127.0.0.0/8 in via ${wan}
${fwcmd} 10062 deny all from any to ::1 in via ${wan}
${fwcmd} 10063 deny all from ::1 to any via ${wan}

# DENY specific IPs
# currently none

# number 00015 reserved for bans from fail2ban (-> TBD in the future)
# ${fwcmd} 00015 deny all from <ban_ip> to me in via ${wan}

# ALLOW inbound SSH connections to real sshd
${fwcmd} 11000 set 31 allow log tcp from any to me 2244 in via ${wan} setup limit src-addr 3
${fwcmd} 11001 set 31 allow log tcp from any to me6 2244 in via ${wan} setup limit src-addr 3
# ALLOW inbound SSH connections to tar pit sshd
${fwcmd} 11002 allow tcp from any to me 2222 in via ${wan} setup keep-state
${fwcmd} 11003 allow tcp from any to me6 2222 in via ${wan} setup keep-state

# ALLOW inbound connections to services on jails
# Apache routed via proxy_jail
${fwcmd} 12000 ${jumpNAT} tcp from any to ${proxy_jail} 80,443 in via ${wan} setup keep-state 
# Prosody in chat_jail 
${fwcmd} 12100 ${jumpNAT} tcp from any to ${chat_jail} 5222 in via ${wan} setup keep-state

# DENY and log all other incoming connections
${fwcmd} 19999 deny log all from any to any in via ${wan}



################################################
## FINAL rules (>=65000)
################################################

# DENY and LOG all uncaptured messages on ANY interface
${fwcmd} 65000 deny log all from any to any

# ALLOW skipto location for outbound statefule rules
${fwcmd} 65100 nat 1 ip from 192.168.0.0/24 to any out via ${wan}
${fwcmd} 65101 allow ip from any to any
 
${fwcmd} 10011 deny ipv6-icmp from any to any in via ${wan} not icmp6types 0
${fwcmd} 10062 deny all from any to ::1 in via ${wan} ${fwcmd} 10063 deny all from ::1 to any via ${wan} (and next rule may block IPv6)
IPv6 need icmpv6 to work. Ehh, there's "not" in the rule...

IPv6 with jails on cloned lo is interesting thing for me too, but with internal cloned bridges there is some practic like in this article.
 
Thank you,
the articel is using pf as firewall, right? If that is the only choice for my scenario, I would be willing to switch, but if possible I'd stick to IPFW.
I think I'll do some experiments with a new firewall from scratch up, starting with a simple IPFW rule set without any IPv4 NAT but only IPv6 rules with an open sshd.
If I got that to work I hopefully can make progress in combining my old and my new rule set.

For my better understanding: Does ipfw nat capture only IPv4 packages or does it also capture IPv6?
I see that not mentioned in the NETWORK ADDRESS TRANSLATION (NAT) section of ipfw().
Since there are extra commands like ipfw nat64lsn I would imply the first.
Would ipfw nat64lsn be maybe a solution for me? So that I keep my whole IPv4 NAT routing and IPFW rules as is and somehow (using that IPv6/IPv4 translation) translate all incoming IPv6 traffic infront into my IPv4?
 
Ok,
for getting some experience with IPv6 rules for IPFW I ignored all my Jail / NAT setup and only created rules for a very simple firewall that should only allow connections to my sshd via IPv4 and IPv6 and block all the rest.
This rules work for a ssh connection via IPv4, but it doesn't work for IPv6.
If I disable IPFW I can ssh into my server using IPv6, so I think I can exclude an issue with my IPv6 network configuration.

CeXP1917 mentioned that icmpv6 is required for IPv6 to work; does that mean I need to allow icmpv6 as well? I do not really understand why I need icmp for a ssh connection? I thought icmp is required for ping / traceroute etc.?

These are my current rules:

sh:
#!/bin/sh

# ipfw command definition
fwcmd="/sbin/ipfw -q add"

# flush out the list before we add any rules
/sbin/ipfw -q -f flush

# allow established connections
${fwcmd} 1 check-state

# allow loopback traffic
${fwcmd} 2 allow all from any to any via lo0

# allow previously established TCP connections
${fwcmd} 3 allow tcp from any to any established

# allow incoming ssh
${fwcmd} 100 allow tcp from any to me 22 in setup keep-state
${fwcmd} 101 allow tcp from any to me6 22 in setup keep-state

# allow all traffic going out
${fwcmd} 200 allow udp from me to any out keep-state
${fwcmd} 201 allow tcp from me to any out setup keep-state

# deny the rest
${fwcmd} 999 deny all from any to any

Thanks!
 
I've was poking at ipv6 a bit as well. Resources on ipfw and ipv6 are sadly lacking. I seem to recall that icmpv6 is required. I also seem to recall that me6 didn't match on the link local address. There are a couple of things like that caused me some confusion (eg ip matches ipv4 but not ipv6). It's been a bit though.
 
Not an expert at all in networking but I also noticed several times that ICMP is mandatory for IPV6 in order to work while for IPV4 it's just optional, quote from Wikipedia:
ICMPv6 is an integral part of IPv6 and performs error reporting and diagnostic functions.
ICMPv6 has a framework for extensions to implement new features. Several extensions have been published, defining new ICMPv6 message types as well as new options for existing ICMPv6 message types. For example, Neighbor Discovery Protocol (NDP) is a node discovery protocol based on ICMPv6 which replaces and enhances functions of ARP

If you want to know what icmp type you need for IPFW, check the file /etc/rc.firewall at the top of script there is a function called setup_ipv6_mandatory which will give you some details.
If I am not wrong IPFW works out of the box for IPV4 and IPV6 so you can copy the parts from the script that you need and use this as a starting point.
 
While responding to this question yesterday I discovered a syntax error with the profile called "workstation" in /etc/rc.firewall that actually implies ICMP. That's an easy fix it's only a missing "s" to imcptypes and icmp6types keywords line 462,464,468,470.

Code:
$ grep -n -E -w "icmp6type|icmptype" /etc/rc.firewall
462:    ${fwcmd} add pass icmp from any to any icmptype 8
464:            ${fwcmd} add pass ipv6-icmp from any to any icmp6type 128,129
468:    ${fwcmd} add pass icmp from any to any icmptype 3,4,11
470:            ${fwcmd} add pass ipv6-icmp from any to any icmp6type 3

This is the bug report:

To summarize it looks like the bare minimum icmp6types for IPV6 are: 1,2,135,136 (destination unreachable, packet too big, neighbor solicitation, neighbor advertisement).
The profile workstation adds those: 3,128,129 (time exceeded, echo request, echo reply)
 
Personally, I would tidy up a bunch of your configs, to make settings easier to find and reference.

First, put the IPs in /etc/hosts on the jail master:

Code:
192.168.0.1   jail_host
192.168.0.2   database_jail
192.168.0.3   proxy_jail
192.168.0.4   chat_jail
192.168.0.5   nextcloud_jail
192.168.0.6   svn_jail

Then edit in the IPv6 IPs for those same hosts so the whole thing looks like the following. I'll use the IPv6 example netblock 2001:DB8::/32 but you should sub in your actual IPv6 allocation ("aaaa.bbbb.cccc.dddd" in your example).

/etc/hosts:
Code:
192.168.0.1     jail_host
2001:DB8::1     jail_host

192.168.0.2     database_jail
2001:DB8::20    database_jail

192.168.0.3     proxy_jail
2001:DB8::30    proxy_jail

192.168.0.4     chat_jail
2001:DB8::40    chat_jail

192.168.0.5     nextcloud_jail
2001:DB8::50    nextcloud_jail

192.168.0.6     svn_jail
2001:DB8::60    svn_jail

You may want to include a subset of those in each jail's /etc/hosts also, depending on which jails need to contact other jails. When you get really fancy, instead of kludging up /etc/hosts, put them in a response policy zone (RPZ) in jail_host's DNS server.

Now, I suggest you clean out the jail-related ifconfig...alias lines in your /etc/rc.conf:

Code:
# Additional IPv6s from assigned subnet by ISP (for jails)
ifconfig_em0_alias0="inet6 aaaa:bbbb:cccc:dddd::2/64"
ifconfig_em0_alias1="inet6 aaaa:bbbb:cccc:dddd::3/64"
...

Do keep this one, which is for the physical host:

Code:
# First IPv6 from assigned subnet by ISP
ifconfig_em0_ipv6="inet6 aaaa:bbbb:cccc:dddd::1/64"

Next, I suggest you don't clone interface lo1 but instead keep all your jail IPs on interface em0:

Delete from /etc/rc.conf:
Code:
 # internal local interface for jail communication
cloned_interfaces="lo1"
ifconfig_lo1="inet 192.168.0.1 netmask 255.255.255.0 mtu 1500"

After you've deleted the jail-related IPv6 ifconfig...alias lines, set them up in /etc/jail.conf instead:

/etc/jail.conf:

Code:
# The general syntax of a jail definition is:
#
#       jailname {
#               parameter = "value";
#               parameter = "value";
#               ...
#       }

# Jail defaults:

path                    = "/jail/$name";        # use the jail's short name as the jail root directory:
interface               = "em0";             # interface to create IP aliases on
mount.devfs;                                    # mount a devfs inside the jail
#devfs_ruleset          = 1;                    # Do we want this?  I guess not.  But see /etc/defaults/devfs.rules
exec.clean;
exec.consolelog         = "/var/log/jail_$name.log";
exec.jail_user          = "root";
exec.start              = "/bin/sh /etc/rc";
exec.stop               = "/bin/sh /etc/rc.shutdown";
exec.system_user        = "root";
allow.raw_sockets       = false;                # by default, ping/traceroute not allowed
zfs.mount_snapshot      = 1;
allow.set_hostname      = 0;
allow.sysvipc           = 0;

database {
host.hostname           = 'database_jail';
path                    = '/jail/database';
mount.fstab             = '/etc/fstab.database';
ip_hostname;
allow.raw_sockets       = 1;
allow.sysvipc           = 1;
}
proxy {
host.hostname           = 'proxy_jail';
path                    = '/jail/proxy';
mount.fstab             = '/etc/fstab.proxy';
ip_hostname;
allow.raw_sockets       = 1;
}
chat {
host.hostname           = 'chat_jail';
path                    = '/jail/chat';
mount.fstab             = '/etc/fstab.chat';
ip_hostname;
allow.raw_sockets       = 1;
}
nextcloud {
host.hostname           = 'nextcloud_jail';
path                    = '/jail/nextcloud';
mount.fstab             = '/etc/fstab.nextcloud';
ip_hostname;
allow.raw_sockets       = 1;
}
svn {
host.hostname           = 'svn_jail';
path                    = '/jail/svn';
mount.fstab             = '/etc/fstab.svn';
ip_hostname;
allow.raw_sockets       = 1;
}

Make sure the
Code:
host.hostname
entries match the hostnames defined in /etc/hosts. If they match, then because each jail uses
Code:
ip_hostname
the jails will get their IPv4 and IPv6 settings automatically.

I may be skipping some stuff, but the idea is to get rid of the kludges in /etc/rc.conf, and define your hostnames and IPv4 and IPv6 values in /etc/hosts where they are useful to your DNS resolver and the jail subsystem to look up those names and bind each jail to the correct IPv4 and IPv6 IPs. Once the /etc/hosts name resolution works, leveraging it in /etc/jail.conf avoids unnecessary duplication and opportunity for errors. Omit the fstab entries in cases where you don't need them.

Once you get all the paths right and you are able to start your jails, you should see something like:

Code:
# service jail start
Starting jails: database proxy chat nextcloud svn.
# jls -v
   JID  Hostname                      Path
        Name                          State
        CPUSetID
        IP Address(es)
     1  database_jail                 /jail/database
        database                      ACTIVE
        3
        192.168.0.2
        2001:DB8::20
     2  proxy_jail                    /jail/proxy
        proxy                         ACTIVE
        5
        192.168.0.3
        2001:DB8::30
     3  chat_jail                     /jail/chat
        chat                          ACTIVE
        7
        192.168.0.4
        2001:DB8::40
     4  nextcloud_jail                /jail/nextcloud
        nextcloud                     ACTIVE
        9
        192.168.0.5
        2001:DB8::50
     5  svn_jail                      /jail/svn
        svn                           ACTIVE
        11
        192.168.0.6
        2001:DB8::60

If that much looks like it makes sense to you, get those changes in place and then you can move on to the firewalling. Feel free to reply back to this thread when you're ready.
 
Hi,

thanks for all your responses.
Just as an update:
If I add the mandatory IPv6 rules from /etc/rc.firewall to my simple firewall it works - I can successful ssh into my machine with both, IPv4 and IPv6. :)
But if I add these rules also to my larger firewall ruleset with NAT and my jails etc. it doesn't work. So I'm assuming it is somehow in conflict with NAT or I have it at a wrong place (order).
But seems like a should have a deeper look into /etc/rc.firewall because it might provide some very good examples / inspirations...



Jim L. : Ok, that sounds really interesting and I will give that a try.
In fact I already have the internal IPv4 for each jail in /etc/hosts, but haven't done that yet for IPv6.

I'm not a network expert, so sorry if I need to ask: If I add these IP addresses in my /etc/hosts, I do not need to create an alias in /etc/rc.conf for them? Does this basically the same or what else is the purpose of an
ifconfig_em0_alias?

And why are you suggesting to not use an cloned interface? I always was assuming that this is somehow a "more secure" solution because all my jails are using an internal and isolated interface to communicate amongst each other.
Is that only an illusion? I think I copied that over years ago from a tutoral or so...

What would you suggest as IPFW rules regarindg IPv4, IPv6 and NAT after I've done your proposed changes?
If possible I would have both in parallel: The jails reachable by their own unique IPv6 from the IPv6 subnet, that I got assigned from my ISP; but I'd also like to have each jail be reachable via IPv4. At least I assume that should be still a useful thing nowadays to support IPv4 in case of a client / user does not support IPv6. Or is that only like 0.1% meanwhile?
Since I only have one IPv4 assigned by my ISP, I think there is no other way that supporting NAT + pound for the jails to route IPv4 from and to my external IPv4 to the 192.168.0.x IP addresses of my jails.

Thanks & kind regards,
Fool

PS: I'm using iocage for my jails but that shouldn't make a difference.
 
If your /etc/jail.conf has the ip_hostname verb in each jail definition, then the service jail start ... routine will automatically set up the IPs on jail startup and turn them off on jail shutdown. That is why you would no longer need the alias lines in /etc/rc.conf.

The reason I suggested not cloning a loopback interface for the IPv4 jail addresses is because the IPv6 jail addresses are on a different interface, so A) the jails are already publicly exposed via IPv6 on em0; and B) it will likely make management easier to have all the jail IPs (IPv4 and v6) on the same interface. You can still protect the jail IPs using the firewall rules you are developing.

You're probably right about the single IPv4 from your ISP, but one of the servers I have uses a similar set up, and I set up each jail with direct access via IPv6, and then do NAT/port redirection on IPv4:

Code:
# jls -v
   JID  Hostname                      Path
        Name                          State
        CPUSetID
        IP Address(es)
    10  ns1                           /jail/ns1
        ns1                           ACTIVE
        3
        10.0.0.2
        [noparse]2001:DB8[/noparse]:3000:fe0::20
    11  psql                          /jail/psql
        psql                          ACTIVE
        5
        10.0.0.10
        [noparse]2001:DB8[/noparse]:3000:fe0::100
    13  mail.example.com              /jail/mail
        mail                          ACTIVE
        9
        10.0.0.30
        [noparse]2001:DB8[/noparse]:3000:fe0::300
    15  www                           /jail/www
        www                           ACTIVE
        8
        10.0.0.20
        [noparse]2001:DB8[/noparse]:3000:fe0::200

# ipfw nat show config
ipfw nat 1 config ip (my IPv4 IP) \
    redirect_port tcp 10.0.0.20:443 443 \
    redirect_port tcp 10.0.0.20:80 80 \
    redirect_port tcp 10.0.0.10:5432 5432 \
    redirect_port udp 10.0.0.2:53 53 \
    redirect_port tcp 10.0.0.2:53 53

So for IPv6, traffic can be addressed directly to and from each jail, subject to the firewall's rules.

For incoming IPv4:
* https/443 and http/80 traffic goes to jail "www" on 10.0.0.20
* SQL traffic on tcp port 5432 goes to jail "psql" on 10.0.0.10
* DNS traffic on udp 53 or tcp 53 goes to jail "ns1" on 10.0.0.2

I haven't implemented it yet, but at some point, incoming SMTP on port 25 or 587 (and possibly IMAPS, etc. also) would go to jail "mail" on 10.0.0.30.

Outgoing IPv4 traffic from any of the jails is NAT'ed normally.
 
Back
Top