SOCKS

SOCKS is a system that allows computers behind a firewall to access services on the Internet. The program allows you to centrally control how programs on your organization's network communicate with the Internet. With SOCKS, you can allow specific services to specific computers, disable access to individual hosts on the Internet, and log as much or as little as you want.

SOCKS was originally written by David Koblas and Michelle Koblas. It has since been extended by Ying-Da Lee at NEC's Systems Laboratory, and a commercially supported version is available from NEC. The name SOCKS stands for "SOCK-et-S." According to the SOCKS FAQ, "it was one of those `development names' that never left."

SOCKS consists of two parts:

The standard SOCKS distribution comes with client programs for finger, ftp, telnet, and whois. SOCKS also includes a library you can use to create other SOCKS clients at will. Furthermore, many programs, such as NCSA Mosaic, include provisions for using SOCKS to negotiate firewalls.

SOCKS is available for most versions of UNIX, including SunOS, Sun Solaris, IRIX, Ultrix, HP-UX, AIX, Interactive Systems UNIX, OSF/1, NetBSD, UNIXWare, and Linux. A version called PC SOCKS, by Cornell Kinderknecht, is available for Microsoft Windows. A Macintosh version is under development.

What SOCKS Does

The SOCKS client software works by replacing calls to the UNIX socket functions - connect(), getsocketname(), bind(), accept(), listen() and select() - with its own versions of these functions. In practice, this replacement is done by adding a few macro definitions to the CFLAGS in the Makefile of the program that is used to compile the network client program, and then linking the resulting program with the SOCKS library.

When a SOCKS-modified client attempts to connect to a server on the Internet, the SOCKS library intercepts the connection attempt and instead opens up a connection to the SOCKS server. After the connection is established, the SOCKS client sends through the following information:

The SOCKS server then checks its access control list to see if the connection should be accepted or rejected. If the connection is accepted, the server opens up a connection to the remote machine and then relays all information back and forth. If the connection is rejected, the server disconnects from the client. This configuration is shown graphically in Figure 22.1.

Figure 22.1: : Using SOCKS for proxying

Figure 22.1

SOCKS can also be used to allow computers behind a firewall to receive connections. In this case, a connection is opened to the SOCKS server, which in turn gets ready to accept connections from the Internet.

SOCKS works only with TCP/IP; for UDP services (such as Archie), use UDP Relayer as described later in this chapter.

Getting SOCKS

Socks may be freely downloaded from the Internet. The address is:

ftp://ftp.nec.com/pub/security/socks.cstc/
http://www.socks.nec.com/

If you operate two nameservers to hide information from the Internet, you will also need to download the file Rgethostbyname.c. This file contains a function that can be used to query multiple nameservers to resolve a hostname.

There is a mailing list devoted to SOCKS and related issues. To join it, send the message "subscribe socks your-email-address" to majordomo@syl.dl.nec.com.

NOTE: This section discusses SOCKS Version 4. At the time of this writing, SOCKS Version 5 was under development. New features in SOCKS 5 include strong authentication, authentication method negotiation, message integrity, message privacy, and support for UDP applications.

Getting SOCKS Running

After you have downloaded the system, you will need to follow these steps to get the system running:

  1. Unpack the SOCKS distribution.
  2. Decide whether you wish to have the SOCKS daemon started automatically when the system starts (boot time), or started by inetd when each SOCKS request is received.

    The advantage of having the daemon start automatically at system start-up is that the daemon will need to read its configuration file only once. Otherwise, the configuration file will have to be read each time a SOCKS connection is requested. We recommend that you have SOCKS started at boot time.

  3. Edit the file Makefile in the main SOCKS directory and the file include/socks.h to reflect the policy of your site. Be sure to edit the variables found in Table 22.4.
    Variables
    Variable Location Purpose/Setting
    SOCKS_DEFAULT_SERVER include/socks.h Set with the hostname of the computer that hosts the sockd daemon.
    SOCKS_DEFAULT_NS include/socks.h Set if the clients inside your firewall cannot look up the IP addresses of external hosts.
    NOT_THROUGH_INETD include/socks.h Set if socksd will be started automatically at system boot.
    SOCKS_CONF include/socks.h Location of the SOCKS configuration file for client machines.
    SOCKD_CONF include/socks.h Location of the SOCKS configuration file for the sockd daemon.
    MULTIHOMED_SERVER include/socks.h Set if sockd will be running on a multihomed server (a gate computer with two Ethernet ports).
    SOCKD_ROUTE_FILE include/socks.h Location of the SOCKS routing file, for use with multihomed servers.
    FACIST Makefile Causes SOCKS FTP client to log names of all files transferred.
    FOR_PS Makefile Causes sockd to display information about its current activity in the output from the ps command.
    SERVER_BIN_DIR Makefile Directory containing the sockd daemon.
    CLIENTS_BIN_DIR Makefile Directory containing the SOCKS client programs.
  4. Compile SOCKS with a suitable C compiler.
  5. Verify that sockd compiled properly and with the correct configuration by running sockd with the -ver option:

    % /sockd -ver CSTC single-homed, stand-alone SOCKS proxy server version 4.2. Supports clients that use Rrcmd(). %
    


  6. Become superuser.
  7. Install the SOCKS daemon in the location that you specified in the Makefile; you may be able to do this by typing "make install.server".
  8. Add the SOCKS service to your /etc/services file. It should look like this:

    socks 1080/tcp
    


  9. Now you need to set up the SOCKS configuration file. See the section called "The SOCKS Server Configuration File: /etc/sockd.conf below.
  10. If you decided to have SOCKS start automatically at system boot time, modify your boot configuration files (either by adding a few lines to /etc/rc.local or by creating a new file in /etc/rc2.d/). You can set the start-up by adding a few lines that look like this:

    # Start SOCKS server if [ -f /usr/etc/sockd ]; then (echo -n "sockd... ") >/dev/console /usr/etc/sockd >/dev/console 2>&1 fi
    


  11. If you decided to have SOCKS start from inetd (and you probably don't want to do this), add this line to the /etc/inetd.conf file:

    socks stream tcp nowait nobody /usr/etc/sockd 
    


  12. Start the sockd daemon manually, or reset inetd.
  13. Test the system.

SOCKS and Usernames

SOCKS permits you to allow or deny access to Internet services based on both IP address and the username of the person on the local network making the request. There are two ways that SOCKS can determine the username of a person on the internal network:

  1. Normally, a SOCKS client will send through the username of the person initiating the connection as part of the SOCKS protocol.
  2. SOCKS can also use the ident protocol. For more information, see the section "Identification Protocol (auth) (TCP Port 113)" in Chapter 17.

SOCKS Identification Policy

The choice of identification policy is determined by the way in which the sockd program is invoked and by the /etc/sockd.conf configuration file.

Normally, sockd is invoked with one of three options:

sockd [-ver | -i | -I]

These options have the following meanings:

The identification options -i and -I can be overridden by a statement in the SOCKS configuration file, /etc/sockd.conf.

The SOCKS Server Configuration File: /etc/sockd.conf

The sockd configuration file, /etc/sockd.conf, allows you to control which TCP/IP connections are passed by the sockd daemon. As the daemon usually runs on a computer that has access to both your organization's internal network and the Internet, the sockd.conf file controls, in part, which services are passed between the two.

The sockd program doesn't know the difference between your internal and external networks. It simply receives connections, determines the parameters of the connections (username, source, requested destination, and TCP/IP service), then scans rules in the /etc/sockd.conf file to determine if the connections should be permitted or denied.

The /etc/sockd.conf file is an ASCII text file. Each line consists of a rule to either allow connections or reject (deny) them. The sockd program scans the file from the first line to the last line until a match is found. When a match is found, the action specified by the line is followed.

Lines in the /etc/sockd.conf file may be up to 1023 characters long. Each line has the following form:

[allow | deny] [?=auth] [*=username(s)|filename(s)] source-address source-mask [destination-address destination-mask] [operator destination-port] [: shell-command]

Fields are separated by spaces or tabs. If a number sign (#) is found on the line, everything after the number sign is assumed to be a comment, except as noted below.

If an incoming TCP/IP connection does not match any of the lines in the /etc/sockd.conf configuration file, it is rejected.

Here is an explanation of the fields:

Username Result
*=simsong Matches the user simsong.
*=fred,julie Matches the users fred and julie.
*=/etc/goodusers Matches anybody in the file /etc/goodusers.
*=fred,/etc/goodusers Matches the user fred and all of the users in the file /etc/goodusers.
source-address source-mask Result
Matches the host 18.80.0.1.
Matches any host on the subnet 204.17.190.
Matches any host on net 10.
Matches every host on the Internet.
operator Meaning
eq Equal to
neq Not equal to
lt Less than
le Less than or equal to
gt Greater than
ge Greater than or equal to
Token Replaced With
%A The fully qualified domain name (FQDN) of the client (the computer contacting sockd), if it can be determined; otherwise, the computer's IP address
%a The IP address of the client
%c The direction of the connection; replaced with connect if the client is attempting to make an outgoing connection, or bind if the client is waiting for an incoming connection
%p The process ID of sockd
%S The service name, if it can be determined from the /etc/services database; otherwise, the destination port number
%s The destination port number
%U The username reported by identd
%u The username sent by the client program
%Z The FQDN name of the destination host, if it can be determined; otherwise, the computer's IP address
%z The IP address of the destination computer
%% "%"

Obviously, token expansions that require that sockd look up a value in a database (such as %A, %S, and %Z) will take longer to execute than token expansions that merely report an IP or port number (such as %a, %s and %z).

This example command runs finger to determine the users on a particular computer, and then sends the results to the root account of the computer that is running sockd:

/usr/ucb/finger @%A | /bin/mailx -s 'SOCKS: rejected %u@%A' root


#NO_IDENTD and #BAD_ID

In addition to the pattern matching described above, sockd allows you to specify rules that will match any computer contacting the sockd daemon which is not running the ident protocol, or for which the username returned by the ident protocol is different from the username provided in the initial sockd contact. These lines have the form:

#NO_IDENTD: command #BAD_ID: command


Example /etc/sockd.conf configuration files

Here are some example lines from an /etc/sockd.conf configuration file. The configuration file is designed to protect an organization that has placed a set of UNIX workstations on IP subnet 204.99.90.

This rather complex rule denies any attempted login to the organization's internal network. In addition to stopping the logins, it also does a finger of the computer from where the attempt is coming and sends email to the root account of the computer running sockd. If the remote machine is running the ident protocol, the username will be sent as well.

NOTE: Do not use reverse finger for logging contacts on the finger port (port 79). Otherwise, a loop may result, with two sockd daemons continually attempting to finger each other until they are manually shut down or the disks fill up.

SOCKS Client Configuration File: /etc/socks.conf

Each client that wishes to use the sockd server must also have its own configuration file. The configuration file has a syntax that is similar to, but slightly different from, the syntax of the /etc/sockd.conf file.

When a SOCKS client attempts to make an outgoing connection to another host on the Internet, or when it calls the Rbind() function to accept an incoming connection, the SOCKS library scans the /etc/socks.conf configuration file line by line, starting with the first line, until it finds a line that matches the requested connection. The library then performs the action that is specified in the file.

Each line in the file can have the following form:

deny [*=username(s)|filename(s)] destination-address destination-mask [operator destination-port] [: shell-command] direct [*=username(s)|filename(s)] destination-address destination-mask [operator destination-port] [: shell-command] sockd [@=serverlist] [*=username(s)|filename(s)] destination-address destination-mask [operator destination-port] [: shell-command]

Most of these fields are similar to those in the /etc/sockd.conf file. The differences are described below:



sockd @=socks1,socks2,sock3 0.0.0.0 0.0.0.0

In SOCKS version 4.2, the servers are tried in the order in which they appear in the configuration file. Thus, you can specify different servers in different orders on different clients to distribute the load. (A more intelligent approach, though, would be for the servers to be tried in random order.)

Example /etc/socks.conf file

This simple configuration file, for an organization administrating the subnet 204.90.80, specifies that all connections to organization's internal subnet should go direct, while all connections to the outside network should go through the SOCKS server:

direct 204.90.80.0 255.255.255.0 sockd @=socks-server 0.0.0.0 0.0.0.0