Setting Up a Server

Setting Up a Server

This section discusses issues that you may need to address when setting up a server: how to write configuration files; how to specify hosts and subnets; how to use port-map, rpcinfo, xinetd, and TCP wrappers (hosts.allow and hosts.deny); and how to set up a chroot jail. Setting up specific servers is covered in and . Setting up a LAN is covered in .

Standard Rules in Configuration Files

Most configuration files, which are typically named *.conf, rely on the following conventions:

Configuration files that do not follow these conventions are noted in the text.

Specifying Clients

shows some common ways to specify a host or a subnet. Most of the time you can specify multiple hosts or subnets by separating the host or subnet specifications with SPACEs.

Table 11-3. Specifying a client

Client name pattern

Matches

n.n.n.n

One IP address.

name

One hostname, either local or remote.

Name that starts with .

Matches a hostname that ends with the specified string. For example, .tcorp.com matches the systems kudos.tcorp.com and speedy.tcorp.com, among others.

IP address that ends with .

Matches a host address that starts with the specified numbers. For example, 192.168.0. matches 192.168.0.255. If you omit the trailing period, this format does not work.

Starts with @

Specifies a netgroup

.n.n.n.n/m.m.m.m or n.n.n.n/mm

An IP address and subnet mask specify a subnet.

Starts with /

An absolute pathname of a file containing one or more names or addresses as specified in this table.

Wildcard

Matches

* and ?

Matches one (?) or more (*) characters in a simple hostname or IP address. These wildcards do not match periods in a domain name.

ALL

Always matches.

LOCAL

Matches any hostname that does not contain a period.

Operator

 

EXCEPT

Matches anything in the preceding list that is not in the following list. For example, a b c d EXCEPT c matches a, b, and d. Thus you could use 192.168. EXCEPT 192.168.0.1 to match all IP addresses that start with 192.168. except 192.168.0.1.


Examples

Each of the following examples specifies one or more systems:

10.10.

Matches all systems with IP addresses that start with 10.10.

.redhat.com

Matches all named hosts on the Red Hat network

localhost

Matches the local system

127.0.0.1

The loopback address; always resolves to localhost

192.168.*.1

Could match all routers on a network of /24 subnets


Specifying a Subnet

When you set up a server, you frequently need to specify which clients are allowed to connect to the server. Sometimes it is convenient to specify a range of IP addresses, called a subnet. The discussion on page explains what a subnet is and how to use a subnet mask to specify a subnet. Usually, you can specify a subnet as


n.n.n.n/m.m.m.m

or


n.n.n.n/maskbits

where n.n.n.n is the base IP address and the subnet is represented by m.m.m.m (the subnet mask) or maskbits (the number of bits used for the subnet mask). For example, 192.168.0.1/255.255.255.0 represents the same subnet as 192.168.0.1/24. In binary, decimal 255.255.255.0 is represented by 24 ones followed by 8 zeros. The /24 is shorthand for a subnet mask with 24 ones. Each line in presents two notations for the same subnet followed by the range of IP addresses that the subnet includes.

Table 11-4. Different ways to represent a subnet

Bits

Mask

Range

10.0.0.0/8

10.0.0.0/255.0.0.0

10.0.0.0 10.255.255.255

172.16.0.0/12

172.16.0.0/255.240.0.0

172.16.0.0 172.31.255.255

192.168.0.0/16

192.168.0.0/255.255.0.0

192.168.0.0 192.168.255.255


rpcinfo: Displays Information About portmap

The rpcinfo utility displays information about programs registered with portmap and makes RPC calls to programs to see if they are alive. For more information on portmap, refer to "" on page . The rpcinfo utility takes the following options and arguments:


rpcinfo p [host]
rpcinfo [n port] u | t host program [version]
rpcinfo b | d program version

p

(probe) Lists all RPC programs registered with portmap on host or on the local system if host is not specified.

n

(port number) With t or u, uses the port numbered port instead of the port number specified by portmap.

u

() Makes a UDP RPC call to version (if specified) of program on host and reports whether it received a response.

t

() Makes a TCP RPC call to version (if specified) of program on host and reports whether it received a response.

b

() Makes an RPC broadcast to version of program and lists hosts that respond.

d

(delete) Removes local RPC registration for version of program. Available to Superuser only.

Give the following command to see which RPC programs are registered with the portmap daemon on the system named peach:

$  /usr/sbin/rpcinfo -p peach
   program vers proto    port
    100000    2   tcp     111  portmapper
    100000    2   udp     111  portmapper
    100024    1    udp  32768  status
    100024    1    tcp  32768  status
    100021    1    udp  32769  nlockmgr
    100021    3    udp  32769  nlockmgr
...

Use the u option to display a list of versions of a daemon, such as ypserv, registered on a remote system (peach):

$ /usr/sbin/rpcinfo -u peach ypserv
program 100004 version 1 ready and waiting
program 100004 version 2 ready and waiting

Specify localhost to display a list of versions of a daemon registered on the local system:

$ /usr/sbin/rpcinfo -u localhost nfs
program 100003 version 2 ready and waiting
program 100003 version 3 ready and waiting

Locking down portmap

Because the portmap daemon holds information about which servers are running on the local system and which port each server is running on, only trusted systems should have access to this information. One way to ensure that only selected systems have access to portmap is to lock it down in the /etc/hosts.allow and /etc/hosts.deny files (page ). Put the following line in hosts.deny to prevent all systems from using portmap on the local (server) system:

portmap: ALL

Test this setup from a remote system with the following command:

$ /usr/sbin/rpcinfo -p hostname
No remote programs registered.

Replace hostname with the name of the remote system that you changed the hosts.deny file on. The change is immediate; you do not need to kill/restart a daemon.

Next add the following line to the hosts.allow file on the server system:

portmap: host-IP

where host-IP is the IP address of the trusted, remote system that you gave the preceding rpcinfo command from. Use only IP addresses with portmap in hosts.allow; do not use system names that portmap could get stuck trying to resolve. Give the same rpcinfo command, and you should now see a list of the servers that RPC knows about, including portmap. See page for more examples.

Caution: Set the clocks

The portmap daemon relies on the client's and the server's clocks being synchronized. A simple (page ) can be initiated by setting the server's clock to the wrong time.

The xinetd Superserver

The xinetd daemon is a more secure replacement for the inetd superserver that was originally shipped with 4.3BSD. The xinetd superserver listens for network connections. When one is made, it launches a specified server daemon and forwards the data from the socket (page ) to the daemon's standard input.

The version of xinetd distributed with CentOS Linux is linked against libwrap.a, so it can use the /etc/hosts.allow and /etc/hosts.deny files for access control (see "" on page for more information). Using TCP wrappers can simplify configuration but hides some of the more advanced features of xinetd.

Tip: xinetd may not be installed

Working as root, give the following command to install xinetd on a FEDORA system:

# yum install xinetd

Use RHN to install it on a RHEL system.

The base configuration for xinetd is stored in the /etc/xinetd.conf file. If this file is not present, xinetd is probably not installed. See the preceding tip. The file supplied with CentOS Linux is shown here:

$ cat /etc/xinetd.conf
#
# Simple configuration file for xinetd
#
# Some defaults, and include /etc/xinetd.d/
defaults
{
        instances               = 60
        log_type                = SYSLOG authpriv
        log_on_success          = HOST PID
        log_on_failure          = HOST
        cps                     = 25 30
}
includedir /etc/xinetd.d

The section specifies the default configuration of xinetd; the files in the included directory, /etc/xinetd.d, specify server-specific configurations. Defaults can be overridden by server-specific configuration files.

In the preceding file, the instances directive specifies that no daemon may run more than 60 copies of itself at one time. The log_type directive specifies that xinetd send messages to the system log daemon (syslogd, page ) using the authpriv facility. The next two lines specify what to log on success and on failure. The cps (connections per second) directive specifies that no more than 25 connections to a specific service should be made per second and that the service should be disabled for 30 seconds if this limit is exceeded.

The following xinetd configuration file allows telnet connections from the local system and any system with an IP address that starts with 192.168.. This configuration file does not rely on TCP wrappers, so it does not rely on the hosts.allow and hosts.deny files.

$ cat /etc/xinetd.d/telnet
service telnet
{
        socket_type   = stream
        wait          = no
        user          = root
        server        = /usr/sbin/in.telnetd
        only_from     = 192.168.0.0/16 127.0.0.1
        disable       = no
}

The socket_type indicates whether the socket uses TCP or UDP. TCP-based protocols establish a connection between the client and the server and are identified by the type . UDP-based protocols rely on the transmission of individual datagrams and are identified by the type dgram.

When wait is set to no, xinetd handles multiple concurrent connections to this service. Setting wait to yes causes xinetd to wait for the server process to complete before handling the next request for that service. In general, UDP services should be set to yes and TCP services to no. If you were to set wait to yes for a service such as telnet, only one person would be able to use the service at any given time.

The user specifies which user the server runs as. If this user is a member of multiple groups, you can also specify the group on a separate line with the keyword group. The user directive is ignored if xinetd is run as other than root. The provides the pathname of the server program that xinetd runs for this service.

The only_from specifies which systems xinetd allows to use the service. It is a good idea to use IP addresses onlyusing hostnames can make the service unavailable if DNS fails. Zeros at the right of an IP address are treated as wildcards. For example, 192.168.0.0 allows access from any system in the 192.168 subnet.

The disable line can disable a service without removing the configuration file. As shipped by Red Hat, a number of services include an xinetd configuration file with disable set to yes. To run one of these services, change disable to no in the appropriate file in xinetd.d and restart xinetd:

# /sbin/service xinetd restart
Stopping xinetd:                                            [  OK  ]
Starting xinetd:                                            [  OK  ]

Securing a Server

You may secure a server either by using TCP wrappers or by setting up a chroot jail.

TCP Wrappers: Client/Server Security (hosts.allow and hosts.deny)

When you open a local system to access from remote systems, you must ensure that the following criteria are met:

As part of the client/server model, TCP wrappers, which can be used for any daemon that is linked against libwrap.a, rely on the /etc/hosts.allow and /etc/hosts.deny files as the basis of a simple access control language. This access control language defines rules that selectively allow clients to access server daemons on a local system based on the client's address and the daemon the client tries to access.

Each line in the hosts.allow and hosts.deny files has the following format:


daemon_list : client_list [: command]

where daemon_list is a comma-separated list of one or more server daemons (such as portmap, vsftpd, or sshd), client_list is a comma-separated list of one or more clients (see , "," on page ), and the optional command is the command that is executed when a client from client_list tries to access a server daemon from daemon_list.

When a client requests a connection with a local server, the hosts.allow and hosts.deny files are consulted as follows until a match is found:

  1. If the daemon/client pair matches a line in hosts.allow, access is granted.

  2. If the daemon/client pair matches a line in hosts.deny, access is denied.

  3. If there is no match in either the hosts.allow or the hosts.deny files, access is granted.

The first match determines whether the client is allowed to access the server. When either hosts.allow or hosts.deny does not exist, it is as though that file was empty. Although it is not recommended, you can allow access to all daemons for all clients by removing both files.

Examples

For a more secure system, put the following line in hosts.deny to block all access:

$ cat /etc/hosts.deny ...
ALL : ALL : echo '%c tried to connect to %d and was blocked' >> /var/log/tcpwrappers.log

This line prevents any client from connecting to any service, unless specifically permitted in hosts.allow. When this rule is matched, it adds a line to the file named /var/log/tcpwrappers.log. The %c expands to client information and the %d expands to the name of the daemon the client attempted to connect to.

With the preceding hosts.deny file in place, you can include lines in hosts.allow that explicitly allow access to certain services and systems. For example, the following hosts.allow file allows anyone to connect to the OpenSSH daemon (ssh, scp, sftp) but allows telnet connections only from the same network as the local system and users on the 192.168. subnet:

$ cat /etc/hosts.allow
sshd : ALL
in.telnet : LOCAL
in.telnet : 192.168.* 127.0.0.1
...

The first line allows connection from any system (ALL) to sshd. The second line allows connection from any system in the same domain as the server (LOCAL). The third line matches any system whose IP address starts 192.168. and the local system.

Setting Up a chroot Jail

On early UNIX systems, the root directory was a fixed point in the filesystem. On modern UNIX variants, including Linux, you can define the root directory on a per-process basis. The chroot utility allows you to run a process with a root directory other than /.

The root directory appears at the top of the directory hierarchy and has no parent: A process cannot access any files above the root directory (because they do not exist). If, for example, you run a program (process) and specify its root directory as /home/sam/jail, the program would have no concept of any files in /home/sam or above: jail is the program's root directory and is labeled / (not jail).

By creating an artificial root directory, frequently called a (chroot) jail, you prevent a program from accessing or modifyingpossibly maliciouslyfiles outside the directory hierarchy starting at its root. You must set up a chroot jail properly to increase security: If you do not set up a chroot jail correctly, you can actually make it easier for a malicious user to gain access to a system than if there were no chroot jail.

Using chroot

Creating a chroot jail is simple: Working as root, give the command /usr/sbin/chroot directory. The becomes the root directory and the process attempts to run the default shell. Working as root from the /home/sam directory, the following command sets up a chroot jail in the (existing) /home/sam/jail directory:

# /usr/sbin/chroot /home/sam/jail
/usr/sbin/chroot: cannot run command '/bin/bash': No such file or directory

This example sets up a chroot jail, but when it attempts to run the bash shell, it fails. Once the jail is set up, the directory that was named jail takes on the name of the root directory, /, so chroot cannot find the file identified by the pathname /bin/bash. In this situation the chroot jail is working but is not useful.

Getting a chroot jail to work the way you want is a bit more complicated. To have the preceding example run bash in a chroot jail, you need to create a bin directory in jail (/home/sam/jail/bin) and copy /bin/bash to this directory. Because the bash binary is dynamically linked to shared libraries (page ), you need to copy these libraries into jail as well. The libraries go in lib. The next example creates the necessary directories, copies bash, uses ldd to display the shared library dependencies of bash, and copies the necessary libraries into lib. The linux-gate.so.1 file is a dynamically shared object (DSO) provided by the kernel to speed system calls; you do not need to copy it to the lib directory.

$ pwd
/home/sam/jail
$ mkdir bin lib
$ cp /bin/bash bin
$ ldd bin/bash
        linux-gate.so.1 =>  (0x0089c000)
        libtermcap.so.2 => /lib/libtermcap.so.2 (0x00cdb000)
        libdl.so.2 => /lib/libdl.so.2 (0x00b1b000)
        libc.so.6 => /lib/libc.so.6 (0x009cb000)
        /lib/ld-linux.so.2 (0x009ae000)
$ cp /lib/{libtermcap.so.2,libdl.so.2,libc.so.6,ld-linux.so.2} lib

Now that everything is set up, you can start the chroot jail again. Although all of the setup can be done by an ordinary user, you have to run chroot as Superuser:

$ su
Password:
# /usr/sbin/chroot .
bash-3.1# pwd
/
bash-3.1# ls
bash: ls: command not found
bash-3.1#

This time the chroot finds and starts bash, which displays its default prompt (bash-3.1#). The pwd command works because it is a shell builtin (page ). However, bash cannot find the ls utility (it is not in the chroot jail). You can copy /bin/ls and its libraries into the jail if you want users in the jail to be able to use ls.

To set up a useful chroot jail, first determine which utilities the users of the chroot jail will need. Then copy the appropriate binaries and their libraries into the jail. Alternatively you can build static copies of the binaries and put them in the jail without installing separate libraries. (The statically linked binaries are considerably larger than their dynamic counterparts. The base system with bash and the core utilities exceeds 50 megabytes.) You can find the source code for most of the common utilities in the bash and coreutils SRPMS (source rpm) packages.

Whichever technique you choose, you must put a copy of su in the jail. The su command is required to run programs as a user other than root. Because root can break out of a chroot jail, it is imperative that you run a program in the chroot jail as a user other than root.

The dynamic version of su distributed by Red Hat requires PAM and will not work within a jail. You need to build a copy of su from the source to use in a jail. By default any copy of su you build does not require PAM. Refer to "" on page for instructions on how to build packages such as coreutils (which includes su).

To use su, you must copy the relevant lines from the /etc/passwd and /etc/shadow files into files with the same names in the etc directory inside the jail.

Tip: Keeping multiple chroot jails

If you plan to deploy multiple chroot jails, it is a good idea to keep a clean copy of the bin and lib files somewhere other than in one of the active jails.

Running a Service in a chroot Jail

Running a shell inside a jail has limited usefulness. Instead you are more likely to need to run a specific service inside the jail. To run a service inside a jail, you must make sure all files needed by that service are inside the jail. The format of a command to start a service in a chroot jail is

# /usr/sbin/chroot jailpath /bin/su user daemonname &

where jailpath is the pathname of the jail directory, user is the username that runs the daemon, and daemonname is the path (inside the jail) of the daemon that provides the service.

Some servers are already set up to take advantage of chroot jails. You can set up DNS so that named runs in a jail (page ), and the vsftpd FTP server can automatically start chroot jails for clients (page ).

Security Considerations

Some services need to be run as root, but they release their root privilege once started (Procmail and vsftpd are examples). If you are running such a service, you do not need to put su inside the jail.

A process run as root could potentially escape from a chroot jail. For this reason, you should always su to another user before starting a program running inside the jail. Also, be careful about which setuid (page ) binaries you allow inside a jaila security hole in one of them could compromise the security of the jail. In addition, make sure the user cannot access executable files that he uploads.

DHCP: Configures Hosts

Instead of storing network configuration information in local files on each system, DHCP (Dynamic Host Configuration Protocol) enables client systems to retrieve network configuration information each time they connect to the network. A DHCP server assigns an IP addresses from a pool of addresses to clients as needed. Assigned addresses are typically temporary, but need not be.

This technique has several advantages over storing network configuration information in local files:

DHCP is particularly useful for administrators who are responsible for maintaining a large number of systems because individual systems no longer need to store unique configuration information. With DHCP, the administrator can set up a master system and deploy new systems with a copy of the master's hard disk. In educational establishments and other open access facilities, the hard disk image may be stored on a shared drive, with each workstation automatically restoring itself to pristine condition at the end of each day.

More Information

Web

FAQ

HOWTO

DHCP Mini HOWTO

How DHCP Works

The client daemon, dhclient (part of the dhcp package), contacts the server daemon, dhcpd, to obtain the IP address, netmask, broadcast address, nameserver address, and other networking parameters. The server provides a lease on the IP address to the client. The client can request the specific terms of the lease, including its duration; the server can, in turn, limit these terms. While connected to the network, a client typically requests extensions of its lease as necessary so its IP address remains the same. The lease can expire once the client is disconnected from the network, with the server giving the client a new IP address when it requests a new lease. You can also set up a DHCP server to provide static IP addresses for specific clients (refer to "" on page ).

DHCP is broadcast based, so both client and server must be on the same subnet (page ).

DHCP Client

A DHCP client requests network configuration parameters from the DHCP server and uses those parameters to configure its network interface.

Prerequisites

Install the following package:

dhclient: The DHCP Client

When a DHCP client system connects to the network, dhclient requests a lease from the DHCP server and configures the client's network interface(s). Once a DHCP client has requested and established a lease, it stores information about the lease in a file named dhclient.leases, which is stored in /var/lib/dhcp (RHEL) or /var/lib/dhclient (FEDORA). This information is used to reestablish a lease when either the server or the client needs to reboot. The DHCP client configuration file, /etc/dhclient.conf, is required only for custom configurations. The following dhclient.conf file specifies a single interface, eth0:

$ cat /etc/dhclient.conf
interface "eth0"
{
send dhcp-client-identifier 1:xx:xx:xx:xx:xx:xx;
send dhcp-lease-time 86400;
}

In the preceding file, the 1 in the dhcp-client-identifier specifies an Ethernet network and xx:xx:xx:xx:xx:xx is the MAC address (page ) of the device controlling that interface. See page for instructions on how to display a MAC address. The dhcp-lease-time is the duration, in seconds, of the lease on the IP address. While the client is connected to the network, dhclient automatically renews the lease each time half of the lease is up. The lease time of 8,6400 seconds (or one day) is a reasonable choice for a workstation.

DHCP Server

The DHCP server maintains a list of IP addresses and other configuration parameters. When requested to do so, the DHCP server provides configuration parameters to a client.

Prerequisites

Install the following package:

Run chkconfig to cause dhcpd to start when the system enters multiuser mode:

# /sbin/chkconfig dhcpd on

Start dhcpd:

# /sbin/service dhcpd start

dhcpd: The DHCP Daemon

A simple DCHP server allows you to add clients to a network without maintaining a list of assigned IP addresses. A simple network, such as a home LAN sharing an Internet connection, can use DHCP to assign a dynamic IP address to almost all nodes. The exceptions are servers and routers, which must be at known network locations to be able to receive connections. If servers and routers are configured without DHCP, you can specify a simple DHCP server configuration in /etc/dhcpd.conf:

$ cat /etc/dhcpd.conf
default-lease-time 600;
max-lease-time 86400;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.1.255;
option routers 192.168.1.1;
option domain-name-servers 192.168.1.1;
subnet 192.168.1.0 netmask 255.255.255.0 {
   range 192.168.1.2 192.168.1.200;
}

The preceding configuration file specifies a LAN where the router and DNS are both located on 192.168.1.1. The default-lease-time specifies the number of seconds the dynamic IP lease will remain valid if the client does not specify a duration. The max-lease-time is the maximum time allowed for a lease.

The information in the lines is sent to each client when it connects. The names following the word option specify what the following argument represents. For example, the option broadcast-address line specifies the broadcast address of the network. The and domain-name-servers options allow multiple values separated by commas.

The section includes a range line that specifies the range of IP addresses that the DHCP server can assign. If you define multiple subnets, you can define options, such as subnet-mask, inside the subnet section. Options defined outside all subnet sections are global and apply to all subnets.

The preceding configuration file assigns addresses in the range between 192.168.1.2 and 192.168.1.200. The DHCP server starts at the bottom of this range and attempts to assign a new IP address to each new client. Once the DHCP server reaches the top of the range, it starts reassigning IP addresses that have been used in the past, but are not currently in use. If you have fewer systems than IP addresses, the IP address of each system should remain fairly constant. You cannot use the same IP address for more than one system at a time.

Once you have configured a DHCP server, you can start (or restart) it by using the dhcpd init script:

# /sbin/service dhcpd restart

Once the server is running, clients configured to obtain an IP address from the server using DHCP should be able to do so.

Static IP Addresses

As mentioned earlier, routers and servers typically require static IP addresses. While you can manually configure IP addresses for these systems, it may be more convenient to have the DHCP server provide them with static IP addresses.

When a system that requires a specific static IP address connects to the network and contacts the DHCP server, the server needs a way to identify the system so the server can assign the proper IP address to the system. The DHCP server uses the MAC address (page ) of the system's Ethernet card (NIC) as an identifier. When you set up the server, you must know the MAC address of each system that requires a static IP address.

Displaying a MAC address

You can use ifconfig to display the MAC addresses of the Ethernet cards (NICs) in a system. In the following example, the MAC addresses are the colon-separated series of hexadecimal number pairs following HWaddr:

$ /sbin/ifconfig | grep -i hwaddr
eth0       Link encap:Ethernet  HWaddr BA:DF:00:DF:C0:FF
eth1       Link encap:Ethernet  HWaddr 00:02:B3:41:35:98

Run ifconfig on each system that requires a static IP address. Once you have determined the MAC address of each of these systems, you can add a host section to the /etc/dhcpd.conf file for each system, instructing the DHCP server to assign a specific address to the system. The following host section assigns the address 192.168.1.1 to the system with the MAC address of BA:DF:00:DF:C0:FF:

$ cat /etc/dhcpd.conf
...
host router {
   hardware ethernet BA:DF:00:DF:C0:FF;
   fixed-address 192.168.1.1;
   option host-name router;
}

The name following host is used internally by dhcpd. The name specified after option host-name is passed to the client and can be a hostname or an FQDN.

After making changes to dhcpd.conf, restart dhcpd using service and the dhcpd init script (page ).