Tangling with Untangle

Posted: October 18th, 2010 | Author: | Filed under: computing | Tags: , | 8 Comments »

This is a work in progress as I build up an Untangle box for personal use. Using the Lite (open source) version 7.4 (EDIT 11.15.2010 -- now running 8.0.0) on a Xeon server with 4 physical interfaces.

DO NOT follow any of this verbatim. This is a jumble of notes for my personal use that I hope may help a few other folks trying for a similar setup.

Install from USB disk: http://wiki.untangle.com/index.php/Installing_Untangle_from_a_USB_Flash_Disk
Use manual partitioning to setup full disk encryption (sda2_crypt) with LVM for separate / and /home. ext2 /boot, xfs for root & home

Enable & lockdown ssh:
* edit /etc/ssh/sshd.conf with my preferred config
* mv /etc/ssh/sshd_not_to_be_run /etc/ssh/sshd_not_to_be_run.bak
* restart ssh

Use the terminal from the gui to create root password and a non-root user
Lockdown ssh from root login and setup key login for non-root user (disable direct root login and restrict to specific user account using AllowUsers, also enable MaxStartups 10:30:60).

Add USB key for LUKS

Install GRUB password and backup menu.lst against future Untangle updates
Add grub boot option for verbose, non-splash boot and make default selection
# altoptions=(text boot) vga=791
Add /boot/grub/menu.lst as a file override in the gui.

/etc/default/bootlogd change BOOTLOGD_ENABLE=Yes

Edit /etc/apt/sources.list to uncomment debian main. (re-comment and apt-get update when done installing)

Install xfsprogs
Install/configure smartmontools
Install mlocate
Install memtest86+
Install/configure lm-sensors & i2c-tools

Secure the Untangle kiosk (X does not belong on servers but Untangle depends on it.. oh well.)
Instructions for locking down physical access to the Untangle kiosk:

First, follow jdelagarza’s excellent post on setting up xscreensaver and test that it’s working:

Unfortunately this can still be easily defeated using ctrl+alt key combos to restart X.
1) build a good xorg.conf (see example below) so Xserver uses /etc/X11/xorg.conf instead of falling back to /etc/X11/xorg-untangle-vesa.conf (which is useless to modify directly as it automatically overwritten by /home/kiosk/.bashrc)

2) add a ServerFlags section with the following options:
“DontZap” to disable ctrl+alt+bksp and ctrl+alt+del
“DontVTSwitch” to disable ctrl+alt+F[1-12] (especially want to disable F10 which also kills X)
“DontZoom” to disable using ctrl+alt+[+/-] to crash X

3) reboot/restart X
My current /etc/X11/xorg.conf

# xorg.conf (X.Org X Window System server configuration file)
# If you have edited this file but would like it to be automatically updated
# again, run the following command:
# sudo dpkg-reconfigure -phigh xserver-xorg

Section "ServerFlags"
Option "DontZap" "true"
Option "DontVTSwitch" "true"
Option "DontZoom" "true"

Section "InputDevice"
Identifier "Generic Keyboard"
Driver "kbd"
Option "XkbRules" "xorg"
Option "XkbModel" "pc104"
Option "XkbLayout" "us"

Section "InputDevice"
Identifier "Configured Mouse"
Driver "mouse"

Section "Device"
Identifier "Configured Video Device"
Driver "vesa"

Section "Monitor"
Identifier "Configured Monitor"
VertRefresh 60

Section "Screen"
Identifier "Default Screen"
Monitor "Configured Monitor"
Device "Configured Video Device"
DefaultDepth 24
SubSection "Display"
Depth 24
Virtual 1024 768
Modes "1024x768"

You can verify which xorg.conf file the Xserver is using with this command:
# cat /var/log/Xorg.0.log | grep “Using config file”

See this forum post for comments: http://forums.untangle.com/hacks/19035-secure-kiosk-locking-down-xscreensaver.html

Reconfiguring packet filter to allow DHCP on other interfaces

Hmmm.. trying to research how to serve DHCP on interfaces other than the Internal and DMZ but still be able to use packet filter to block unwanted interfaces. The following post explains how we can config dnsmasq to serve on multiple interfaces but the only suggestion for configuring the packet filter is to turn off DHCP filtering for all interfaces, which leaves the External interface exposed:

I didn’t like this, and after a bit of searching it appears I’m not alone:

So.. as a long time linux user it seemed only proper to crack open my Untagle box and do a bit of digging.

It appears that the following ruby script is responsible for doing most the work of translating the packet filter gui into actual iptables rules:


When you apply changes in the gui the script then rebuilds the iptables rules in this file:


By studying this file you can see that when you apply the built-in “Allow DHCP Requests from the internal interface.” rule it creates the following iptables rule:

iptables -t filter -I INPUT 1 -p udp -m mark --mark 2/2 -m multiport --destination-ports 67 -j RETURN

The “Allow DMZ..” rule does the same except that the “--mark 2/2” portion changes for each interface.

I then tried making an “Allow DHCP” rule of my own for my eth3 using the gui which creates this actual iptable rule:

iptables -t mangle -A firewall-rules -p udp -m multiport --destination-ports 67 -m mark --mark 8/8 -j RETURN

Now we’re onto something… I then checked the “Block all DHCP Requests to the local DHCP Server.” rule and found it creates:

iptables -t filter -A INPUT -p udp -m multiport --destination-port 67 -j DROP

Bingo! The difference is that all the user rules are created by appending rules to the end of “firewall-rules” rule set of the “mangle” table whereas the built-in set of Allow rules are inserting rules into the top of the input chain (INPUT 1) in the default “filter” table. In short this means that when creating custom user rules they’re getting added after the the built-in “Block all DHCP..” rule so the DHCP packets are being dropped before they ever get to the user created Allow rules (vs the built-in Allow rules that get inserted before the built-in “Block all DHCP..” rule).

I was able to test this by manually adding an iptable rule for my eth3 interface that uses the insert vs the append method and it was successful in allowing DHCP (but this would get overwritten by untangle in the next rule refresh):

iptables -t filter -I INPUT 1 -p udp -m mark --mark 8/8 -m multiport --destination-ports 67 -j RETURN

So.. now understanding the issue. The simplest solution I found was to just abandon the built-in rules and do it all through a couple user rules.

1) Uncheck: “Block all DHCP Requests to the local DHCP Server.”, “Allow DHCP Requests from the DMZ interface.”, “Allow DHCP Requests from the internal interface.”

2) Create a user rule to accept on any of the interfaces you do want DCHP:
Action: Pass, Protocol: UDP, Destination Port: 67, Source Interface: Internal, eth3

3) Create a rule to Drop on all the interfaces:
Action: Drop, Protocol: UDP, Destination Port: 67, Source Interface: all (even the ones you checked in the previous Pass rule)

Make sure the Pass rule is ordered above the Drop rule. Assuming your DHCP is configured correctly you should now have DHCP access on any interfaces you have checked within the Pass rule.

Mapping the Untangle Packet Filter rules.

The interfaces on this box are identified by Untangle as follows ( the “--mark #/#” is basically another identifier for the different interfaces within iptables):
eth0 = External (--mark 1/1)
eth1 = Internal (--mark 2/2 and --mark 258/258)
eth2 = DMZ (--mark 4/4)
eth3 = eth3 (--mark 8/8)
VPN (--mark 128/128)
All Interfaces (--mark 256/256)

First line = the built-in rule description listed in the Untangle gui.
Second/third lines = actual rule(s) created in /etc/untangle-net-alpaca/iptables-rules.d/400-firewall by checking the gui description.


Allow DHCP Requests from the internal interface.
${IPTABLES} -t filter -I INPUT 1 -p udp -m mark --mark 2/2 -m multiport --destination-ports 67 -j RETURN

Allow DHCP Requests from the DMZ interface.
${IPTABLES} -t filter -I INPUT 1 -p udp -m mark --mark 4/4 -m multiport --destination-ports 67 -j RETURN

Block all DHCP Requests to the local DHCP Server.
${IPTABLES} -t filter -A INPUT -p udp -m multiport --destination-port 67 -j DROP

Prefer Local DHCP Traffic from non-internal interfaces.
${IPTABLES} -t mangle -A FORWARD -p udp -m multiport --destination-ports 67,68 -m physdev --physdev-is-bridged --physdev-out eth1 -j DROP
${IPTABLES} -t mangle -A FORWARD -p udp -m multiport --destination-ports 67,68 -m physdev --physdev-is-bridged --physdev-in eth1 -j DROP

Accept DHCP traffic to the local DHCP client.
${IPTABLES} -t filter -I INPUT 1 -p udp -m multiport --destination-ports 68 -j RETURN

Accept DNS traffic from the Internal and VPN interfaces to the local DNS Server.
${IPTABLES} -t mangle -A firewall-rules -p udp -m multiport --destination-ports 53 -m mark --mark 258/258 -j RETURN
${IPTABLES} -t mangle -A firewall-rules -p udp -m multiport --destination-ports 53 -m mark --mark 384/384 -j RETURN

Accept DNS traffic to the local DNS Server from all interfaces.
${IPTABLES} -t mangle -A firewall-rules -p udp -m multiport --destination-ports 53 -m mark --mark 256/256 -j RETURN

Accept SNMP traffic from the Internal interface.
${IPTABLES} -t mangle -A firewall-rules -p udp -m multiport --destination-ports 161 -m mark --mark 258/258 -j RETURN

Accept SNMP traffic from all interfaces.
${IPTABLES} -t mangle -A firewall-rules -p udp -m multiport --destination-ports 161 -m mark --mark 256/256 -j RETURN

Block OpenVPN traffic from the internal interface.
${IPTABLES} -t mangle -A firewall-rules -p udp -m multiport --destination-ports 1194 -m mark --mark 258/258 -j alpaca-pfi-drop

Accept OpenVPN traffic from all interfaces.
${IPTABLES} -t mangle -A firewall-rules -p udp -m multiport --destination-ports 1194 -m mark --mark 256/256 -j RETURN

Accept SSH traffic from all interfaces.
${IPTABLES} -t mangle -A firewall-rules -p tcp -m multiport --destination-ports 22 -m mark --mark 256/256 -j RETURN

Allow Ping on all interfaces.
${IPTABLES} -t mangle -A firewall-rules -p icmp -m mark --mark 256/256 -j RETURN

Block all local traffic.
(added to 700-nat-firewall)
${IPTABLES} -t mangle -A firewall-rules -j alpaca-pfi-drop

Accept incoming VPN traffic when running as a VPN client.

Route VPN traffic that would go through the Bridge.

Samba + SWAT + GOsa setup:
# apt-get install samba=2:3.2.5-4lenny11 samba-common=2:3.2.5-4lenny11
# apt-get install swat smbfs samba-docs
Create separate Packet Filter rules to allow 135,139,445 TCP and 137,138 UDP from select interfaces
Setup via SWAT (localhost 901)

uncomment apt deb sources and add deb unstable
# apt-get install gosa (to install dependent packages)
# apt-get install -t unstable (to install newest gosa with fcgi bug fix)
# apt-get install gosa-schema gosa-plugin-ldapmanager gosa-plugin-samba smbldap-tools libnss-ldap libpam-ldap
# apt-get remove lighttpd (conflicts with apache2)

Use /usr/share/doc/gosa/slapd.conf-example/slapd.conf.gz for /etc/ldap/slapd.conf and customize

pulling gosa off and using webmin instead.
# add webmin repo
deb http://download.webmin.com/download/repository sarge contrib

Other good references:

Untangle -- useful files:

* Configure untangle modules
* Add LUKS disk encryption for second SATA drive and for external eSATA backup drives
* Setup filesharing via Samba
* OpenVPN
* Bootp
* Enable sadc in /etc/default/sysstat ?

*** This post is still under construction ***