In computing, a firewall is a software or hardware-based network security system that controls the incoming and outgoing network traffic by analyzing the data packets and determining whether they should be allowed through or not, based on applied rule set. A firewall establishes a barrier between a trusted, secure internal network and another network (e.g., the Internet) that is not assumed to be secure and trusted. Source: http://en.wikipedia.org/wiki/Firewall_(computing)
In this chapter we are going to install a personal software firewall. The description from Wikipedia explains pretty well, what it is for. We are going to use the firewall to block traffic to(/from) our machine and only going to allow communication through ports we open.
Keep in mind that Linux DROPs all packages by default that do not target an open port/running service. A host-based firewall is therefor often not required when used in its simplest form. As this guide will cover in NIDS chapter however, one can use the log messages produces by firewalls to take further actions, such as blocking an attacker before he finds targetable wholes in your system. Make sure to define your assumptions and goals first, before blindly installing/following this guide, to see, if a host based firewall is really the right choice for you.
A lot of firewall software exists. They mostly rely on IPTables/Netfilter, which are standard Linux kernel modules. For this guide, we take the stateful Shorewall
suite.
Before we start installing the firewall within our container, we need to prepare the hardware node for it. As said, Shorewall
depends on various IPTables
/Netfilter
kernel modules, so one must load and enable them. You can use the script below (execute it on the hardware node).
Note that this only works, when you have access to the node - if you are renting a VPS from a provider, you will have to contact the support and ask them to enable the modules from below for you.
#!/bin/sh
# Script to load Shorewall required IPTable/Netfilter modules
# source functions
. /etc/init.d/functions
MODULES="xt_set, xt_AUDIT, xt_CHECKSUM, xt_CLASSIFY, xt_CONNMARK, xt_CONNSECMARK, xt_DSCP, xt_HL, xt_LED, xt_MARK, xt_NFLOG, xt_NFQUEUE, xt_NOTRACK, xt_RATEEST, xt_SECMARK, xt_TPROXY, xt_TCPMSS, xt_TCPOPTSTRIP, xt_TRACE, xt_cluster, xt_comment, xt_connbytes, xt_connlimit, xt_connmark, xt_conntrack, xt_dccp, xt_dscp, xt_esp, xt_hashlimit, xt_helper, xt_hl, xt_iprange, xt_length, xt_limit, xt_mac, xt_mark, xt_multiport, xt_osf, xt_owner, xt_physdev, xt_pkttype, xt_policy, xt_quota, xt_rateest, xt_realm, xt_recent, xt_sctp, xt_socket, xt_state, xt_statistic, xt_string, xt_tcpmss, xt_time, xt_u32, xt_wdog_tmo, ipt_addrtype, ipt_ah, ipt_ecn, ipt_CLUSTERIP, ipt_ECN, ipt_LOG, ipt_MASQUERADE, ipt_NETMAP, ipt_REDIRECT, ipt_REJECT, ipt_ULOG, ip6table_filter, ip6table_mangle, ip6table_raw, ip6t_ah, ip6t_eui64, ip6t_frag, ip6t_ipv6header, ip6t_mh, ip6t_hbh, ip6t_rt, ip6t_LOG, ip6t_REJECT, iptable_filter, iptable_mangle, iptable_nat, iptable_raw, nf_conntrack, nf_conntrack_proto_dccp, nf_conntrack_proto_gre, nf_conntrack_proto_sctp, nf_conntrack_proto_udplite, nf_conntrack_netlink, nf_conntrack_amanda, nf_conntrack_ftp, nf_conntrack_h323, nf_conntrack_irc, nf_conntrack_broadcast, nf_conntrack_netbios_ns, nf_conntrack_snmp, nf_conntrack_pptp, nf_conntrack_sane, nf_conntrack_sip, nf_conntrack_tftp, nf_tproxy_core, nf_conntrack_ipv4, nf_nat, nf_defrag_ipv4, nf_nat_amanda, nf_nat_ftp, nf_nat_h323, nf_nat_irc, nf_nat_pptp, nf_nat_sip, nf_nat_snmp_basic, nf_nat_tftp, nf_nat_proto_dccp, nf_nat_proto_gre, nf_nat_proto_udplite, nf_nat_proto_sctp, nf_conntrack_ipv6, nf_defrag_ipv6, ip_set, ip_set_bitmap_ip, ip_set_bitmap_ipmac, ip_set_bitmap_port, ip_set_hash_ip, ip_set_hash_ipport, ip_set_hash_ipportip, ip_set_hash_ipportnet, ip_set_hash_net, ip_set_hash_netport, ip_set_list_set, ip_vs, ip_vs_rr, ip_vs_wrr, ip_vs_lc, ip_vs_wlc, ip_vs_lblc, ip_vs_lblcr, ip_vs_dh, ip_vs_sh, ip_vs_sed, ip_vs_nq, ip_vs_ftp, ip_vs_pe_sip, ip_tables, ip_queue"
OLD=`lsmod | wc -l`
for module in ${MODULES//, / }; do
modprobe $module
done
NEW=`lsmod | wc -l`
echo_success
echo "Loaded `expr $NEW - $OLD` new kernel modules [ $OLD/$NEW ]"
That will load all required modules. Finally, make sure the OpenVZ container configuration contains:
NETFILTER="stateful"
which will enable the modules inside the container.
A container restart may be required to apply the new settings.
Future-aware people like us tend to support IPv6 (don't we? ;)). For that, we install the IPTables
support package:
yum install ipset iptables-ipv6
More information about
ipset
: http://ipset.netfilter.org/
After a first try of installing and using the CentOS provided shorewall
packages, you would notice that one is not able to run shorewall
and shorewall6
side-by-side. The reason for that is the version of Shorewall included within the default CentOS repository - it contains a known-bug that has been fixed in later version. Lucky us, precompiled RPM
s can be downloaded from here: http://www.invoca.ch/pub/packages/shorewall/RPMS/ils-6/noarch/
To install, follow the steps below:
cd /usr/local/src
wget http://www.invoca.ch/pub/packages/shorewall/RPMS/ils-6/noarch/shorewall-core-4.5.21.9-1.el6.noarch.rpm
wget http://www.invoca.ch/pub/packages/shorewall/RPMS/ils-6/noarch/shorewall-4.5.21.9-1.el6.noarch.rpm
wget http://www.invoca.ch/pub/packages/shorewall/RPMS/ils-6/noarch/shorewall6-4.5.21.9-1.el6.noarch.rpm
The shorewall(6)
packages have some dependencies:
yum install bc perl-Digest-SHA
After fixing these, we can continue with installing the RPMs:
rpm -ivh shorewall-core-4.5.21.9-1.el6.noarch.rpm
rpm -ivh shorewall-4.5.21.9-1.el6.noarch.rpm
rpm -ivh shorewall6-4.5.21.9-1.el6.noarch.rpm
As mentioned earlier, getting Shorewall to work inside OpenVZ containers can be a pain. To verify that you will be able to run Shorewall, issue the following two commands:
shorewall show capabilities
shorewall6 show capabilities
If one of them throws an error, something is broken. Do not continue in that case!
Shorewall is very powerful and as such has a lot of options and parameters one can adjust. For that reason, the developers are friendly enough to include sample configurations as part of their releases.
Navigate to /usr/share/doc/shorewall-4.5.21.9/Samples
and check the available samples. Copy the one that reflects your setup. Within an OpenVZ container this will be one-interface
most of the time:
cp one-interface/* /etc/shorewall/
Do the same for IPv6 version, but this time from
/usr/share/doc/shorewall-4.5.21.9/Samples
.
Another singularity of OpenVZ is the venet0
interface. It's like eth0
on physical machines. Since Shorewall is pre-configured for common setups, we need to adjust the interface name in the configuration files:
nano /etc/shorewall/interfaces
nano /etc/shorewall6/interfaces
and change eth0
to venet0
in both files.
If we would enable Shorewall right now, all incoming connections would get blocked and we would have no chance to connect to our machine anymore. Shorewall ships with so called Macros
- "include" the one for SSH, which will allow incoming SSH connections:
nano /etc/shorewall/rules
nano /etc/shorewall6/rules
and add:
SSH(ACCEPT) net $FW
at the end of both files to allow SSH connections.
Finally nano /etc/shorewall/shorewall.conf
(and the IPv6 version)
and set:
STARTUP_ENABLED=Yes
Now, start them:
chkconfig shorewall on
chkconfig shorewall6 on
service shorewall start
service shorewall6 start