Akadia Information Technology

Relay and DNS configuration tips for Sendmail
How to setup IP-Aliasing ?
Using RPM (RedHat Package Manager)
RECODE Character Set Converter
Routing aufsetzen
Kermit auf Linux installieren
Neue SCSI Harddisk anschliessen
Grafik Library für Perl installieren (GD.pm)
Shared Libraries konfigurieren
Tracing System Calls
Search Engine ht://dig for Apache / Linux
How to setup Apache as a Proxy HTTP Server ?
How to setup Linux as a Router / Firewall
Collection of (RedHat) Linux Administrating Tools
How to serve several domains with one IP-address ?
Debugging Network Problems with TCPDUMP
Setup native MS Window Manager with Exceed
RedHat Linux Hardening
Common Unix Tools and Shell Scripts
Sendmail Tips (Architecture, Troubleshooting)
Postfix Tips (Architecture, Troubleshooting)
Linux SYSLOGD Performance
Managing Linux Services (Daemons)
LSOF - list open files, directories, streams, sockets
Make your Linux System less vulnerable
Automatically rotating your Log Files
How to install SCSI Ultra 320 Support on RedHat Linux
Basic Apache Security Hardening
Read-only files that even root can't manipulate
Mounting Windows Shares on Linux using Samba
Replace TraceRoute with TcpTraceroute

Talk to interactive Programs using Expect

How to setup IP-Aliasing ?

Usually a certain Network Card is asscociated with one IP-Adress, this is the default. However it is possible to setup more than one IP-Adress for one Network Card, therefore you can connect a host with one physical card to severals IP-Subnets. Routing is done over the same physical card, but with different IP-Adresses, this is so called "Poor Man Routing".

IP-Aliasing for RedHat Linux

Setup IP-Aliasing using the Tool netcfg

$ netcfg
  Click Button "Alias"         Click here to see the Screendump
  Enter IP-Adress (Alias)      Click here to see the Screendump

Check IP-Aliasing

$ ifconfig      (Show currently configured network cards)
$ route         (Display current routing table)
$ netstat -nr   (Display current routing table)

IP-Aliasing for NT4

- Click Settings, Control Panel, Network
- Choose Protocols, TCP/IP-Protocol, Properties, Advanced
- Enter IP-Address (Alias) and / or Gateway

IP-Aliasing for SUN Solaris

# How to setup IP-Alias on SUN Solaris

1. Setup File /etc/hostname.hme0:1 for the second IP-Address

   cat /etc/hostname.hme0:1


2. Insert IP-Address in /etc/hosts

   # Internet host table
   #      ux-portal1       # IP-address on hme0:0      ldap             # IP-alias on hme0:1

3. Start alias IP-Address on Interface in /etc/rc2.d

   S99ipalias -> ../init.d/ipalias

   # Akadia AG, Arvenweg 4, CH-3604 Thun
   # ----------------------------------------------------------------------
   # File:       ipalias
   # Autor:      Martin Zahn / 10.05.2000
   # Purpose:    Setup second IP address on hme0:1
   # ----------------------------------------------------------------------

   if [ -f /etc/hostname.hme0:1 ]
     case "$1" in

       'start')  # Start second IP address on hme0:1

                 echo "Start multi-homed server for UX-ALIAS1 on hme0:1"
                 ifconfig hme0:1 up

        'stop')  # Stop second IP address on hme0:1

                 echo "Stop multi-homed server for UX-ALIAS1 on hme0:1"
                 ifconfig hme0:1 down

4. Check IP-Address on second Interface

   ifconfig -a

Using RPM (RedHat Package Manager)

In general, normal usage of the rpm command can be summarised as follows:


To install a package: rpm -ivh <filename>

$ rpm -ivh somepackage.1.1-4.i386.rpm

To upgrade a package: rpm -Uvh <filename>

$ rpm -Uvh somepackage.1.1-5.i386.rpm

To remove a package: rpm -e <packagename>

$ rpm -e somepackage

Also for upgrading or installing some packages you may need to use additional flags to force the install happen. It is only recommended to use these if you know why these flags were needed.

--force will overwrite files that are owned by other packages.
--nodeps will install even if the package needs packages that were not installed.


To see if a package is installed: rpm -q <packagename>

$ rpm -q somepackage

To get info on an installed package: rpm -qi <packagename>

$ rpm -qi somepackage

To list which files belong to a package: rpm -ql <packagename>

$ rpm -ql somepackage

To see what package a file belongs to: rpm -qf <path-to-filename>

$ rpm -qf /usr/bin/some_executable

One can usually join various query commands together, so rpm -qil will give info and list all the files in the package.
To look in a rpm filename that isnt installed, you tag on the p to the query line.

$ rpm -qilp somepackage.1.1-4.i386.rpm

will list the information and the files contained in somepackage.

More Advanced

More advanced usages can be found in the man page for rpm and at the web site: ftp.rpm.org


To see what files on the system may have changed from their initial settings you can use
RPM, to check up on them.

$ rpm -Va

will give you a list of all files that have changed in one form or another since the package it is associated was installed. This can be a lot of files (and a lot may be changed due to post installation work). To just see what packages have changed so that you can verify them more individually, you can do the following:

$ rpm -Va | awk ''{print $2}'' | xargs rpm -qf | sort -u &> /tmp/file1

Then look in the file /tmp/file1 for which packages have had changes from them.

RECODE Character Set Converter 

Das Programm RECODE dient zur Konvertierung von Character Sets, beispielsweise um einen Text der auf einem PC erstellt wurde mit einem bestimmten Codepage in ein ISO-Format für Unix umzuwandeln. Dabei werden Carriage Return und Newlines korrekt umformatiert. Das Unixtool dos2unix verwendet ebenfalls RECODE in der Form recode ibmpc:lat1, und unix2dos verwendet recode lat1:ibmpc

Recode als RPM

Recode kann als fertiges RPM-Package von http://rpmfind.net/linux/rpm2html/search.php?query=recode heruntergeladen werden.

$ rpm -ivh recode-3_4-3_i386.rpm
$ rpm -ql recode


GNU Recode (Original) selber bauen

Recode von herunterladen:

-rw-r--r-- 1 ftp ftp 324047 Nov 6 1994 recode-3.4.tar.gz
-rw-r--r-- 1 ftp ftp 879673 Jun 13 1999 recode-3.5.tar.gz
-rw-r--r-- 1 ftp ftp 1751886 Jan 22 19:38 recode-3.6.tar.gz

The simplest way to compile this package is:

  1. Change to the directory containing the package's source code and type ./configure to configure the package for your system. If you're using csh on an old version of System V, you might need to type sh ./configure instead to prevent csh from trying to execute configure itself. Running configure takes awhile. While running, it prints some messages telling which features it is checking for.

  2. Type make to compile the package.

  3. Optionally, type make check to run any self-tests that come with the package.

  4. Type make install to install the programs and any data files and documentation.

  5. You can remove the program binaries and object files from the source code directory by typing make clean. To also remove the files that configure created (so you can compile the package for a different kind of computer), type make distclean. There is also a make maintainer-clean target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution.


PCNFS wird mit RedHat 5.1 nicht mitgeliefert, da Samba die bessere Alternative ist. Wir benutzen jedoch PCNFS weiterhin und haben deshalb das Binary RPC.PCNFSD von Linux 1.2.12 auf RedHat in das Directory /usr/sbin kopiert. Anschliessend muss im File /etc/rc.d/init.d/nfs der Eintrag für PCNFSD gemacht werden. Exportierte Directories werden in /etc/exports eingetragen.

$ rpm -ivh pcnfsd-2_0lsh-6shadow_i386.rpm
$ rpm -ql pcnfsd

# See exports(5) for a description.
# This file contains a list of all directories exported to other computers.
# It is used by rpc.nfsd and rpc.mountd.
/ arkum(rw,insecure,no_root_squash)

Nun muss NFS gestoppt und neu gestartet werden:

cd /etc/rc.d/init.d
nfs stop
nfs start
rpcinfo -p

program vers proto port
100000 2 tcp 111 rpcbind
100000 2 udp 111 rpcbind
300019 1 tcp 963 amd
300019 1 udp 964 amd
100005 1 udp 635 mountd
100005 2 udp 635 mountd
100005 1 tcp 635 mountd
100005 2 tcp 635 mountd
100003 2 udp 2049 nfs
100003 2 tcp 2049 nfs
150001 1 udp 611 pcnfsd
150001 2 udp 611 pcnfsd
150001 1 tcp 614 pcnfsd
150001 2 tcp 614 pcnfsd

Routing aufsetzen 

Mit dem Command route add .... wird eine statische route eingerichtet. Unter RedHat Linux verwendet man am besten das "Network Panel" (einloggen als root und startx). Damit werden die Routen im File /etc/sysconfig/static-routes eingetragen. Zur Kontrolle Linux stoppen und starten.

eth0 net netmask gw

netstat -nr

Kernel IP routing table
Destination     Gateway          Genmask          Flags   MSS Window  irtt Iface   U       1500 0           0 eth0

Damit werden die Hosts in den Netzwerken "Destination" via Gateway erreicht.

Kermit auf Linux installieren 

  1. Binary mit Konfigurationsfiles herunterladen
    ftp://kermit.columbia.edu/kermit/bin/ckuker.linux-2.1.13-i386-elf   (Binary)
    ftp://kermit.columbia.edu/kermit/archives/cku192txt.tar.gz (Konfigurationsfiles)

  2. Binary umbenennen
    After obtaining the desired file, rename (mv) it to "wermit" and then read the ckuins.doc file (among the text files), which suggests some tests. If it seems to work OK, follow the directions in that file for installing it on your system.

  3. Installing the Kermit Files
    cp ckuker.linux-2.1.13-i386-elf /usr/local/bin/kermit
    chmod 775 /usr/local/bin/kermit
    cp ckuker.nr /usr/man/manl/kermit.l
    cp ckermit.ini $HOME/.kermrc
    chown zahn:dba $HOME/.kermrc

Neue SCSI Harddisk anschliessen 

SCSI Adresse kontrollieren, am besten beim Booten mit CTRL-A in das BIOS des SCSI Adapters vezweigen.

  1. Partitionen anlegen mit fdisk

    fdsik /dev/sdc

    - Alle Partitionen loeschen
    - Partitionen anlegen
    - Eventuell SWAP Partition anlegen mit Type=82

  2. Filesystem anlegen

    mkfs -V -t ext2 /dev/sdc1

  3. SWAP Partition enablen

    mkswap /dev/sdc2

  4. Eintrag in /etc/fstab vornehmen

Shared Libraries konfigurieren (nur für Oracle 8.0.5 notwendig)

Shared Libraries werden unter LINUX nicht mit über die Environment Variable LD_LIBRARY_PATH definiert, sondern in der Konfigurationsdatei /etc/ld.so.conf eingetragen:

run-time link bindings aktivieren:
ldconfig -v
ldconfig -p

Tracing System Calls 

You can trace system calls with truss on Solaris an strace on Linux

strace svrmgrl

Search Engine ht://dig for Apache / Linux 

The ht://Dig system is a complete world wide web indexing and searching system for a small domain or intranet. We use ht://Dig on our Website to search for the contents of all the publicly available WWW documents.

Download from: http://www.htdig.org


$ gunzip < htdig-3.1.4.tar.gz | tar xvf -
$ ./configure
Edit the File CONFIG manually
$ make
$ make install


ht://Dig requires a configuration file and several HTML files to operate correctly. Fortunately, when ht://Dig is installed, a very reasonable configuration is created and in most cases only minor modifications to the files are necessary. Below, we will use the variables that were set in CONFIG to designate specific paths.

Standard files:

  • ${CONFIG_DIR}/htdig.conf
  • ${SEARCH_DIR}/search.html
  • ${COMMON_DIR}/header.html
  • ${COMMON_DIR}/footer.html
  • ${COMMON_DIR}/nomatch.html
  • ${COMMON_DIR}/syntax.html

How to setup Apache as a Proxy HTTP Server ? 

The famous Apache Web Server has one very useful configuration option -- the Proxy Server. With this option you have the following advantages:

  • You have a direct access to the internet with a HTTP server running and you want to offer another HTTP Server for one of your friend under his name. Your friend is connected with you through a LAN or WAN connection, but your friend has no direct internet connection.

  • You want to hide your "real" HTTP Server IP-Address behind a Proxy HTTP Server.

  • You want to cache the most used HTML pages used in your Intranet for your clients.

The installation and configuration of the Apache HTTP Proxy Service is very easy. In the following example we show you the necessary entries in the Apache configurationfile httpd.conf for the first case (Serving a HTTP Proxy Server for your friend).

Let's suppose, that your HTTP Server with direct internet access is on For your friend HTTP server you establish the IP-Address on Port 80. Of course, this HTTP Server is not only a Proxy Server, it's a real full featured Apache Server with the Proxy module enabled. Your friend has his own Apache Server on and you are connected through a LAN connection with this server. Specify the following Proxy Server directives within a virtual host entry in the configurationfile httpd.conf for your HTTP Server.

  ServerAdmin   yourname@yourdomain.domain
  ServerName    yourfriend.yourdomain.domain
  ServerPath    /yourfriend
  ErrorLog      logs/yourfriend.error_log
  TransferLog   logs/yourfriend.access_log
  ProxyRequests On
  ProxyPass     /


E-Mail address for automatic pages generated when some errors occur.


You must specify a hostname and IP-Address for your friends machine. The hostname must no be equivalent with the real hostname of this machine on your friends site.


Let your friends name be accessed through the following URL:


Logfile for yourfriend's site


Accesslog  for yourfriend's site


This directive turns proxy serving on for this virtual host


This directive passes requests to your friends HTTP Server on


How to setup Linux as a Router / Firewall 

One of the great features of Linux, is it's easy installation and configuration as a IP-Router and Firewall. You can masquerade the internal LAN so called Trusted Network, which is often in the private range (no routable range, e.g. 192.168.x.x). There are two steps needed for this configuration, which we want to show you in the next example, the trusted (or masqueraded) network is The needed steps are as follows:

  • Install two Network Cards in the PC, and attach an IP-address for each of this cards.

  • Configure the IP-Masquerading software on this Linux machine.

Install two Network Cards in the PC, and attach an IP-address for each of this cards

Install the network cards and attach an IP-Address using the following scripts in /etc/sysconfig/network-scripts for RedHat Linux.

Script: if-cfg-eth0 (first LAN card)


Script: if-cfg-eth1 (second LAN card)


After you have rebooted the machine, check if both LAN devices are properly configured with the command ifconfig.

eth0 Link encap:Ethernet HWaddr 00:01:02:0F:1A:85
inet addr: Bcast: Mask:
RX packets:146003 errors:0 dropped:0 overruns:1 frame:0
TX packets:100427 errors:0 dropped:0 overruns:0 carrier:0
collisions:500 txqueuelen:100
Interrupt:10 Base address:0x6e00

eth1 Link encap:Ethernet HWaddr 00:01:02:0F:1B:3C
inet addr: Bcast: Mask:
RX packets:13249 errors:0 dropped:0 overruns:0 frame:0
TX packets:14200 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
Interrupt:15 Base address:0x6d00

Configure the IP-Masquerading software on this Linux machine

Install the Script rc.firewall in /etc/rc.d/init.d, then create a symblic link in /etc/rc.d/rc3.d.

lrwxrwxrwx 1 root root S91firewall -> ../init.d/rc.firewall

# rc.firewall
# Enable IP Masquerade (NAT = Network Address Translation,
# SUA = Single User Access)on this host

# Needed to initially load modules

/sbin/depmod -a

# Supports the proper masquerading of FTP file
# transfers using the PORT method

/sbin/modprobe ip_masq_ftp

# CRITICAL:  Enable IP forwarding since it is disabled
# by default. Redhat Users: you may try changing the options
# in /etc/sysconfig/network from:
# FORWARD_IPV4=false to FORWARD_IPV4=true

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

# MASQ timeouts
#  2 hrs timeout for TCP session timeouts
# 10 sec timeout for traffic after the TCP/IP "FIN" 
#        packet is received.
# 160 sec timeout for UDP traffic (Important for 
#         MASQ'ed ICQ users)

/sbin/ipchains -F
/sbin/ipchains -M -S 7200 10 160

# Enable simple IP forwarding and Masquerading
#  NOTE:  The following is an example for an internal
#  LAN address in the 192.168.138.x network with a 
# or a "24" bit subnet mask.
# Please change this network number and subnet mask
# to match your internal LAN setup

/sbin/ipchains -P forward DENY
/sbin/ipchains -A forward -s -j MASQ

# Now show current settings

NAT=`cat /proc/sys/net/ipv4/ip_forward`
if [ "$NAT" = "1" ]
  echo "IP Masquerading is ON"
  echo "IP Masquerading is OFF"

/sbin/ipchains -L

Collection of (RedHat) Linux Administrating Tools 

Actually, Linux do not offer a consistent view for administrating the operating system. Even worse, the various derivates distribute their Linux software with different tools. In the following article, we have collected the useful standard tools for RedHat Linux 6.x

Redhat Linux offers three different places for their admin tools which are:

  • Character oriented tools, which can be used from the command line of your concole.

  • X11 oriented tools (Requires X11)

  • Control-Panel, Graphical Interface that hosts a number of RedHat tools

Tool X11 Control
Xconfigurator     X Xconfigurator generates an XF86Config file, which is used to configure X11. XF86Config is located in: /usr/X11R6/lib/X11
wmconfig     X Creates resource files for use in your home directory for the X window managers.

wmconfig --output=fvwm > .fvwm2rc

chkconfig --list
    X Updates and queries runlevel information for system services
ntsysv     X Simple interface for configuring runlevels
comanche X X   Tool to configure Apache Web Server
fetchmailconf X X   Configure E-Mail retrieval
glint X X   Graphical User Interface to Package Manager
helptool X X   Search Manual Pages
kdbconfig     X Configure your Keyboard
kernelcfg X X   Load, unload Kernel Moduls
linuxconf   X   Overall, total configuration tool for RedHat Linux
modemtool X X   Create /dev/modem symbolic Links used for Modem Devices Files
mouseconfig     X Configure your mouse
netcfg X X   Install, configure, administer network interfaces
printtool X X   Install, configure Printers
setup     X Dialog for ntsysv, X, kdb, mouse, snd and time configuration tools
sndconfig     X Configure your sound card
timeconfig     X Setup your timezone
timetool X X   Set system date and time
tksysv X X   Configure system services

Ways to shutdown RedHat Linux

  • Properly shutdown the system immediately
    shutdown -h now

  • Restart after Shutdown
    shutdown -r now

  • Use Linuxconf to shutdown (preferred)
    linuxconf -shutdown

  • Quick Reboot

Split, Concatenate and Checksum big Files

Linux offers the utility cksum, to compute a cyclic redundancy check (CRC). Therefore the easiest way to split, concatenate and check big files is as follows.

  • First check the CRC on the original file
    cksum ALL_FILES.tar.gz
    4188925921 4113714 ALL_FILES.tar.gz

  • Split the big file into smaller pieces
    split -b1m ALL_FILES.tar.gz ALL_FILES.tar.gz.

  • Concatenate the pieces to one file
    cat ALL_FILES.tar.gz.?? > all_files.tar.gz

  • Again check the CRC on the concatenated File
    cksum all_files.tar.gz
    4188925921 4113714 all_files.tar.gz

How to serve several domains with one IP-address ? 

The answer is ... use Apache's virtual host support. Apache was one of the first servers to support IP-based virtual hosts right out of the box. Versions 1.1 and later of Apache support both, IP-based and name-based virtual hosts (vhosts). The latter variant of virtual hosts is sometimes also called host-based or non-IP virtual hosts.

Name Based Virtual Hosts

Using Name Based Virtual Hosts is quite easy. The notable difference between IP-based and name-based virtual host configuration is the NameVirtualHost directive which specifies an IP address that should be used as a target for name-based virtual hosts.

For example, we use both www.akadia.ch and www.arkum.ch at the IP address We simply add to one of the Apache configuration files (most likely httpd.conf) code similar to the following:


    ServerName www.akadia.ch
    DocumentRoot /www/akadia

    ServerName www.arkum.ch
    DocumentRoot /www/arkum

Of course, any additional directives can (and should) be placed into the <VirtualHost> section. To make this work, all that is needed is to make sure that the names www.akadia.ch and www.arkum.ch are pointing to the IP address

When you specify an IP address in a NameVirtualHost directive then requests to that IP address will only ever be served by matching <VirtualHost>s. The "main server" will never be served from the specified IP address. If you start to use virtual hosts you should stop to use the "main server" as an independent server and rather use it as a place for configuration directives that are common for all your virtual hosts. In other words, you should add a <VirtualHost> section for every server (hostname) you want to maintain on your server.

More information can be found at www.apache.org

  Debugging Network Problems with TCPDUMP 

The tcpdump program (dump traffic on a network) can be used to view network traffic, and, if necessary, its output can be parsed do deduce the source of excess packets. You can get the tcpdump-smb program, an extension to tcpdump, from the Samba Website (www.samba.org). It's used to investigate SMB networking problems over NetBUI and TCP/IP. Typically, it must be run as root due to the hardware access level and the information it provides. The following examples shows a debugging session for Samba, but tcpdump can be used for any other networking problems.

Capture all SMB packets to debug Name Resolution Problems (WINS)

# tcpdump port 137

tcpdump: listening on eth0
15:33:15.437022 opal.netbios-ns >
Name=AKADIA NameType=0x1D (Master Browser)

In the example above, the machine opal sends a broadcast request to the broadcast address for the NetBIOS name resolution.

Capture all SMB packets to debug Network Neighborhood Browsing Problems

# tcpdump port 138

tcpdump: listening on eth0
15:46:19.420347 rabbit.netbios-dgm >
>>> NBT UDP PACKET(138) Res=0x110A ID=0x3B1F IP= Port=138 Length=183 Res2=0x0
SourceName=RABBIT NameType=0x00 (Workstation)

Capture all SMB packets to debug NetBIOS Session Problems

# tcpdump -s 100 port 139

tcpdump: listening on eth0
15:51:00.155440 akadia01.10032 > rabbit.netbios-ssn: P 3139570112:3139570160(48) ack 3279569702 win
8721NBT Packet
NBT Session Packet

SMB Command = 0x10
Error class = 0x0
Error code = 0
Flags1 = 0x18
Flags2 = 0x3
Tree ID = 2
Proc ID = 51966
UID = 101
MID = 3200
Word Count = 0

While the above command is running, issue a net view command from a windows client and you will see an output similar the the shown above.

To print traffic between rabbit and either paragon or diamond

# tcpdump host rabbit and \( paragon or diamond \)

Telnet from paragon to rabbit and watch the output.

  How to setup native MS Window Manager with Exceed ? 

If you are using Hummingbird's Exceed X windows emulator while installing and using Oracle8i, or using other X-Windows tools, set the window manager to run in "Native" mode so that Microsoft Windows functions as the window manager.

While Oracle supports the use of Exceed for installing and configuring products, users should be aware of the following common problems with using this X Windows Emulator for installation:

There is a bug in the way Exceed handles screen coordinates. The installer window and related installer dialogs or configuration assistants may encounter display problems when run through the emulator. These display problems may include the sudden truncation of the main window when clicking the [Next] button during the install, rendering the screen unreadable, or the expansion of an installer window such that the dialog buttons are displayed off the screen and are thus not selectable with a mouse. In such cases, users must exit the entire X Windows session and start a new session to fix the problem. Opening a new shell and re-running the installer from the shell does not fix the problem.

There are consistent display problems with the AQ Database Information dialog which is part of the Oracle Applications InterConnect installation. The last text field on this dialog which prompts for "Consumer Name:" appears truncated when viewed through Exceed. This dialog displays as expected when viewed through native X Windows on Sun SPARC Solaris.

To correct any problems with hidden dialog fields, try the following:

  1. Select the xconfig application under the Exceed Program Group from the Windows Start Menu and click the "Fonts" Applet.
  2. Click the [Font Database] button in the "Font Settings" dialog box.
  3. Uncheck the "Automatic Font Substitution" option in the "Font Database" dialog box.
  4. Click the [Add...] button. The "Add Font Directory" dialog box is displayed.
  5. Click the [Server] radio button in the "Add Font Directory" dialog box.
  6. Enter the hostname for your machine in the "Host Name" field in the "Add Font Server" dialog box. Leave all the other entries at their default settings.

  7. Click [OK] and [Close] on all dialogs to save the settings.

RedHat Linux Hardening 

Here are some hints how to hardening RedHat Linux - this should be done from time to time.

mkbootdisk --device /dev/fd0 2.2.14-5.0smp

Create a Boot Floppy for an emergency. The Floppy in the first slot /dev/fd0. The Kernel is 2.2.14-5.0smp which can be verified with uname -r

chkconfig --list

Active services can be examined with

chkconfig xinetd off

Deactivate the internet daemon xinetd, which starts other services on demand like TELNET or FT.

rpm -Va

Verifying a package compares information abaout files installed from a package with the same information from the original package. The following characters denote failure of certain tests:

5 -- MD5 checksum
S -- File size
L -- Symbolic link
T -- File modification time
D -- Device
U -- User
G -- Group
M -- Mode (Perm & File Type)

Linux SYSLOGD Performance  

LINUX syslogd uses synchronous writes by default, which is very expensive. For services such as mail it is recommended that you disable synchronous logfile writes by editing /etc/syslog.conf and by prepending a ''-'' to the logfile name.

You may prefix each entry with the minus ''-'' sign to omit syncing the file after every logging. Note that you might lose information if the system crashes right behind a write attempt. Nevertheless this might give you back some performance, especially if you run programs that use logging in a very verbose manner.

mail.*         -/var/log/mail.log

Send a "kill -HUP" to the syslogd to make the change effective.

Managing Linux Services (Daemons) 

The linux commandline tool chkconfig updates and queries runlevel information for system services.


chkconfig --list [name]
chkconfig --add name
chkconfig --del name
chkconfig [--level levels] name <on|off|reset>
chkconfig [--level levels] name

chkconfig provides a simple command-line  tool  for  main taining  the  /etc/rc.d  directory  hierarchy by relieving system administrators of the task of directly manipulating the numerous symbolic links in those directories.

List all services

$ chkconfig --list

amd           0:off   1:off   2:off   3:off   4:on    5:off   6:off
httpd         0:off   1:off   2:off   3:on     4:on    5:on    6:off
apmd          0:off   1:off   2:on    3:off   4:on    5:off   6:off
arpwatch      0:off   1:off   2:off   3:off   4:off   5:off   6:off
atd           0:off   1:off   2:off   3:on     4:on    5:on    6:off
autofs        0:off   1:off   2:off   3:off   4:off   5:off   6:off
named         0:off   1:off   2:off   3:on     4:off   5:off   6:off
bootparamd    0:off   1:off   2:off   3:off   4:off   5:off   6:off
keytable      0:off   1:off   2:on    3:on    4:on    5:on    6:off
crond         0:off   1:off   2:on    3:on    4:on    5:on    6:off
syslog        0:off   1:off   2:on    3:on     4:on    5:on    6:off
netfs         0:off   1:off   2:off   3:off   4:on    5:on    6:off

Activate INETD in runlevel 3 ( 3 = the most important )

$ chkconfig --level 3 inet on

LSOF - list open files, directories, streams, sockets  

LSOF is a utility that lists information about files opened by processes. An open file may be a regular file, a directory, a block special file, a character special file, an executing text reference, a library, a stream or a network file (Internet socket, NFS file or UNIX domain socket).

We think, that is utility is very handy, therefore you find some examples below. For a more extensive set of examples, documented more fully, click here. Most of the information in this tip is from Vic Abell <abe@purdue.edu>.

A Quick Start for LSOF

Finding Uses of a Specific Open File
Finding Open Files Filling a File System
Finding Processes Blocking Umount
Finding Listening Sockets
Finding a Particular Network Connection
Finding Files Open to a particular Command
Listing Open NFS Files
Listing Files Open by a Specific Login

Finding Uses of a Specific Open File

Often you're interested in knowing who is using a specific file. You know the path to it and you want lsof to tell you the processes that have open references to it. Simple -- execute lsof and give it the path name of the file of interest. This only works if lsof has permission to get the status.

$ lsof /etc/passwd

Finding Open Files Filling a File System

Oh! Oh! /tmp is filling and ls doesn't show that any large files are being created. Can lsof help? Maybe. If there's a process that is writing to a file that has been unlinked, lsof may be able to discover the process for you. You ask it to list all open files on the file system where /tmp
is located. Sometimes /tmp is a file system by itself. In that case

$ lsof /tmp

is the appropriate command. If, however, /tmp is part of another file system, typically /, then you may have to ask lsof to list all files open on the containing file system and locate the offending file and its process by inspection

$ lsof / | more


$ lsof / | grep ...

Finding Processes Blocking Umount

When you need to unmount a file system with the umount command, you may find the operation blocked by a process that has a file open on the file systems. Lsof may be able to help you find the process. In response to:

$ lsof <file_system_name>

Finding Listening Sockets

Sooner or later you may wonder if someone has installed a network server that you don't know about. Lsof can list for you all the network socket files open on your machine with:

$ lsof -i

The -i option without further qualification lists all open Internet socket files. You can add network names or addresses, protocol names, and service names or port numbers to the -i option to refine the search. (See the next section.)

Finding a Particular Network Connection

When you know the source or destination of a network connection whose open files and process you'd like to identify, the -i option may help. If, for example, you want to know what process has a connection open to or from the Internet host named aaa.bbb.ccc, you can ask
lsof to search for it with:

$ lsof -i@aaa.bbb.ccc

If you're further interested in a particular protocol -- TCP or UDP -- and a specific port number or service name, you can add those discriminators to the -i information:

$ lsof -iTCP@aaa.bbb.ccc:ftp-data

Finding Files Open to a particular Command

When you want to look at the files open to a particular command, you can look up the PID of the process running the command and use lsof's -p option to specify it.

$ lsof -p <PID>

However, there's a quicker way, using lsof's -c option, provided you don't mind seeing output for every process running the named command.

$ lsof -c <first_characters_of_command_name_that_interest_you>

The lsof -c option is useful when you want to see how many instances of a given command are executing and what their open files are. One useful example is for the sendmail command.

$ lsof -c sendmail

Listing Open NFS Files

Lsof will list all files open on remote file systems, supported by an NFS server. Just use:

$ lsof -N

Note, however, that when run on an NFS server, lsof will not list files open to the server from one of its clients. That's because lsof can only examine the processes running on the machine where it is called -- i.e., on the NFS server. If you run lsof on the NFS client, using the -N option, it will list files open by processes on the client that are on remote NFS file systems.

Listing Files Open by a Specific Login

If you're interested in knowing what files the processes owned by a particular login name have open, lsof can help.

$ lsof -u<login>


$ lsof -u<User ID number>

Make your Linux System less vulnerable 

Here are some guidelines to make linux more stable against hacker attacks.

Stopping services

Despite choosing minimal software during installation. Many services will have to be manually disabled with chkconfig

Active services can be examined with:

$ chkconfig --list

For firewall and DMZ systems you may switch off basically everything, except SSH

$ chkconfig httpd off
$ chkconfig apmd off
$ chkconfig atd off
$ chkconfig xfs off
$ chkconfig pcmcia off
$ chkconfig lpd off
$ chkconfig nfs off
$ chkconfig gpm off
$ chkconfig linuxconf off
$ chkconfig identd off
$ chkconfig portmap off
$ chkconfig rhnsdoff
$ chkconfig sendmail off
$ chkconfig xinetd off

The list of open tcp/udp ports is now VERY small (in fact only SSH is listening):

# netstat -a

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 *:ssh *:* LISTEN
raw 0 0 *:icmp *:* 7
raw 0 0 *:tcp *:* 7

Configuration notes

  • The "init level" should be set to 3 (command line login), rather than 5 (graphical login). If a GUI is needed, it can always be started manually with startx.
  • To login via the 'serial port A' on x86 Hardware, which is useful for troubleshooting, installations and getting to know the command line. Add the following to /etc/inittab.

con:23:respawn:/sbin/getty ttyS0 VC

To allow root to login via this serial port, add ttyS0 to /etc/securetty

echo "ttyS0" >> /etc/securetty


  • Environment such as /.cshrc /.profile /.bashrc /etc/profile /etc/bashrc: set aliases, variables (such as VISUAL, EDITOR and PATH don't include ".") for your favourite shell. Set umask to 077, or 027.

Disk mounting

  • To reduce the risk of trojan horses and unauthorised modifications, in
     /etc/vfstab, mount /var and other data disks with "nosuid".
  • Configure /etc/hosts with a list of critical machines
    (which you don't want resolved via DNS).
  • DNS client (avoid if not needed): add domain name & DNS servers to /etc/resolv.conf. Add a DNS entry for "hosts" in /etc/nsswitch.conf (and remove nis and nisplus entries).

Keyboard security

  • If your hosts are in secured rooms, it might be desirable to disable certain key functions such as the following. To disable hotkey interactive startup, set PROMPT=no in /etc/sysconfig/init.
  • On x86: To allow ctrl-alt-delete to shutdown the system, an entry in /etc/inittab like the following is used:

ca::ctrlaltdel:/sbin/shutdown -t3 -r now

Comment it out and reboot or "killall -HUP init" to activate the change.

  • Use default routes: add the IP address of the router to /etc/sysconfig/network.
  • In /etc/inetd.conf, all services should be disabled: reopen very specific services only if absolutely needed, and adapt /etc/hosts.allow and /etc/hosts.deny.
  • If a sensitive host is to be administered by several people, consider
    using a tool such as sudo.

User Access

If user accounts will be allowed on the system, consider restricting access to:
  • cron: via /etc/cron.allow and cron.deny
    at: via /etc/al.allow and at.deny
  • ftp: Disallowed users are listed in /etc/ftpusers
  • SSH: See /etc/ssh/sshd_config (look for AllowUsers DenyUsers entries) and /etc/hosta.allow
  • General inetd services: /etc/hosts.allow and hosts.deny
  • File system groups: /etc/groups and use file and directly permissions accordingly.

Setup Syslog

  • Setup a syslog server to receive messages from all clients.
  • So, to configure syslog to send all messages to the syslog server, 
    and keep a local copy too:

1. Add an entry to /etc/hosts for the "loghost" loghost loghost.akadia.ch

2. Add the follwoing as the first line of /etc/syslog.conf 
    (important: the two fields are separated by a TAB):

*.*     @loghost

3.  Restart syslog: either reboot, or kill -1 SYSLOG_PID

Filesystems, directories and files

  • Mount filesystems (in /etc/fstab) not containing systems programs nosuid, such as /var.
  • What SUID files are on the system? The find command can be used to list all 
    SUID or SGID   files:

find / -perm -u+s -type f -ls
find / -perm -g+s -type f -ls

Why both touching them? Because they are often e source of weaknesses, and if problems are found in the future, we won't be exposed and we won't have to rush and install patches.

  • rlogin/rsh/rcp are not needed, since we use SSH. Lets restrict access 
    to root & remove SUID

chmod 700 /usr/bin/rcp /usr/bin/rlogin /usr/bin/rsh

  • We only allow root to use cron, at and bring network interfaces up or down:

chmod 700 /usr/bin/crontab /usr/bin/at /usr/sbin/usernetctl

  • Users don't need to be able to mount any devices (non-root users can't 
    use floppies of CDs after this):

chmod ug-s /bin/umount /bin/mount

  • On sensitive systems, only root needs access to account management
    and network debugging

chmod ug-s /usr/bin/chage /usr/bin/gpasswd
chmod ug-s /usr/bin/chsh /usr/bin/chfn
chmod ug-s /usr/sbin/traceroute /bin/ping

  • If no SUID perl scripts are needed, we can remove the SUID bit from perl itself:

chmod ug-s /usr/bin/suidperl /usr/bin/sperl*

Login banners

  • Delete any indications of the system version from /etc/issue and put in a warning about unauthorised use of the system.

mv /etc/issue /etc/issue.orig

  • The other warning banner /etc/motd is emty on RH7, but the same applies.

Integrity checking

  • Tripwire

There are both free and commercial versions. Red Hat x86 is the only Linux for which the Commercial version is officially available (and included for free in RH7). The free version can be tricky to get working correctly and has a few bugs. Source code is provided. The commercial version is a bit pricey (for non Linux users), reports are too verbose (you may need filter scripts), more configuration examples should be provided. It is more stable than the free version, also runs on UNIX and NT and offers enhanced security by cryptographic signing of policy and configuration files. Support (even when paid for) is not great.

  • PGP

Can also be used, by signing files to be protected (creating lots of signature files), then writing a script to check the validity of signatures. This will not catch permission, link, inode or modify date changes though.

MD5 signatures could also be used in a similar way, but the list of MD5 signatures should not be stored on the system being monitored, unless it is PGP signed or encrypted.

Automatically rotating your Log Files 

Uncontrolled growing of log files may fill up important filesystems like /var. One, not documented features under Linux is logrotate, which belongs to the standard RedHat Linux distribution.

Logrotate is designed to ease administration of systems that generate large numbers of log files. It allows automatic rotation, compression, removal, and mailing of log files. Each log file may be handled daily, weekly, monthly, or when it grows too large. Normally, logrotate is run as a daily cron job. It will not modify a log multiple times in one day unless the criterium for that log is based on the log’s size and logrotate is being run multiple times each day, or unless the -f or -force option is used.

Any number of config files may be given on the command line. Later config files may override the options given in earlier files, so the order in which the logrotate config files are listed in is important. Normally, a single config file which includes any other config files which are needed should be used.

Configuration File 

The configuration file for logrotate can be found in /etc/logrotate.conf

# rotate log files daily

# keep 1 day of backlogs
rotate 1

# send errors to
errors martin dot zahn at akadia dot ch

# create new (empty) log files after rotating old ones

# uncomment this if you want your log files compressed

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own lastlog or wtmp -- we'll rotate them here
/var/log/wtmp {
  create 0664 root utmp
  rotate 1

Included Files from /etc/logrotate.d (e.g. apache)

/var/log/httpd/akadia.log {
    /bin/kill -HUP `cat /var/run/httpd.pid 2>/dev/null`
    2> /dev/null || true

/var/log/httpd/error.log {
    /bin/kill -HUP `cat /var/run/httpd.pid 2>/dev/null`
    2> /dev/null || true

For more information type the following commands:

# man logrotate
# man logrotate | col -b > logrotate.txt
# man -t logrotate > logrotate.ps

How to install SCSI Ultra 320 Support on RedHat Linux 


A driver disk adds support for hardware that is not otherwise supported by the installation program. The driver disk could be produced by Red Hat, it could be a disk you make yourself from drivers found on the Internet, or it could be a disk that a hardware vendor (e.g. Adaptec) includes with a piece of hardware.

There is no need to use a driver disk unless you need a particular device in order to install Red Hat Linux. Driver disks are most often used for non-standard or very new CD-ROM drives, SCSI adapters, or NICs. These are the only devices used during the installation that might require drivers not included on the Red Hat Linux CD-ROMs.

How to obtain a Driver Disk for SCSI Ultra 320 Support

Download the Image File from www.adaptec.com (e.g. aic79xx-1.3.5-i686-rh80.img) for RedHat 8.0 or from http://people.freebsd.org/~gibbs/linux/DUD/aic79xx/ for Linux Distributions.

Creating a Driver Disk from the Image File

If you have the image that you need to write to a floppy disk, this can be done from within DOS or Red Hat Linux.

To create a driver disk from a driver disk image using Red Hat Linux:

Insert a blank, formatted floppy disk into the first floppy drive. From the same directory containing the driver disk image do as root:

dd if=aic79xx-1.3.5-i686-rh80.img of=/dev/fd0

To create a driver disk from a driver disk image using DOS:

Insert a blank, formatted floppy disk into the a: drive. From the same directory containing the driver disk image do:

rawrite aic79xx-1.3.5-i686-rh80.img a:

Using a Driver Disk During Installation

Having a driver disk is not enough; you must specifically tell the Red Hat Linux installation program to load that driver disk and use it during the installation process.

A driver disk is different than a boot disk. If you require a boot disk to begin the Red Hat Linux installation, you will still need to create that floppy and boot from it before using the driver disk.

Once you have created your driver disk, begin the installation process by booting from the Red Hat Linux CD-ROM 1 (or the installation boot disk). At the boot: prompt, enter either:

linux dd

The Red Hat Linux installation program will ask you to insert the driver disk. Once the driver disk is read by the installer, it can apply those drivers to hardware discovered on your system later in the installation process.

Basic Apache Security Hardening

The default Apache access for <Directory /> is Allow from All. This means that Apache will serve any file mapped from an URL. It is recommended to limit the directories that can be accessed. The best way to do this is to stop Apache accessing any directory at all, and then enable the directories we want it to be able to access.

We can do this with the followin Directory directive in the http.conf file:

# First, we configure the "default" to be a very
# restrictive set of permissions. Also, for security,
# we disable indexes globally.

<Directory />
   Options None
   AllowOverride None
   <IfModule mod_access.c>
     Order deny,allow
     Deny from all

This tells Apache to stop access to all directories below /. The next task is to allow access to the document root.

DocumentRoot /home/webmail

<Directory /home/webmail>
   Options -All -Multiviews FollowSymLinks Indexes
   AllowOverride None
   <IfModule mod_access.c>
      Order allow,deny
      Allow from all

First we specify where the document root is. Then we use the Directory directive to tell Apache that it is accessible by everyone.

Finally we need to make sure that the .htaccess files cannot be viewed.

# AccessFileName: The name of the file to look for in
# each directory for access control informationAccessFileName .htaccess
# The following lines prevent .htaccess files from being viewed by
# Web clients.  Since .htaccess files often contain authorization
# information, access is disallowed for security reasons.  Comment
# these lines out if you want Web visitors to see the contents of
# .htaccess files.  If you change the AccessFileName directive above,
# be sure to make the corresponding changes here.
# Also, folks tend to use names such as .htpasswd for password
# files, so this will protect those as well.
<IfModule mod_access.c>
<Files ~ "^\.ht">
    Order allow,deny
    Deny from all

These are only very basic hardenings, more can be found in the Book: Hardening Apache

Read-only files that even root can't manipulate

In the Linux ext2 and ext3 filesystems, there are a number of additional file attributes that are available beyond the standard bits accessible through chmod. If you haven't seen it already, take a look at the manpages for chattr and its companion, lsattr.

One of the very useful new attributes is -i, the immutable flag. With this bit set, attempts to unlink, rename, overwrite, or append to the file are forbidden. Even making a hard link is denied (so you can't make a hard link, then edit the link). And having root privileges makes no difference when immutable is in effect:

# lsattr immutable
------------- immutable

# chattr +i immutable
# lsattr immutable
----i-------- immutable

No, we have a read-only file - first try to delete the whole directory:

# cd ..
# rm -rf test
rm: cannot remove 'test/immutable': Operation not permitted

No try to delete (as root):

# cd test
# rm immutable
rm: remove write-protected regular empty file 'immutable'? y
rm: cannot remove `immutable': Operation not permittedst

Let's try emptying the file instead of deleting it:

# cp /dev/null immutable
cp: cannot create regular file 'immutable': Permission denied

# > immutable
-bash: immutable: Permission denied

# Try to create a hard link

# ln immutable link-immutable
ln: creating hard link 'link-immutable' to
'immutable': Operation not permitted

Clear the flag:

# chattr -i immutable
# rm immutable

This could be very useful for adding an extra security step on files you know you'll never want to change. While little will help you on a box that has been rooted, immutable files probably aren't vulnerable to simple overwrite attacks from other processes, even if they are owned by root.

Mounting Windows Shares on Linux using Samba


Accessing MS/Windows file servers from Linux can be established using the SMBFS Filesystem, which is part of the Samba Package. The Linux Kernel must be compiled with the SMBFS support. With smbmount you can mount a Windows Share. It is usually invoked as mount.smbfs by the mount command when using the "-t smbfs" option.


The following example shows, how you can mount the Share \\XEON\Akadia (on a W2K Server) under the Linux mount point: /mnt/xeon/Akadia.

First verify, which Shares are accessible from Linux:

zahn@linux> smbclient ---user=zahn --list=xeon

Domain=[XEON] OS=[Windows 5.0] Server=[Windows 2000 LAN Manager]

        Sharename       Type      Comment
        ---------       ----      -------
        E$              Disk      Default share
        Photos          Disk
        IPC$            IPC       Remote IPC
        D$              Disk      Default share
        print$          Disk      Printer Drivers
        Archive         Disk
        Users           Disk
        Akadia          Disk
        F$              Disk      Default share
        ADMIN$          Disk      Remote Admin
        C$              Disk      Default share
        HPColorL        Printer   HP LaserJet 2500 PCL 6
        Pmz             Disk
        Vorlagen        Disk
Domain=[XEON] OS=[Windows 5.0] Server=[Win 2000 LAN Manager]

        Server               Comment
        ---------            -------

        Workgroup            Master
        ---------            -------

As you can see, the Share Akadia is accessible.

Mount Share with smbmount

root@linux> mkdir -p /mnt/xeon/Akadia
smbmount //xeon/Akadia /mnt/xeon/Akadia/ \
            -o username=zahn,password=
root@linux> df -k
Filesystem   1K-blocks    Used Avail   Use% Mounted on
/dev/sda7     64342248 2885788 58188040  5% /
/dev/sda1       489992   11448   453244  3% /boot
/dev/sda6     10072456 4537756  5023032 48% /var
none            253724       0   253724  0% /var/tempfs
//xeon/Akadia 25671680 2201088 23470592  9% /mnt/xeon/Akadia

Note, that the given password is the Windows Password. Check that this password is not shown when listing the linux processes!

root@linux> ps -ef
root smbmount ..... -o username zahn password XXXXXXXX
root [smbiod]

Permanently mount with /etc/fstab

If you want to mount the Windows Share when the Linux System boots do the following steps:

  1. Create the File $HOME/.smbpassword

    username = zahn
    password =
  2. Set correct Access Rights

    chmod 400 $HOME/.smbpassword
  3. Add an Entry in /etc/fstab (All in one line)

    //xeon/Akadia /mnt/xeon/Akadia smbfs \
    credentials=/home/zahn/.smbpassword, \
    workgroup=AKADIA,uid=500,gid=500 0 0
  4. Mount the Share

    mount -a

The files in the Share are now mapped to the Linux User with UID=500, GID=500 which is zahn. The Share is mounted with mount.smbfs. You have read/write access to this Share.

Replace TraceRoute with TcpTraceroute

The more traditional traceroute sends out either UDP or ICMP ECHO packets with a TTL of one, and increments the TTL until the destination has been reached. By printing the gateways that generate ICMP time exceeded messages along the way, it is able to determine the path packets are taking to reach the destination.

The problem is that with the widespread use of firewalls on the modern Internet, many of the packets that traceroute sends out end up being filtered, making it impossible to completely trace the path to the destination. However, in many cases, these firewalls will permit inbound TCP packets to specific ports that hosts sitting behind the firewall are listening for connections on. By sending out TCP SYN packets instead of UDP or ICMP ECHO packets, tcptraceroute is able to bypass the most common firewall filters.

It is worth noting that tcptraceroute never completely establishes a TCP connection with the destination host. If the host is not listening for incoming connections, it will respond with an RST indicating that the port is closed. If the host instead responds with a SYN|ACK, the port is known to be open, and an RST is sent by the kernel tcptraceroute is running on to tear down the connection without completing three-way handshake. This is the same half-open scanning technique that nmap uses when passed the -sS flag.


Download it from http://michael.toren.net/code/tcptraceroute/

Manual Page

tcptraceroute [-nNFSAE] [ -i interface ] [ -f first ttl ]
[ -l length ] [ -q number of queries ] [ -t tos ]
[ -m max ttl ] [ -p source port ] [ -s source address ]
[ -w wait time ] host [ destination port ] [ length ]


Display numeric output, rather than doing a reverse DNS lookup for each hop. By default, reverse lookups are never attempted on RFC1918 address space, regardless of the -n flag.


Perform a reverse DNS lookup for each hop, including RFC1918 addresses.


Set the initial TTL used in the first outgoing packet. The default is 1.


Set the maximum TTL used in outgoing packets. The default is 30.


Use the specified local TCP port in outgoing packets. The default is to obtain a free port from the kernel using bind(2). Unlike with traditional traceroute(8), this number will not increase with each hop.


Set the source address for outgoing packets. See also the -i flag.


Use the specified interface for outgoing packets.


Set the number of probes to be sent to each hop. The default is 3.


Set the timeout, in seconds, to wait for a response for each probe. The default is 3.


Set the TCP SYN flag in outgoing packets. This is the default, if neither -S or -A is specified.


Set the TCP ACK flag in outgoing packets. By doing so, it is possible to trace through stateless firewalls which permit outgoing TCP connections.


Send ECN SYN packets, as described in RFC2481.


Set the IP TOS (type of service) to be used in outgoing packets. The default is not to set any TOS.


Set the IP "don't fragment" bit in outgoing packets.


Set the total packet length to be used in outgoing packets. If the length is greater than the minimum size required to assemble the necessary probe packet headers, this value is automatically increased.


Enable debugging, which may or may not be useful.


To trace the path to a web server listening for connections on port 80:

tcptraceroute www.akadia.com

Selected device eth0, address, port 32852 for outgoing packets
Tracing the path to www.akadia.com ( on TCP port 80, 30 hops max
1 ( 0.928 ms 0.876 ms 0.874 ms
2 bwadf2zhb.bluewin.ch ( 12.416 ms 11.497 ms 13.179 ms
3 net300.bwrt1zhb.bluewin.ch ( 13.353 ms 13.322 ms 13.486 ms
4 ( 13.201 ms 14.332 ms 14.289 ms
5 net125.bwrt1inb.bluewin.ch ( 12.125 ms 13.699 ms 13.334 ms
6 if114.ip-plus.bluewin.ch ( 13.478 ms 13.357 ms 13.334 ms
7 i79tix-005-pos2-0.bb.ip-plus.net ( 14.290 ms 12.638 ms 13.507 ms
8 cabcom-00-ser0.ce.ip-plus.net ( 13.247 ms 13.990 ms 14.962 ms
9 tengig-2-4.mlrZHZ006.gw.cablecom.net ( 14.561 ms 14.545 ms 14.955 ms
10 62-2-210-210.webcom.cablecom.ch ( 25.312 ms 26.091 ms 26.373 ms
11 62-2-210-215.webcom.cablecom.ch ( [open] 23.411 ms 24.017 ms 26.060 ms

To trace the path to a mail server listening for connections on port 25:

tcptraceroute mail.akadia.com 25

Talk to interactive Programs using Expect

Expect is a tool primarily for automating interactive applications such as telnet, ftp, passwd, fsck, rlogin, tip, etc. Expect really makes this stuff trivial. Expect is also useful for testing these same applications. Expect is described in many books, articles, papers, and FAQs. There is an entire book on it available from O'Reilly.

Get Started With Expect

The three commands send, expect, and spawn are the building power of Expect. The send command sends strings to a process, the expect command waits for strings from a process, and the spawn command starts a process.

The send Command

If Expect is already interacting with a program, the string will be sent to that program. But initially, send will send to the standard output. Here is what happens when I type this to the Expect interpreter interactively:

send "hello world"
hello world expect1.2> exit

The send command does not format the string in any way, so after it is printed the next Expect prompt gets appended to it without any space. To make the prompt appear on a different line, put a newline character at the end of the string. A newline is represented by "\n". The exit command gets you out of the Expect interpreter.

expect1.1> send "hello world\n"
hello world

If these commands are stored in a file, speak.exp, the script can be executed from the UNIX command line:

send "hello world\n"


The expect Command

The expect command waits for a response, usually from a process. Expect can wait for a specific string or any string that matches a given pattern. Like send, the expect command initially waits for characters from the keyboard. To see how the expect command works, create a a file response.exp that reads:

expect "hi\n"
send "hello there!\n"

When I make response.exp executable and run it, the interaction looks like this:

hello there!

If you get an error that goes like couldn't read file " ": No such file or directory, it may be because there are non-printable characters in your file. This is true if you do cut-and-paste from Netscape to your file. To solve this problem, try deleting trailing spaces at the end of each command line (even if there seems to be nothing there) in the script and follow the above steps again.

What Happens When Input Does Not Match ?

If expect reads characters that do not match the expected string, it continues waiting for more characters. If I had type hello instead of hi followed by a return, expect would continue to wait for "hi\n". Finding unexpected data in the input does not bother expect. It keeps looking until it finds something that matches. If no input is given, expect command eventually times out and returns. By default, after 10 seconds expect gives up waiting for input that matches the pattern. This default value can be changed by setting the variable timeout using the Tcl set command. For example, the following command sets the timeout to 60 seconds.

set timeout 60

A timeout of -1 signifies that expect should wait forever and a timeout of 0 indicates that expect should not wait at all.


To prevent expect from matching unexpected data, expect patterns can include regular expressions. The caret ^ is a special character that only matches the beginning of the input; it cannot skip over characters to find a valid match. For example, the pattern ^hi matches if I enter "hiccup" but not if I enter "sushi" . The dollar sign ($) is another special character. It matches the end of the data. The pattern hi$ matches if I enter "sushi" but not if I enter "hiccup". And the pattern ^hi$ matches neither "sushi" nor "hiccup". It matches "hi" and nothing else.

Patterns that use ^ or $ are said to be anchored. When patterns are not anchored, patterns match beginning at the earliest possible position in the string.

Pattern-Action Pairs

Expect also allows association between a command and a pattern. The association is made by listing the action (also known as command) immediately after the pattern in the expect command itself. Here is an example of pattern-action pairs:

#!/usr/bin/expect -f
expect "hi" { send "You said hi\n" } \
"hello" { send "Hello yourself\n" } \
"bye" { send "Good-bye cruel world\n" }

This command looks for "hi", "hello", and "bye". If any of the three patterns are found, the action immediately following it gets executed. If there is no match and the default timeout expires, expect stops waiting and execution continues with the next command in the script.

The spawn Command

The spawn command starts another program. The first argument of the spawn command is the name of a program to start. The remaining arguments are passed to the program. For example:

spawn ftp ftp.uu.net

This command spawns an ftp process and ftp.uu.net is the argument to the ftp process.

Example: Anonymous FTP

To partially automate an anonymous FTP action, create a file aftp.exp that looks like this:

#!/usr/bin/expect -f

spawn ftp $argv
expect "Name"
send "anonymous\r"
expect "Password:"
send "
martin dot zahn at akadia dot ch\r"

./aftp.exe ftp.uu.net

spawn ftp ftp.uu.net
Connected to ftp.uu.net.
220 FTP server ready.
Name (ftp.uu.net:root): anonymous
530 Please login with USER and PASS.
SSL not available
331 Guest login ok, send your complete e-mail address as password.
230- Welcome to the UUNET archive.
230- A service of UUNET Technologies Inc, Falls Church, Virginia
230- For information about UUNET, call +1 703 206 5600, or see the files
230- in /uunet-info
230- Please see http://www.us.uu.net/support/usepolicy/ for Acceptable
230- Use Policy
230- Access is allowed all day. Current time is Tue Jun 28 13:18:19 2005 GMT.
230- All transfers are logged with your host name and email address.
230- If you don't like this policy, disconnect now!
230- If your FTP client crashes or hangs shortly after login, try using a
230- dash (-) as the first character of your password. This will turn off
230- the informational messages which may be confusing your ftp client.
230-Please read the file /info/README.ftp
230- it was last modified on Fri Jun 29 00:54:02 2001 - 1459 days ago
230-Please read the file /info/README
230- it was last modified on Fri Jun 29 00:54:02 2001 - 1459 days ago
230 Guest login ok, access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.

Notice that each send command in the script ends with \r and not \n (\r denotes a return character while \n denotes a linefeed character). Interact is an Expect command that turns control from the script over to you. When this command is executed, Expect stops reading commands from the script and instead begins reading from the keyboard.

Example: Download RFC

With the script ftp-rfc you can download a RFC article:

# \
exec expect "$0" ${1+"$@"}

# ftp-rfc <rfc-number>
# ftp-rfc -index

# retrieves an rfc (or the index) from uunet

exp_version -exit 5.0

if {$argc!=1} {
send_user "usage: ftp-rfc \[#] \[-index]\n"

set file "rfc$argv.Z"

set timeout 60
spawn ftp ftp.uu.net
expect "Name*:"
send "anonymous\r"
expect "Password:"
send "martin.zahn@akadia.ch\r"
expect "ftp>"
send "binary\r"
expect "ftp>"
send "cd inet/rfc\r"
expect "550*ftp>" exit "250*ftp>"
send "get $file\r"
expect "550*ftp>" exit "200*226*ftp>"
send_user "\nuncompressing file - wait...\n"
exec uncompress $file

Example: Telnet Session


set timeout 20
set name [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]

spawn telnet $name
expect "login:"
send "$user "
expect "Password:"
send "$password "

./logon.exp telnet-host name password

Example: Talking to a Mail Server


set timeout 20
set mailserver [lindex $argv 0]

spawn telnet $mailserver 25
expect "*Postfix*"
send "helo $mailserver\r"
expect "*250*"
send "mail from: <martin.zahn@akadia.ch>\r"
expect "*250*"
send "rcpt to: <martin dot zahn at akadia dot ch>\r"
expect "*250*"
send "data\r"
expect "*354*"
send "hello\n.\n"
expect "*250*"
send "quit"

./smtp mail-server

spawn telnet rabbit.akadia.com 25
Connected to rabbit.akadia.com.
Escape character is '^]'.
220 rabbit.akadia.com ESMTP Postfix
helo rabbit.akadia.com
250 rabbit.akadia.com
mail from: <martin.zahn@akadia.ch>
250 Ok
rcpt to: <martin dot zahn at akadia dot ch>
250 Ok
354 End data with <CR><LF>.<CR><LF>
250 Ok: queued as 9B0BD3BA3D7

Example: Check if Mail Server is up and running

Script: check_smtp.exp


set timeout 2
spawn telnet mailserver 25
expect "220 mailserver ESMTP Postfix"
send "quit\r"

In the calling script:

# Check if SMTP is up
check_smtp.exp 1>/dev/null 2>&1
if [ $? != 0 ]
  echo "OK, running"
  echo "NOT OK, probably down"