Kevin Steves <stevesk@sweden.hp.com>
Hewlett-Packard Consulting, Sweden
A bastion host is a computer system that is exposed to attack, and may be a critical component in a network security system. Special attention must be paid to these highly fortified hosts, both during initial construction and ongoing operation. Bastion hosts can include:This paper presents a methodology for building a bastion host using HP-UX 10, and walks through the steps used to build a sample, generic bastion host using HP-UX 10.20. While the principles and procedures can be applied to other HP-UX versions as well as other Unix variants, our focus is on HP-UX 10.
- Firewall gateways
- Web servers
- FTP servers
- Name servers (DNS)
- Mail hubs
- Victim hosts (sacrificial lambs)
1. A projecting part of a rampart or other fortification. 2. A well-fortified position or area. 3. Something regarded as a defensive stronghold.Marcus Ranum is generally credited with applying the term bastion to hosts that are exposed to attack, and its common use in the firewall community. In [1] he says:
Bastions are the highly fortified parts of a medieval castle; points that overlook critical areas of defense, usually having stronger walls, room for extra troops, and the occasional useful tub of boiling hot oil for discouraging attackers. A bastion host is a system identified by the firewall administrator as a critical strong point in the network's security. Generally, bastion hosts will have some degree of extra attention paid to their security, may undergo regular audits, and may have modified software.Bastion hosts are not general purpose computing resources. They differ in both their purpose and their specific configuration. A victim host may permit network logins so users can run untrusted services, while a firewall gateway may only permit logins at the system console. The process of configuring or constructing a bastion host is often referred to as hardening. The effectiveness of a specific bastion host configuration can usually be judged by answering the following questions:
See [2] for a thorough treatment of bastion hosts.
We take a paranoid stance--what we don't know can hurt us, and what we think we know we may not trust. We start with a clean operating system install. If subsystems are not needed for the applications we plan to run on the bastion host, we will not install them in the first place, or disable or remove them after the install. We remove the set-id bits on programs that do not need to be run by non-privileged users. This proactive approach may save us time and future vulnerabilities when the next security defect is discovered in our operating system version. We tighten up the world-write permissions on system files. We install HP-UX security patches that apply to our installed software configuration, and set security network tuning parameters. At this point, the applications that will run on the bastion host can be installed, configured and tested. After testing is complete, we create a failsafe tape image of our root disk, followed by a level 0 gold backup of the system.
During the initial installation, configuration and testing, make sure that your system is not connected to any untrusted networks. Boot from the HP-UX install CD and perform the following steps:
This yields a pretty lean configuration, as shown by the following output of bdf, ps -ef and netstat -anf inet (we still have work to do):
# uname -a HP-UX bastion B.10.20 A 9000/712 2005411384 two-user license # bdf Filesystem kbytes used avail %used Mounted on /dev/vg00/lvol3 83733 12409 62950 16% / /dev/vg00/lvol1 47829 7708 35338 18% /stand /dev/vg00/lvol8 153613 1195 137056 1% /var /dev/vg00/lvol7 331093 73010 224973 25% /usr /dev/vg00/lvol6 30597 13 27524 0% /tmp /dev/vg00/lvol5 199381 1027 178415 1% /opt /dev/vg00/lvol4 11925 9 10723 0% /home # ps -ef UID PID PPID C STIME TTY TIME COMMAND root 0 0 0 11:31:54 ? 0:00 swapper root 1 0 0 11:31:55 ? 0:00 init root 2 0 0 11:31:54 ? 0:00 vhand root 3 0 0 11:31:54 ? 0:00 statdaemon root 4 0 0 11:31:54 ? 0:00 unhashdaemon root 7 0 0 11:31:54 ? 0:00 ttisr root 13 0 0 11:31:55 ? 0:00 lvmkd root 14 0 0 11:31:55 ? 0:00 lvmkd root 15 0 0 11:31:55 ? 0:00 lvmkd root 16 0 0 11:31:55 ? 0:00 lvmkd root 17 0 0 11:31:55 ? 0:00 nvsisr root 18 0 0 11:31:55 ? 0:00 supsched root 19 0 0 11:31:55 ? 0:00 strmem root 20 0 0 11:31:55 ? 0:00 strweld root 730 1 1 11:35:47 console 0:00 -sh root 648 1 0 11:35:34 ? 0:00 /usr/sbin/snmpdm root 518 1 0 11:35:28 ? 0:00 sendmail: accepting connections root 528 1 0 11:35:28 ? 0:00 /usr/sbin/syslogd -D root 460 1 0 11:35:23 ? 0:00 /usr/sbin/swagentd root 409 1 0 11:35:18 ? 0:00 /usr/sbin/syncer root 537 1 0 11:35:28 ? 0:00 /usr/sbin/ptydaemon root 708 1 0 11:35:46 ? 0:00 /usr/sbin/cron root 760 730 5 11:38:11 console 0:00 ps -ef root 596 1 0 11:35:31 ? 0:00 /usr/sbin/inetd # netstat -anf inet Active Internet connections (including servers) Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp 0 0 *.543 *.* LISTEN tcp 0 0 *.544 *.* LISTEN tcp 0 0 *.19 *.* LISTEN tcp 0 0 *.9 *.* LISTEN tcp 0 0 *.7 *.* LISTEN tcp 0 0 *.37 *.* LISTEN tcp 0 0 *.13 *.* LISTEN tcp 0 0 *.515 *.* LISTEN tcp 0 0 *.113 *.* LISTEN tcp 0 0 *.512 *.* LISTEN tcp 0 0 *.514 *.* LISTEN tcp 0 0 *.513 *.* LISTEN tcp 0 0 *.25 *.* LISTEN tcp 0 0 *.23 *.* LISTEN tcp 0 0 *.21 *.* LISTEN tcp 0 0 *.2121 *.* LISTEN udp 0 0 *.* *.* udp 0 0 *.* *.* udp 0 0 *.161 *.* udp 0 0 *.19 *.* udp 0 0 *.9 *.* udp 0 0 *.7 *.* udp 0 0 *.37 *.* udp 0 0 *.13 *.* udp 0 0 *.518 *.* udp 0 0 *.514 *.* udp 0 0 *.2121 *.*
Add umask 077 to /.profile.
Add umask 022 to /etc/profile and /etc/csh.login.
# touch /var/adm/btmp # chmod 600 /etc/btmp
# echo console > /etc/securetty # chmod 400 /etc/securetty
Add the -l (minus ell) argument to the INETD_ARGS environment variable in /etc/rc.config.d/netdaemons:
export INETD_ARGS=-l
# rm /sbin/rc2.d/S500inetd # rm /sbin/rc1.d/K500inetdFor the remaining services, consider using inetd.sec(4), which permits IP address based authentication of remote systems.
With all services removed from inetd.conf, netstat yields:
# netstat -af inet Active Internet connections (including servers) Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp 0 0 *.2121 *.* LISTEN udp 0 0 *.* *.* udp 0 0 *.* *.* udp 0 0 *.snmp *.* udp 0 0 *.syslog *.* tcp 0 0 *.smtp *.* LISTEN udp 0 0 *.2121 *.*This is much better, though we still need to determine what the remaining services are. We see that servers are listening on the UDP SNMP and syslog port, and the SMTP port. However, 2121/udp and 2121/tcp were not found in /etc/services, so netstat is unable to print the service name. An extremely useful tool for identifying network services is lsof (LiSt Open Files) [3]. lsof -i shows us the processes that are listening on the remaining ports:
# lsof -i COMMAND PID USER FD TYPE DEVICE SIZE/OFF INODE NAME swagentd 460 root 6u inet 0x009dd800 0t0 TCP *:2121 swagentd 460 root 7u inet 0x009d6a80 0t0 UDP *:2121 syslogd 528 root 5u inet 0x00973a00 0t0 UDP *:syslog snmpdm 648 root 0u inet 0x00992400 0t0 UDP *:snmp sendmail: 418 root 4u inet 0x009cbc00 0t0 TCP *:25 snmpdm 648 root 3u inet 0x009f2a80 0t0 UDP *:0 snmpdm 648 root 5u inet 0x00a14500 0t0 UDP *:0
Comment out the syslog service in /etc/services:
# Disable remote logging to syslogd. #syslog 514/udp # remote system loggingThis causes syslogd(1M) to not listen on UDP port 514 for forwarded syslog messages from remote systems; a side-effect of this change is a warning message that will appear on the console when syslogd is started, which can be safely ignored:
Jan 1 14:34:42 bastion syslogd: syslog/udp: unknown service
Edit SNMP startup configuration files:
Disable swagentd startup and shutdown by removing the corresponding symbolic links from the rc directories:
# rm /sbin/rc2.d/S100swagentd # rm /sbin/rc1.d/K900swagentdYou'll have to make sure that swagentd is running before you install a patch or product, and stop it afterwards. You can do this through the start and stop arguments to swagentd:
# /sbin/init.d/swagentd start # /sbin/init.d/swagentd stop
Set the SENDMAIL_SERVER environment variable to 0 in /etc/rc.config.d/mailservs:
export SENDMAIL_SERVER=0
# ps -ef UID PID PPID C STIME TTY TIME COMMAND root 0 0 0 13:45:06 ? 0:00 swapper root 1 0 0 13:45:07 ? 0:00 init root 2 0 0 13:45:06 ? 0:00 vhand root 3 0 0 13:45:06 ? 0:00 statdaemon root 4 0 0 13:45:06 ? 0:00 unhashdaemon root 7 0 0 13:45:06 ? 0:00 ttisr root 13 0 0 13:45:07 ? 0:00 lvmkd root 14 0 0 13:45:07 ? 0:00 lvmkd root 15 0 0 13:45:07 ? 0:00 lvmkd root 16 0 0 13:45:07 ? 0:00 lvmkd root 17 0 0 13:45:07 ? 0:00 nvsisr root 18 0 0 13:45:07 ? 0:00 supsched root 19 0 0 13:45:07 ? 0:00 strmem root 20 0 0 13:45:07 ? 0:00 strweld root 486 1 0 13:45:34 console 0:00 -sh root 520 486 5 13:48:33 console 0:00 ps -ef root 316 1 0 13:45:28 ? 0:00 /usr/sbin/ptydaemon root 231 1 0 13:45:25 ? 0:00 /usr/sbin/syncer root 307 1 0 13:45:28 ? 0:00 /usr/sbin/syslogd -D root 375 1 0 13:45:31 ? 0:00 /usr/sbin/inetd -l root 464 1 0 13:45:33 ? 0:00 /usr/sbin/cron
# ps -el F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME COMD 3 S 0 0 0 0 128 20 308fc8 0 - ? 0:00 swapper 141 S 0 1 0 0 168 20 95c380 81 7ffe6000 ? 0:00 init 3 S 0 2 0 0 128 20 8ae800 0 30afb0 ? 0:00 vhand 3 S 0 3 0 0 128 20 8aeb00 0 2cb050 ? 0:00 statdaemon 3 S 0 4 0 0 128 20 8aee00 0 30ad30 ? 0:00 unhashdaemon 3 S 0 7 0 0 -32 20 95c100 0 3082b4 ? 0:00 ttisr 3 S 0 13 0 0 153 20 95c680 0 3085cc ? 0:00 lvmkd 3 S 0 14 0 0 153 20 95cb00 0 3085cc ? 0:00 lvmkd 3 S 0 15 0 0 153 20 95cd80 0 3085cc ? 0:00 lvmkd 3 S 0 16 0 0 153 20 95ce80 0 3085cc ? 0:00 lvmkd 3 S 0 17 0 0 100 20 96a300 0 - ? 0:00 nvsisr 3 S 0 18 0 0 100 20 96a480 0 30b438 ? 0:00 supsched 3 S 0 19 0 0 100 20 96a980 0 308c54 ? 0:00 strmem 3 S 0 20 0 0 100 20 96ac80 0 30aff8 ? 0:00 strweld 1 S 0 486 1 0 158 20 973300 74 570d40 console 0:00 sh 1 R 0 527 486 4 179 20 a00300 20 - console 0:00 ps 1 S 0 316 1 0 155 20 9bbb80 14 31fab8 ? 0:00 ptydaemon 1 S 0 231 1 0 154 20 9cae00 5 307814 ? 0:00 syncer 1 S 0 307 1 0 154 20 9dd780 14 30a918 ? 0:00 syslogd 1 S 0 375 1 0 168 20 9e4700 20 7ffe6000 ? 0:00 inetd 1 S 0 464 1 0 154 20 a00780 16 9a87aa ? 0:00 cronNot all flag bits are documented in ps(1); undocumented flag bits include:
The list of non-system processes include:
By examining the man pages available for these daemons we determine that
we need most of them. As mentioned earlier, you can disable
inetd if you have no inetd-launched services. I suppose
cron could be disabled if you do not plan to have any cron
jobs, but that seems unlikely. ptydaemon is a mystery, since
it does not have a man page. A little detective work leads us to the
belief that it may only be used by vtydaemon, which we are not
using. We decide to kill it and see if we can still login to the system
remotely (we temporarily enable telnetd to test this). This
works fine, so we decide to permanently disable the startup of
ptydaemon.
Set the PTYDAEMON_START environment variable to 0 in /etc/rc.config.d/ptydaemon:
PTYDAEMON_START=0
# find / \( -perm -4000 -o -perm -2000 \) -type f -exec ll {} \;You'll probably see around 100 or so files listed. You may notice that there are two sets of LVM commands, each with greater than 20 links, which are set-uid root. Also, the SD commands are set-uid root. The following permission changes will greatly reduce the size of your set-id list:
# chmod 500 /usr/sbin/swinstall # chmod 500 /usr/sbin/swreg # chmod 500 /usr/sbin/swpackage # chmod 500 /usr/sbin/vgcreate # chmod 500 /sbin/vgcreateThe following command will remove the set-uid and set-gid bits from all files:
# find / \( -perm -4000 -o -perm -2000 \) -type f -exec chmod 500 {} \;Then you can selectively add set-id bits back as needed to specific programs that need to be executed by non-privileged users. These programs may include:
The commands you choose to leave set-id depend on the specific use and
design of your bastion host. Let's say that the bastion host is a
firewall gateway, where a few administrators will login via a unique,
personal login, then su to root to manage the gateway. Here,
/usr/bin/su may be the only program on the system that needs to
be set-uid. On the other hand, if the bastion host is a web server,
where webmasters do not have root privilege, you may want to permit the
use of specific set-id commands, like bdf, uptime and
ping.
# find / -perm -002 ! -type l -exec ll -d {} \;We don't display symbolic links with the write other bit set because the mode bits are not used for permission checking.
One approach is to remove the write other bit from all files then selectively add it back to those files and directories where it is necessary. The following can be executed to remove the write other bit from all files with it set:
# find / -perm -002 ! -type l -exec chmod o-w {} \;Now we open up the permissions of files that need to be writable by other users:
# chmod 1777 /tmp # chmod 1777 /usr/tmp # chmod 1777 /var/preserve # chmod 666 /dev/nullNote that we also set the sticky bit (01000) in publicly writable directories like /tmp and /usr/tmp. This prevents unprivileged users from removing or renaming files in the directory that are not owned by them (see chmod(2)).
For our sample s700, 10.20 host, at the time of this writing, the current security patches are:
s700 10.20:PHCO_10048 s700_800 10.20 LVM commands cumulative patch PHCO_10274 s700_800 10.20 passwd(1) cumulative patch PHCO_8654 s700_800 10.20 expreserve(1) patch PHCO_9597 s700_800 10.20 chfn(1) cumulative patch PHCO_9602 s700_800 10.20 chsh(1) cumulative patch PHCO_9605 s700_800 10.10-20 cumulative newgrp(1) patch PHKL_9580 s700 10.20 direct audio app's can panic system PHNE_10010 s700_800 10.20 ftpd(1M) cumulative patch PHNE_10011 s700_800 10.20 kftpd(1M) cumulative patch PHNE_10365 s700_800 10.20 ppl(1) cumulative patch PHNE_10638 s700_800 10.20 rlogin(1M) and rlogind(1M) cumulative patch PHNE_9106 s700 10.20 ARPA Transport cumulative patch PHNE_9219 s700_800 10.20 rdist(1) cumulative patch PHSS_9117 s700_800 10.20 Glance B.10.13 fix error file PHSS_9669 s700_800 10.20 MPower/Web 1.1 movemail point patch PHSS_9773 s700_800 10.X MPower 2.03 file permissions patch PHSS_9803 s700_800 10.20 CDE Runtime Mar97 PatchEach patch for a product currently installed on the system should be analyzed to determine if it needs to be installed. You can get each patch shar file, and look at the patch .text file for details about the patch, including dependencies, filesets effected, and files patched. You can determine filesets installed on the system by executing swlist -l fileset.
Just because a patch exists doesn't mean that you need to install it. For example, all the expreserve patch does is remove the set-uid bit from the expreserve executable. You may have already done that earlier. Some patches may fix buffer overrun defects in set-uid root commands (e.g. the chfn and chsh patches). If they are no longer set-uid you can choose not to install them. If you're not sure whether a particular patch needs to be installed, it's best to just install it.
After installing patches, you should examine set-id programs and file permissions again. The patch installation process may undo some of the permission changes you performed previously.
# nettune -s ip_forwarding 0
The following adb sequence pokes ip_block_source_routed to true in the running kernel:
echo 'ip_block_source_routed/W1'|adb -w /stand/vmunix /dev/kmem
BOOT_ADMIN> boot scsi.2.0 isl ISL> ode ODE> copyutil COPYUTIL> backup Enter the Disk Index ([q]/?): 0 Enter the Tape Index ([q]/?): 2 Use data compression? (y/[n])? yNext create a level 0 backup of the system; I tend to use tar:
# cd / # tar c .
[2] D. Brent Chapman and Elizabeth D. Zwicky, "Building Internet Firewalls", O'Reilly & Associates, September 1995.
[3] Vic Abell's lsof (LiSt Open Files), ftp://vic.cc.purdue.edu/pub/tools/unix/lsof/.
[4] HP-UX patches are available via anonymous FTP in North America at ftp://i3107ffs.external.hp.com/hp-ux_patches/; and Europe at ftp://gvaweb7.net.external.hp.com/hp-ux_patches/.
[5] The HP-UX Patch Security Matrix is available via anonymous FTP at ftp://i3107ffs.external.hp.com/export/patches/hp-ux_patch_matrix.
[6] HP Security Bulletin #60, "SYN Flooding Security Vulnerability in HP-UX", is available at the HP Electronic Support Center, http://us-support.external.hp.com/.
HEWLETT-PACKARD DOES NOT WARRANT THE ACCURACY OR COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
$Id: bastion.html,v 1.2 1999/10/14 10:53:50 stevesk Exp $