Depending on your perspective (system administrator,
user), firewalls can be either a blessing or a curse:
you buy in security, you often pay for in convenience
For some years I ran a traditional dual-homed gateway,
logged in, did their work using vt100 emulation, and
logged out. This
worked well for applications like telnet, gopher, and
but the picture changed dramatically when Mosaic and
the World Wide
Web (WWW) came to town. Was it possible to allow all
50 or 60 concurrent
users to run this behemoth of a program (on the same
not put the system performance in the dumpster? Along
How SOCKS Works
SOCKS is officially classified as an Authenticated Firewall
protocol (that's the name of the working group in the
the protocol). With SOCKS I could allow users to run
on their workstations and tunnel the traffic to and
from the Internet
through my firewall. The SOCKS protocol, as discussed
in this article,
was developed by David and Michelle Kolbas (see References).
implementation is maintained by Ying-Da Lee of NEC corporation
can be obtained by anonymous ftp from ftp.nec.com
(188.8.131.52) in /pub/security/socks. The current
(as of this writing) is version 4.2 pre-release number
3. It's been
built and tested on many platforms, including SunOS,
HP-UX, AIX, and
others (see the README for specifics).
To understand how SOCKS works, it's useful first to
look at a traditional
TCP-based client/server model. Figure 1 diagrams the
for such a model. The client first sets up for socket-level
by issuing a socket() call, which returns a socket descriptor
-- typically an integer value. The connect() call then
initiates the TCP session to the server on a given port.
traditionally listens on that port for incoming data,
while the client
writes the data to the port (perhaps with a write()
and listens with a read(). In general, in an open environment,
each client connects directly with and establishes its
own TCP connection
to a server, as in Figure 2.
SOCKS is like a relay between the client and the server.
same example, the networking flow would look like that
shown in Figure 3.
So in essence, the SOCKS server is really a funnel.
All of the
internal clients connect to the firewall, and the firewall
of the connections to the Internet on behalf of the
as in Figure 4.
SOCKS has two components: the server (sockd) and the
that connect to the server. When you build the package,
build the two parts: the server (sockd) and the SOCKS
(libsocks.a). The SOCKS library consists of replacements
the traditional TCP/IP networking calls connect, bind,
listen, accept and getsockname. The replacement
calls just prepend an "r" to the standard
call (e.g., the
replacement for connect() is rconnect()).
Building the package is relatively straightforward.
Once you have
unpacked the archive, issue a make all to build the
(sockd), the sample clients (telnet, ftp,
and finger) and the SOCKS library (libsocks.a). You'll
need to make a few decisions and set some variables
in the main Makefile
based on your platform, but the documentation makes
these steps clear
and easy to manage.
One option that is not in the Makefile is
If you #define this, you're indicating that you want
the SOCKS server from the command line rather than run
it from the
inetd process. I prefer to run it through inetd, but
if you have a large /etc/sockd.conf file (explained
you may want to consider this option for performance
for every connection to the SOCKS server, the file /etc/sockd.conf
must be consulted to determine if the connection is
valid or not.
If you run from the command line, this configuration
file is read
once and stored in memory, thus speeding up the performance
The process of modifying your clients to use a SOCKS
gateway is called
"socks-ification" (see the file called How_to_SOCKSIFY,
included in the package). Over the releases of SOCKS,
has become much easier. With the library, libsocks.a,
you need only replace the basic networking calls (connect,
accept, bind, etc.) with their SOCKS counterparts
(rconnect, raccept, rbind). To make life even
easier, copy from the Makefile the #define line that
connect as Rconnect and accept as Raccept,
then just build your application (it's not necessary
the source, just recompile and link with the SOCKS library).
Assume, for the sake of this article, a network that
looks like one
in Figure 5. The host that will run the socksified clients
a control file, /etc/socks.conf, on it. This file looks
direct 127.0.0.1 255.255.255.255
direct 184.108.40.206 255.255.255.0
direct 220.127.116.11 255.255.255.0
sockd @=18.104.22.168 0.0.0.0 0.0.0.0
When a client application (like a Web browser or telnet)
to make a connection, it consults the /etc/socks.conf
on the host. Once the name of the far end client has
to an IP address, the address is compared with those
listed in this
file to determine whether the client should make the
the SOCKS gateway, or go directly to the server. The
tells this client to connect directly (i.e., don't use
for all internal hosts, and to use the gateway at address
for everything else (0.0.0.0).
If you don't have access to the external namespace on
your local nameserver,
you may want to define the environment variable SOCKS_NS
point to a nameserver that can resolve names in the
I run a caching-only nameserver on the same machine
where I run my
SOCKS server. You can also define SOCKS_SERVER to point
a different server than that defined in /etc/socks.conf.
Setting up and running the SOCKS server isn't difficult:
must remember is that you don't "create" a
by running SOCKS on a machine. SOCKS is a "tunnel"
hole (a diode -- or one-way hole) that you open in your
For details on firewalling beyond the scope of this
article, see Cheswick
and Belovin, Firewalls and Internet Security. If you
out of inetd, move the binary to your firewall and edit
to add the following line:
socks 1080/tcp # socks service on port 1080
then edit /etc/inetd.conf to include:
socks stream tcp nowait nobody /usr/local/sockd sockd
You must maintain two configuration files to run SOCKS.
is /etc/sockd.route. This file was put into place for
hosts to enable the system administrator to point (or
out through a pre-defined interface. Here's an example
of an /etc/sockd.route
22.214.171.124 126.96.36.199 255.255.255.0
188.8.131.52 184.108.40.206 255.255.255.0
220.127.116.11 0.0.0.0 0.0.0.0
Figure 5 shows the firewall, with network 18.104.22.168
being the Internet
(or un-secure) side, and 22.214.171.124 being the secure
I made up these network addresses; they are not meant
actual networks. The /etc/sockd.route example above
that anything in networks 126.96.36.199 and 188.8.131.52
(both with a
mask of 255.255.255.0) should be routed out via interface
and that everything else should be routed to the 184.108.40.206
(or the un-secure, Internet side).
The second key configuration file is /etc/sockd.conf.
file defines which IP addresses can pass through the
box and which
addresses it can "talk" to. Figure 6 shows
an example of the
/etc/sockd.conf file. These are basic source/destination
The first rule that matches a particular pattern is
the rule applied
to the packets. For example, according to the first
rule, any packet
with no masking -- i.e., 0.0.0.0 -- that is destined
internal network (220.127.116.11) will be denied -- packets
only be destined for the un-secure network adapter.
The same is true for rule number 2 -- anything destined
internal network should be denied.
Rule 3 permits any machine in the 18.104.22.168 network
mask 255.255.255.0) access to any machine (0.0.0.0)
on the Internet.
Rule 4 will allow only the machine at 22.214.171.124 (note
the full host
mask) to communicate with any machine on the Internet.
Rule 5 a catchall: deny all access.
Nameservice and Protocol Requirements
There are two important things to remember regarding
a SOCKS setup:
the nameservice and the protocol used by the client
SOCKS is a TCP relaying protocol. This means that the
that can use SOCKS are those based on TCP connections
ftp, and WWW are examples; archie, though, uses UDP
cannot use SOCKS). Clients must have full access to
the Internet DNS
tree. I accomplish this by running bind (or named)
on the firewall as a caching-only nameserver. The named.boot
file is relatively simple:
cache . /etc/named.ca
The /etc/named.ca file contains entries for the
Internet root nameservers, which can be obtained from
the NIC via
anonymous ftp from rs.internic.net, in the file domain/named.root.
Here's a sample:
; last update: Oct 5, 1994
; related version of root zone: 1994100500
. 99999999 IN NS NS.INTERNIC.NET.
NS.INTERNIC.NET. 99999999 A 126.96.36.199
. 99999999 NS NS1.ISI.EDU.
NS1.ISI.EDU. 99999999 A 188.8.131.52
. 99999999 NS C.PSI.NET.
C.PSI.NET. 99999999 A 184.108.40.206
. 99999999 NS TERP.UMD.EDU.
Despite these caveats, I think you'll find SOCKS a handy
for your firewalls. If your users are looking for WWW
access, I think
they'll thank you as well.
Cheswick, William R., and Steven M. Bellovin. Firewalls
and Internet Security: Repelling the Wily Hacker. Reading,
Addison-Wesley, 1994. ISBN-0-201-63357-4.
Kolbas, David, and Michelle Kolbas. SOCKS. Available
for anonymous ftp: ftp.ibm.net (/pub/socks/socks.ps).
About the Author
Matt Ganis is currently manager of Internet Server
Design and Integration
group for the IBM Global Network in
White Plains, NY. In his spare time he teaches Astronomy
at Pace University
in Pleasantville, NY. He can be reached at 14 Udell
Manor, NY 10566 or email@example.com.