One extremely common use for Linux systems is the defense of critical computer networks and data. The power of the TCP/IP protocol is its openness and ubiquity. Unfortunately, these advantages can become great drawbacks when a computer network is attacked by a hostile intruder. When a computer is configured in such a way that its primary function is the defense of a TCP/IP network, it is commonly called an Internet “firewall,” or sometimes a “bastion host.”

There are two main firewall designs commonly in use on Linux. One is the proxy approach, where access to external resources can only be obtained by contacting a specific host which acts as an intermediary (or proxy). The other method involves the use of the Linux kernel as a router, where the kernel will simply forward, modify, or discard network data based upon a set of rules defined by the administrator.

It is far easier to maintain internal hosts where Linux is used as a filtering router. The use of a proxy can complicate the configuration of the internal hosts enormously. The techniques can be mingled to some extent, but proxies will always introduce additional layers of complexity.

This chapter assumes that one or more networking interfaces are properly configured and that routes to these interfaces are defined. A proxy firewall might be designed that used only a single network interface in conjunction with blocking routers, but a firewall relying upon IP Forwarding or Masquerading will require at least two network interfaces. Information on network configuration can be found elsewhere in this text.

While safe and efficient Linux firewalls can be configured on a modest computer (an 80386-based system could conceivably be used), high-utilization environments might benefit from more powerful hardware. In such a case, ISA-based network cards should be eschewed, as well as any cards based upon an NE2000 chipset. Currently, two very popular PCI ethernet designs are the Tulip chipset (i.e., the 21040 and 21140 ethernet chipsets designed by Digital Equipment Corporation), and the 3Com 905 series. Some cards based upon the 21140 Tulip design are very inexpensive and they also implement 100BaseT fast ethernet.

DHCP can also play an extremely productive role in a protected network. DHCP should be omitted from a firewall design only for sound reasons, as the benefits it extends in centralized administration can dramatically reduce the complexity of a network. See the DHCP section of this text for more information.

There are several UNIX security issues that also have great bearing upon proper firewall design. In particular is the inetd Internet “super server” daemon. The /etc/inetd.conf file should be examined carefully, and services that are not required should be removed. In particular, the shell and login services should be eliminated unless their presence is absolutely necessary. Serious consideration should also be given to the removal of telnet and ftp services, especially if ssh will be used. All other services should be studied and, if possible, removed.

Fictitious IP Addresses

It is occasionally necessary to “make up” IP addresses for positions on internal networks (especially as real Internet IP addresses become more difficult to obtain). Should this practice be necessary, the “synthetic” addresses should be selected from the following list:

Class Network
A 10.0.0.0
B 172.16.0.0 through 172.31.0.0
C 192.168.0.0 through 192.168.255.0

These addresses are reserved for private use. They will not be routed over the Internet.

Kernel IP Forward and Masquerade Rules

Before a routing firewall can be configured on a Linux system, the kernel must be instructed to forward packets across the network interfaces. One way to accomplish this is with the netcfg command, run under X windows. The option to enable forwarding is shown in Figure 4-1:

This option does not take effect until the system is rebooted. While it may seem complex, it is actually only modifying a line in the /etc/sysconfig/network file. After the option is set, there will be an entry of the form:

FORWARD_IPV4=true

If an entry of “false” is present, it can be manually modified to “true” without the inconvenience of starting X-Windows.

However, the /etc/sysconfig/network file merely runs the following command at boot time, which enables forwarding across the network interfaces in the kernel:

echo 1 > /proc/sys/net/ipv4/ip_forward

This command can be run at any time to enable packet forwarding. Conversely, if a “0” is echoed onto the file, packet forwarding will be disabled.

A similar option to enable packet forwarding is available in the linuxconf utility.

Setting this configuration will transform Linux into a simple router. However, the normal (and safest) way to configure a firewall is to deny all packet forwarding by default, then allow only explicit types of routes to pass. The ipchains administration utility is used to make such changes. To change the default routing behavior to deny routing, enter the command:

ipchains -P forward DENY

Older Linux kernels used a different utility called “ipfwadm” to administer the kernel firewall resources. This utility was replaced with ipchains in the Linux 2.2 kernel because of several design deficiencies. Red Hat Linux 6.0 comes with a wrapper script called “ipfwadm-wrapper” which allows the older syntax to be used:

ipfwadm-wrapper -F -p deny

Use the ipfwadm-wrapper script if the firewall controls must remain compatible with a system running an older version of the Linux kernel (such as Red Hat Linux 5.2 or below). However, ipchains and ipfwadm-wrapper cannot be mixed; use one or the other.

The following command can be used to flush all routing rules that might remain in the kernel, ensuring that all network traffic returns to default behavior:

ipchains -F

The syntax to flush routing rules for ipfwadm is slightly different (the forwarding, input, output and accounting rules must be flushed separately):

ipfwadm-wrapper -F -f
ipfwadm-wrapper -I -f
ipfwadm-wrapper -O -f
ipfwadm-wrapper -A -f

At this point, individual accepted routes can be added to the kernel. For example, the following command allows all hosts to access a web server on the host 1.2.3.4:

ipchains -A forward -s 0.0.0.0/0 -p TCP -d 1.2.3.4/32 http -j ACCEPT -b

Some discussion of the options to the above command is in order:

-A forward
Specify that a rule should be added to the “forward” chain. There are three predefined chains: “input,” “output,” and “forward.” Additional chains can be created, but the procedure is not documented in this text.
-s 0.0.0.0/0
The -s option denotes a packet source. The network address of 0.0.0.0/0 is a special nomenclature indicating that the packet can have an origin of any IP address. If the -s option is omitted, 0.0.0.0/0 will be assumed.
-p TCP
Packets with a TCP protocol, and only those packets, will be passed. UDP or ICMP will be rejected.
-d 1.2.3.4/32 http
The -d option indicates a destination. The 1.2.3.4/32 is a fully-qualified Internet address. A complete network can be specified for either source or destination by indicating the number of bits in the netmask. For example, a 1.2.3.0/24 would allow web traffic over the entire 1.2.3 Class C network.
-j ACCEPT
The argument to the -j parameter is the desired target action for packets matching the previous parameters. In this case, the packet is accepted for forwarding. The allowable targets are: ACCEPT, DENY, MASQ, REDIRECT, REJECT, and RETURN. DENY and REJECT are similar, but REJECT generates an ICMP destination unreachable message, while DENY discards the packet with no further action. MASQ allows one computer to masquerade as another. REDIRECT allows packets destined for a remote machine to be received locally (which can be useful for transparent proxies). RETURN indicates that the default chain policy should be used for this rule.
-b
The -b parameter indicates that the rule is bidirectional. This will allow packets to pass to and from either host. This behavior can also be achieved by adding the rule twice, reversing the source and destination for the second rule. The -b option in truth really inserts two rules. If an “ipchains -L” is issued to list the contents of the chains, rules for both forward and reverse will be observed.

The ipfwadm syntax is slightly different:

ipfwadm -F -a accept -P tcp -S 0.0.0.0/0 -D 1.2.3.4/32 http -b -o
-F
This argument indicates that the command will affect the Forwarding rules (as opposed to Input, Output, or Accounting rules).
-S 0.0.0.0/0
The -S option denotes a packet source. The network address of 0.0.0.0/0 is a special nomenclature indicating that the packet can have any origin.
-D 1.2.3.4/32
The -D option indicates a destination. The 1.2.3.4/32 is a fully-qualified Internet address. A complete network can be specified for either source or destination by indicating the number of bits in the netmask. For example, a 1.2.3.0/24 would allow web traffic over the entire 1.2.3 Class C network.
http
This is the name of a protocol from /etc/services. A numerical port number may also be used.
-b
This argument indicates that the traffic is bi-directional, and the reverse of the rule is also allowed.
-o
Logging of matching packets to /var/log/messages is activated by this option.

A list of rules similar to the ones above can be entered into the Linux kernel. This list is parsed from the top down. If two contradictory commands are entered, or if a packet matches several rules, the rule entered first will determine the packet's fate.

Using commands of this form, holes can be “punched” through the bastion host, opening paths for desired services, but blocking potentially threatening traffic.

If the network on either side of this firewall is connected to the Internet, hosts on both sides must have valid Internet IP addresses. There is a method, however, to use synthetic network addresses on one side of the network. This has the valuable side-effect of conserving Internet IP addresses - only a single such “real” address will be required. The technique is called “IP Masquerading,” and an example follows:

ipchains -P forward DENY
ipchains -F
ipchains -A forward -j MASQ -s 192.168.1.0/24 -d 0.0.0.0/0

The ipfwadm syntax follows:

ipfwadm-wrapper -F -p deny
ipfwadm-wrapper -F -f
ipfwadm-wrapper -I -f
ipfwadm-wrapper -O -f
ipfwadm-wrapper -A -f
ipfwadm-wrapper -F -a m -S 192.168.1.0/24 -D 0.0.0.0/0

Masquerade specifically requires that routing be disabled by default, which is accomplished by the first command. The last call to ipchains (or ipfwadm) establishes a masquerading rule.

In this case, it is assumed that one of the network interfaces has an address on the 192.168.1 Class C network. Hosts on this network should be configured to use the masquerade “server” network interface IP address as their default gateway.

Packets traveling through a masquerading route such as this one will usually be rewritten so that their source network addresses will be the same as the IP address of the network interface that lies on the default route of the masquerade server (the source port will also be changed). The kernel will keep track of all masqueraded connections; when a remote server replies to the masquerade server, the kernel will rewrite the return packet with the original (synthetic) IP address and port number, then forward the packet onto the internal network. External hosts will think the firewall is initiating all traffic, but internal hosts should never know the difference.

Masquerade works for most protocols, but not all. FTP (in active mode) will specifically cease to function when run behind such a network. Masquerade servers for some of these protocols are available as kernel modules. The following commands will load all the additional available masquerade protocols:

depmod -a
modprobe ip_masq_autofw
modprobe ip_masq_cuseeme
modprobe ip_masq_ftp
modprobe ip_masq_irc
modprobe ip_masq_mfw
modprobe ip_masq_portfw
modprobe ip_masq_quake
modprobe ip_masq_raudio
modprobe ip_masq_user
modprobe ip_masq_vdolive

Obviously, only the masquerade modules that are required should be loaded; omit the others.

If a network application ceases to function when placed behind such a masquerade server, it is probably creating a server on some port. If the server is on a random port (and not a well-defined port), the odds are slim that the application will work easily with masquerade. The use of proxies to access servers on synthetic networks is discussed in the next section.

Masquerade rules can coexist with other forward rules. They can also apply to real Internet IP addresses.

In the example below, all external hosts are allowed to access web and email services on the 1.2.3 network, but all other traffic originating from hosts in 1.2.3 is masqueraded:

ipchains -P forward DENY
ipchains -F
ipchains -A forward -s 0.0.0.0/0 -p TCP -d 1.2.3.0/24 http -j ACCEPT -b
ipchains -A forward -s 0.0.0.0/0 -p TCP -d 1.2.3.0/24 smtp -j ACCEPT -b
ipchains -A forward -j MASQ -s 1.2.3.0/24 -d 0.0.0.0/0

The ipfwadm follows:

ipfwadm -F -p deny
ipfwadm -F -f
ipfwadm -I -f
ipfwadm -O -f
ipfwadm -A -f
ipfwadm -F -a accept -P tcp -S 0.0.0.0/0 -D 1.2.3.0/24 http -b
ipfwadm -F -a accept -P tcp -S 0.0.0.0/0 -D 1.2.3.0/24 smtp -b
ipfwadm -F -a m -S 1.2.3.0/24 -D 0.0.0.0/0

This will open only the HTTP and SMTP ports on the servers residing within the internal network; all other ports will be blocked. Connections on these ports will use the real IP addresses of the internal hosts. Any other outgoing communication from the internal network will be masqueraded.

Please note that the order of the last three commands is important. The sequence could be restated in the following manner:

ipchains -A forward -j MASQ -s 1.2.3.0/24 -d 0.0.0.0/0
ipchains -A forward -s 0.0.0.0/0 -p TCP -d 1.2.3.0/24 http -j ACCEPT -b
ipchains -A forward -s 0.0.0.0/0 -p TCP -d 1.2.3.0/24 smtp -j ACCEPT -b

Or, with the older syntax:

ipfwadm -F -a m -S 1.2.3.0/24 -D 0.0.0.0/0
ipfwadm -F -a accept -P tcp -S 0.0.0.0/0 -D 1.2.3.0/24 http -b
ipfwadm -F -a accept -P tcp -S 0.0.0.0/0 -D 1.2.3.0/24 smtp -b

However, this sequence would never allow web or email traffic through. The rules are parsed top-down, so the connection would always be masqueraded.

It might also be important to prevent “IP-Spoofing.” There is a simple configuration directive for the kernel that enables “Source Address Verification,” which will prevent spoofing. Place the following shell script fragment in a startup file that is executed after the networking devices are brought up:

# This is the best method: turn on Source Address Verification and get
# spoof protection on all current and future interfaces.

if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then
	echo -n "Setting up IP spoofing protection..."
	for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
		echo 1 > $f
	done
	echo "done."
else
	echo PROBLEMS SETTING UP IP SPOOFING PROTECTION.  BE WORRIED.
	echo "CONTROL-D will exit from this shell and continue system startup."
	echo
	# Start a single user shell on the console
	/sbin/sulogin $CONSOLE
fi

As a general rule, only machines running servers should be given real Internet IP addresses; hosts that are mainly used as clients should use masqueraded if the client applications will allow it.

A complete example of a simple masquerade which is integrated with a DHCP configuration is presented in the DHCP section of Chapter 2.

Extensive information on Linux firewall design is available in the IPCHAINS-HOWTO.

As a final point, it should be stressed that masquerading is not a security feature alone. Masquerade can be used in situations where a single IP address must be used to provide Internet service for several hosts. It is commonly used with dialup PPP connections.

tcpd

tcpd is a simple security feature that is included with Red Hat Linux 6.0.

The two main configuration files for tcpd are the /etc/hosts.deny and /etc/hosts.allow files. The only place where the tcpd program is actually invoked is in the /etc/inetd.conf file (tcpd is never called from the command line).

If some Linux host has an /etc/hosts.deny file of the following form:

in.telnetd: ALL except 1.2.3.4

Then Telnet access will be disabled on this Linux host from all sites except the 1.2.3.4 host. Similar entries will disable FTP and the Berkley r-utilities:

in.ftpd: ALL except 1.2.3.4
in.rshd: ALL except 1.2.3.4
in.rlogind: ALL except 1.2.3.4

Optionally, all available protocols controlled by tcpd can be disabled with entry of the following form:

ALL: ALL EXCEPT 1.2.3.0/255.255.255.0, \
	5.6.7. \
	.allowed.com \
	.permitted.org

Note the wildcards in the above entry. A full netmask can be specified, or a matching domain name (which will require reverse lookups). Additional information on and syntax of the /etc/hosts.deny file man be obtained by entering the command man 5 hosts_access at a shell prompt.

A complete denial of access to all local services is the safest choice in the design of a firewall. Should this not be practical, a tcpd configuration such as the one above should deny access to all but a few hosts.

Obviously, this utility does not control traffic that is routed between the network interfaces on a firewall in its normal configuration; tcpd protects only local services. It is mentioned here only to further ensure the security of the bastion host.

Learning exactly what tcpd controls is quite simple. The telnet configuration entry in /etc/identd.conf is of the following form:

telnet  stream  tcp     nowait  root    /usr/sbin/tcpd  in.telnetd

Any service entry in /etc/identd.conf containing a reference to tcpd similar to the one above will be controlled by tcpd. Please note that there are a number of such services that are not, including SMTP, in.identd, httpd, Postgres, and many others.

The TIS Firewall Toolkit

The FireWall ToolKit (FWTK) from Trusted Information Systems (TIS) is a free package containing a set of small programs that can be used for a variety of network functions, including firewall design.

If two hosts communicate across a routing firewall, it should not be necessary for either host to be aware of the mechanics of the connection. They would generate packets for one another that would be checked (and perhaps slightly modified) by the firewall, but the hosts would be otherwise oblivious to the presence of the bastion host.

A proxy firewall, on the other hand, normally requires that at least one of the pair of hosts be aware of its location and the methods used to access it.

The FWTK includes small programs that implement proxies for several types of services within the TCP/IP suite, including FTP, Telnet, HTTP (web), SMTP, Berkley rlogin, and X. There is also a generic proxy which is extremely useful both as a part of a firewall design and in general UNIX administration.

Unfortunately, the TIS FWTK is not included with Red Hat Linux. While it is open source, its licensing agreement is somewhat more restrictive than the GPL (certain types of commercial use are restricted). The FWTK can be obtained from http://www.fwtk.org, but do not download the product unless you can abide by the license.

Network Associates (who recently acquired Trusted Information Systems) also sells a commercial firewall called “Gauntlet.” Gauntlet is very powerful; it contains all the proxy features of the FWTK, the same packet masquerading features as the Linux kernel, plus a number of advanced features and a graphical administration interface. It is not difficult to migrate from the FWTK to Gauntlet. However, Gauntlet does not as yet run on Red Hat Linux, so a change in platform would be required.

The latest version of the FWTK when this text was prepared was fwtk2.1.tar.Z. By default, the proxy applications and a control file will be installed to /usr/local/etc (the directory will be created if it does not exist).

There is a problem with the crypt() library function when building the FWTK on Red Hat Linux. Run the following commands as root to compile and install the package:

tar xvzf fwtk2.1.tar.gz 
cd fwtk
sed 's/^AUXLIB=.*/AUXLIB= -lcrypt/
	s/^COPT=.*/COPT= -O2 $(DEFINES) -I\/usr\/include\/db1/
	s/^LDFL=.*/LDFL= -s -static/' Makefile.config.linux > Makefile.config
make
make install

Please note that the above commands enable optimization and stripping (and disable debugging) of the toolkit components in addition to setting the usage of the crypt library. This is not the default build environment for the kit. Review Makefile.config.linux for additional build configuration details.

These are some of the files that will be installed in /usr/local/etc:

netperm-table
This is the master configuration file for the toolkit.

ftp-gw
This is the FTP proxy.

http-gw
This is the HTTP (web) proxy. It can be configured to block Java and JavaScript, should it be necessary. It can also route web requests to multiple hosts depending upon the form of the URL.

netacl
This is a utility similar to tcpd. It is somewhat more flexible in that it can execute different programs depending upon the origin of the network connection.

plug-gw
This is the generic proxy. It can allow connections to and from arbitrary TCP ports.

rlogin-gw
This is the Berkley rlogin proxy.

tn-gw
This is the telnet proxy.

x-gw
This is the proxy for X-Windows applications. It will only be built if the X-Windows development libraries were installed.

Each proxy application can be configured to restrict the set of hosts that are allowed to access the proxy, the possible destinations that might be requested, or both.

While the behavior of the proxies is configured with netperm-table, their invocation is usually controlled with /etc/inetd.conf. Below is an entry in this file that would configure the telnet proxy:

telnet	stream  tcp 	nowait.1024  root    /usr/local/etc/netacl	tn-gw

A particular point of interest is the parameter to nowait in the line above. inetd is configured by default to allow 40 invocations of any particular service over the period of 60 seconds. Should this limit be exceeded, the service will be shut down for a time (inetd will cease forking it), and a note of the fact will be made to /var/log/messages. The above 1024 parameter to nowait increases this limit. This parameter is extremely important on busy firewalls.

Continuing the example configuration of a telnet proxy, the following lines in netperm-table will allow use of the proxy:

netacl-tn-gw:	permit-hosts * -exec /usr/local/etc/tn-gw
tn-gw:		permit-hosts * -passok -xok

Please note that this new configuration will not be activated until inetd has been refreshed. This can be accomplished by either rebooting the system or sending the HUP signal to the daemon. Conversely, nothing must be refreshed when netperm-table changes as the proxies are re-spawned each time they are invoked. They scan netperm-table at that time.

The netperm-table itself has limitations. The maximum line lengths allowed in this file vary, depending upon the operating system, but usually it is 1,024 characters. Also, no method is provided for continuing lines (i.e. a “\” to continue on the next line). Strict observance of these rules will allow your netperm-table to be easily ported.

Once inetd has been refreshed, attempts to telnet to the bastion host will be greeted with the following menu:

tn-gw->

There are only a few options available at the proxy menu. The most useful option opens a connection to another host:

tn-gw-> connect another.host.com
Trying 1.2.3.4 port 23...
Connected to another.host.com.
login:

This firewall configuration is not very secure, as it permits anyone to initiate connections anywhere. Restricting access is straightforward:

netacl-tn-gw: permit-hosts 1.2.3.* 192.168.1.* -exec /usr/local/etc/tn-gw
tn-gw: permit-hosts 1.2.3.* 192.168.1.* -passok -xok -dest { 1.2.3.4 *.remotehost.com }

Observe that while it may appear redundant to list the allowed hosts twice (once for netacl, and once for tn-gw), it is safer to do so in case netacl is removed from /etc/inetd.conf at some later date. Netacl in this case is somewhat superfluous. However, it can be configured to run multiple server binaries on a connection, based on the remote IP, so its use is suggested.

Note that it is possible to allow Telnet connections into the bastion host, but it is extremely inadvisable to do so. If shell connections into the firewall are required, they should be done with an encrypted protocol such as ssh with careful access control.

Finally, take special account that the proxy can bridge the firewall in both directions; it can allow general connections out of the protected network(s), but it can also at the same time allow restricted access inside.

The FTP proxy is somewhat similar in operation to tn-gw. It is not normally configured with netacl. Following is a line that might be used in /etc/inetd.conf to configure it:

ftp	stream	tcp	nowait.1024	root	/usr/local/etc/ftp-gw	ftp-gw

And a corresponding entry in netperm-table that permits maximum access would be:

ftp-gw: permit-hosts *

A more restricted level of access might be:

ftp-gw: permit-hosts 1.2.3.* 192.168.1.* -dest { 1.2.3.4 *.remotehost.com }

While the FTP proxy is rather simple to configure, it can be frighteningly confusing to use. Consider the following FTP session that passes through the proxy:

$ ftp bastion
Connected to bastion.
220 bastion FTP proxy (Version V2.1) ready.
Name (bastion:root): ftp@ftp.redhat.com
331-(----GATEWAY CONNECTED TO ftp.redhat.com----)
331-(220 ProFTPD 1.2.0pre1 Server (ProFTPD) [gonzales.redhat.com])
331 Anonymous login ok, send your complete e-mail address as password.
Password:
230-            Red Hat Software -- FTP Site
 
        For the following sites, use the appropriate server:
 
        Red Hat Linux Updates   - ftp://updates.redhat.com
        Red Hat Rawhide         - ftp://rawhide.redhat.com
 
        Red Hat Contrib Net     - ftp://developer.redhat.com
        For Incoming RHCN RPMS  - ftp://in-rhcn.redhat.com
 
        User Contributed RPMS   - ftp://contrib.redhat.com
        To Upload Incoming RPMS - ftp://incoming.redhat.com
230 Anonymous access granted, restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -l
200 PORT command successful.
150 Opening ASCII mode data connection for file list.
total 0
-rw-r--r--   1 root     root         4050 Nov 18 16:30 MIRRORS.html
drwxr-xr-x   3 root     root         1024 Nov 15 04:03 XBF
drwxr-xr-x   3 root     root         1024 Nov 15 04:03 XFCom
drwxr-xr-x  10 dledford dledford     1024 Dec  8 11:46 aic
drwxr-xr-x  31 root     root         1024 Dec  1 10:06 home
drwxr-xr-x   6 jbj      jbj          1024 Nov 14 04:03 large-fd
-rw-r--r--   1 root     root      2951395 Dec  9 04:07 ls-lR
-rw-r--r--   1 root     root       421475 Dec  9 04:07 ls-lR.gz
lrwxrwxrwx   1 root     root            1 Oct 21 10:53 pub -> .
drwxr-xr-x  10 root     root         1024 Nov 14 04:05 redhat
drwxr-xr-x   7 root     root         1024 Nov 14 04:13 sound
drwx--x--x   2 root     root         1024 Nov 14 04:13 sybase
226 Transfer complete.
ftp> get MIRRORS.html
local: MIRRORS.html remote: MIRRORS.html
200 PORT command successful.
150 Opening BINARY mode data connection for MIRRORS.html (4050 bytes).
226 Transfer complete.
4050 bytes received in 1.24 secs (3.2 Kbytes/sec)
ftp> quit
221 Goodbye.

After a connection is established to the proxy, the login name is specified as user@remotehost. The proxy then initiates an FTP session with the remote server. This manipulation of the hostname/username can be extremely difficult on complex GUI FTP clients. It is also possible to pass through multiple ftp-gw servers, but the semantics are tortureous.

The HTTP proxy has many features that make it especially powerful. Following is a line from /etc/inetd.conf which will allow it to run:

http  stream  tcp  nowait.1024  root  /usr/local/etc/http-gw  http-gw

A netperm-table entry to allow access might be:

http-gw:	permit-hosts *

The web browser must be configured to use the proxy. Below are the relevant dialog boxes from Netscape Communicator that configure use of the proxy:

In the above proxy configuration dialog, insert the hostname or the IP address of the proxy. http-gw can also be used as the FTP and Gopher proxy (do not attempt to use ftp-gw here).

The proxy can restrict the active content that it delivers to the browser:

http-gw:	permit-hosts * -nojava -nojavascript -noactivex

The HTTP proxy also can direct to various servers depending upon the form of the URL:

http-gw: forward /Home* -protocol http -tohost www.tis.com
http-gw: forward /pub/* -protocol ftp -tohost ftp.uu.net

Perhaps the most flexible proxy is plug-gw. It allows the redirection of arbitrary TCP ports, which has great potential use beyond that of a firewall. For example:

pop-3   stream  tcp     nowait.1024  root    /usr/local/etc/plug-gw plug-gw pop-3

The above line from /etc/inetd.conf directs the POP mail port to be served by plug-gw...

plug-gw:	port pop-3 * -plug-to mail.remotehost.com -port 110

This configuration directive will automatically establish a connection to a remote POP port when a connection on the local POP port is initiated.

Note that the service name (pop-3) and the port number (110) are used interchangeably in the directives above (the service names are defined in /etc/services). The only place where the name must be used is in the service definition in /etc/inetd.conf. The final -port 110 above is also optional, as plug-gw will redirect to the same numerical port from which it originated by default.

Note also that either the service name or number must be passed as an argument to plug-gw in /etc/inetd.conf. The plug proxy will not work without the argument.

There are a few other important proxies that are not covered here (Berkley rlogin, x-gw, and smap), but their configuration is either similar enough to the previously discussed proxies to be trivial, or their configuration is complex enough to be beyond the scope of this text.

These proxies can also be configured stand-alone, running outside of inetd. This configuration is not covered here.

The use of a proxy firewall (over a routing solution) has both advantages and drawbacks. A great advantage is the increased ability to filter both the data and the origin/destination. A tremendous drawback is the responsibility placed upon those behind the firewall to understand the architecture of the proxy.

Do not imagine, however, that proxy firewall components cannot coexist with route filtering. In fact, proxies are an ideal method for accessing network services within a masqueraded network (which would otherwise be inaccessible to the Internet at large). A well-balanced firewall will combine all of these techniques while preserving security concerns for the good of the network.

ssh

The ssh protocol and the suite of programs that implement it provide secure, encrypted network communication channels between hosts on a TCP/IP network. The primary focus of ssh is UNIX, but versions for Microsoft Windows, VMS, and OS/2 are available.

Because ssh uses strong encryption technology, it's distribution is complicated in many countries because of legal restrictions (for example, its use is altogether forbidden in France, Russia, Iraq, and Pakistan, and once ssh has been brought into the United States, it cannot then leave the country in any form). Do not be overzealous to make use of this application; understand and obey your nation's laws governing encryption before you even consider installing this software.

The Internet web page for ssh is http://www.ssh.fi (the company is based in Finland). Copies of ssh are available there, both for download and for purchase.

Please note that the later versions of ssh (2.0 and above) are free only for non-commercial use. If you intend to use it in any way that is connected with profit, you must pay a licensing fee.

There can be some confusion regarding different versions of ssh. A major rewrite of the software has recently occurred, and the current release of ssh at the time this text was prepared was 2.0.11. However, many installations of ssh 1 are still in use (even though there are bugs and security risks in the older versions). What is more problematic is that ssh 1 clients will not work with ssh 2 servers, so the major version numbers of the client and server ssh versions must match. If you must use ssh 1, use the 1.2.26 release, and apply the kerberos security patches if you intend to use kerberos.

Part of the encryption technology behind ssh is public key cryptography (which is also used in SSL and PGP). It is not so important to understand the mechanics with ssh, so it will only be summarized. When most people think of conventional cryptography, they imagine a single key that can be used to unlock or decipher a message. Public key cryptography relies upon not one but two keys, a public key and a private key. When either key is used to encrypt a message, only the other key will be able to decrypt it. The public key is usually given out freely to others; the private key is kept secret. When two people exchange messages, they first exchange public keys. The person sending the message encrypts it with both their private key and the other's public key (encrypting a message with a private key is also called “signing” the message in PGP). This technique allows secure encryption to take place without exchanging the data that unlocks the encryption, which a design that used only a single password could never accomplish. ssh is actually quite careful with these sets of keys, and a section of the host/server key is actually destroyed and rebuilt once an hour to ensure that if the server equipment is seized, the keys cannot be obtained. There are several other encryption technologies that may be included with ssh, including IDEA, Triple DES, and RSA, but these technologies are mostly transparent to the user.

ssh will also transparently forward communications from remote graphical X-Window clients over the secure connection (it will automatically configure xauth and the DISPLAY environment variable). Simply run X-Windows applications on the remote server, and they will appear on the local display - usually no more configuration is required than that. This is a powerful convenience for users of X-Windows.

ssh is not made available in an RPM format from the main distribution site. Only the C source code is available in a tar, gzip format. Assuming release 1.2.26 of ssh has been obtained, the following commands can be run by root to compile and install it on Red Hat Linux 6.0:

# The below call to sed could also be written as:
# sed '/^#.*UTMPX/s/^/\/\//' config.h > config.h.new
#
tar xvzf ssh-1.2.26.tar.gz
cd ssh-1.2.26
LDFLAGS="-s" CFLAGS="-O2" ./configure
sed '556d' config.h > config.h.new
mv -f config.h.new config.h
make
make install

This will install most everything in /usr/local/bin, but will install sshd (the server daemon) in /usr/local/sbin if ssh 1 is being prepared. At this point, the sshd daemon should be started. The path to ssh and/or sshd may not be in the shell search path; add the path to /etc/profile if this is troubling. If ssh services should be started at boot, add the commands to the system rc files (at least /etc/rc.d/rc.local).

Install the ssh software on another host that can be used as a client. If a machine will only be an ssh client, it is not necessary to run sshd. One might simply copy the ssh and scp binaries from the server to the client. Then, as root, enter the command:

ssh remotehost.com

Where “remotehost.com” is the fully-qualified host name of a host running an ssh server. ssh will prompt for the remote root password, then a UNIX shell will be opened.

ssh uses command line arguments that are similar to the Berkley r-utilities, and ssh actually encompasses the function of both rsh and rlogin. For example, to log in as a user other than the one originating the connection, use the syntax:

ssh -l luser remotehost.com

Replace luser with any valid login id on the remote host. ssh will prompt for the remote password, then open a shell.

It is possible to use ssh to run a single command on a remote host, rather than opening an interactive connection. For example, enter the following:

ssh -l luser remotehost.com "df; ps aux"

The remote computer will issue a disk free space report, then a process list (which will run correctly only on systems that use the BSD semantics for ps, such as Linux), then close the connection.

Data can be piped into and out of ssh, even if password prompting occurs. Consider the following two commands:

cd /home/httpd/html; tar cf - * | \
	ssh remotehost.com "cd /home/httpd/html; tar xvf -"

ssh remotehost.com "cd /usr/local/bin; tar cf - *" | \
	(cd /usr/local/bin; tar xvf -)

These two commands launch tar processes on the local and remote servers that exchange data through an ssh connection. The first copies the contents of the local /home/httpd/html directory to the same location on the remote server, the second copies the remote /usr/local/bin directory onto the local server.

The two previous examples are perhaps the most convenient method available to cleanly move an entire directory hierarchy between two UNIX systems. These methods should be studied and practiced.

Of course, much simpler examples of ssh piping can be used:

ssh remotehost.com "cat /etc/passwd" | grep luser

This command will print luser's entry in the password file on the remote host.

Files can be transferred over encrypted connections between hosts using the scp command, with semantics similar to Berkley rcp. Unfortunately, the full path to the remote files must be known before the transfer can take place. For example:

scp /local/file.txt remotehost.com:/long/paths/make/this/hard.txt

The file can be copied as another user by prepending the user's login and the “@” symbol to the host name:

scp /local/file.txt luser@remotehost.com:/long/paths/make/this/hard.txt

Of course, the transfer can go the other direction:

scp luser@remotehost.com:/long/paths/make/this/hard.txt /local/file.txt

A few final points concerning this brief introduction to scp should be made. Transfers can be conducted that do not involve files on the local system at all. More than one source file can be specified if the target is a directory (just like cp). Wildcards cannot be used on remote files, as the remote file system is not available to the shell for expansion (in other words, the command scp remote:/root/* /root simply will not work). If the -p option is supplied to scp, it will attempt to preserve modification times, access times, and modes on the copy (this will fail if the destination is a DOS FAT file system, for example). The -r option can be applied to recursively copy an entire directory structure, but it won't preserve soft links - use the previous tar/ssh examples to obtain a more “high-fidelity” copy. Currently, “secure FTP” utilities are available in later versions of ssh that use scp and ssh together to browse a directory structure over an scp connection, but such a utility is not included with the UNIX ssh 1.2.26 distribution. Please also note that, unlike telnet and rlogin, root is allowed to login remotely under an ssh or scp connection.

The /etc/sshd_config and /etc/ssh_config files control the behavior of the server and client respectively. A few useful options deserve description.

/etc/sshd_config:

AllowHosts *.permitted.org 1.2.3.* 1.?.2.3
This option will only permit ssh connections from the specified hosts (wildcards are permitted).
AllowGroups groupname1 groupname2
This permits connections only from those users that are registered members of the specified groups (in the /etc/group file).
DenyHosts *.goaway-spammer.com 5.6.7.* 8.?.9.10
This option explicitly denies ssh connections from the specified hosts (wildcards are permitted).
DenyGroups groupname1 groupname2
This explicitly denies connections from those users that are registered members of the specified groups (in the /etc/group file).

/etc/ssh_config:

Compression yes
This will cause the data exchanged between the ssh client and server to be compressed. This will actually slow down transfers on fast networks. Use only in limited bandwidth situations where every byte counts. Compression can also be enabled by passing the -C parameter to ssh.
CompressionLevel 6
The compression level can be between 1 and 9 (which is similar to the gzip utility). 1 is fast, but the data is not compressed very well; 9 is very slow but the data is much more thoroughly compressed. The default is 6.

The -g and -L options to ssh can be particularly useful to firewall design. These options allow TCP ports to be forwarded to the remote server over a secure connection. The following command:

ssh -L 2300:remotehost.com:23 -g remotehost.com

Will allow encrypted telnet connections from port 2300 while the remote shell session is active (this behavior is rather similar to plug-gw from the TIS FWTK). If a user telnets to port 2300 on the local host, their connection is encrypted, sent to the remote, then forwarded to the destination port specified on the command line (23).

The one last question for ssh is how to force it not to ask for a password. With the Berkley r-utilities, a properly configured .rhosts file could allow password-free connections. ssh can use .rhosts, but this usage is disabled by default. A safer way for password-free logins is public key cryptography.

Run the following command as root on the local host to generate a key pair. Accept all the defaults, but do not enter a passphrase - just press enter instead (this does open up a security risk, which will be discussed in a moment).

ssh-keygen

Now copy the public key to the remote server:

scp ~/.ssh/identity.pub remotehost.com:/root/.ssh/authorized_keys

Alternately, the following syntax could be used to append to a remote authorized_keys file:

cat ~/.ssh/identity.pub | ssh remotehost.com "cat >> ~/.ssh/authorized_keys"

The next ssh login should not require a password (scp should be open as well):

ssh remotehost.com

This technique really shouldn't be used unless it is absolutely required. Scripting done with crontabs might be a good excuse. Try to do the work with a login that has few privileges. Keep root away from the automatic logins if at all possible.

Please note that, in this example, if the local host is damaged or destroyed by an attacker, the remote host could very likely go down with it. In this case, the price of convenience is risk.

Conclusion

It is not useful for an Internet firewall administrator to consider their “secure” network impregnable. A determined attacker sees these security features as mere obstacles, not insurmountable obstructions. Only with true vigilance can hostile attacks be repelled.

An administrator should review each of the following system components:

  1. The exact function of each service entry in /etc/inetd.conf, and why the service cannot be disabled.
  2. An exact explanation of any running daemons reported by ps aux (although this can be forged by a rogue kernel).
  3. A clear view of the permitted route origins and destinations, with documentation.
  4. A precise reckoning of all unencrypted communication channels passing through the firewall, and why they do not compose a security risk.
  5. The installation status of the Red Hat Errata packages that have been issued for the platform.

Also, neither the C compiler nor the Linux kernel source should be allowed to remain upon an active firewall (in fact, no development tools, nor any other non-related packages should be installed).

In a perfect world bounded by courtesy, such bothersome security features would be unnecessary. Unintentional abuse would be corrected; malevolence would be unthinkable. But such is not the world in which we live; good fences make good neighbors.