FreeBSD: PF and NAT for internal network


Recently I’ve needed to install another Linux OS in a virtualbox machine (FreeBSD as host) with a Host-Only Adapter network configuration. This permits to have connectivity between the host and the guest as two single machines in a network. As an example, one of the machines can act as a server (apache, mysql, etc.) and the other one as a client. This article explains my configuration.

VBox Host: FreeBSD

Outside Network: 192.168.0.0 / 24 (wlan0 or em0 ->wifi router->internet)

IP: 192.168.0.19

GW: 192.168.0.1 (wifi router)

Internal Network (virtualbox Network): 192.168.56.0/24

IP: 192.168.56.1 (this is assigned by VirtualBox: File->Preferences->Network->Host-only Networks and add a new one, named as vboxnet0)

Vbox loaded kernel modules in /boot/loader.conf :

vboxdrv_load=”YES”

 

And in /etc/rc.conf:

vboxnet_enable=”YES”

Guest: Linux

From virtual machine settings I added to interfaces, one with NAT and cable disconnected (to avoid use it) and the other one as Host-Only Adapter connected to the previously created network vboxnet.

IP: 192.168.56.101 (VirtualBox acts as DHCP server and automatically assigns this address)

GW: 192.168.56.1 (static route)

In this situation there is only connectivity between machines host and guests through shared network 192.168.56.0/24.

Target: connectivity from guest machine to outer space and beyond.

My FreeBSD runs PF Firewall. Complete configuration can be grabbed at the end, but relevant settings are:

To permit routing in /etc/sysctl.conf :

net.inet.ip.forwarding=1
net.inet.ip6.forwarding=1

To permit traffic through firewall, in /etc/pf.conf :

#external interfaces:

ext_if  = “wlan0”
ext_if2 = “em0”

#My Networks:

internal_network = “{192.168.0.0/24}”
vbox_network = “{192.168.56.0/24}”

#NAT on external interfaces for traffic from virtualbox network

nat on $ext_if from $vbox_network to any -> ($ext_if)
nat on $ext_if2 from $vbox_network to any -> ($ext_if2)

# permit ping from virtualbox network
pass in quick proto icmp from $vbox_network to any keep state

#traffic from virtualbox networkvbox=>out
pass inet proto { tcp, udp } from $vbox_network to any flags S/SA keep state

Finally my complete /etc/pf.conf:

————————

tcp_services = “{ ssh  137 138 139 445  51413               4662:4672  54662:54672   21  3900:3920  }”
udp_services = “{ ssh  137 138 139 445  51413   7881 51414  4662:4672  54662:54672   21  3900:3920  }”
icmp_types = “{ echoreq, unreach }”

#NAT purposes
#(for VirtualBox y Host-Only)
ext_if  = “wlan0”
ext_if2 = “em0”

#Allowed services in internal network
#                          rsync_daemon
tcp_services_internal = “{ 873           }”
udp_services_internal = “{ 873           }”


internal_network = “{192.168.0.0/24}”
vbox_network = “{192.168.56.0/24}”

# Don’t send rejections. Just drop.
set block-policy drop

# Exempt the loopback interface to prevent services utilizing the
# local loop from being blocked accidentally.
set skip on lo

# all incoming traffic on external interface is normalized and fragmented
# packets are reassembled.
scrub in on $ext_if all fragment reassemble
scrub in on $ext_if2 all fragment reassemble

########################################
#NAT
#NAT for VirtualBox Network Host-Only
#Nat before filtering
#Rules must be in order: options, normalization, queueing, translation, filtering
nat on $ext_if from $vbox_network to any -> ($ext_if)
nat on $ext_if2 from $vbox_network to any -> ($ext_if2)
########################################

pass            # to establish keep-state

# By default, do not permit remote connections to X11
block in on ! lo0 proto tcp to port 6000:6010

#Block all
block all

# permit ping
pass in quick proto icmp from $internal_network to $internal_network keep state

# permit ping from virtualbox network
pass in quick proto icmp from $vbox_network to any keep state

#To/From anywhere
pass in proto tcp from any to any port $tcp_services
pass in proto udp from any to any port $udp_services

#To/From internal network
#pass in quick tcp from $internal_network to $internal_network port $tcp_services_internal
#pass in quick udp from $internal_network to $internal_network port $udp_services_internal

#All all from and to internal network due to random ports in mountd for NFS
pass in quick proto {tcp, udp} from $internal_network to $internal_network

#traffic from virtualbox networkvbox=>out
#remember “sysctl net.inet.ip.forwarding=1”
pass inet proto { tcp, udp } from $vbox_network to any flags S/SA keep state

#for upnp
pass in quick proto igmp from $internal_network to $internal_network
pass in quick proto igmp from $vbox_network to $vbox_network

#Web Server
pass in proto tcp from any to any port 8000:8002 flags S/SA keep state

##################
#FreeBSD fail2ban
table <fail2ban> persist
block quick proto tcp from <fail2ban> to any port ssh

#to list current banned IPs:
#pfctl -t fail2ban -T show
##################

pass from lo0 to lo0 keep state

pass out all keep state
————————

Hope you find it interesting.

About jjjesss

I'm a guy interested in technology, bsd fan and concerned about the world around.
This entry was posted in BSD, FreeBSD. Bookmark the permalink.

One Response to FreeBSD: PF and NAT for internal network

  1. Pingback: FreeBSD: virtualized acestream | nix/bsd

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s