In the time before general public use of the Internet, communications between machines were not regularly encrypted because most communications didn t take place over public networks, only a few machines were connected to the Internet and most people knew the other machines on the network, and there were few publicized cases of data theft, destruction, or monitoring. This all changed as the Internet grew into what we know of it today. In order to provide more security to your network, and to protect information traversing your network, you should implement the use of secure protocols that encrypt the information contained within the payload. Using unencrypted protocols can allow attackers to gather sensitive information such as account names and passwords (as shown in Chapter 14) or gather information during transit.
SUSE SLES8 and Red Hat Enterprise Linux AS 3.0, the examples used in this book, do not have some of the more dangerous protocols enabled (as discussed in Chapter 2). This does not preclude someone from using the service to connect to an outside entity, though, unless you remove or restrict the binary files as discussed in Chapter 4. The following are the most commonly used insecure services:
r tools such as rsh , rcp , and rlogin
These protocols have alternatives that encrypt the session as described in Table 10-1.
The services in the first column of Table 10-1, in addition to others, are unencrypted and care should be taken when using them with sensitive information. If at all possible within your environment, utilize encrypted protocols for all transmissions.
SSH and its accompanying tools are included by default with most major Linux distributions, as they are the de facto standard. SSH provides many benefits, including
Prevention of host spoofing (host authentication)
Secure file transfer
There are two versions of SSH available, protocols 1 and 2. Protocol 1 had a couple of issues that were of concern, primarily because of patent issues with RSA (RSA was patented, but that patent has run out) and security concerns, such as the vulnerability for insertion attacks. Protocol 2 is rewritten with security in mind and used a non-patented algorithm (DSA).While protocol 2 is the more secure of the two protocols, some environments require protocol 1 use, so you may have to allow both to run for maximum compatibility. This is wholly dependent on your environment, and if at all possible, you should use protocol 2 for all SSH connections due to its enhanced security.
Before you can use SSH for network communications, you need to ensure that both the host and server have SSH installed (and a server available for the client to connect to) as well as allowing TCP port 22 through your firewall (as discussed in Chapter 3). If you are using TCP wrappers, you will need to allow SSHD access in /etc/ hosts .allow. RHEL AS 3.0 and SUSE SLES8 have SSH installed and enabled by default, but if you are running a Linux distribution that doesn t have it installed, you can visit http://www.openssh.org/ to download and install the latest version.
To use these tools, you can use the ssh command just like you would the telnet command. You have to provide the hostname as an argument to the command, so if you were trying to connect to a machine called linux2, you would type
If this were the first time you were connecting to the machine via SSH, you would see output similar to that shown in Figure 10-1.
Lines 2, 3, and 4 show a feature of SSH that prevents spoofing of a trusted machine, meaning that it prevents one machine from presenting itself as another, so you can be generally assured that you are connected to the correct machine. To determine the hostkey fingerprint for the server you are connecting to, use the ssh-keygen -l command. When asked for the file the key is in, use /etc/ssh/ssh_host_rsa_key or /etc/ssh/ssh_host_dsa_key, with /etc/ssh/ssh_host_rsa_key as the default. Figure 10-2 shows the output of the command run from the machine locally. Note there are two ways to run the command, with the -l option and with the -lf option, both of which produce the same results.
|Heads Up|| |
Don't run ssh-keygen from the initial ssh connection, as you are only verifying the machine you are connected to, not necessarily the one you think it is. You will want to separately run it on the remote machine locally (via console or trusted network connection) to ensure you are getting the fingerprint of the machine you want.
Your key fingerprint should match what the remote machine shows as the key fingerprint. If you have connected to the machine in the past and you see a message similar to that in Figure 10-3, you should terminate your connection if the system doesn t do so automatically and contact the system administrator of the remote machine.
This indicates that there is a difference between the hostkey you have and the hostkey the server presents . This could be as innocuous as a simple key regeneration on the distant end or reinstallation of software, or it could be that someone is trying to intercept your traffic. Always err on the side of caution and investigate the cause behind the change.
A habit you should get into, especially if you are logging in as another user from time to time, is to specify the user you want to connect to the remote machine as. This alleviates the problem of trying to connect to the remote server as the user you are logged in as, which may not be the same user you want to connect as. To do this, you only need to specify on the command line as follows :
This tells SSH you want to log in as jdoe even if you are currently logged in as root on the machine you are connecting from. If you don t specify the user, SSH will try to log onto the remote machine as the user you are currently logged on as. This is because it will pass the username of the account you are logged in if you don t specify it, which could be a problem when accounts are local to the machine and possibly different.
In some environments, you will have legacy applications that might require running remote commands on another system via scripts. This was often done in the past using rsh and rlogin , which are unencrypted protocols. SSH allows for the same functionality, with much more security. Password-free logins allow you to use the public key infrastructure to allow machines to log in using public keys instead of using a simple username/password combination. There are multiple ways to use SSH for password-free logins, including host-based authentication, using trust relationships between systems, rhosts authentication, which can be set up to allow password-free logins via a file, and the version we will be talking about, identity-based authentication. The steps outlined for password-free logins will seem attractive for everyday use, but you should only use this when required and if at all possible avoid using it on the root account. If you aren t using ssh-agent and someone breaks into your system and gains access to an account on one system, you have handed them access to multiple other systems as well.
The steps involved in setting up password-free logins are shown next and described in the rest of this section.
Set up keys using ssh-keygen .
Ensure files are created in your home directory s .ssh directory.
Put a copy of the local machine s public key to the remote server.
Modify permissions on the remote server s .ssh directory and public key files.
You will need to set up the keys first by running one of the following commands in your home directory:
ssh-keygen -t dsa ssh-keygen -t rsa
As shown in Figure 10-4, the tilde ( ~ ) represents the home directory, which in this case is /home/jdoe. If you choose not to enter a passphrase, you are removing some of the security functionality of SSH and it is therefore highly discouraged. We will assume you are going to enter a passphrase and use ssh-agent . Depending on your requirements, you may decide that you cannot run ssh-agent and not enter a passphrase.
|Heads Up|| |
With ssh-agent , you will be required to enter a passphrase at least once, which may present a problem if your machine is rebooted or another issue causes ssh-agent to lose the password. You may be tempted to not use a password because of this, but this creates tremendous security vulnerabilities if an unauthorized or malicious entity gains access to the account with ssh-agent enabled. With no password the attacker can then potentially access other systems on the network that have SSH logins enabled with no password.
After generating the keys, you will see that you have two new files in your home directory, an .ssh directory called id_rsa and id_rsa.pub as shown in Figure 10-4 (you can also create dsa keys using the -t dsa command in addition to or in place of the -t rsa command). Your private key is id_rsa and id_rsa.pub is your public key, or if you re using dsa, your files will be id_dsa and id_dsa.pub for your private and public key, respectively. You will now need to put a copy of your public key on the server you want to connect to, using the sftp or scp command. If we wanted to put jdoe s public key on linux2, so that he could log in without a password on linux2, we would run the sftp command (as noted later in this chapter in the section Replace r services and FTP with SSH Equivalents ) to connect to the remote server, create a .ssh directory in the login directory if it doesn t already exist, and then copy the id_rsa.pub (or id_dsa.pub) file from the local home directory to the remote directory. An example of this process is shown in Figure 10-5.
SSH requires a strict permission set on the files for security reasons. You will need to modify your .ssh directory to have read/write/execute for the owner only permissions, using the following command:
chmod 700 ~/.ssh
The authorized keys file will need read-only permissions for the owner, as follows:
chmod 400 ~/.ssh/authorized_keys
For maximum protection you should also provide read-only permission for the owner on your private key on the host. Since you entered in a passphrase when you generated your key, you need to have a way to pass those keys to the programs that will use SSH. To do this, you need to run ssh-agent , which passes your passphrase to other processes spawned from the original. Run the ssh-agent and ssh-add commands as shown in Figure 10-6, and then you will only have to enter your password the one time for any processes spawned from that shell window.
If you want to automate the process somewhat, you can add an entry to your .bashrc (or other initialization file) to run ssh-agent automatically upon login, and you will be asked your password at login or bootup , which makes it available for the entire session. If you didn t enter a passphrase during key generation, by pressing RETURN only, you would not need to add the ssh-agent portion of this as there is no passphrase required. We only mention it because it is required for some environments due to operating constraints, but again, this is highly discouraged as you weaken the built-in security that SSH provides and open a path for intrusion to other systems if the main server is compromised.
The functionality that rsh and rlogin provide can be easily replaced by SSH using the password-free login mentioned before, while providing encryption for the session. The rsh and rlogin commands are usually used in environments that permit password-free logins between machines for scripting or ease of use. Another function that is provided by rsh is that users can run commands without actually logging in to an interactive session. The benefit of using SSH instead of rsh or rlogin is that the session is encrypted and the authentication mechanisms are more secure. To do this with SSH, you need to provide the command you run after the login information within quotation ( ) or tick (") marks as shown in Figure 10-7.
Note that in this example the user is still on the original machine after the command completes. This allows you to script commands to run on different machines without an interactive session, similar to the functionality provided by rsh . Some programs run interactively and these will require that you use the -t option in order to set up a pseudo-terminal so that you may run the application interactively (such as pine, links, and so on).
sftp provides the same functionality as provided by FTP, with the same command structure as well. To use sftp you need only type the command as you would ftp , such as
although a better way is to specify the user you will be sftp -ing as, similar to
Most commands are similar to the ftp command as well as having some added features that can be found by using pressing ? and pressing RETURN at the sftp > prompt. One particularly interesting option is -b (for batch), which allows you to script commands to sftp . This works with non-interactive authentication (password-free login as described previously in this chapter). One benefit of this is if you consistently run a set series of commands with the sftp command, you can put those commands in a file and run them in the order listed in the file. For instance, you have a process that you run every hour of every weekday where you download a file called production_file with get , upload a different file to the server called put_file with put , and then remove the original production_file using the rm command. Every hour a new version of all these files is put on the system from another program, so every time the data is new. Instead of running these commands every time interactively, you can put the three commands in a file and use the -b option to run them. In our example, we could put the following commands in a text file called hourly_process, which would contain the following lines:
get production file put put_file rm production_file
We could now run the following command to replace three interactive commands that would have been required without the -b option ( assuming the file is in /home/jdoe):
sftp -b /home/jdoe/hourly_process jdoe@linux1
rcp provides the ability to copy files to a remote system without an interactive session, making the transmission of files via script or one-line commands extremely easy. This functionality is provided by the scp command that comes with SSH (which is encrypted). To use this command you need to provide the name of the file you want to copy, the machine you want to copy it to, and the new filename. The format for this command is
scp < filename > < username >@< remote machine hostname or IP >:< filename to save as >
Figure 10-8 shows jdoe copying a file in his current directory from linux1 to linux2 and an ls of jdoe s home directory after the copy.
One of strong points of scp is that it can easily be inserted into a shell script when used in conjunction with password-free logins for non-interactive scripting. These tools allow you to replace most of the more insecure, unencrypted protocols that may exist on your network, increasing your overall security posture .
SSH provides the ability to encrypt other TCP/IP protocols via a technique called port forwarding or tunneling. You need to have SSH installed on the local and remote machines you are trying to port forward to, but other than that, there are no special requirements for implementation of this. SSH port forwarding allows your users to encrypt traffic that would otherwise be unencrypted and hence not as secure. When using these techniques you are only encrypting the connections specified and not all your communications, which is something that a virtual private network (VPN) does. SSH port forwarding could be set up to allow an external host that is not within your network to a border host (externally exposed server with firewall protections ) for instance. An example of this is that you have a Linux mail server on your network. Using SSH port forwarding, you can set up your Windows client to check e-mail via an encrypted session. SSH port forwarding is not limited to this specific example, but can be used for any protocol the administrator needs. To enable this, you only need to provide an argument to the standard ssh command. The syntax for running port forwarding from the local host to a remote host is as follows:
ssh -L < local port to forward >:< hostname (usually localhost ) >:< remote port > < username to forward as >@< hostname to forward packets to >
To allow remote connections to connect to the local port, use this syntax:
ssh -R < remote port >:< hostname (usually localhost ) >:< local port to forward )> < username to forward as >@< hostname >
To better understand the process, the following example is one where it is necessary to allow FTP connections, but you do not want to allow unencrypted FTP traffic. Your FTP server is linux2. Your users will be connecting to linux2 while connected to linux1. To set up a connection on the local host, you would type the following at a command prompt on linux1:
ssh -L 9001:localhost:21 jdoe@linux2
You can now open another terminal on linux1 and run this command:
ftp localhost 9001
You can only forward ports below 1024 as root for security reasons, but all other ports can be forwarded as any valid user (the first port before the hostname). When running the command you are connecting to the local host (127.0.0.1), which is another name for the local machine, on port 9001. This request is forwarded over the encrypted path to port 21 on the remote computer (via SSH).
Another scenario might be that you want to check your e-mail on a remote server that also supports SSH from your local computer named linux1. Your mail server is linux2, which uses port 25 (SMTP) for sending your mail and port 110 (POP3) to receive your mail. Your login is jdoe and you want to check your mail over an encrypted transmission. You can run the following command on your local computer:
ssh -L 9090:localhost:25 -L 9091:localhost:110 jdoe@linux2 -N
This forwards ports 9090 and 9091 to 25 and 110 on linux2, respectively, without running a command ( -N ). In your mail client, you would configure your mail to use localhost (or 127.0.0.1) as the mail server for send and receive, port 9090 for sending mail, and port 9091 for receiving mail. When you check your mail, it will be encrypted and carried over the SSH transmission.
If you have Windows clients that have a mail client such as Outlook or Eudora, you can set up your users to use SSH port forwarding as well. Using an SSH client that supports port forwarding, you can give your Windows users the same functionality for encryption that your Linux users enjoy. PuTTY (http://www.chiark.greenend.org.uk/~sgtatham/putty/) is a Windows SSH client that supports SSH port forwarding and includes documentation on using these features.
Remote forwarding works in the same manner as local forwarding with some minor adjustments as noted previously. Using the -g option allows other machines to use your remote tunnel as well, although you should be careful in using this as it does give you the ability to encrypt partial points of a transmission if you can t encrypt an entire session.
Using -N at the end of the forwarded command will tell SSH to not execute any commands so you don t get a shell on the remote machine you are forwarding to. If you set up your keys and are using ssh-agent , you won t be prompted for your password after the first time you enter it, making port forwarding very unobtrusive . You can identify what connections are currently open by pressing ~# in the terminal you started your forward in. You should also note that SSH port forwarding is good for as long as your SSH session is open. When you close it, you will lose the port forwarding that you had. This can be easily scripted and added to your initialization or startup files in conjunction with ssh-agent .
You can make this a little easier for users and yourself by adding the port forwarding capabilities to the ssh_config file. Edit your /etc/ssh/ssh_config file and use LocalForward or RemoteForward as appropriate to the type of forward you are doing. For the command
ssh -L 9001:localhost:21 jdoe@linux2
we can add the following to the /etc/ssh/ssh_config:
Host linux2ftp Hostname linux2 LocalForward 9001 localhost:21
The first Host line specifies the alias we are going to use to call the directive. Hostname is the host the forward is going to, and the LocalForward line is the local port to forward, the hostname of the local forward (usually localhost), and the remote port to use. To use the command to start port forwarding, you would type
Your local forward is run from that point. The same format applies to the RemoteForward directive.
Before using SSH forwarding, you should determine if it violates your company s security policy, as it could be seen (and is sometimes used) to subvert firewall rules that have been put in place for the protection of the network. Attackers can also use these techniques to mask their activities through encryption and by subverting firewall restrictions on ports other than SSH.
SSH allows you to secure your X Window communications between an X server and a client. This allows you to run graphical programs from one machine onto another machine, with full encryption and the protection of SSH. This could be useful if you want to run a graphical configuration utility, check packages via a package manager on another machine, or just run any other type of graphical applications off a server without having to log in locally.
The first step in configuring X11 forwarding is to edit the /etc/ssh/sshd_config file and set the X11Forwarding directive to yes. Restart sshd as follows:
[root@linux1 ssh]# /etc/init.d/sshd restart Stopping sshd: [ OK ] Starting sshd: [ OK ] [root@linux1 ssh]#
To use the graphical programs, you only need to ssh with the -X option and after logging in, run the command you normally would on the remote system. The graphical program will come onscreen on your local machine. For instance, if you wanted to run xeyes graphically on your local machine (linux1) from a remote connection (linux2), you would run these commands:
ssh -X linux2 xeyes
This would show an xeyes initiation on your local machine served from the remote machine. This should be used with caution, as it could be used for nefarious purposes as described in the man pages.
A virtual private network (VPN) is a private, encrypted network that traverses a public network. This offers the VPN user security and network resources without the added costs of a dedicated network line. Most companies use VPNs today to allow remote users or different offices to communicate with one another over the Internet, at a significantly reduced cost than previously required. VPNs can be set up over any type of network connection, such as a leased line, but the standard use is over public networks. VPNs should be configured and planned carefully , and should be implemented with care. Most medium to large organizations will implement dedicated VPN solutions, managed by trained network staff. There are many VPN programs available, and this chapter will briefly cover one of the easier to install programs. Note that there are other more complicated, but equally robust packages available such as FreeS /WAN (http://www.freeswan.org/).
CIPE (Crypto IP Encapsulation) is a relatively easy to use VPN implementation that operates on the network level and is available on the CDs that come with SUSE SLES8 and Red Hat Enterprise Linux AS 3.0. To set up CIPE you need to install it from your distribution CDs or you can download it from the CIPE homepage at http:// sourceforge .net/projects/cipe-linux (click on the homepage section to see the latest files), which is the recommended route.
To use CIPE, you need to configure a few parameters in a file called options. Copy the options template file located in either /usr/share/doc/cipe<VERSION>/samples/options or /etc/cipe/samples.options to /etc/cipe/options. There you need to configure the /etc/cipe/options file and configure your local area network addresses and the publicly routable addresses of your firewall. Here a sample:
# Surprise, this file allows comments (but only on a line by themselves) # This is probably the minimal set of options that has to be set # Without a "device" line, the device is picked dynamically # the peer's IP address ptpaddr <My IP Address for this virtual link> # our CIPE device's IP address ipaddr <Remote IP Address for this virtual link> # my UDP address. Note: if you set port 0 here, the system will pick # one and tell it to you via the ip-up script. Same holds for IP 0.0.0.0. me <My Routeable IP>:<a port that I choose> # ...and the UDP address we connect to. Of course no wildcards here. peer <The Remote Routeable IP>:<a port that I choose> # The static key. Keep this file secret! # The key is 128 bits in hexadecimal notation. key 1234567890abcdefghijklmnopqrstuv
This file will need to be configured on both endpoints and the comments above apply to the machine you are one. So <my routable IP> is the routable IP of the machine you are configuring the options file on. Here s an example CIPE options file for the local machine:
# Surprise, this file allows comments (but only on a line by themselves) # This is probably the minimal set of options that has to be set # Without a "device" line, the device is picked dynamically # the peer's IP address ptpaddr 192.168.10.1 # our CIPE device's IP address ipaddr 192.168.20.1 # my UDP address. Note: if you set port 0 here, the system will pick # one and tell it to you via the ip-up script. Same holds for IP 0.0.0.0. me 10.0.0.1:8080 # ...and the UDP address we connect to. Of course no wildcards here. peer 10.0.0.2:8080 # The static key. Keep this file secret! # The key is 128 bits in hexadecimal notation. key 1234567890abcdefghijklmnopqrstuv
Here s an example CIPE options file for the remote machine:
# Surprise, this file allows comments (but only on a line by themselves) # This is probably the minimal set of options that has to be set # Without a "device" line, the device is picked dynamically # the peer's IP address ptpaddr 192.168.20.1 # our CIPE device's IP address ipaddr 192.168.10.1 # my UDP address. Note: if you set port 0 here, the system will pick # one and tell it to you via the ip-up script. Same holds for IP 0.0.0.0. me 10.0.0.2:8080 # ...and the UDP address we connect to. Of course no wildcards here. peer 10.0.0.1:8080 # The static key. Keep this file secret! # The key is 128 bits in hexadecimal notation. key 1234567890abcdefghijklmnopqrstuv
Your firewalls will need to allow the traffic on the ports you indicate on the UDP address lines (in the previous example, port 8080 would need to be allowed incoming and outgoing traffic, as that is the port that is in use).
The 10.0.0.0 network is not really routable, but in this example we are using it in place of where you would put your real, routable IP. The shared secret key must be the same in both configuration files. You can create a quick key with a command such as
#cat /var/log/messages md5sum 1234567890abcdefghijklmnopqrstuv -
The shared secret key (or static link keys) is a reference key for the different CIPE networks to pass information to each other. It is absolutely imperative if you use a shared secret key that you keep the keys secure and private. You should set appropriate file permissions on the /etc/cipe/options file as discussed in Chapter 6 to prevent unauthorized users from viewing the shared keys.
Set the permissions to remove read, write, and execute permissions for group and others on the /etc/cipe/options file before running cipe-cb , use
chmod go-rwx /etc/cipe/options
CIPE also supports the use of public keys with PKCIPE if you do not want to use shared secret keys. Now that your configuration files are set up, you can start CIPE by running the ciped-cb command. To add network routes, you can edit the /etc/cipe/ip-up and /etc/cipe/ip-down scripts for additional interfaces for your environment. You are ready to use the VPN.
For more information on CIPE and some of its many uses, see the CIPE homepage at http://sites.inka.de/bigred/ devel /cipe.html or the Red Hat documentation at http://www.redhat.com/docs/manuals/linux/ ( specifically look at the security guide for information on CIPE).