Quick HOWTO : Ch17 : Secure Remote Logins and File Copying

来自Ubuntu中文
跳到导航跳到搜索

{{#ifexist: :Quick HOWTO : Ch17 : Secure Remote Logins and File Copying/zh | | {{#ifexist: Quick HOWTO : Ch17 : Secure Remote Logins and File Copying/zh | | {{#ifeq: {{#titleparts:Quick HOWTO : Ch17 : Secure Remote Logins and File Copying|1|-1|}} | zh | | }} }} }} {{#ifeq: {{#titleparts:Quick HOWTO : Ch17 : Secure Remote Logins and File Copying|1|-1|}} | zh | | }}


Introduction

One of the most popular file transfer and remote login Linux applications is OpenSSH, which provides a number of ways to create encrypted remote terminal and file transfer connections between clients and servers. The OpenSSH Secure Copy (SCP) and Secure FTP (SFTP) programs are secure replacements for FTP, and Secure Shell (SSH) is often used as a stealthy alternative to TELNET. OpenSSH isn't limited to Linux; SSH and SCP clients are available for most operating systems including Windows.

A Quick Introduction To SSH Encryption

Data encryption is accomplished by using special mathematical equations to scramble the bits in a data stream to make it unreadable to anyone who does not have access to the corresponding decryption equation. The process is usually made even harder through the use of an encryption key that is used to modify the way the equations do the scrambling. You can recover the original data only if you have access to this key and the corresponding programs. Data encryption helps to prevent unauthorized users from having access to the data.

SSH uses the concept of randomly generated private and public keys to do its encryption. The keys are usually created only once, but you have the option of regenerating them should they become compromised.

A successful exchange of encrypted data requires the receiver to have a copy of the sender's public key beforehand. Here's how it's done with SSH.

When you log into an SSH server, you are prompted as to whether you want to accept the download of the server's public key before you can proceed. The SSH client's key is uploaded to the server at the same time. This creates a situation in which the computers at each end of the SSH connection have each other's keys and are able to decrypt the data sent from the other end of the encrypted link or "tunnel".

All the public keys that an SSH client's Linux user encounters are stored in a file named ~/.ssh/known_hosts along with the IP address that provided it. If a key and IP address no longer match, then SSH knows that something is wrong. For example, reinstalling the operating system or upgrading the SSH application might regenerate the keys. Of course, keys changes can be caused by someone trying some sort of cyber attack, as well. Always investigate changes to be safe. Your server's own public and private SSH keys are stored in the /etc/ssh/ directory.

Note: The .ssh directory is a hidden directory, as are all files and directories whose names begin with a period. The ls -a command lists all normal and hidden files in a directory. The ~/ notation is a universally accepted way of referring to your home directory and is recognized by all Linux commands.

Linux uses other key files also to provide the capability of password-less logins and file copying to remote servers using SSH and SCP. In this case, the SSH connection is established, then the client automatically sends its public key which the server uses to match against a predefined list in the user's directory. If there is a match then the login is authorized. These files are also stored in your ~/.ssh directory and need to be specially generated. The id_dsa and id_dsa.pub files are your private and public keys respectively, and authorized_keys stores all the authorized public keys from remote hosts that may log into your account without the need for passwords (more on this later).

Starting OpenSSH

OpenSSH is installed by default during Linux installations. With Ubuntu / Debian, this may not be the case and it will have to be installed after the initial installation. The apt-get install ssh command will be sufficient to activate SSH using these latter mentioned distributions.

Because SSH and SCP are part of the same application, they share the same configuration file and are governed by the same /etc/init.d/sshd startup script.

You can configure SSH to start at boot by using the chkconfig command when running Fedora / Redhat or with the sysv-rc-conf command with Debian / Ubuntu.

[root@bigboy tmp]# chkconfig sshd on

You can also start, stop, and restart SSH after booting by running the sshd initialization script.

[root@bigboy tmp]# service sshd start
[root@bigboy tmp]# service sshd stop
[root@bigboy tmp]# service sshd restart

Remember to restart the SSH process every time you make a change to the configuration files for the changes to take effect on the running process.

Testing The Status of SSH

You can test whether the SSH process is running with

[root@bigboy tmp]# pgrep sshd

You should get a response of plain old process ID numbers.

The /etc/ssh/sshd_config File

The SSH configuration file is called /etc/ssh/sshd_config. By default SSH listens on all your NICs and uses TCP port 22. Take a look at a snippet from configuration:

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options change a
# default value.

#Port 22
#Protocol 2,1

#ListenAddress 0.0.0.0
#ListenAddress ::

SSH Versions 1 and 2

The original encryption scheme of SSH was adequate for its time but was eventually found to have a number of limitations. The answer to these was version 2. Always force your systems to operate exclusively with version 2 by setting the protocol statement in the /etc/ssh/sshd_config file to 2. Remember to restart SSH to make this take effect.

#
# File: /etc/ssh/sshd_config
#

Protocol 2

How To Change The TCP Port On Which SSH Listens

If you are afraid of people trying to hack in on a well known TCP port, then you can change port 22 to a location that won't interfere with other applications on your system, such as port 435. This is a rudimentary precaution only, because good network scanning programs can detect SSH running on alternative ports.

What you need to do is:

1) Use the netstat command to make sure your system isn't listening on port 435, using grep to filter out everything that doesn't have the string "435":

[root@bigboy root]# netstat -an | grep 435
[root@bigboy root]#

2) No response allows us to proceed. Change the Port line in /etc/ssh/sshd_config to mention 435 and remove the # at the beginning of the line. If port 435 is being used, pick another port and try again.

Port 435

3) Restart SSH:

[root@bigboy tmp]# service sshd restart

4) Check to ensure SSH is running on the new port:

[root@bigboy root]# netstat -an | grep 435
tcp    0    0    192.168.1.100:435    0.0.0.0:*    LISTEN
[root@bigboy root]#

Next you'll discover how to actually login to systems using SSH.

Using SSH To Login To A Remote Machine

Using SSH is similar to Telnet. To login from another Linux box use the ssh command with a -l to specify the username you wish to login as. If you leave out the -l, your username will not change. Here are some examples for a server named smallfry in your /etc/hosts file.

If you are user root and you want to log in to smallfry as yourself, use the command

[root@bigboy tmp]# ssh smallfry

User root can also log in to Smallfry as user peter via the default port 22:

[root@bigboy tmp]# ssh -l peter smallfry

or via port 435 using the username@remote_server alternative login format:

[root@bigboy tmp]# ssh -p 435 peter@smallfry

What To Expect With Your First Login

The first time you log in, you get a warning message saying that the remote host doesn't know about your machine and prompting you to store a copy of the remote host's SSH identification keys on your local machine. It will look something like this:

[root@bigboy tmp]# ssh smallfry
The authenticity of host 'smallfry (smallfry)' can't be established.
RSA key fingerprint is 5d:d2:f5:21:fa:07:64:0d:63:1b:3b:ee:a6:58:58:bb.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'smallfry' (RSA) to the list of known hosts. root@smallfry's password:
Last login: Thu Nov 14 10:18:45 2002 from 192.168.1.98
No mail.
[root@smallfry tmp]#

The key is stored in your ~/.ssh/known_hosts file and you should never be prompted for this again.

SSH Failures Due To Linux Reinstallations

If Linux or SSH is reinstalled on the remote server then the keys are regenerated and your SSH client will detect that this new key doesn't match the saved value in the known_hosts file. The SSH client will fail giving an error like this, erring on the side of caution to alert you to the possibility of a form of hacking attack.

[root@bigboy tmp]# ssh 192.168.1.102
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
5d:d2:f5:21:fa:07:64:0d:63:1b:3b:ee:a6:58:58:bb.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending key in /root/.ssh/known_hosts:2
RSA host key for 192.168.1.102 has changed and you have requested strict checking.
Host key verification failed.
[root@bigboy tmp]#

If you are confident that the error is due to a reinstallation, then edit your ~/.ssh/known_hosts text file, removing the entry for the offending remote server. When you try connecting via SSH again, you'll be prompted to add the new key to your ~/.ssh/known_hosts file and the login session should proceed as normal after that.

Deactivating Telnet After Installing SSH

You should always consider SSH over TELNET, because of the inherent data encryption features of SSH and the current widespread availability of SSH clients for both Linux and Windows.

By default, the TELNET server isn't installed with Fedora Linux. If you do decide to deactivate an active TELNET server, then use procedures detailed in Chapter 16, "Telnet, TFTP, and xinetd".

Executing Remote Commands on Demand with SSH

A nice feature of SSH is that it is capable of logging in and executing single commands on a remote system. You just have to place the remote command, enclosed in quotes, at the end of the ssh command of the local server. In the example below, a user on server smallfry who needs to know the version of the kernel running on server bigboy (192.168.1.100) remotely runs the uname -a command. The command returns the version of 2.6.8-1.521 and the server's name, bigboy.

[root@smallfry tmp]# ssh 192.168.1.100 "uname -a"
[email protected]'s password:
Linux bigboy 2.6.8-1.521 #1 Mon Aug 16 09:01:18 EDT 2004 i686 i686 i386 GNU/Linux
[root@smallfry tmp]#

This feature can be very useful. You can combine it with password-free login, explained later in this chapter, to get the status of a remote server whenever you need it. More comprehensive monitoring may best be left to such purpose built programs as MRTG, which is covered in Chapter 22, " Monitoring Server Performance".

SSH Tunneling

You already know that SSH creates an encrypted data session between a client and server. With SSH tunneling the server computer can also receive data from other computers on the client's network over the very same session. The client is configured to listen on a specified TCP port and all data received on that port will be automatically SSH encrypted and relayed to the remote server. It is for this reason that SSH tunneling is also called SSH port forwarding.

There are two types of forwarding:

Local Forwarding: Forwards traffic coming to a local port to a specified remote port. This is also known as outgoing tunneling, as the tunnel is established to the remote server.

Remote Forwarding: Forwards traffic coming to a remote port to a specified local port. This is also known as incoming tunneling, as the tunnel is established from the remote server.

As always it is best to explain these methodologies with some examples.

Local Forwarding

The syntax for local forwarding relies on the -L SSH command line qualifier which is configured like this:

-L bind-address:bind-port:remote-server-address:remote-port

Where the bind-address and bind-port are the IP address and TCP port on which the local computer will listen for connections from its neighbors. If the bind-address isn't listed, then the server will only accept connections from localhost. The remote-server-address and remote-port specify the same options for the remote server.

Note: Sometimes an intermediary relay host for the data can be used. In this case the data passes through an encrypted SSH connection for the part of the journey between the local server and the intermediary. The connection between the intermediary and remote host is not. This is not a security issue when forwarding SSH traffic, which is already encrypted, but it can be so when forwarding unencrypted data such as POP mail, SMTP mail or, telnet.
Intermediaries can be useful especially when the intermediary host is the only host on the local network with access to the remote host.

Here are some explanatory examples:

Example 1: The local computer forwards any connection to its NIC IP address on a specified port to a remote host.

[root@bigboy ~]# ssh -L 192.168.1.100:9999:216.10.135.26:22  [email protected]
[email protected]'s password: 
Last login: Sat Mar 17 22:00:50 2007 from 192.168.1.201
[root@bigboy ~]#

Here server bigboy is configured to forward any connections its NIC IP address of 192.168.1.100 receives on port 9999 to port 22 on server 216.10.135.26.

The outbound connection to 216.10.135.26 is managed by a separate shell process with the login credentials you specify. In this case the connection will be created on bigboy itself, 192.168.1.100, and will run as user root. This can be tricky, as after executing this command it will appear as if you have logged into bigboy all over again and nothing appears to be happening. Don't be fooled, the new login is shell is the master process for the connection that needs to be created. If you log out, the forwarding will be broken.

This can easily be tested. Using SSH to connect to bigboy on port 9999 actually logs you into the remote server web-003.

[root@smallfry ~]# ssh -p 9999 [email protected]
[email protected]'s password: 
Last login: Sat Mar 17 21:56:03 2007 from home.my-web-site.org
[root@web-003 ~]#

You can then use the netstat and ps commands to verify that the shell process has been created and that the connection has been established.

[root@bigboy ~]# netstat -an | grep 216.10.135.26
tcp   0   0   192.168.1.100:36342   216.10.135.26:22   ESTABLISHED 
[root@bigboy ~]#

[root@bigboy ~]# ps -ef | grep 216.10.135.26
root     22901 21955  0 13:59 pts/0    00:00:00 ssh -L 192.168.2.200:9999:216.10.135.26:222 -p 222 [email protected]
[root@bigboy ~]#

Forwarding can be useful! Let's see some more examples.

Example 2: The local computer forwards any connection to localhost on a specified port, to a remote host via an intermediary server. Connection's to the local computer's NIC on the specified port is not allowed.

[root@smallfry ~]# ssh -L localhost:9999:216.10.135.26:22 \
  [email protected] 
[email protected]'s password: 
[root@bigboy ~]#

Here server smallfry is configured to local forward any connections its localhost IP address receives on port 9999 to port 22 on a remote server with an IP address of 216.10.135.26. Server bigboy is used as the intermediary.

[root@smallfry ~]# ssh -p 9999 localhost
root@localhost's password: 
Last login: Sat Mar 17 20:11:09 2007 from home.my-web-site.org
[root@web-003 ~]#

You can use the netstat command on smallfry and bigboy to verify that connections have been established between bigboy and web-003, and smallfry and bigboy.

[root@smallfry ~]# netstat -an | grep EST | grep 192.168.1.100
tcp   0   0   192.168.1.50:40679   192.168.1.100:22   ESTABLISHED 
[root@smallfry ~]#
[root@bigboy ~]# netstat -an | grep EST | grep 216.10.135.26 
tcp    0   0   192.168.1.100:56236  216.10.135.26:22   ESTABLISHED 
[root@bigboy ~]#

SSH connections to the NICs of either bigboy or smallfry fail.

[root@smallfry ~]# ssh -p 9999 192.168.1.100
ssh: connect to host 192.168.1.100 port 9999: Connection refused
[root@smallfry ~]# ssh -p 9999 192.168.1.50 
ssh: connect to host 192.168.1.50 port 9999: Connection refused
[root@smallfry ~]# 

The final example which follows discusses forwarding unencrypted protocols.

Example 3: The local computer forwards any POP mail queries to localhost directly to the remote POP mail server over an SSH tunnel.

[root@smallfry ~]# ssh -L 9999:mailserver:110 root@mailserver
root@mailserver's password: 
Last login: Sat Mar 17 20:11:09 2007 from home.my-web-site.org
[root@mailserver ~]#

In this case an SSH connection is created to mailserver using a shell process owned by user root. The server mailserver then creates an unencrypted POP session (TCP port 110) to itself. The advantage of this configuration is that POP data never leaves the POP server unencrypted.

POP mail users on smallfry can then get their mail over the encrypted link by configuring localhost as the POP mail server in their mail client, and not mailserver.


Remote Forwarding

The syntax for local forwarding relies on the -R SSH command line qualifier which is configured like this:

-R bind-address:bind-port:remote-server-address:remote-port

The syntax is similar to that of the -L option. The bind-address and bind-port are the IP address and TCP port on which the local computer will listen for connections from its neighbors. If the bind-address isn't listed, then the server will only accept connections from localhost. The remote-server-address and remote-port specify the same options for the remote server and are from the remote server's perspective. If you specify localhost as the remote-server-address, SSH will be interpret it to mean the Internet IP address of the remote server.

This can be useful in a number of scenarios. For example, you cannot connect to your office workstation via VPN due to network maintenance, but during this time your workstation still has access to the Internet. Remote forwarding could provide you with access.

Here's another scenario. You are moving into a new Internet data center, all the network gear has been configured, but the installation of the data circuits has been delayed. This has caused the configuration of the servers to be delayed. If one server wired to your network can get access to a server on the Internet, via a wireless card, or otherwise, then remote access to the data center could be achieved using remote forwarding.

Example 1: The local computer forwards any connection to localhost on a specified port to a remote host. Forwarding occurs over a previously established connection from the remote host. If we revisit our scenario where VPN access will be down due to maintenance, the first thing to be done is to configure your workstation at work to establish a remote forwarding SSH session to your home server.

[root@work-001 ~]# ssh -R localhost:9999:localhost:22 [email protected]
[email protected]'s password: 
Last login: Sat Mar 17 21:15:36 2007 from 216.10.135.26
[root@bigboy ~]# ping localhost
PING bigboy (127.0.0.1) 56(84) bytes of data.
64 bytes from bigboy (127.0.0.1): icmp_seq=1 ttl=64 time=0.091 ms
64 bytes from bigboy (127.0.0.1): icmp_seq=2 ttl=64 time=0.082 ms
64 bytes from bigboy (127.0.0.1): icmp_seq=3 ttl=64 time=0.097 ms
64 bytes from bigboy (127.0.0.1): icmp_seq=4 ttl=64 time=0.078 ms

Here workstation work-001 creates an SSH session to server bigboy at home. It also tells bigboy to use this session to forward data to work-001 when bigboy receives SSH connections to localhost on port 9999. Remember, the remote-server-address of the -R option is from the remote server's perspective (work-001). If you specify localhost as the remote-server-address, SSH will be interpret it to mean the Internet IP address of the remote server.

We have setup a ping session to ensure that there is constant traffic between bigboy and work-001 over the connection so that any intermediary firewall doesn't kill it due to inactivity.

When you arrive home, all you have to do is SSH to localhost on your home system to gain access to your workstation at work.

[root@bigboy ~]# ssh -p 9999 root@localhost
root@localhost's password: 
Last login: Sun Mar 18 15:50:16 2007 from 65.115.71.35
[root@work-001 ~]#

As you can see, remote forwarding can be both useful, convenient and productivity enhancing.

Example 2: The local computer forwards any connection to it's NIC on a specified port to a remote host. Forwarding occurs over a previously established connection from the remote host.

This is more fitting for our limited connectivity data center scenario. In this case the local computer can be accessed by anyone on the Internet and it will forward any SSH connections it receives on the specified port to the server in the data center with the wireless access. Here's how it's done:

  • Your local computer may be configured to only accept SSH connections for remote forwarding on the loopback localhost interface. Edit your sshd_config file and make sure the GatewayPorts setting is set to yes.
#
# File: /etc/ssh/sshd_config
#

GatewayPorts yes
Restart the SSH daemon to activate the setting.
[root@netserver-001  ~]# /etc/init.d/sshd restart
Stopping sshd: [  OK  ]
Starting sshd: [  OK  ]
[root@netserver-001  ~]#
  • The next step is to establish the remote port forwarding session. Set up a ping if you need constant activity on the link. In this case Internet server is netserver-001.my-web-site.org.
[root@datacenter-001 ~]# ssh -R netserver-001.my-web-site.org:9999:localhost:22 [email protected]
[email protected]'s password: 
Last login: Sat Mar 17 21:15:36 2007 from 216.10.135.26
[root@netserver-001 ~]# ping localhost
PING netserver-001 (127.0.0.1) 56(84) bytes of data.
64 bytes from netserver-001 (127.0.0.1): icmp_seq=1 ttl=64 time=0.091 ms
64 bytes from netserver-001 (127.0.0.1): icmp_seq=2 ttl=64 time=0.082 ms
64 bytes from netserver-001 (127.0.0.1): icmp_seq=3 ttl=64 time=0.097 ms
64 bytes from netserver-001 (127.0.0.1): icmp_seq=4 ttl=64 time=0.078 ms
Here workstation datacenter-001 creates an SSH session to Internet server netserver-001. It also tells netserver-001 to use this session to forward data to datacenter-001 when netserver-001 receives SSH connections on any interface IP address (*) on port 9999.
  • Now it's time to test it. From our home server bigboy, we can SSH into server netserver-001 on port 9999 and get access to the data center.
[root@bigboy~]# ssh -p 9999 [email protected]
root@ netserver-001.my-web-site.org's password: 
Last login: Sun Mar 18 15:50:16 2007 from 65.115.71.35
[root@datacenter-001 ~]#

Success! You have saved the day with your ingenuity.

Configuring Forwarding with GUI Clients

You won't always have SSH command line access for the servers at both end of a port forwarding connection. Sometimes a GUI is either easier to use, or is your only option.

Most GUI clients will have SSH forwarding capabilities and it will be configurable on each of your saved connections, not globally. The options to do this should be found under the advanced properties or equivalent tab and with your new Linux command line knowledge, the setup should be relatively easy.

Troubleshooting SSH Port Forwarding

There can be many complications with SSH port forwarding, and they are mostly related to typographical errors. Here are a few symptoms that are easy to overcome:

  • If remote forwarding doesn't work from a remote server, but works from localhost, then make sure you have activated the GatewayPorts setting on your computer. If not, change it, restart the SSH daemon and try again.
  • If you get a message like this stating that the address is already in use, then you may have another port forwarding session already started on the port or the port you intend to use for forwarding is already in use by another application.
bind: Address already in use
channel_setup_fwd_listener: cannot listen to port: 9999
Could not request local forwarding.
  • "Connection closed" messages like this one could be caused by typing in an incorrect forwarding address.
ssh_exchange_identification: Connection closed by remote host
  • If you are attempting remote forwarding using your server's NIC IP address and get this message, then it could be because the GatewayPorts setting has been disabled. With local forwarding, it could be caused by specifying an incorrect port on which the server should listen.
[root@bigboy ~]# ssh -p 9999 192.168.1.100
ssh: connect to host 192.168.1.200 port 9999: Connection refused
[root@bigboy ~]

SSH port forwarding is a very useful tool that can provide you with a great deal of versatility when administering your servers. It's always a good thing to remember.

SCP: A Secure Alternative to FTP

From a networking perspective, FTP isn't very secure, because usernames, passwords, and data are sent across the network unencrypted. More secure forms such as SFTP (Secure FTP) and SCP (Secure Copy) are available as a part of the OpenSSH package that is normally installed by default on RedHat and Fedora Core. Remember, unlike FTP, SCP doesn't support anonymous downloads like FTP.

The Linux scp command for copying files has a format similar to that of the regular Linux cp command. The first argument is the source file and the second is the destination file. When copying to or from a remote server, SCP logs in to the server to transfer the data and this therefore requires you to supply a remote server name, username, and password to successfully execute the command. The remote filename is therefore preceded by a prefix of the remote username and server name separated by an @ symbol. The remote filename or directory then follows separated by a colon. The format therefore looks like this:

username@servername:filename
username@servername:directoryname

For example, file /etc/syslog.conf on a server with IP address 192.168.1.100 that needs to be retrieved as user peter would have the format [email protected]:/etc/syslog.conf, the entire /etc directory would be [email protected]:/etc/.

Note: You can download an easy-to-use Windows SCP client called WinSCP from http://winscp.vse.cz/eng/

Copying Files To The Local Linux Box

If you understand how scp represents remote filenames, you can start copying files fairly easily. For example, to copy file /tmp/software.rpm on the remote machine to the local directory /usr/rpm use the commands

[root@bigboy tmp]# scp root@smallfry:/tmp/software.rpm /usr/rpm
root@smallfry's password:
software.rpm                      100% 1011    27.6KB/s   00:00
[root@bigboy tmp]#

To copy the file /tmp/software.rpm on the remote machine to the local directory /usr/rpm using TCP port 435, use the commands

[root@bigboy tmp]# scp -P 435 root@smallfry:/tmp/software.rpm /usr/rpm
root@smallfry's password:
software.rpm                       100% 1011    27.6KB/s   00:00
[root@bigboy tmp]#

Copying Files To The Remote Linux Box

Copying files to the local Linux server now becomes intuitive. For examples, to copy file /etc/hosts on the local machine to directory /tmp on the remote server

[root@bigboy tmp]# scp /etc/hosts [email protected]:/tmp
[email protected]'s password:
hosts                             100% 1011    27.6KB/s   00:00    
[root@bigboy tmp]#

To copy file /etc/hosts on the local machine to directory /tmp on the remote server via TCP port 435, use the commands

[root@bigboy tmp]# scp -P 435 /etc/hosts [email protected]:/tmp
hosts                             100% 1011    27.6KB/s   00:00    
[root@bigboy tmp]#

SFTP: Another Secure Alternative to FTP

OpenSSH also has the SFTP program, which runs over an encrypted SSH session but whose commands mimic those of FTP. SFTP can be more convenient to use than SCP when you are uncertain of the locations of the files you want to copy, because it has the directory browsing abilities of FTP. Unlike FTP, SFTP doesn't support anonymous logins.

Here is a sample login sequence that logs in, gets help on the available commands and downloads a file to the local server.

[root@bigboy tmp]# sftp 192.168.1.200
Connecting to 192.168.1.200...
[email protected]'s password:
sftp> help
Available commands:
cd path                       Change remote directory to 'path'
lcd path                      Change local directory to 'path'
chgrp grp path                Change group of file 'path' to 'grp'
chmod mode path               Change permissions of file 'path' to 'mode'
...
...
sftp> ls
...
...
anaconda-ks.cfg
install.log
install.log.syslog
...
...
sftp> get install.log
install.log                        100%   17KB  39.4KB/s   00:00
sftp> exit
[root@bigboy tmp]#

Using SSH and SCP without a password

From time to time you may want to write scripts that will allow you to copy files to a server, or login, without being prompted for passwords. This can make them simpler to write and also prevents you from having to embed the password in your code.

SCP has a feature that allows you to do this. You no longer have to worry about prying eyes seeing your passwords nor worrying about your script breaking when someone changes the password. You can configure SSH to do this by generating and installing data transfer encryption keys that are tied to the IP addresses of the two servers. The servers then use these pre-installed keys to authenticate one another for each file transfer. As you may expect, this feature doesn't work well with computers with IP addresses that periodically change, such as those obtained via DHCP.

There are some security risks though. The feature is automatically applied to SSH as well. Someone could use your account to log in to the target server by entering the username alone. It is therefore best to implement this using unprivileged accounts on both the source and target servers.

The example that follows enables this feature in one direction (from server bigboy to server smallfry) and only uses the unprivileged account called filecopy.

Configuration: Client Side

Here are the steps you need to do on the computer that acts as the SSH client:

1) Generate your SSH encryption key pair for the filecopy account. Press the Enter key each time you are prompted for a password to be associated with the keys. (Do not enter a password.)

[filecopy@bigboy filecopy]# ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key
(/filecopy/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in
/filecopy/.ssh/id_dsa.
Your public key has been saved in
/filecopy/.ssh/id_dsa.pub.
The key fingerprint is:
1e:73:59:96:25:93:3f:8b:50:39:81:9e:e3:4a:a8:aa
filecopy@bigboy
[filecopy@bigboy filecopy]#

2) These keyfiles are stored in the.ssh subdirectory of your home directory. View the contents of that directory. The file named id_dsa is your private key, and id_dsa.pub is the public key that you will be sharing with your target server. Versions other than RedHat/Fedora may use different filenames, use the SSH man pages to verify this.

[filecopy@bigboy filecopy]# cd ~/.ssh
[filecopy@bigboy filecopy]# ls
id_dsa  id_dsa.pub  known_hosts
[filecopy@bigboy .ssh]#

3) Copy only the public key to the home directory of the account to which you will be sending the file.

[filecopy@bigboy .ssh]# scp id_dsa.pub filecopy@smallfry:public-key.tmp

Now, on to the server side of the operation.

Configuration - Server Side

Here are the steps you need to do on the computer that will act as the SSH server.

1) Log into smallfry as user filecopy. Create an .ssh subdirectory in your home directory and then go to it with cd.

[filecopy@smallfry filecopy]# ls
public-key.tmp
[filecopy@smallfry filecopy]# mkdir .ssh
[filecopy@smallfry filecopy]# chmod 700 .ssh
[filecopy@smallfry filecopy]# cd .ssh

2) Append the public-key.tmp file to the end of the authorized_keys file using the >> append redirector with the cat command. The authorized_keys file contains a listing of all the public keys from machines that are allowed to connect to your Smallfry account without a password. Versions other than RedHat/Fedora may use different filenames, use the SSH man pages to verify this.

[filecopy@smallfry .ssh]# cat ~/public-key.tmp >> authorized_keys
[filecopy@smallfry .ssh]# rm ~/public-key.tmp

From now on you can use ssh and scp as user filecopy from server bigboy to smallfry without being prompted for a password.

Conclusion

Most Linux security books strongly recommend using SSH and SCP over TELNET and FTP because of their encryption capabilities. Despite this, there is still a place for FTP in the world thanks to its convenience in providing simple global access to files and TELNET, which is much easier to implement in price-sensitive network appliances than SSH. Consider all options when choosing your file transfer and remote login programs and select improved security whenever possible as the long term benefits eventually outweigh the additional cost over time.