Using Encryption with Samba
The usual mode of operation for SMB/CIFS, and hence for Samba, is to pass all data, with the possible exception of passwords, over the network unencrypted. This practice is perfectly reasonable on most small wired networks, but sometimes a greater degree of security is in order. The following sections investigate the problem and possible solutions to it, starting with a look at when the lack of encryption is a problem. Three solutions to this problem are using Secure Sockets Layer (SSL) encryption, using a Secure Shell (SSH) tunnel, and using a Virtual Private Network (VPN).
Tip?/td> | Encrypting all data can be a CPU-intensive process and is tedious to configure. In many cases, a much simpler but less complete solution is to change your network hardware. In particular, Ethernet hubs are susceptible to data sniffing. Any computer connected to a hub can monitor all the traffic to or from any other computer on the same hub. Converting your network to use Ethernet switches rather than hubs greatly reduces the severity of this problem because switches direct packets to only the true target computer, thus making sniffers on other computers largely ineffective. (Switches can't completely eliminate sniffing, though; broadcast packets can still be sniffed, and switches' targeted packet delivery can sometimes be disabled. Switches also won't help if a sniffer resides on the source or destination computer itself.) In the case of wireless networks, ensure that your network hardware is configured to encrypt all data, but be aware that wireless encryption protocols are themselves far from perfect. |
The Problem: Lack of Encryption on SMB/CIFS Data Transfers
SMB/CIFS is typically used on local networks, and most people don't bother with encrypting their local network traffic. The unstated assumption is that the "bad guys" don't have direct access to your network wires. This assumption isn't always valid, though. Sometimes the crackers lie in wait disturbingly close to home. They could be corporate spies, disgruntled employees, or true remote crackers who've managed to compromise one of your systems. Although rare, there are also cases where SMB/CIFS is used over the Internet at large. In this case, the packets may traverse a dozen or more computers and their networks, any one of which could hold an unauthorized sniffer. Eavesdropping on wireless networks is extremely easy if they're unencrypted, as many are; a cracker can sit in a car with a laptop computer and listen in on your local wireless data transfers.
In all of these cases, the normal unencrypted mode of operation for SMB/CIFS is a liability. An intruder might be able to steal any data transferred via Samba, such as employee evaluations, product schematics, legal documents, and so on. An intruder can potentially intercept documents as they're being loaded, saved, copied, or printed.
Encryption helps protect sensitive data by making unauthorized decryption difficult to the point of impossibility. A typical workstation, or even a small cluster of them, would have to work for months, years, or centuries to decrypt most modern encryption techniques. (To be sure, governments and very large businesses can afford the computing power to do the job more quickly, but even they can't do it in anywhere near real time.)
Note?/td> | Data encryption, as described here, is somewhat different from password encryption as practiced by SMB/CIFS and in the Unix password database. Encrypted passwords use hashes, which are one-way data transformations. Once hashed, it's mathematically impossible to recover the original data using the hashed password alone. Crackers do the job by encrypting random words until they find a match. Encryption for entire data transfer sessions must be reversible, and much more data is encrypted, which makes the decryption task harder—the sort of dictionary attack that works with password databases won't work on an encrypted SMB/CIFS connection. |
Unfortunately, SMB/CIFS wasn't built with encryption in mind, so using it isn't as simple as setting a Samba parameter or two. Configuring encryption requires taking special steps, and you'll lose some functionality. The practice will also chew up some CPU time on both the clients and the server, thus increasing your network hardware requirements. Therefore, you shouldn't embark on the task of encrypting your data lightly. You must decide whether encrypting your data is worth the effort involved. In most cases, it's not. Most local networks are well enough protected from outside attackers that your main concern is local users. (A partial exception is wireless networks, but these can usually be configured to use encryption via low-level network configuration options.) Although local security shouldn't be taken lightly, chances are good that would-be local data thieves have easier ways of stealing data than sniffing the network wire. This is particularly true if you replace any hubs your network uses with switches. If your network is not protected from the outside world, you should invest your time and effort into doing so by installing a firewall and other security measures. This action will have far greater impact on your overall network security than encrypting your Samba traffic alone. Most methods of encrypting SMB/CIFS data handle only TCP traffic. This means that name resolution and browsing won't work, at least not using the encrypted connections.
Of course, there are exceptions to this rule. One is if your network carries extraordinarily sensitive data. If this is the case, though, you probably have a security expert on hand to help secure your network. Another condition when you might want to encrypt your SMB/CIFS traffic is if that traffic is unusually exposed, say because it's being routed between offices over the Internet. In both of these cases, encrypting some or all of your local network traffic, including your Samba traffic, may make sense.
You may want to consider encryption as falling into two distinct categories. The first is local encryption—encryption of data on your own local network segment. The second category is encryption of traffic that passes between networks. Although both categories share many commonalities in configuration, each has its own unique features.
First Solution: SSL
One solution for encrypting your network data is to use SSL. Through the 2.2.x Samba series, the server included native support for SSL. This support was often omitted from binary packages but could be compiled by issuing the --with-ssl option to the configure script when compiling the server.
Actually using Samba's SSL support required installing an SSL package, such as OpenSSL (http://www.openssl.org), obtaining or creating certificates (digitally signed files that can be used by SSL to prove a system's identity) for each client and the server, and enabling various global smb.conf parameters, most of which began with ssl. Each client also had to be configured with compatible software. Typically, these programs functioned like local proxy servers—they would accept connections from the client to itself but pass the data, using SSL encryption, to the server. This entire process, from Samba configuration through to client configuration, was fairly tedious, but the result was that a Samba server could communicate with a Samba client or with an appropriately configured Windows client using a secure connection. If the concern was with an Internet connection, two servers could function as, in effect, proxies for each other's networks, providing encrypted connections across the Internet and unencrypted local connections.
Unfortunately for fans of SSL, this option has been removed from Samba 3.0. If you've implemented SSL encryption in Samba 2.2.x or earlier and want to upgrade to Samba 3.0, you'll have to either abandon your upgrade plans or find some other way to implement encryption.
Second Solution: SSH
Even for Samba 2.2.x and earlier, an alternative to SSL encryption was SSH tunneling. This technique involves setting up an SSH link between the client and the server and using it to tunnel SMB/CIFS data—that is, to "piggyback" the SMB/CIFS packets on the SSH connection. Because SSH encrypts all the data it passes between systems, the SMB/CIFS data acquire all the benefits of the SSH encryption. Configuring this system requires running an SSH server on the Samba server and running an SSH client on the SMB/CIFS client or some nearby system.
Configuring the Server
Four SSH server packages are common:
-
SSH Tectia: The original SSH is a commercial package from SSH Communications Security (http://www.ssh.com). Originally known only as SSH, the official name has become SSH Tectia with version 4.0. This package is available as both a binary for various platforms, including AIX, HP-UX, Linux, and Solaris, and in source code form. Commercial SSH Tectia server licenses are rather pricey, though ($642 in February 2004).
-
OpenSSH: The second option is the open-source OpenSSH (http://www.openssh.org), which is distributed under a BSD-style license and is closely associated with the OpenBSD OS but is available for various other platforms. The OpenSSH Web site includes a page dedicated to using the server on non-OpenBSD OSs (http://www.openssh.org/portable.html). Some older Linux binaries are available from the OpenSSH site, but for the most part the assumption is that you'll obtain binaries with your OS or compile the source code yourself.
-
FreSSH: A second open-source SSH implementation is FreSSH (http://www.fressh.org), which uses a BSD-style license and is a completely fresh from-the-ground-up implementation of SSH.
-
lsh: The final common SSH server package is lsh, which is distributed under the GPL. You can learn more at http://www.lysator.liu.se/~nisse/lsh/.
Note?/td> | Technically, the acronym SSH refers only to the commercial offering or to the protocol it implements. For simplicity's sake, though, I use the term in reference to any implementation because they all have similar features. The configuration files and options described in this chapter, though, work with the commercial Tectia SSH and with OpenSSH; FreSSH and lsh may work differently. |
In one form or another, most Unix-like OSs shipping in 2004 come with some form of SSH—usually OpenSSH. Check your OS's documentation to learn more, or check for a binary called sshd, which is the SSH server. Typically, the SSH server runs as a stand-alone server process, started via a SysV or local startup script, but it can be started via a super server. (Chapter 3 describes starting Samba in any of these ways, and the same methods can be applied to SSH.) Some OSs provide GUI controls that can enable various servers. The most notable of these is Mac OS X, which uses the Sharing item in the System Preferences tool to activate SSH. Figure 11-2 shows this window, with the SSH item (called Remote Login) highlighted. Be sure the box in the On column is checked.
You configure the SSH server via a file called sshd_config, which is typically stored in /etc, /etc/ssh, /usr/local/etc/ssh, or a similar location. (Do not confuse this file with the ssh_config file, which configures the SSH client.) As a general rule, the default configuration will work fine for accepting forwarded SMB/CIFS traffic; however, you may want to check the file to be sure it includes this line:
AllowTcpForwarding yes
This line tells the server to accept non-SSH programs' traffic tunneled through the SSH connection. This option should be enabled by default, so if the option isn't present in your sshd_config file, it should still function fine.
Linking Individual Systems vs. Linking Networks
You can proceed with the configuration in one of two ways: linking together two individual systems or linking together a network to an individual system. You might use the first method to create encrypted connections between computers on a local network to protect against localized sniffing. The second approach ties together all the computers on a network to a server, which will typically be on a remote network. The local network connections in this second case are unencrypted, but communication with the remote system is encrypted.
Figure 11-3 depicts the network connections in the first case. The SMB/CIFS client program contacts the SMB/CIFS port on the computer on which it's running. The SSH client listens to this port (becoming, in effect, a proxy server) and encrypts the data it receives, passing it to the SSH server on the Samba server computer. The SSH server then passes the piggybacked SMB/CIFS traffic to the Samba server on the local computer. This configuration has certain problems. For one, the client can't communicate with more than one SMB/CIFS server, at least not when using the normal ports. (You could run the SSH client and tell it to create tunnels to multiple SMB/CIFS servers using different local ports, but this is awkward and confusing.) You must also tell the SMB/CIFS client to contact the local computer in order to initiate a connection with the remote system—again, this is potentially confusing. Windows computers also have problems operating in this way; their SMB/CIFS clients tend to bind to the SMB/CIFS ports when the computer boots, so SSH can't do so.
Figure 11-4 depicts a local network that uses an SSH-encrypted tunnel to a remote server. The local computers make what appear to be ordinary SMB/CIFS connections to the SSH client computer. (The SSH client is functioning as a proxy for the Samba server; it's listening to the SMB/CIFS port.) To the clients, it appears as though the SSH client is actually the remote Samba server. That computer, in turn, is configured just like its equivalent in Figure 11-3. It accepts the SSH connection and passes the tunneled SMB/CIFS data to its Samba server. The local connections between the SMB/CIFS clients are unencrypted, but the connection between the SSH client and the Samba server is encrypted. This configuration is a good one if you need to tie a remote office with a few computers to a central office via the Internet or some other insecure network. If you need to connect to multiple remote servers, the simplest solution is to configure multiple local SSH clients to do the job. You can also use Windows SMB/CIFS clients in this configuration, as long as the SSH client computer is running Unix or is a Windows system that does not run any SMB/CIFS clients or servers.
Running a Samba server on the SSH client computer can be tricky at best. In the case of local encryption (Figure 11-3), you can do it by telling the SMB/CIFS server to not listen on the localhost (127.0.0.1) interface while configuring the SSH client to listen for SMB/CIFS connections on only that address. So configured, connections to localhost are passed to the remote system, but connections to the regular interface are handled locally. In either case, you could use nonstandard ports for tunneling the connection, but this approach won't work with all clients.
In all of these cases, you sacrifice browsing and NetBIOS name resolution because these duties are performed using UDP ports, which SSH can't forward. One workaround is to start with a configuration like the local encryption one (Figure 11-3), but configure it to run its own Samba server using the localhost/external interface dichotomy. Configure the Samba server system to mount remote shares via the encrypted connection and then share them using the local Samba server. This configuration is tricky to configure, and it will chew up more resources because the system will have to interpret every access request and re-encode it.
Configuring the SSH Client
You can obtain SSH clients from the same sources that provide SSH servers. In the case of recent Unix-like OSs, an SSH client usually ships with the OS. In addition to the reference SSH clients, many additional terminal programs have been developed that integrate SSH functionality. You can learn about many of these programs at http://www.freessh.org, which provides pointers to no-cost SSH clients.
Note?/td> | Don't confuse http://www.freessh.org with http://www.fressh.org; note that the number of e letters in these domain names is different. The former site provides links to free SSH implementations, especially clients. The latter site is a specific SSH client and server implementation. |
In the case of Unix and Unix-like systems, you can establish an encrypted local connection to the Samba server by typing the following command on the SSH client system:
# ssh -N -f -L 139:target.example.com:139 user@target.example.com
This command creates a connection between TCP port 139 on the local computer and TCP port 139 on target.example.com, using the user account on the remote system. When used to tunnel ports below 1024, you must run this command as root. Any traffic directed at the local TCP port 139 is tunneled, with SSH encryption, to target.example.com's TCP port 139. Note that this command means that the local computer can't be running a Samba server, at least not on the localhost (127.0.0.1) interface. If you want to run a Samba server on the client computer, you must change the first instance of 139 in this command to another port number and specify that port number when making connections to the remote system.
In a default configuration, after you type the preceding command, ssh will ask you for a password. Type the password belonging to user. SSH uses user's account to establish the local connection to the local Samba server. Note that this has nothing to do with the Samba users or permissions, which can be anything the Samba server supports.
If you want to configure a Unix system as a proxy, such as the SSH client computer in Figure 11-4, you type the same command on the SSH client system; however, you must ensure that a specific line is set in the ssh_config file on that system:
GatewayPorts yes
If you omit this line, the SSH client will accept connections from only the localhost (127.0.0.1) system, so it won't be useful for tunneling connection requests from other systems, as in Figure 11-4.
In theory, a process similar to the one just described should work with Windows systems but using a Windows SSH client. Unfortunately, in practice it just doesn't work because the Windows SMB/CIFS implementations bind to TCP port 139, even when the server package is removed from the computer. Needless to say, this severely limits the utility of SMB/CIFS encryption. You can still use an encryption proxy, as in Figure 11-4, but a direct encrypted connection, as in Figure 11-3, won't work with Windows clients.
Establishing a Connection
To test the functioning of your encrypted connection, I recommend using smbclient. This program, described in more detail in Chapter 18, is a relatively straightforward client program that ships with Samba. It provides more in the way of error feedback than many SMB/CIFS client programs, so it can be a good way to test a connection.
To start, from the SSH client computer, try using smbclient to connect to a share on the server. For instance, to connect to a share called TESTSHARE using the username fastaire, you might type the following command:
$ smbclient //localhost/TESTSHARE -U fastaire added interface ip=192.168.1.2 bcast=192.168.1.255 nmask=255.255.255.0 error connecting to 192.168.1.3:445 (Invalid argument) Password: Domain=[RINGWORLD] OS=[Unix] Server=[Samba 3.0.1] smb: />
You can omit the -U fastaire parameter if you're logged in as that user. If all goes well, you should see output similar to that shown here. You can disregard the error message about an attempt to connect to 192.168.1.3:445; this message indicates that the server wasn't listening on port 445, which is the port SMB/CIFS uses when it bypasses NetBIOS. After entering a password, the system responds with a smb: /> prompt, at which you can type FTP-style commands to view files, copy files, and so on.
If this connection attempt goes smoothly, you can try more. For instance, you might use smbmount on a Linux system to mount a remote share using the localhost address:
# smbmount //localhost/TESTSHARE /mnt/test -o username=fastaire Password:
Note?/td> | The smbmount program must normally be run as root, although you can set the set user ID (SUID) bit on the program to run it as a normal user. |
If you've set up the system as a proxy for your local network, as in Figure 11-4, you should then test it with other computers on that network. You can use smbclient if some of your local computers run Unix. In the case of Windows clients, you must type the complete path to the share, using the SSH client system name rather than the real target system name. Unfortunately, many Windows systems have troubles with name resolution when the SSH client system isn't using the NetBIOS name service (that is, running nmbd under Unix). If you can't seem to connect, try editing your system's lmhosts file, described in Chapter 9. Most Windows systems ship with a sample file, called LMHOSTS.SAM. On Windows 9x/Me systems, this file usually resides in C:/WINDOWS; in Windows NT/200x/XP, it's usually in C:/WINNT/SYSTEM32/DRIVERS/ETC. Copy or rename the sample file to LMHOSTS, and add an entry for your SSH client system.
Third Solution: A VPN
A third solution for data encryption is using a VPN. VPNs can provide encryption for all of the traffic passing between two network segments, each of which contains many computers. Sometimes, though, individual clients (such as computers belonging to telecommuters) are linked via VPN software to a central network.
Computers running VPN software are similar in many ways to routers, but they provide the illusion of a direct link between two networks that may actually be separated by many routers. Many VPN packages and protocols are available, including the following:
-
PPTP: The Point-to-Point Tunneling Protocol (PPTP) ships with recent versions of Windows and is frequently used to link single clients to a central office. Various PPTP implementations for Unix-like systems exist, such as PoPToP for Linux (http://www.poptop.org; see also http://heyer.supranet.net/pptp/ for information on running PoPToP in FreeBSD), which is a PPTP server, and pptpclient (http://pptpclient.sourceforge.net), which is a client implementation for several Unix-like OSs.
-
FreeS/WAN: This package, headquartered at http://www.freeswan.org, is a more Unix-centric VPN package. It's also more often used to link together entire networks.
-
SSH: This program's tunneling capabilities can be combined with a slightly modified Point-to-Point Protocol (PPP) client and server to create a VPN. The VPN PPP-SSH Mini-HOWTO document (http://tldp.org/HOWTO/ppp-ssh/) describes how to create such a connection under Linux. The process is similar under other Unix-like OSs.
VPNs have the advantage of encrypting and passing all traffic between their networks, typically including both UDP and TCP. This fact means that they can support browsing features, and they don't require the use of stand-in names—you can use the network exactly as if it were a single large network, without worrying about the presence of the VPN.
VPNs typically encrypt only the connection between networks. Most VPN solutions aren't designed for use on a single network segment, although some can be configured in this way. One system serves as a VPN server, and all of the other systems use VPN client software. All traffic passes through the VPN server. This configuration can be handy if your hardware is necessarily insecure, as in a wireless network. A VPN's encryption is likely to be far better than that built into most wireless hardware. VPNs are a relatively new technology compared to most common networking tools. As such, they tend to be difficult to configure. If you need to create a VPN, you should consult documentation for whatever VPN package you choose.
http://book.opensourceproject.org.cn/sysadmin/samba/definitive/opensource/8885final/lib0071.html