Linux Admin Tips

By Mitch Stuart
Copyright © 2002-2006 FullSpan Software  -  Usage subject to license
Document Version: $Revision: 1.9 $, $Date: 2006/01/22 22:34:21 $

These are some simple tips that I have found to be useful when doing basic Linux configuration and system administration.

Contents

1. Startup

1.1. Runlevels

1.2. Running Programs at Boot Time

1.3. Automatic Service Start/Stop

1.4. Network Interface Configuration

1.5. Network Interface Start/Stop

1.6. Shell Initialization Files

1.7. Shell Prompt

2. Firewall and Network Services

2.1. iptables

2.2. Restarting xinetd

2.3. FTP Configuration

2.4. Telnet Configuration

2.5. CVS pserver Configuration

2.6. Windows Mount Points

3. Miscellaneous

3.1. Garbled UTF-8 Characters

3.2. Non-login Shell

3.3. Virtual Consoles

3.4. Restarting X Windows

3.5. Log Location

3.6. Operating System Version

3.7. man Sections

3.8. cron Environment

4. Unused Features

4.1. xinetd Access Control

4.2. TCP Wrappers

4.3. tcp_en Connection Refused

Startup

Runlevels

Runlevels determine what mode the operating system is running in. Also, some services are launched only in certain runlevels. The file /etc/inittab shows the list of runlevels and the selected runlevel. Here is an excerpt from the file:
# Default runlevel. The runlevels used by RHS are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
This initdefault ID number is set to the runlevel you want to boot into:
id:5:initdefault:

Running Programs at Boot Time

Add a line to /etc/rc.d/rc.local

Automatic Service Start/Stop

Examples of services are the httpd (web) service, and the smb (Samba file sharing) service. You can check the configuration of a service by running (using httpd as an example):

  chkconfig --list httpd

To change the start/stop properties of a service, edit the service control file to indicate the runlevel settings. For example, if you enable httpd for runlevels 3 and 5, you would change the line in /etc/init.d/httpd from this:

  # chkconfig: - 85 15

to this:

  # chkconfig: 35 85 15

The dash (-) means do not start in any runlevel, the 35 means start in run levels 3 (console) and 5 (GUI). The 85 is the start priority and the 15 is the stop priority. The "# chkconfig" line is just a comment, but it is used by the chkconfig command to control the configuration by managing the files in the /etc/rc.d directory.

To activate the changes you made in the service control file, use the chkconfig reset command:

  chkconfig httpd reset

Network Interface Configuration

Set the IP address and DHCP options in /etc/sysconfig/network-scripts/ifcfg-eth0. Sample:
  DEVICE=eth0
  BOOTPROTO=static
  BROADCAST=192.168.1.255
  IPADDR=192.168.1.221
  NETMASK=255.255.255.0
  NETWORK=192.168.1.0
  ONBOOT=yes
For a static IP address, use BOOTPROTO=static. For DHCP, use BOOTPROTO=DHCP and then also add DHCP_HOSTNAME="somehost" where "somehost" is the name of the DHCP server (which may be this server itself).

Network Interface Start/Stop

Use /sbin/ifup and ifdown to start and stop network interfaces. For example, ifdown eth0 to shutdown.

Shell Initialization Files

I like to put all of my shell initialization commands in the .bashrc file, and invoke that file from .bash_profile, as recommended in the GNU Bash Reference Manual. The .bash_profile file looks like this:
   # .bash_profile
   if [ -f ~/.bashrc ]; then
      . ~/.bashrc
   fi
My .bashrc file sources the global bashrc file (if it exists), and then sets my user-specific environment variables and aliases:
   # .bashrc
   if [ -f /etc/bashrc ]; then
      . /etc/bashrc
   fi
   export ANT_HOME="/usr/local/ant"
   alias fs='/usr/local/bin/filesnap.pl'
   # More export and alias commands . . .

Shell Prompt

Set the shell prompt by setting the environment variable PS1 in your shell initialization file. My preferred prompt is:
  export PS1="[\h \w] "
which results in a prompt like this:
  [lanai ~/download/temp] 
This works well for me because I typically use one login account for almost all of my work. If I'm using multiple accounts, I add \u to the prompt to include the user:
  export PS1="[\u@\h \w] "  ---> [mitch@lanai ~/download/temp] 

Firewall and Network Services

iptables

iptables is the Linux firewall subsystem (the successor to the earlier ipchains subsystem). See the netfilter site for details. This section presents a few very basic iptables rules.

Use iptables -L to list current configuration

The simple iptables commands in this section use the format shown in the following example (which opens port 22 for ssh):

iptables -I INPUT -s 192.168.1.0/255.255.255.0 -p tcp --dport 22 -j ACCEPT

After adding/testing a rule, to persist the rule use the command:

service iptables save

The following iptables commands show how to open the firewall for various types of traffic. Most of these openings are for the local network only.

Open FTP (port 21) for local network:

  iptables -I INPUT -s 192.168.1.0/255.255.255.0 -p tcp --dport 21 -j ACCEPT

Open FTP passive data ports (10100-10199) for local network:
FTP is a bit of a special case. Above we opened port 21 for the FTP control connection (used for the client connecting to the server and asking for services). However, FTP also opens a data port to transfer the actual file and directory information. In the commonly-used passive FTP scenario, the server sends the client a port number and the client initiates the connection on that port. This is necessary because the client is likely sitting behind a firewall and would not accept an incoming connection from the FTP server.

There are two ways (that I know of) to enable passive FTP to pass through the server's firewall. The simple approach (implemented here) is to specify a range of passive port numbers that the FTP server should use, and then open that range. The opening of the range is shown here in the iptables section; see the FTP Configuration section below for how to configure the FTP server to actually use this port range. The second and more sophisticated way to do FTP passive connection firewalling is to have iptables open up based on the dynamic port determined at passive connect time. For example, see this explanation of connection tracking.

  iptables -I INPUT -s 192.168.1.0/255.255.255.0 -p tcp --dport 10100:10199 -j ACCEPT

Open ssh (port 22) for local network:

  iptables -I INPUT -s 192.168.1.0/255.255.255.0 -p tcp --dport 22 -j ACCEPT

Open telnet (port 23) for local network:

  iptables -I INPUT -s 192.168.1.0/255.255.255.0 -p tcp --dport 23 -j ACCEPT

Open HTTP (port 80) for access from anywhere:

  iptables -I INPUT -p tcp --dport 80 -j ACCEPT

Open SMB/SAMBA (ports 137-139) for local network:

  iptables -I INPUT -s 192.168.1.0/255.255.255.0 -p tcp --dport 137:139 -j ACCEPT
  iptables -I INPUT -s 192.168.1.0/255.255.255.0 -p udp --dport 137:139 -j ACCEPT

Open CVS pserver (port 2401) for local network:

  iptables -I INPUT -s 192.168.1.0/255.255.255.0 -p tcp --dport 2401 -j ACCEPT

Restarting xinetd

To restart xinetd (e.g., after creating a new service entry):
  cd /etc/rc.d/init.d
  ./xinetd reload

FTP Configuration (vsftpd)

As discussed above, we have chosen to open the passive FTP ports by specifying a range that should be used. The firewall opening is shown above, this section shows how to specify the port range to the FTP server. Edit /etc/vsftpd.conf, set passive ports:

  pasv_min_port=10100
  pasv_max_port=10199

Edit /etc/xinetd.d/vsftpd, set disable=no

Telnet Configuration

Edit /etc/xinetd.d/telnet, set disable=no

CVS pserver Configuration

The book Open Source Development with CVS is the best resource that I have found for setting up and using CVS. After doing the basic CVS setup, I was having problems using the CVS pserver, and had to go through several stages to fix it.

1. The older CVS documentation (including the above book) gives examples using the older inetd daemon instead of the newer xinetd daemon. The xinetd FAQ explains how to set up the pserver with an /etc/xinetd.d/cvspserver file like this:

  service cvspserver
  {
    socket_type  = stream
    protocol     = tcp
    wait         = no
    user         = root
    passenv      = 
    server       = /usr/bin/cvs
    server_args  = --allow-root=/home/cvsrepos pserver -f
  }

2. After the initial setup of the cvspserver file as above, when I tried connecting to CVS I got an error message like: "cvs server: cannot open /root/.cvsignore: Permission denied". According to some reading on the web, this is due to the value of the HOME environment variable when xinetd launches CVS. Various options for a fix are available and I felt the best suggestion was to simply tell xinetd to use a different HOME directory by adding this line to the cvspserver file above:

    env             = HOME=/home/cvsrepos
This fixed the problem just fine.

3. But then I realized I didn't really want to run cvs as root. From a security standpoint, the fewer processes running as root, the better (if an intruder gains control of a running process, they can do much less damage if the process is not running as root). It was easy enough to create a cvs user and change the cvspserver file above from "user=root" to "user=cvs". But then after that I could not longer login to CVS! The reason was that I had not set up CVS-specific passwords, I was relying on pserver to authenticate me based on my actual login account on the CVS server machine - and now that pserver is not running as root, it is no longer able to do this. This is actually a good thing, since it gave me incentive to set up a CVS-specific password file, which is more secure than using the login password (since the CVS password is transmitted in cleartext). Setting up a CVS password file is described in the CVS book mentioned above, basically you just create a CVSROOT/passwd file and add your users to it with lines like this:

  jdoe:xyABCDEFGH:cvs
  bsmith:suJKLMNOP:cvs
where "jdoe" and "bsmith" are users who will login to CVS, the next string is the encrypted password for that user, and "cvs" is the common CVS user (the actual account that the pserver process runs under on the CVS server machine).

4. You can enforce the use of CVS-specific passwords by adding or uncommenting this line in CVSROOT/config:

  SystemAuth=no
This tells pserver not to allow users in by authenticating them with their operating system credentials - instead they must have a CVS-specific password in the CVSROOT/passwd file. This adds a bit more administrative overhead in managing the CVS passwords, but it allows the pserver to run as a non-privileged user and improves password security.

5. And finally, it is worth mentioning that there are other methods besides the pserver for remotely accessing CVS. The pserver is good for setting up anonymous access or for managing CVS as a separate service with specific rights. However, you may wish to explore the other connection methods supported by CVS: rsh, ssh, kerberos, etc.

Windows Mount Points

If you want to read and write files on a Windows computer from your Linux computer, you can create a "mount point" - a directory on the Linux computer that points to a directory on the Windows computer. This section shows several ways to create such a mount point.

All of these methods assume that you have already shared the Windows directory (folder) on the network. To share a directory, right-click on the directory name in Windows Explorer and select "Sharing and Security...". See Windows Help for more information on sharing directories.

1. Interactive mount command. For example (shown on multiple lines for clarity):

  mount
  -t smbfs
  -o credentials=/root/.credentials-fiji-backup,workgroup=TROPICS
  //fiji/backup
  /root/mount/fiji/backup
Replace the parameters in italics with your values: After running the above command, when you read or write files in the /root/mount/fiji/backup directory, those files will actually be accessed in the shared Windows directory \\fiji\backup.

2. Persistent mount command. To have the mount point re-mounted each time the Linux computer starts up, place the mount command in the file /etc/fstab. For example (shown on multiple lines for clarity):

  //fiji/backup
  /root/mount/fiji/backup smbfs
  credentials=/root/.credentials-fiji-backup,workgroup=TROPICS 0 0
The values are the same as described in the earlier interactive mount command example, just in a slightly different order and format.

3. Automount command. To have the mount point mounted "on demand" (when it is accessed by a command or program on the Linux computer), you can use automount / autofs.

In the file /etc/auto.master, define the directory that will contain the mount point, for example:

  /misc /etc/auto.misc
This tells automount that the mount point(s) defined in the file /etc/auto.misc should be mounted under the Linux /misc directory.

Now, in the file /etc/auto.misc, define the actual mount point. For example (shown on multiple lines for clarity):

  fiji-backup
  -fstype=smbfs,credentials=/root/.credentials-fiji-backup,workgroup=TROPICS
  ://fiji/backup
The values are the same as described in the earlier interactive mount command example, just in a slightly different order and format. In this example, the Linux directory /misc/fiji-backup will point to the Windows shared directory \\fiji\backup.

Credentials File
The credentials file (such as .credentials-fiji-backup in the examples above) has the following format:

  username=backupuser
  password=secretpass
In this file, specify a Windows user name and password that will allow the Linux computer to access the shared Windows directory.

Take the following steps to enhance the security of your mount points:

Miscellaneous

Garbled UTF-8 Characters

RedHat 8.0 was showing garbled characters in ssh and telnet sessions (e.g., "man ls" would show the bold/underlined characters as garbled). This is because RedHat 8.0 uses the UTF-8 character set by default.

I first noticed this problem with my SecureCRT client program, however I later noticed it with other client programs. The vendor of SecureCRT, VanDyke Software, has published a list of several methods to solve this issue. Briefly, any of the following should work:

Non-login Shell

For daemon users that should never have an interactive login, you can configure a shell that does not permit login: /sbin/nologin. Or: /bin/false.

Virtual Consoles

Use Ctrl+Alt+F1 through F6 to go to virtual consoles 1 through 6. Use Ctrl+Alt+F7 to return to X.

Restarting X Windows

To restart X use Ctrl+Alt+Backspace or the startx command.

Log Location

Logs are in /var/log

Operating System Version

To get OS brand and version: uname -a

man sections

man pages are divided into sections, and sometimes information about a particular topic may appear in multiple sections. For example, if you type:
   man crontab
You will see an indication at the top of the output that you are looking at section 1:
   CRONTAB(1)
and an indication near the bottom of the output that there is additional information in section 5:
   SEE ALSO
      crontab(5), cron(8)
To display information from a particular man section, specify the section number, for example:
   man 5 crontab
To display information from all man sections, use the -a option:
   man -a crontab

cron Environment

When a cron job runs, it runs in a relatively "bare" environment with only a few environment variables set. In particular, the normal starup files (such as .bash_profile) are not executed before the cron job runs. It is often necessary to adjust the environment in which the cron job run. Two methods for doing this are:

Unused Features

xinetd Access Control

xinetd has configuration settings to restrict access to services. I believe that this is not needed when using iptables, since iptables restricts access at a lower level, and thus the packets would not even hit xinetd. For example, you could restrict telnet to only allow local network connections by editing /etc/xinetd.d/telnet, and adding the line:

  only_from=192.168.1.1/255

TCP Wrappers

Programs that use TCP Wrappers (probably many xinetd-based and other reasonably modern programs) will automatically honor access restrictions configured at the TCP Wrappers level. I believe that this is not needed when using iptables, since iptables restricts access at a lower level, and thus the packets would not even hit the xinetd level. For example, you could restrict Telnet and FTP as follows. Edit /etc/hosts.deny, add the following lines to deny access to all:

  in.telnetd: ALL
  vsftpd: ALL

Then edit /etc/hosts.allow, add the following lines to allow local network access:

  in.telnetd: 192.168.1. LOCAL
  vsftpd: 192.168.1. LOCAL

tcp_ecn Connection Refused

I had this issue with a Non-Red Hat flavor of Linux. Could not connect from Windows to Linux (got a connection refused with ssh). Found the following tip in a newsgroup and it worked for me:
  echo 0 >/proc/sys/net/ipv4/tcp_ecn
If this were a continuing problem, I would add this to the startup sequence, but it's no longer a problem because my current RedHat Linux install does not have this issue.