<?xml version="1.0"?>
<book id="lnag"><title>Linux Network Administrators Guide</title><preface><title>Preface</title><para>The Internet is now a household term in many countries. With otherwise
serious people beginning to joyride along the Information Superhighway,
computer networking seems to be moving toward the status of TV sets
and microwave ovens. The Internet has unusually high media coverage, and
social science majors are descending on Usenet newsgroups, online virtual
reality environments, and the Web to conduct research on the new
Internet Culture.</para><para>Of course, networking has been around for a long time. Connecting
computers to form local area networks has been common practice, even
at small installations, and so have long-haul links using transmission
lines provided by telecommunications companies. A rapidly growing
conglomerate of world-wide networks has, however, made joining the
global village a perfectly reasonable option for even small non-profit
organizations of private computer users. Setting up an Internet host
with mail and news capabilities offering dialup and ISDN access has
become affordable, and the advent of DSL (Digital Subscriber Line) and
Cable Modem technologies will doubtlessly continue this trend.</para><para>Talking about computer networks often means talking about Unix. Of
course, Unix is not the only operating system with network
capabilities, nor will it remain a frontrunner forever, but it has
been in the networking business for a long time, and will surely
continue to be for some time to come.</para><para>What makes Unix particularly interesting to private users is that there has
been much activity to bring free Unix-like operating systems to the PC, such
as 386BSD, FreeBSD, and Linux.</para><para>Linux is a freely distributable Unix clone for personal computers.  It
currently runs on a variety of machines that includes the Intel family
of processors, but also Motorola 680x0 machines, such as the Commodore
Amiga and Apple Macintosh; Sun SPARC and Ultra-SPARC machines; Compaq
Alphas; MIPS; PowerPCs, such as the new generation of Apple Macintosh;
and StrongARM, like the rebel.com Netwinder and 3Com Palm
machines. Linux has been ported to some relatively obscure platforms,
like the Fujitsu AP-1000 and the IBM System 3/90. Ports to other
interesting architectures are currently in progress in developers'
labs, and the quest to move Linux into the embedded controller space
promises success.</para><para>Linux was developed by a large team of volunteers across the Internet.
The project was started in 1990 by Linus Torvalds, a Finnish college
student, as an operating systems course project. Since that time,
Linux has snowballed into a full-featured Unix clone capable of
running applications as diverse as simulation and modeling programs,
word processors, speech recognition systems, World Wide Web browsers,
and a horde of other software, including a variety of excellent
games. A great deal of hardware is supported, and Linux contains a
complete implementation of TCP/IP networking, including SLIP, PPP,
firewalls, a full IPX implementation, and many features and some
protocols not found in any other operating system. Linux is powerful,
fast, and free, and its popularity in the world beyond the Internet is
growing rapidly.</para><para>The Linux operating system itself is covered by the GNU General Public
License, the same copyright license used by software developed by the Free
Software Foundation. This license allows anyone to redistribute or modify
the software (free of charge or for a profit) as long as all modifications
and distributions are freely distributable as well. The term free
software refers to freedom of application, not freedom of cost.</para><sect1><title>Purpose and Audience for This Book</title><para>This book was written to provide a single reference for network
administration in a Linux environment. Beginners and experienced users
alike should find the information they need to cover nearly all
important administration activities required to manage a Linux network
configuration. The possible range of topics to cover is nearly
limitless, so of course it has been impossible to include everything
there is to say on all subjects. We've tried to cover the most
important and common ones. We've found that beginners to Linux
networking, even those with no prior exposure to Unix-like operating
systems, have found this book good enough to help them successfully
get their Linux network configurations up and running and get them
ready to learn more.</para><para>There are many books and other sources of information from which you
can learn any of the topics covered in this book (with the possible
exception of some of the truly Linux-specific features, such as the
new Linux firewall interface, which is not well documented elsewhere)
in greater depth. We've provided a bibliography for you to use when
you are ready to explore more.</para></sect1><sect1><title>Sources of Information</title><para><indexterm significance="normal"><primary>information on Linux</primary></indexterm>
<indexterm significance="normal"><primary>Linux</primary><secondary>sources of information
on</secondary></indexterm> If you are new to the world of Linux, there
are a number of resources to explore and become familiar with. Having
access to the Internet is helpful, but not essential.</para><variablelist><varlistentry><term>Linux Documentation Project guides</term><listitem><para><indexterm significance="normal"><primary>Linux Documentation Project</primary></indexterm>
<indexterm significance="normal"><primary>LDP (Linux Documentation Project)</primary></indexterm>
<indexterm significance="normal"><primary>Welsh, Matt</primary></indexterm> <indexterm significance="normal"><primary>Wirzenius, Lars</primary></indexterm>
<indexterm significance="normal"><primary>Oja, Joanna</primary></indexterm>
<indexterm significance="normal"><primary>Frampton, Steve</primary></indexterm>
<indexterm significance="normal"><primary>Burkett, B. Scott</primary></indexterm>
<indexterm significance="normal"><primary>Goldt, Sven</primary></indexterm>
<indexterm significance="normal"><primary>Harper, John D.</primary></indexterm>
<indexterm significance="normal"><primary>Meer, Sven van der</primary></indexterm>
<indexterm significance="normal"><primary>Rusling, David A.</primary></indexterm>
<indexterm significance="normal"><primary>Pomerantz, Ori</primary></indexterm>
The Linux Documentation Project is a group of volunteers who have
worked to produce books (guides), HOWTO documents, and manual pages on
topics ranging from installation to kernel programming. The LDP works
include:

<variablelist><varlistentry><term><emphasis>Linux Installation and Getting Started</emphasis></term><listitem><para>By Matt Welsh, et al. This book describes how to obtain, install, and use
Linux. It includes an introductory Unix tutorial and information on systems
administration, the X Window System, and networking.</para></listitem></varlistentry><varlistentry><term><emphasis>Linux System Administrators Guide</emphasis></term><listitem><para>By Lars Wirzenius and Joanna Oja. This book is a guide to general Linux system
administration and covers topics such as creating and configuring users,
performing system backups, configuration of major software packages, and
installing and upgrading software.</para></listitem></varlistentry><varlistentry><term><emphasis>Linux System Adminstration Made Easy</emphasis></term><listitem><para>By Steve Frampton. This book describes day-to-day administration and
maintenance issues of relevance to Linux users.</para></listitem></varlistentry><varlistentry><term><emphasis>Linux Programmers Guide</emphasis></term><listitem><para>By B. Scott Burkett, Sven Goldt, John D. Harper, Sven van der Meer, and
Matt Welsh. This book covers topics of interest to people who wish to
develop application software for Linux.</para></listitem></varlistentry><varlistentry><term><emphasis>The Linux Kernel</emphasis></term><listitem><para>By David A. Rusling. This book provides an introduction to the Linux
Kernel, how it is constructed, and how it works. Take a tour of your
kernel.</para></listitem></varlistentry><varlistentry><term><emphasis>The Linux Kernel Module Programming
Guide</emphasis></term><listitem><para>By Ori Pomerantz. This guide explains how to write Linux kernel <?troff .hw modules?>modules.</para></listitem></varlistentry></variablelist></para><para>More manuals are in development. For more information about the LDP
you should consult their World Wide Web server at <systemitem moreinfo="none" role="url">http://www.linuxdoc.org/</systemitem> or one of its many
mirrors.</para></listitem></varlistentry><varlistentry><term>HOWTO documents</term><listitem><para><indexterm significance="normal"><primary>Linux</primary><secondary>HOWTOs</secondary></indexterm>
<indexterm significance="normal"><primary>HOWTOs</primary></indexterm> The Linux HOWTOs are
a comprehensive series of papers detailing various aspects of the
systemsuch as installation and configuration of the X Window
System software, or how to write in assembly language programming
under Linux. These are generally located in the
<filename moreinfo="none">HOWTO</filename> subdirectory of the FTP sites listed later,
or they are available on the World Wide Web at one of the many Linux
Documentation Project mirror sites.  See the Bibliography at the end
of this book, or the file <filename moreinfo="none">HOWTO-INDEX</filename> for a list
of what's available.</para><para>You might want to obtain the <emphasis>Installation HOWTO</emphasis>, which
describes how to install Linux on your system; the <emphasis>Hardware
Compatibility HOWTO</emphasis>, which contains a list of hardware known to
work with Linux; and the <emphasis>Distribution HOWTO</emphasis>, which lists
software vendors selling Linux on diskette and CD-ROM.</para><para>The bibliography of this book includes references to the HOWTO documents
that are related to Linux networking.</para></listitem></varlistentry><varlistentry><term>Linux Frequently Asked Questions</term><listitem><para>The <emphasis>Linux Frequently Asked Questions with Answers</emphasis>
(FAQ) contains a wide assortment of questions and answers about the
system. It is a must-read for all newcomers.</para></listitem></varlistentry></variablelist><sect2><title>Documentation Available via FTP</title><para><indexterm significance="normal"><primary>Linux</primary><secondary>documentation</secondary></indexterm>
<indexterm significance="normal"><primary>documentation (Linux)</primary><secondary>via
FTP</secondary></indexterm> If you have access to anonymous FTP, you
can obtain all Linux documentation listed above from various sites,
including <systemitem moreinfo="none" role="url"> metalab.unc.edu:/pub/Linux/docs</systemitem> and <systemitem moreinfo="none" role="url"> tsx-11.mit.edu:/pub/linux/docs</systemitem>.</para><para>These sites are mirrored by a number of sites around the world.</para></sect2><sect2><title>Documentation Available via WWW</title><indexterm significance="normal"><primary>documentation (Linux)</primary><secondary>via
WWW</secondary></indexterm><para>There are many Linux-based WWW sites available. The home site for the
Linux Documentation Project can be accessed at <systemitem moreinfo="none" role="url">http://www.linuxdoc.org/</systemitem>.</para><para><indexterm significance="normal"><primary>Open Source Writers Guild</primary></indexterm>
<indexterm significance="normal"><primary>OSWG (Open Source Writers
Guild)</primary></indexterm> The Open Source Writers Guild (OSWG) is a
project that has a scope that extends beyond Linux. The OSWG, like
this book, is committed to advocating and facilitating the production
of OpenSource documentation. The OSWG home site is at
<systemitem moreinfo="none" role="url">http://www.oswg.org:8080/oswg</systemitem>.</para><para>Both of these sites contain hypertext (and other) versions of many Linux
related documents.</para></sect2><sect2><title>Documentation Available Commercially</title><para><indexterm significance="normal"><primary>documentation
(Linux)</primary><secondary>commercial</secondary></indexterm> A
number of publishing companies and software vendors publish the works
of the Linux Documentation Project. Two such vendors are:</para><literallayout format="linespecific" class="normal">Specialized Systems Consultants, Inc. (SSC) 
<systemitem moreinfo="none" role="url">http://www.ssc.com/</systemitem> 
P.O. Box 55549 Seattle, WA 98155-0549 
1-206-782-7733 
1-206-782-7191 (FAX) 
<systemitem moreinfo="none" role="emailaddr">sales@ssc.com</systemitem></literallayout><para>and:</para><literallayout format="linespecific" class="normal">Linux Systems Labs
<systemitem moreinfo="none" role="url">http://www.lsl.com/</systemitem>
18300 Tara Drive
Clinton Township, MI 48036
1-810-987-8807
1-810-987-3562 (FAX)
<systemitem moreinfo="none" role="emailaddr">sales@lsl.com</systemitem></literallayout><para>Both companies sell compendiums of Linux HOWTO documents and other
Linux documentation in printed and bound form.</para><para><indexterm significance="normal"><primary>Running Linux</primary></indexterm>
<indexterm significance="normal"><primary>Learning Debian GNU/Linux</primary></indexterm>
<indexterm significance="normal"><primary>Learning Red Hat Linux</primary></indexterm>
<indexterm significance="normal"><primary>Linux in a Nutshell</primary></indexterm> O'Reilly
 Associates publishes a series of Linux books. This one is a work
of the Linux Documentation Project, but most have been independently
authored. Their range includes:

<variablelist><varlistentry><term><emphasis>Running Linux</emphasis></term><listitem><para>An installation and user guide to the system describing how to get the most
out of personal computing with Linux.</para></listitem></varlistentry><varlistentry><term><emphasis>Learning Debian GNU/Linux</emphasis></term><term><emphasis>Learning Red Hat Linux</emphasis></term><listitem><para>More basic than <emphasis>Running Linux</emphasis>, these books
contain popular distributions on CD-ROM and offer robust directions
for setting them up and using them.</para></listitem></varlistentry><varlistentry><term><emphasis>Linux in a Nutshell</emphasis></term><listitem><para>Another in the successful "in a Nutshell" series, this book focuses on
providing a broad reference text for Linux.</para></listitem></varlistentry></variablelist>
</para></sect2><sect2><title>Linux Journal and Linux Magazine</title><indexterm significance="normal"><primary>Linux Journal</primary></indexterm><indexterm significance="normal"><primary>Linux Magazine</primary></indexterm><para><emphasis>Linux Journal</emphasis> and <emphasis>Linux
Magazine</emphasis> are monthly magazines for the Linux community,
written and published by a number of Linux activists. They contain
articles ranging from novice questions and answers to kernel
programming internals. Even if you have Usenet access, these magazines
are a good way to stay in touch with the Linux community.</para><para><emphasis>Linux Journal</emphasis> is the oldest magazine and is
published by S.S.C. Incorporated, for which details were listed
previously. You can also find the magazine on the World Wide Web at
<systemitem moreinfo="none" role="url">http://www.linuxjournal.com/</systemitem>.</para><para><emphasis>Linux Magazine</emphasis> is a newer, independent
publication. The home web site for the magazine is <systemitem moreinfo="none" role="url">http://www.linuxmagazine.com/</systemitem>.</para></sect2><sect2><title>Linux Usenet Newsgroups</title><indexterm significance="normal"><primary>newsgroups</primary><secondary>Usenet</secondary></indexterm><para>If you have access to Usenet news, the following Linux-related newsgroups
are available:

<variablelist><indexterm significance="normal"><primary>comp.os.linux.announce</primary></indexterm><varlistentry><term><systemitem moreinfo="none" role="newsgroup">comp.os.linux.announce</systemitem></term><listitem><para>A moderated newsgroup containing announcements of new software,
distributions, bug reports, and goings-on in the Linux community. All
Linux users should read this group. Submissions may be mailed to
<systemitem moreinfo="none" role="emailaddr">linux-announce@news.ornl.gov</systemitem>.</para></listitem></varlistentry><indexterm significance="normal"><primary>comp.os.linux.help</primary></indexterm><varlistentry><term><systemitem moreinfo="none" role="newsgroup">comp.os.linux.help</systemitem></term><listitem><para>General questions and answers about installing or using Linux.</para></listitem></varlistentry><indexterm significance="normal"><primary>comp.os.linux.admin</primary></indexterm><varlistentry><term><systemitem moreinfo="none" role="newsgroup">comp.os.linux.admin</systemitem></term><listitem><para>Discussions relating to systems administration under Linux.</para></listitem></varlistentry><indexterm significance="normal"><primary>comp.os.linux.networking</primary></indexterm><varlistentry><term><systemitem moreinfo="none" role="newsgroup">comp.os.linux.networking</systemitem></term><listitem><para>Discussions relating to networking with Linux.</para></listitem></varlistentry><indexterm significance="normal"><primary>comp.os.linux.development</primary></indexterm><varlistentry><term><systemitem moreinfo="none" role="newsgroup">comp.os.linux.development</systemitem></term><listitem><para>Discussions about developing the Linux kernel and system itself.</para></listitem></varlistentry><indexterm significance="normal"><primary>comp.os.linux.misc</primary></indexterm><varlistentry><term><systemitem moreinfo="none" role="newsgroup">comp.os.linux.misc</systemitem></term><listitem><para>A catch-all newsgroup for miscellaneous discussions that don't
fall under the previous categories.</para></listitem></varlistentry></variablelist></para><para>There are also several newsgroups devoted to Linux in languages other
than English, such as <systemitem moreinfo="none" role="newsgroup">fr.comp.os.linux</systemitem> in French and <systemitem moreinfo="none" role="newsgroup">de.comp.os.linux</systemitem> in German.</para></sect2><sect2><title>Linux Mailing Lists</title><para><indexterm significance="normal"><primary>mailing lists</primary></indexterm>
There is a large number of specialist Linux mailing lists on which you
will find many people willing to help with questions you might have.</para><para>The best-known of these are the lists hosted by Rutgers University.
You may subscribe to these lists by sending an email message formatted
as follows:

<screen format="linespecific">To: majordomo@vger.rutgers.edu
Subject: anything at all
Body:

subscribe <replaceable>listname</replaceable></screen></para><para>Some of the available lists related to Linux networking are:

<variablelist><indexterm significance="normal"><primary>linux-net mailing list</primary></indexterm><varlistentry><term><systemitem moreinfo="none" role="newsgroup">linux-net</systemitem></term><listitem><para>Discussion relating to Linux networking</para></listitem></varlistentry><indexterm significance="normal"><primary>linux-ppp mailing list</primary></indexterm><varlistentry><term><systemitem moreinfo="none" role="newsgroup">linux-ppp</systemitem></term><listitem><para>Discussion relating to the Linux PPP implementation</para></listitem></varlistentry><indexterm significance="normal"><primary>linux-kernel mailing list</primary></indexterm><varlistentry><term><systemitem moreinfo="none" role="newsgroup">linux-kernel</systemitem></term><listitem><para>Discussion relating to Linux kernel development</para></listitem></varlistentry></variablelist>
</para></sect2><sect2><title>Online Linux Support</title><para><indexterm significance="normal"><primary>support, online</primary></indexterm> 
<indexterm significance="normal"><primary>help, online</primary></indexterm> 
<indexterm significance="normal"><primary>online help</primary></indexterm>
There are many ways of obtaining help online, where volunteers
from around the world offer expertise and services to assist
users with questions and problems.</para><para><indexterm significance="normal"><primary>OpenProjects IRC network</primary></indexterm>
<indexterm significance="normal"><primary>IRC Network, OpenProjects</primary></indexterm>
The OpenProjects IRC Network is an IRC network devoted entirely to
Open ProjectsOpen Source and Open Hardware alike. Some of its
channels are designed to provide online Linux support services. IRC
stands for Internet Relay Chat, and is a network service that allows
you to talk interactively on the Internet to other users. IRC networks
support multiple channels on which groups of people talk. Whatever you
type in a channel is seen by all other users of that channel.</para><para><?troff .hw openprojects?>There are a number of active channels on the OpenProjects IRC network
where you will find users 24 hours a day, 7 days a week who are
willing and able to help you solve any Linux problems you may have, or
just chat. You can use this service by installing an IRC client like
<emphasis>irc-II</emphasis>, connecting to servername <systemitem moreinfo="none" role="sitename">irc.openprojects.org:6667</systemitem>, and joining the
<literal moreinfo="none">#linpeople</literal> channel.</para></sect2><sect2><title>Linux User Groups</title><para><indexterm significance="normal"><primary>user groups</primary></indexterm>
<indexterm significance="normal"><primary>Linux User Groups (LUG)</primary></indexterm>
<indexterm significance="normal"><primary>LUG (Linux User Groups)</primary></indexterm>
Many Linux User Groups around the world offer direct
support to users. Many Linux User Groups engage in activities such as
installation days, talks and seminars, demonstration nights, and other
completely social events. Linux User Groups are a great way of meeting other
Linux users in your area. There are a number of published lists of Linux
User Groups. Some of the better-known ones are:

<variablelist><varlistentry><term>Groups of Linux Users Everywhere</term><listitem><para> <systemitem moreinfo="none" role="url">http://www.ssc.com/glue/groups/</systemitem></para></listitem></varlistentry><varlistentry><term>LUG list project</term><listitem><para><systemitem moreinfo="none" role="url">http://www.nllgg.nl/lugww/</systemitem></para></listitem></varlistentry><varlistentry><term>LUG registry</term><listitem><para><systemitem moreinfo="none" role="url">http://www.linux.org/users/</systemitem></para></listitem></varlistentry></variablelist>
</para></sect2><sect2><title>Obtaining Linux</title><para><indexterm significance="normal"><primary>code, obtaining for</primary><secondary>Linux network</secondary></indexterm>
<indexterm significance="normal"><primary>Linux</primary><secondary>networks</secondary><tertiary>obtaining code for</tertiary></indexterm>
<indexterm significance="normal"><primary>Linux distributions</primary></indexterm>
<indexterm significance="normal"><primary>Caldera (Linux distribution)</primary></indexterm>
<indexterm significance="normal"><primary>Corel (Linux distribution)</primary></indexterm>
<indexterm significance="normal"><primary>Debian (Linux distribution)</primary></indexterm>
<indexterm significance="normal"><primary>RedHat (Linux distribution)</primary></indexterm>
<indexterm significance="normal"><primary>Slackware (Linux distribution)</primary></indexterm>
<indexterm significance="normal"><primary>SuSE (Linux distribution)</primary></indexterm>

There is no single distribution of the Linux software; instead, there
are many distributions, such as Debian, RedHat, Caldera, Corel, SuSE,
and Slackware. Each distribution contains everything you need to run a
complete Linux system: the kernel, basic utilities, libraries, support
files, and applications software.</para><para>Linux distributions may be obtained via a number of online sources, such as
the Internet. Each of the major distributions has its own FTP and web site.
Some of these sites are:

<variablelist><varlistentry><term>Caldera</term><listitem><para><literallayout format="linespecific" class="normal"><systemitem moreinfo="none" role="url">http://www.caldera.com/</systemitem><systemitem moreinfo="none" role="url">ftp://ftp.caldera.com/</systemitem></literallayout></para></listitem></varlistentry><varlistentry><term>Corel</term><listitem><para><literallayout format="linespecific" class="normal"><systemitem moreinfo="none" role="url">http://www.corel.com/</systemitem><systemitem moreinfo="none" role="url">ftp://ftp.corel.com/</systemitem></literallayout></para></listitem></varlistentry><varlistentry><term>Debian</term><listitem><para><literallayout format="linespecific" class="normal"><systemitem moreinfo="none" role="url">http://www.debian.org/</systemitem><systemitem moreinfo="none" role="url">ftp://ftp.debian.org/</systemitem></literallayout></para></listitem></varlistentry><varlistentry><term>RedHat</term><listitem><para><literallayout format="linespecific" class="normal"><systemitem moreinfo="none" role="url">http://www.redhat.com/</systemitem><systemitem moreinfo="none" role="url">ftp://ftp.redhat.com/</systemitem></literallayout></para></listitem></varlistentry><varlistentry><term>Slackware</term><listitem><para><literallayout format="linespecific" class="normal"><systemitem moreinfo="none" role="url">http://www.slackware.com/</systemitem><systemitem moreinfo="none" role="url">ftp://ftp.slackware.com/</systemitem></literallayout></para></listitem></varlistentry><varlistentry><term>SuSE</term><listitem><para><literallayout format="linespecific" class="normal"><systemitem moreinfo="none" role="url">http://www.suse.com/</systemitem><systemitem moreinfo="none" role="url">ftp://ftp.suse.com/</systemitem></literallayout></para></listitem></varlistentry></variablelist>

Many of the popular general FTP archive sites also mirror various
Linux distributions. The best-known of these sites are:
<literallayout format="linespecific" class="normal"><systemitem moreinfo="none" role="url">metalab.unc.edu:/pub/Linux/distributions/</systemitem>
<systemitem moreinfo="none" role="url">ftp.funet.fi:/pub/Linux/mirrors/</systemitem>
<systemitem moreinfo="none" role="url">tsx-11.mit.edu:/pub/linux/distributions/</systemitem>
<systemitem moreinfo="none" role="url">mirror.aarnet.edu.au:/pub/linux/distributions/</systemitem></literallayout></para><?troff .Nd 7?><para>Many of the modern distributions can be installed directly from the
Internet.  There is a lot of software to download for a typical
installation, though, so you'd probably want to do this only if you
have a high-speed, permanent network connection, or if you just need
to update an existing installation.<footnote id="x-087-2-fnpr02"><para> or you are extremely impatient and know that the 24 hours it
might take to download the software from the Internet is faster than
the 72 hours it might take to wait for a CD-ROM to be delivered!</para></footnote></para><para>Linux may be purchased on CD-ROM from an increasing number of software
vendors. If your local computer store doesn't have it, perhaps you
should ask them to stock it! Most of the popular distributions can be
obtained on CD-ROM. Some vendors produce products containing multiple
CD-ROMs, each of which provides a different Linux distribution. This
is an ideal way to try a number of different distributions before you
settle on your favorite one.</para></sect2></sect1><sect1><title>File System Standards</title><indexterm significance="normal"><primary>File System Standard</primary></indexterm><indexterm significance="normal"><primary>FSSTND (File System Standard)</primary></indexterm><indexterm significance="normal"><primary>FHS (File Hierarchy Standard)</primary></indexterm><indexterm significance="normal"><primary>standards, filesystem</primary></indexterm><para>In the past, one of the problems that afflicted Linux distributions,
as well as the packages of software running on Linux, was the lack of
a single accepted filesystem layout. This resulted in
incompatibilities between different packages, and confronted users and
administrators with the task of locating various files and programs.</para><para>To improve this situation, in August 1993, several people formed the
Linux File System Standard Group (FSSTND). After six months of
discussion, the group created a draft that presents a coherent file
sytem structure and defines the location of the most essential
programs and configuration files.</para><para>This standard was supposed to have been implemented by most major
Linux distributions and packages. It is a little unfortunate that,
while most distributions have made some attempt to work toward the
FSSTND, there is a very small number of distributions that has
actually adopted it fully. Throughout this book, we will assume that
any files discussed reside in the location specified by the standard;
alternative locations will be mentioned only when there is a long
tradition that conflicts with this specification.</para><para>The Linux FSSTND continued to develop, but was replaced by the Linux
File Hierarchy Standard (FHS) in 1997. The FHS addresses the
multi-architecture issues that the FSSTND did not. The FHS can be
obtained from the Linux documentation directory of all major Linux FTP
sites and their mirrors, or at its home site at <systemitem moreinfo="none" role="url">http://www.pathname.com/fhs/</systemitem>.  Daniel Quinlan,
the coordinator of the FHS group, can be reached at <systemitem moreinfo="none" role="emailaddr">quinlan@transmeta.com</systemitem>.
</para></sect1><sect1><title>Standard Linux Base</title><indexterm significance="normal"><primary>Linux Standard Base (LSB)</primary></indexterm><indexterm significance="normal"><primary>LSB (Linux Standard Base)</primary></indexterm><indexterm significance="normal"><primary>Linux distributions</primary><secondary>standard base</secondary></indexterm><para>The vast number of different Linux distributions, while providing lots of
healthy choice for Linux users, has created a problem for software
developersparticularly developers of non-free software.</para><para>Each distribution packages and supplies certain base libraries,
configuration tools, system applications, and configuration
files. Unfortunately, differences in their versions, names, and
locations make it very difficult to know what will exist on any
distribution. This makes it hard to develop binary applications that
will work reliably on all Linux distribution bases.</para><para>To help overcome this problem, a new project sprang up called the
Linux Standard Base. It aims to describe a standard base
distribution that complying distributions will use. If a developer
designs an application to work against the standard base platform, the
application will work, and be portable to, any complying Linux
distribution.</para><para>You can find information on the status of the Linux Standard Base
project at its home web site at <systemitem moreinfo="none" role="url">http://www.linuxbase.org/</systemitem>.</para><para>If you're concerned about interoperability, particularly of software
from commercial vendors, you should ensure that your Linux
distribution is making an effort to participate in the standardization
project.</para></sect1><sect1><title>About This Book</title><para>When Olaf joined the Linux Documentation Project in 1992, he wrote two
small chapters on UUCP and <command moreinfo="none">smail</command>, which he meant to
contribute to the System Administrator's Guide. Development of TCP/IP
networking was just beginning, and when those small chapters
started to grow, he wondered aloud whether it would be nice to have a
Networking Guide. Great! everyone said. Go for it!
So he went for it and wrote the first version of the Networking Guide, which
was released in September 1993.</para><para><indexterm significance="normal"><primary>Skahan, Vince</primary></indexterm> Olaf continued
work on the Networking Guide and eventually produced a much enhanced
version of the guide. Vince Skahan contributed the original
<command moreinfo="none">sendmail</command> mail chapter, which was completely
replaced in this edition because of a new interface to the
<command moreinfo="none">sendmail</command> configuration.</para><para>The version of the guide that you are reading now is a revision and
update prompted by O'Reilly  Associates and undertaken by Terry
Dawson.<footnote id="x-087-2-fnpr04"><para> Terry Dawson can be
reached at <systemitem moreinfo="none" role="emailaddr">terry@linux.org.au</systemitem>.</para></footnote>
Terry has been an amateur radio operator for over 20 years and has
worked in the telecommunications industry for over 15 of those. He was
co-author of the original NET-FAQ, and has since authored and
maintained various networking-related HOWTO documents. Terry has
always been an enthusiastic supporter of the Network Administrators
Guide project, and added a few new chapters to this version describing
features of Linux networking that have been developed since the first
edition, plus a bunch of changes to bring the rest of the book up to
date.</para><para><indexterm significance="normal"><primary>Hazel, Philip</primary></indexterm>
The <command moreinfo="none">exim</command> chapter was contributed by
Philip Hazel,<footnote id="x-087-2-fnpr05"><para>Philip Hazel can be reached at
<systemitem moreinfo="none" role="emailaddr">ph10@cus.cam.ac.uk</systemitem>.</para></footnote>
who is a lead developer and maintainer of the package.</para><para>The book is organized roughly along the sequence of steps you have to
take to configure your system for networking. It starts by discussing
basic concepts of networks, and TCP/IP-based networks in particular.
It then slowly works its way up from configuring TCP/IP at the device
level to firewall, accounting, and masquerade configuration, to the
setup of common applications such as <command moreinfo="none">rlogin</command> and
friends, the Network File System, and the Network Information
System. This is followed by a chapter on how to set up your machine as
a UUCP node.  Most of the remaining sections is dedicated to two major
applications that run on top of TCP/IP and UUCP: electronic mail and
news.  A special chapter has been devoted to the IPX protocol and the
NCP filesystem, because these are used in many corporate environments
where Linux is finding a home.</para><para>The email part features an introduction to the more intimate parts of
mail transport and routing, and the myriad of addressing schemes you
may be confronted with. It describes the configuration and management
of <command moreinfo="none">exim</command>, a mail transport agent ideal for use in most
situations not requiring UUCP, and <command moreinfo="none">sendmail</command>, which is for
people who have to do more complicated routing involving UUCP.</para><para>The news part gives you an overview of how Usenet news works. It covers
INN and C News, the two most widely used news transport software packages
at the moment, and the use of NNTP to provide newsreading access to a local
network. The book closes with a chapter on the care and feeding of the most
popular newsreaders on Linux.</para><para>Of course, a book can never exhaustively answer all questions you
might have. So if you follow the instructions in this book and
something still does not work, please be patient. Some of your
problems may be due to mistakes on our part (see the section <xref linkend="x-087-2-submitchanges"></xref>", later in this Preface), but they also may be caused by changes
in the networking software. Therefore, you should check the listed
information resources first. There's a good chance that you are not
alone with your problems, so a fix or at least a proposed workaround
is likely to be known. If you have the opportunity, you should also
try to get the latest kernel and network release from one of the Linux
FTP sites or a BBS near you.  Many problems are caused by software
from different stages of development, which fail to work together
properly. After all, Linux is a work in progress.</para></sect1><sect1><title>The Official Printed Version</title><para>In Autumn 1993, Andy Oram, who had been around the LDP mailing list
from almost the very beginning, asked Olaf about publishing this book
at O'Reilly  Associates. He was excited about this book, never having
imagined that it would become this successful. He and Andy
finally agreed that O'Reilly would produce an enhanced Official
Printed Version of the Networking Guide, while Olaf retained the
original copyright so that the source of the book could be freely
distributed. This means that you can choose freely: you can get the
various free forms of the document from your nearest Linux
Documentation Project mirror site and print it out, or you can
purchase the official printed version from O'Reilly.</para><para>Why, then, would you want to pay money for something you can get for
free?  Is Tim O'Reilly out of his mind for publishing something
everyone can print and even sell themselves?<footnote id="x-087-2-fnpr06"><para> Note that while you are allowed to print
out the online version, you may <emphasis>not</emphasis> run the
O'Reilly book through a photocopier, much less sell any of its
(hypothetical) copies.</para></footnote>
Is there any difference between these versions?</para><para>The answers are it depends, no, definitely not,
and yes and no. O'Reilly  Associates does take a risk in
publishing the Networking Guide, and it seems to have paid off for them
(they've asked us to do it again). We believe this project serves as a fine
example of how the free software world and companies can cooperate to produce
something both can benefit from. In our view, the great service O'Reilly is
providing to the Linux community (apart from the book becoming readily
available in your local bookstore) is that it has helped Linux become
recognized as something to be taken seriously: a viable and useful alternative
to other commercial operating systems. It's a sad technical bookstore
that doesn't have at least one shelf stacked with O'Reilly Linux books.</para><para>Why are they publishing it? They see it as their
kind of book. It's what they'd hope to produce if they contracted with
an author to write about Linux. The pace, level of detail, and style
fit in well with their other offerings.</para><para>The point of the LDP license is to make sure no one gets shut out. Other
people can print out copies of this book, and no one will blame you if you
get one of these copies. But if you haven't gotten a chance to see the
O'Reilly version, try to get to a bookstore or look at a friend's copy. We
think you'll like what you see, and will want to buy it for yourself.</para><para>So what about the differences between the printed and online versions?
Andy Oram has made great efforts at transforming our ramblings into
something actually worth printing. (He has also reviewed a few other
books produced by the Linux Documentation Project, contributing
whatever professional skills he can to the Linux community.)</para><para>Since Andy started reviewing the Networking Guide and editing the
copies sent to him, the book has improved vastly from its original
form, and with every round of submission and feedback it improves
again. The opportunity to take advantage of a professional editor's
skill is one not to be wasted. In many ways, Andy's contribution has
been as important as that of the authors.  The same is also true of
the copyeditors, who got the book into the shape you see now. All
these edits have been fed back into the online version, so there is no
difference in content.</para><para>Still, the O'Reilly version <emphasis>will</emphasis> be different. It
will be professionally bound, and while you may go to the trouble to
print the free version, it is unlikely that you will get the same
quality result, and even then it is more unlikely that you'll do it for
the price. <?troff .ne 7?>Secondly, our amateurish attempts at illustration will have
been replaced with nicely redone figures by O'Reilly's professional
artists. Indexers have generated an improved index, which makes
locating information in the book a much simpler process. If this book
is something you intend to read from start to finish, you should
consider reading the official printed version.</para></sect1><sect1 id="x-087-2-intro.outlook"><title>Overview</title><para><xref linkend="x-087-2-intro"></xref>, discusses the history of Linux and
covers basic networking information on UUCP, TCP/IP, various
protocols, hardware, and security. The next few chapters deal with
configuring Linux for TCP/IP networking and running some major
applications. We examine IP a little more closely in <xref linkend="x-087-2-issues"></xref>, before getting our hands dirty with file
editing and the like. If you already know how IP routing works and how
address resolution is performed, you can skip this chapter.</para><para><xref linkend="x-087-2-hardware"></xref>, deals with very basic configuration issues,
such as building a kernel and setting up your Ethernet card. The
configuration of your serial ports is covered separately in
<xref linkend="x-087-2-serial"></xref>, because the discussion does not apply
to TCP/IP networking only, but is also relevant for UUCP.</para><para><xref linkend="x-087-2-iface"></xref>, helps you set up your machine for TCP/IP
networking.  It contains installation hints for standalone hosts with
loopback enabled only, and hosts connected to an Ethernet.  It also
introduces you to a few useful tools you can use to test and debug your
setup. <xref linkend="x-087-2-resolv"></xref>, discusses how to configure hostname
resolution and explains how to set up a name server.</para><para><xref linkend="x-087-2-slip"></xref>, explains how to establish SLIP connections
and gives a detailed reference for <command moreinfo="none">dip</command>, a tool that
allows you to automate most of the necessary steps.
<xref linkend="x-087-2-ppp"></xref>, covers PPP and <command moreinfo="none">pppd</command>,
the PPP daemon.</para><para><xref linkend="x-087-2-firewall"></xref>, extends our discussion on network
security and describes the Linux TCP/IP firewall and its configuration
tools: <command moreinfo="none">ipfwadm</command>, <command moreinfo="none">ipchains</command>, and
<command moreinfo="none">iptables</command>. IP firewalling provides a means of
controlling who can access your network and hosts very precisely.</para><para><xref linkend="x-087-2-accounting"></xref>, explains how to configure IP Accounting
in Linux so you can keep track of how much traffic is going where and who is
generating it.</para><para><xref linkend="x-087-2-ipmasq"></xref>, covers a feature of the Linux
networking software called IP masquerade, which allows whole IP
networks to connect to and use the Internet through a single IP
address, hiding internal systems from outsiders in the process.</para><para><xref linkend="x-087-2-appl"></xref>, gives a short introduction to setting up some
of the most important network applications, such as <command moreinfo="none">rlogin</command>,
<command moreinfo="none">ssh</command>, etc. This chapter also covers how services are managed
by the <command moreinfo="none">inetd</command> superuser, and how you may restrict certain
security-relevant services to a set of trusted hosts.</para><para><xref linkend="x-087-2-nis"></xref>, and <xref linkend="x-087-2-nfs"></xref>,
discuss NIS and NFS. NIS is a tool used to distribute administative
information, such as user passwords in a local area network. NFS
allows you to share filesystems between several hosts in your network.</para><para>In <xref linkend="x-087-2-ipx"></xref>, we discuss the IPX protocol and the NCP
filesystem. These allow Linux to be integrated into a Novell NetWare
environment, sharing files and printers with non-Linux machines.</para><para><xref linkend="x-087-2-uucp"></xref>, gives you an extensive introduction to the
administration of Taylor UUCP, a free implementation of the UUCP suite.</para><para>The remainder of the book is taken up by a detailed tour of electronic
mail and Usenet news. <xref linkend="x-087-2-mail"></xref>, introduces you to the
central concepts of electronic mail, like what a mail address looks like, and
how the mail handling system manages to get your message to the
recipient.</para><para><xref linkend="x-087-2-sendmail"></xref>, and <xref linkend="x-087-2-exim"></xref>, cover 
the configuration of <command moreinfo="none">sendmail</command> and <command moreinfo="none">exim</command>, 
two mail transport agents you can use for Linux.  This book explains both 
of them, because <command moreinfo="none">exim</command> is easier to install for the 
beginner, while <command moreinfo="none">sendmail</command> provides support for UUCP.</para><para>
<xref linkend="x-087-2-news"></xref>, through <xref linkend="x-087-2-inn"></xref>,
explain the way news is managed in Usenet and how you install and use
C News, <command moreinfo="none">nntpd</command>, and INN: three popular software
packages for managing Usenet news. After the brief introduction in
<xref linkend="x-087-2-news"></xref>, you can read <xref linkend="x-087-2-cnews"></xref>, if you want to transfer news using C News, a
traditional service generally used with UUCP. The following chapters
discuss more modern alternatives to C News that use the Internet-based
protocol NNTP (Network News Transfer Protocol).  <xref linkend="x-087-2-nntp"></xref> covers how to set up a simple NNTP daemon,
<command moreinfo="none">nntpd</command>, to provide news reading access for a local
network, while <xref linkend="x-087-2-inn"></xref> describes a more robust
server for more extensive NetNews transfers, the InterNet News daemon
(INN).  And finally, <xref linkend="x-087-2-newsreaders"></xref>, shows you
how to configure and maintain various newsreaders.</para></sect1><sect1><title>Conventions Used in This Book</title><para>All examples presented in this book assume you are using a
<command moreinfo="none">sh</command> compatible shell. The <command moreinfo="none">bash</command> shell
is <command moreinfo="none">sh</command> compatible and is the standard shell of all Linux
distributions. If you happen to be a <command moreinfo="none">csh</command> user, you will
have to make appropriate adjustments.</para><para>The following is a list of the typographical conventions
used in this book:</para><variablelist><varlistentry><term><emphasis>Italic</emphasis></term><listitem><para>Used for file and directory names,
program and command names, command-line options, email addresses and
pathnames, URLs, and for emphasizing new terms.</para></listitem></varlistentry><varlistentry><term><emphasis role="bold">Boldface</emphasis></term><listitem><para>Used for machine names, hostnames, site names, usernames and IDs, and for occasional emphasis.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">Constant Width</literal></term><listitem><para>Used in examples to show the contents of
code files or the output from commands and to indicate environment
variables and keywords that appear in code.</para></listitem></varlistentry><varlistentry><term><replaceable>Constant Width Italic</replaceable></term><listitem><para>Used to indicate variable options, keywords, or text that the user is to
replace with an actual value.</para></listitem></varlistentry><varlistentry><term><userinput moreinfo="none">Constant Width Bold</userinput></term><listitem><para>Used in examples to show commands or other text that should be typed
literally by the user.</para></listitem></varlistentry></variablelist><warning><para>Text appearing in this manner offers a warning. You can make a
mistake here that hurts your system or is hard to recover from.</para></warning></sect1><sect1 id="x-087-2-submitchanges"><title>Submitting Changes</title><para>We have tested and verified the information in this book to the best of our
ability, but you may find that features have changed (or even that we have
made mistakes!). Please let us know about any errors you find, as well as
your suggestions for future editions, by writing to:</para><literallayout format="linespecific" class="normal">O'Reilly  Associates, Inc.
101 Morris Street
Sebastopol, CA 95472
1-800-998-9938 (in the U.S. or Canada)
1-707-829-0515 (international or local)
1-707-829-0104 (FAX)</literallayout><?troff .Nd 7?><para>You can send us messages electronically. To be put on the mailing list
or request a catalog, send email to:</para><literallayout format="linespecific" class="normal"><emphasis>info@oreilly.com</emphasis>     </literallayout><para>To ask technical questions or comment on the book, send email to:</para><literallayout format="linespecific" class="normal"><emphasis>bookquestions@oreilly.com</emphasis></literallayout><para>We have a web site for the book, where we'll list examples, errata,
and any plans for future editions. You can access this page at:</para><literallayout format="linespecific" class="normal"><emphasis>http://www.oreilly.com/catalog/linag2</emphasis></literallayout><para>For more information about this book and others, see the O'Reilly
web site:</para><literallayout format="linespecific" class="normal"><emphasis>http://www.oreilly.com</emphasis></literallayout></sect1><sect1><title>Acknowledgments</title><para>This edition of the Networking Guide owes almost everything to the
outstanding work of Olaf and Vince. It is difficult to appreciate the
effort that goes into researching and writing a book of this nature
until you've had a chance to work on one yourself. Updating the book
was a challenging task, but with an excellent base to work from, it
was an enjoyable one.</para><para>This book owes very much to the numerous people who took the time to
proof-read it and help iron out many mistakes, both technical and
grammatical (never knew that there was such a thing as a dangling
participle). Phil Hughes, John Macdonald, and Erik Ratcliffe all
provided very helpful (and on the whole, quite consistent) feedback on
the content of the book.</para><para>We also owe many thanks to the people at O'Reilly we've had the
pleasure to work with: Sarah Jane Shangraw, who got the book into the
shape you can see now; Maureen Dempsey, who copyedited the text; Rob
Romano, Rhon Porter, and Chris Reilley, who created all the figures;
Hanna Dyer, who designed the cover; Alicia Cech, David Futato, and
Jennifer Niedherst for the internal layout; Lars Kaufman for
suggesting old woodcuts as a visual theme; Judy Hoer for the index;
and finally, Tim O'Reilly for the courage to take up such a project.</para><para>We are greatly indebted to Andres Seplveda, Wolfgang Michaelis,
Michael K. Johnson, and all developers who spared the time to check
the information provided in the Networking Guide. Phil Hughes, John 
MacDonald, and Eric Ratcliffe contributed invaluable comments on the 
second edition. We also wish to thank all those who read the first version 
of the Networking Guide and sent corrections and suggestions. You can find 
a hopefully complete list of contributors in the file 
<filename moreinfo="none">Thanks</filename> in the online distribution. Finally, this book 
would not have been possible without the support of Holger Grothe, who 
provided Olaf with the Internet connectivity he needed to make the original 
version happen.</para><para>Olaf would also like to thank the following groups and companies that 
printed the first edition of the Networking Guide and have donated
money either to him or to the Linux Documentation Project as a whole:
Linux Support Team, Erlangen, Germany; S.u.S.E. GmbH, Fuerth, Germany;
and Linux System Labs, Inc., Clinton Twp., United States, RedHat
Software, North Carolina, United States.</para><para>Terry thanks his wife, Maggie, who patiently supported him throughout
his participation in the project despite the challenges presented by
the birth of their first child, Jack. Additionally, he thanks the
<emphasis>many</emphasis> people of the Linux community who either
nurtured or suffered him to the point at which he could actually take
part and actively contribute. I'll help you if you promise to
help someone else in return.</para><sect2><title>The Hall of Fame</title><para>Besides those we have already mentioned, a large number of people have
contributed to the Networking Guide, by reviewing it and sending us
corrections and suggestions. We are very grateful.</para><para>Here is a list of those whose contributions left a trace in our mail folders.</para><para>Al Longyear, Alan Cox, Andres Seplveda, Ben Cooper, Cameron Spitzer,
Colin McCormack, D.J. Roberts, Emilio Lopes, Fred N. van Kempen, Gert
Doering, Greg Hankins, Heiko Eissfeldt, J.P. Szikora, Johannes Stille,
Karl Eichwalder, Les Johnson, Ludger Kunz, Marc van Diest, Michael
K. Johnson, Michael Nebel, Michael Wing, Mitch D'Souza, Paul
Gortmaker, Peter Brouwer, Peter Eriksson, Phil Hughes, Raul Deluth
Miller, Rich Braun, Rick Sladkey, Ronald Aarts, Swen Themmler,
Terry Dawson, Thomas Quinot, and Yury Shevchuk.</para><indexterm significance="normal"><primary>electronic mail</primary><see>email</see></indexterm><indexterm significance="normal"><primary>mail</primary><see>email</see></indexterm><indexterm significance="normal"><primary>news (Usenet)</primary><see>news (network); Usenet</see></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>TCP/IP</secondary><see>TCP/IP</see></indexterm><indexterm significance="normal"><primary>LANs</primary><see>Local Area Networks</see></indexterm><indexterm significance="normal"><primary>Internet Protocol</primary><see>IP</see></indexterm><indexterm significance="normal"><primary>Transmission Control Protocol</primary><see>TCP</see></indexterm><indexterm significance="normal"><primary>routing</primary><secondary>IP</secondary><tertiary>datagrams</tertiary><see>IP, routing</see></indexterm><indexterm significance="normal"><primary>serial line IP</primary><see>SLIP; PPP</see></indexterm><indexterm significance="normal"><primary>Compressed Serial Line IP</primary><see>CSLIP</see></indexterm><indexterm significance="normal"><primary>Point-to-Point Protocol</primary><see>PPP</see></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>connections</secondary><see>networks, ports</see></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>interfaces</secondary><see>interfaces</see></indexterm><indexterm significance="normal"><primary>access network hardware</primary><see>interfaces</see></indexterm><indexterm significance="normal"><primary>default IP route</primary><see>IP (Internet Protocol), default route</see></indexterm><indexterm significance="normal"><primary>Address Resolution Protocol</primary><see>ARP</see></indexterm><indexterm significance="normal"><primary>Reverse Address Resolution Protocol</primary><see>RARP</see></indexterm><indexterm significance="normal"><primary>Internet Control Message Protocol</primary><see>ICMP</see></indexterm><indexterm significance="normal"><primary>Domain Name System</primary><see>DNS</see></indexterm></sect2><indexterm significance="normal"><primary>zones, DNS</primary><see>DNS, zones</see></indexterm><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>RR</secondary><see>DNS, resource record</see></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>parallel line</secondary><see>PLIP (Parallel Line IP) protocol</see></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>serial line</secondary><see>SLIP (Serial Line IP) protocol</see></indexterm><indexterm significance="normal"><primary>Parallel Line IP</primary><see>PLIP (Parallel Line IP) protocol</see></indexterm><indexterm significance="normal"><primary>Berkeley Internet Name Domain</primary><see>BIND</see></indexterm><indexterm significance="normal"><primary>Serial Line Internet protocols</primary><seealso>SLIP; PPP</seealso></indexterm><indexterm significance="normal"><primary>Link Control Protocol</primary><see>LCP</see></indexterm><indexterm significance="normal"><primary>Password Authentication Protocol</primary><see>PAP</see></indexterm><indexterm significance="normal"><primary>Internet Protocol Control Protocol</primary><see>IPCP</see></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>interconnecting</secondary><see>internetworking</see></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>UUCP</secondary><see>UUCP</see></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>services</secondary><see>ports</see></indexterm><indexterm significance="normal"><primary>Remote Procedure Call</primary><see>RPC</see></indexterm><indexterm significance="normal"><primary>Network Information System</primary><see>NIS</see></indexterm><indexterm significance="normal"><primary>Network File System</primary><see>NFS</see></indexterm><indexterm significance="normal"><primary>UUCP</primary><secondary>Taylor</secondary><see>Taylor UUCP</see></indexterm><indexterm significance="normal"><primary>Basic Networking Utilities</primary><see>Taylor UUCP, HDB</see></indexterm><indexterm significance="normal"><primary>HoneyDanBer</primary><see>Taylor UUCP, HDB</see></indexterm><indexterm significance="normal"><primary>HDB</primary><see>Taylor UUCP, HDB</see></indexterm><indexterm significance="normal"><primary>BNU (Basic Networking Utilities)</primary><see>Taylor UUCP, HDB</see></indexterm><indexterm significance="normal"><primary>Simple Mail Transfer Protocol (SMTP)</primary><see>SMTP</see></indexterm><indexterm significance="normal"><primary>routing</primary><secondary>email</secondary><see>email, routing</see></indexterm><indexterm significance="normal"><primary>email</primary><secondary>Exim</secondary><seealso>Exim</seealso></indexterm><indexterm significance="normal"><primary>configuring</primary><secondary>Exim</secondary><see>Exim</see></indexterm><indexterm significance="normal"><primary>network news</primary><see>news (network)</see></indexterm><indexterm significance="normal"><primary>Network News Transfer Protocol</primary><see>NNTP</see></indexterm><indexterm significance="normal"><primary>news, C</primary><see>C News</see></indexterm><indexterm significance="normal"><primary>news (network)</primary><secondary>C release</secondary><see>C News</see></indexterm><indexterm significance="normal"><primary>Trivial File Transfer Protocol</primary><see>TFTP</see></indexterm><indexterm significance="normal"><primary>filtering</primary><seealso>masquerade</seealso></indexterm><indexterm significance="normal"><primary>Unix-to-Unix Copy</primary><see>UUCP</see></indexterm><indexterm significance="normal"><primary>Netnews</primary><see>news (network); Usenet</see></indexterm><indexterm significance="normal"><primary>Internet News</primary><see>INN (Internet News)</see></indexterm></sect1></preface><?troff .BLANK?><chapter id="x-087-2-intro"><title>Introduction <?lb?>to Networking</title><sect1 id="x-087-2-intro.history"><title>History</title><para><indexterm significance="normal" class="startofrange" id="chit.netwks.intro"><primary>networks</primary><secondary>introduction
to</secondary></indexterm> The idea of networking is probably as old
as telecommunications itself.  Consider people living in the Stone
Age, when drums may have been used to transmit messages between
individuals. Suppose caveman A wants to invite caveman B over for a
game of hurling rocks at each other, but they live too far apart for B
to hear A banging his drum. What are A's options? He could 1) walk
over to B's place, 2) get a bigger drum, or 3) ask C, who lives
halfway between them, to forward the message. The last option is
called <emphasis>networking</emphasis>.</para><para>Of course, we have come a long way from the primitive pursuits and devices of
our forebears. Nowadays, we have computers talk to each other over vast
assemblages of wires, fiber optics, microwaves, and the like, to make an
appointment for Saturday's soccer match.<footnote id="x-087-2-fnit01"><para>The original spirit of which (see above) still shows on some occasions in
Europe.</para></footnote>
In the following description, we will deal with the means and ways by which
this is accomplished, but leave out the wires, as well as the soccer part.</para><para>We will describe three types of networks in this guide. We will focus on
TCP/IP most heavily because it is the most popular protocol suite in use on
both Local Area Networks (LANs) and Wide Area Networks (WANs), such as the
Internet. We will also take a look at UUCP and IPX. UUCP was once commonly
used to transport news and mail messages over dialup telephone connections.
It is less common today, but is still useful in a variety of situations. The
IPX protocol is used most commonly in the Novell NetWare environment and we'll
describe how to use it<?troff .ne 7?> to connect your Linux machine into a Novell network.
Each of these protocols are networking protocols and are used to carry data
between host computers. We'll discuss how they are used and introduce you to
their underlying principles.</para><para><indexterm significance="normal"><primary>sites</primary></indexterm>
<indexterm significance="normal"><primary>hosts</primary></indexterm> We define a network as
a collection of <emphasis>hosts</emphasis> that are able to
communicate with each other, often by relying on the services of a
number of dedicated hosts that relay data between the
participants. Hosts are often computers, but need not be; one can also
think of X terminals or intelligent printers as hosts. Small
agglomerations of hosts are also called <emphasis>sites</emphasis>.</para><para><indexterm significance="normal"><primary>networks</primary><secondary>protocols</secondary></indexterm>
<indexterm significance="normal"><primary>protocols</primary></indexterm> Communication is
impossible without some sort of language or code. In computer
networks, these languages are collectively referred to as
<emphasis>protocols</emphasis>. However, you shouldn't think of
written protocols here, but rather of the highly formalized code of
behavior observed when heads of state meet, for instance. In a very
similar fashion, the protocols used in computer networks are nothing
but very strict rules for the exchange of messages between two or more
hosts.</para></sect1><sect1 id="x-087-2-intro.tcpip"><title>TCP/IP Networks</title><para><indexterm significance="normal"><primary>networks</primary><secondary>TCP/IP</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="chit.networks.tcp-ip"><primary>TCP/IP (Transmission Control
Protocol/Internet
Protocol)</primary><secondary>networks</secondary></indexterm>
<indexterm significance="normal"><primary>Local Area Networks (LANs)</primary></indexterm>
<indexterm significance="normal"><primary>networks</primary><secondary>Local
Area</secondary></indexterm>
<indexterm significance="normal"><primary>networks</primary><secondary>packet-switched</secondary></indexterm>
<indexterm significance="normal"><primary>packet-switched networks</primary></indexterm>
Modern networking applications require a sophisticated approach to
carrying data from one machine to another. If you are managing a Linux
machine that has many users, each of whom may wish to simultaneously
connect to remote hosts on a network, you need a way of allowing them
to share your network connection without interfering with each
other. The approach that a large number of modern networking protocols
uses is called <emphasis>packet-switching</emphasis>. A
<emphasis>packet</emphasis> is a small chunk of data that is
transferred from one machine to another across the network. The
switching occurs as the datagram is carried across each link in the
network. A packet-switched network shares a single network link among
many users by alternately sending packets from one user to another
across that link.</para><para><indexterm significance="normal"><primary>datagrams</primary></indexterm> The solution that
Unix systems, and subsequently many non-Unix systems, have adopted is
known as TCP/IP. When talking about TCP/IP networks you will hear the
term <emphasis>datagram</emphasis>, which technically has a special
meaning but is often used interchangeably with
<emphasis>packet</emphasis>. In this section, we will have a look at
underlying concepts of the TCP/IP protocols.</para><sect2 id="x-087-2-intro.tcpip.intro"><title>Introduction to TCP/IP Networks</title><para><indexterm significance="normal"><primary>ARPANET</primary></indexterm>
<indexterm significance="normal"><primary>networks</primary><secondary>ARPANET</secondary></indexterm>
TCP/IP traces its origins to a research project funded by the United States
Defense Advanced Research Projects Agency (DARPA) in 1969. The ARPANET was an
experimental network that was converted into an operational one in 1975 after
it had proven to be a success.</para><?troff .Nd 7?><para><indexterm significance="normal"><primary>networks</primary><secondary>Internet</secondary></indexterm>
<indexterm significance="normal"><primary>Internet</primary></indexterm>
<indexterm significance="normal"><primary>networks</primary><secondary>corporate</secondary></indexterm>
In 1983, the new protocol suite TCP/IP was adopted as a standard, and
all hosts on the network were required to use it.  When ARPANET
finally grew into the Internet (with ARPANET itself passing out of
existence in 1990), the use of TCP/IP had spread to networks beyond
the Internet itself. Many companies have now built corporate TCP/IP
networks, and the Internet has grown to a point at which it could
almost be considered a mainstream consumer technology. It is difficult
to read a newspaper or magazine now without seeing reference to the
Internet; almost everyone can now use it.</para><para><indexterm significance="normal"><primary>Marx, Groucho</primary></indexterm>
<indexterm significance="normal"><primary>Groucho Marx University
(GMU)</primary></indexterm> For something concrete to look at as we
discuss TCP/IP throughout the following sections, we will consider
Groucho Marx University (GMU), situated somewhere in Fredland, as an
example.  Most departments run their own Local Area Networks, while
some share one and others run several of them. They are all
interconnected and hooked to the Internet through a single high-speed
link.</para><para><indexterm significance="normal"><primary>remote</primary><secondary>login</secondary></indexterm>
Suppose your Linux box is connected to a LAN of Unix hosts at the Mathematics
department, and its name is <systemitem moreinfo="none" role="sitename">erdos</systemitem>. To
access a host at the Physics department, say
<systemitem moreinfo="none" role="sitename">quark</systemitem>,
you enter the following command:

<screen format="linespecific">$ <userinput moreinfo="none">rlogin quark.physics</userinput>
Welcome to the Physics Department at GMU
(ttyq2) login:</screen></para><para><indexterm significance="normal"><primary>remote</primary><secondary>login</secondary><tertiary>via TCP/IP</tertiary></indexterm> 
At the prompt, you enter your login name, say
<systemitem moreinfo="none" role="userid">andres</systemitem>, and your password. You are then
given a shell<footnote id="x-087-2-fnit02"><para>The shell is a command-line interface to the Unix operating system. It's
similar to the DOS prompt in a Microsoft Windows environment, albeit much
more powerful.</para></footnote> on <systemitem moreinfo="none" role="sitename">quark</systemitem>, to which you
can type as if you were sitting at the system's console. After you exit the
shell, you are returned to your own machine's prompt. You have just used one
of the instantaneous, interactive applications that TCP/IP provides: remote
login.</para><para><indexterm significance="normal"><primary>remote</primary><secondary>login</secondary><tertiary>X Windows session</tertiary></indexterm>
<indexterm significance="normal"><primary>X Windows</primary></indexterm>
<indexterm significance="normal"><primary>DISPLAY (environment variable)</primary></indexterm> 
<indexterm significance="normal"><primary>environment variables</primary><secondary>DISPLAY</secondary></indexterm> 
While being logged into <systemitem moreinfo="none" role="sitename">quark</systemitem>,
you might also want to run a graphical user interface application,
like a word processing program, a graphics drawing program, or even a
World Wide Web browser. The X windows system is a fully network-aware
graphical user environment, and it is available for many different
computing systems. To tell this application that you want to have its
windows displayed on your host's screen, you have to set the
<systemitem moreinfo="none" role="keyword">DISPLAY</systemitem> environment variable:
<screen format="linespecific">$ <userinput moreinfo="none">DISPLAY=erdos.maths:0.0</userinput>
$ <userinput moreinfo="none">export DISPLAY</userinput></screen></para><para>If you now start your application, it will contact your X server instead of
<systemitem moreinfo="none" role="sitename">quark</systemitem>'s, and display all its windows
on your screen. Of course, this requires that you have X11 runnning on
<systemitem moreinfo="none" role="sitename">erdos</systemitem>. The point here is that TCP/IP
allows <systemitem moreinfo="none" role="sitename">quark</systemitem> and
<systemitem moreinfo="none" role="sitename">erdos</systemitem> to send X11 packets back and
forth to give you the illusion that you're on a single system. The network
is almost transparent here.</para><para><indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>via TCP/IP</secondary></indexterm> 
Another very important application in TCP/IP networks is NFS, which
stands for <emphasis>Network File System</emphasis>. It is another
form of making the network transparent, because it basically allows
you to treat directory hierarchies from other hosts as if they
were local file systems and look like any other directories on your
host. For example, all users' home directories can be kept on a
central server machine from which all other hosts on the LAN mount
them. The effect is that users can log in to any machine and find
themselves in the same home directory. Similarly, it is possible to
share large amounts of data (such as a database, documentation or
application programs) among many hosts by maintaining one copy of
the data on a server and allowing other hosts to access it. We will
come back to NFS in <xref linkend="x-087-2-nfs"></xref>.</para><para>Of course, these are only examples of what you can do with TCP/IP networks.
The possibilities are almost limitless, and we'll introduce you to more as you
read on through the book.</para><para>We will now have a closer look at the way TCP/IP works. This information will
help you understand how and why you have to configure your machine. We will
start by examining the hardware, and slowly work our way up.</para></sect2><sect2 id="x-087-2-intro.tcpip.history"><title>Ethernets</title><para><indexterm significance="normal"><primary>protocols</primary><secondary>Ethernet</secondary></indexterm>
<indexterm significance="normal"><primary>networks</primary><secondary>Ethernet</secondary></indexterm> 
<indexterm significance="normal"><primary>Local Area Networks (LANs)</primary><secondary>hardware for</secondary></indexterm> 
The most common type of LAN hardware is known as <emphasis>Ethernet</emphasis>.
In its simplest form, it consists of a single cable with hosts attached to it
through connectors, taps, or transceivers. Simple Ethernets are relatively
inexpensive to install, which together with a net transfer rate of 10, 100,
or even 1,000 Megabits per second, accounts for much of its popularity.</para><para><indexterm significance="normal"><primary>Ethernet</primary><secondary>thick/thin</secondary></indexterm>
<indexterm significance="normal"><primary>Ethernet</primary><secondary>twisted pair</secondary></indexterm>
<indexterm significance="normal"><primary>thinnet</primary></indexterm>
<indexterm significance="normal"><primary>BNC connector</primary></indexterm>
<indexterm significance="normal"><primary>active hubs</primary></indexterm>
<indexterm significance="normal"><primary>networks</primary><secondary>thinnet</secondary></indexterm>
Ethernets come in three flavors: <emphasis>thick</emphasis>,
<emphasis>thin</emphasis>, and <emphasis>twisted pair</emphasis>.
Thin and thick Ethernet each use a coaxial cable, differing in
diameter and the way you may attach a host to this cable. Thin
Ethernet uses a T-shaped BNC connector, which you insert
into the cable and twist onto a plug on the back of your computer.
Thick Ethernet requires that you drill a small hole into the cable,
and attach a transceiver using a vampire tap. One or
more hosts can then be connected to the transceiver. Thin and thick
Ethernet cable can run for a maximum of 200 and 500 meters
respectively, and are also called 10base-2 and 10base-5. The
base refers to baseband modulation and
simply means that the data is directly fed onto the cable without any
modem. The number at the start refers to the speed in Megabits per
second, and the number at the end is the maximum length of the cable
in hundreds of metres. Twisted pair uses a cable made of two pairs of
copper wires and usually requires additional hardware known as
<emphasis>active hubs</emphasis>. Twisted pair is also known as
10base-T, the T meaning twisted pair. The 100 Megabits
per second version is known as 100base-T.</para><para>To add a host to a thin Ethernet installation, you have to disrupt
network service for at least a few minutes because you have to cut the
cable to insert the connector. Although adding a host to a thick
Ethernet system is a little complicated, it does not typically bring
down the network. Twisted pair Ethernet is even simpler. It uses a
device called a hub, which serves as an interconnection
point. You can insert and remove hosts from a hub without interrupting
any other users at all.</para><para>Many people prefer thin Ethernet for small networks because it is very
inexpensive; PC cards come for as little as US 30 (many
companies are literally throwing them out now), and cable is in the
range of a few cents per meter. However, for large-scale
installations, either thick Ethernet or twisted pair is more
appropriate. For example, the Ethernet at GMU's Mathematics Department
originally chose thick Ethernet because it is a long route that the
cable must take so traffic will not be disrupted each time a host
is added to the network. Twisted pair installations are now very
common in a variety of installations. The Hub hardware is dropping in
price and small units are now available at a price that is attractive
to even small domestic networks. Twisted pair cabling can be
significantly cheaper for large installations, and the cable itself is
much more flexible than the coaxial cables used for the other Ethernet
systems. The network administrators in GMU's mathematics department
are planning to replace the existing network with a twisted pair
network in the coming finanical year because it will bring them up to
date with current technology and will save them significant time when
installing new host computers and moving existing computers around.</para><para><indexterm significance="normal"><primary>Ethernet</primary><secondary>drawbacks</secondary></indexterm> 
<indexterm significance="normal"><primary>repeaters</primary></indexterm> 
<indexterm significance="normal"><primary>bridges</primary></indexterm> 
<indexterm significance="normal"><primary>routers</primary></indexterm> 
One of the drawbacks of Ethernet technology is its limited cable length, which
precludes any use of it other than for LANs. However, several Ethernet
segments can be linked to one another using repeaters, bridges, or routers.
Repeaters simply copy the signals between two or more segments so that all
segments together will act as if they are one Ethernet. Due to timing
requirements, there may not be more than four repeaters between any two hosts
on the network. Bridges and routers are more sophisticated. They analyze
incoming data and forward it only when the recipient host is not on the local
Ethernet.</para><para><indexterm significance="normal"><primary>Ethernet</primary><secondary>addresses</secondary></indexterm>
<indexterm significance="normal"><primary>addresses</primary><secondary>Ethernet</secondary></indexterm>
Ethernet works like a bus system, where a host may send packets (or
<emphasis>frames</emphasis>) of up to 1,500 bytes to another host on the same
Ethernet. A host is addressed by a six-byte address hardcoded into the
firmware of its Ethernet network interface card (NIC). These addresses are
usually written as a sequence of two-digit hex numbers separated by colons,
as in <systemitem moreinfo="none" role="sitename">aa:bb:cc:dd:ee:ff</systemitem>.</para><para><indexterm significance="normal"><primary>Ethernet</primary><secondary>collisions</secondary></indexterm>
<indexterm significance="normal"><primary>collisions (Ethernet)</primary></indexterm> A
frame sent by one station is seen by all attached stations, but only
the destination host actually picks it up and processes it. If two
stations try to send at the same time, a
<emphasis>collision</emphasis> occurs. Collisions on an Ethernet are
detected very quickly by the electronics of the interface cards and
are resolved by the two stations aborting the send, each waiting a
random interval and re-attempting the transmission. You'll hear lots
of stories about collisions on Ethernet being a problem and that
utilization of Ethernets is only about 30 percent of the available
bandwidth because of them.  Collisions on Ethernet are a
<emphasis>normal</emphasis> phenomenon, and on a very busy Ethernet
network you shouldn't be surprised to see collision rates of up to
about 30 percent. Utilization of Ethernet networks is more
realistically limited to about 60 percent before you need to start
worrying about it.<footnote id="x-087-2-fnit03"><para> The Ethernet
FAQ at <systemitem moreinfo="none" role="url">http://www.faqs.org/faqs/LANs/ethernet-faq/</systemitem>
talks about this issue, and a wealth of detailed historical and
technical information is available at Charles Spurgeon's Ethernet web
site at <systemitem moreinfo="none" role="url">http://wwwhost.ots.utexas.edu/ethernet/</systemitem>.</para></footnote></para></sect2><sect2 id="x-087-2-intro.tcpip.other-hardware"><title>Other Types of Hardware</title><para>In larger installations, such as Groucho Marx University, Ethernet is usually
not the only type of equipment used. There are many other data communications
protocols available and in use. All of the protocols listed are supported by
Linux, but due to space constraints we'll describe them briefly. Many of the
protocols have HOWTO documents that describe them in detail, so you should
refer to those if you're interested in exploring those that we don't describe
in this book.</para><para><indexterm significance="normal"><primary>FDDI (Fiber Distributed Data Interface)</primary></indexterm>
<indexterm significance="normal"><primary>Fiber Distributed Data Interface (FDDI)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>token-passing</secondary></indexterm>
At Groucho Marx University, each department's LAN is linked to the
campus high-speed backbone network, which is a fiber
optic cable running a network technology called <emphasis>Fiber
Distributed Data Interface</emphasis> (FDDI). FDDI uses an entirely
different approach to transmitting data, which basically involves
sending around a number of <emphasis>tokens</emphasis>, with a station
being allowed to send a frame only if it captures a token. The main
advantage of a token-passing protocol is a reduction in collisions.
Therefore, the protocol can more easily attain the full speed of the
transmission medium, up to 100 Mbps in the case of FDDI.  FDDI, being
based on optical fiber, offers a significant advantage because its
maximum cable length is much greater than wire-based technologies. It
has limits of up to around 200 km, which makes it ideal for linking
many buildings in a city, or as in GMU's case, many buildings on a
campus.</para><para><indexterm significance="normal"><primary>Token Ring</primary><secondary>networks</secondary></indexterm>
<indexterm significance="normal"><primary>networks</primary><secondary>Token
Ring</secondary></indexterm> <indexterm significance="normal"><primary>IBM Token Ring
networks</primary></indexterm> Similarly, if there is any IBM
computing equipment around, an IBM Token Ring network is quite likely
to be installed. Token Ring is used as an alternative to Ethernet in
some LAN environments, and offers the same sorts of advantages as FDDI
in terms of achieving full wire speed, but at lower speeds (4 Mbps or
16 Mbps), and lower cost because it is based on wire rather than
fiber. In Linux, Token Ring networking is configured in almost
precisely the same way as Ethernet, so we don't cover it specifically.</para><para>Although it is much less likely today than in the past, other LAN
technologies, such as ArcNet and DECNet, might be installed. Linux
supports these too, but we don't cover them here.</para><para><indexterm significance="normal"><primary>protocols</primary><secondary>X.25</secondary></indexterm>
<indexterm significance="normal"><primary>X.25 protocol</primary></indexterm>
<indexterm significance="normal"><primary>PAD (Packet Assembler
Disassembler)</primary></indexterm> Many national networks operated by
Telecommunications companies support packet switching
protocols. Probably the most popular of these is a standard named
X.25. Many Public Data Networks, like Tymnet in the U.S., Austpac in
Australia, and Datex-P in Germany offer this service. X.25 defines a
set of networking protocols that describes how data terminal
equipment, such as a host, communicates with data communications
equipment (an X.25 switch). X.25 requires a synchronous data link, and
therefore special synchronous serial port hardware. It is possible to
use X.25 with normal serial ports if you use a special device called a
PAD (Packet Assembler Disassembler). The PAD is a standalone device
that provides asynchronous serial ports and a synchronous serial
port. It manages the X.25 protocol so that simple terminal devices can
make and accept X.25 connections. X.25 is often used to carry other
network protocols, such as TCP/IP. Since IP datagrams cannot simply be
mapped onto X.25 (or vice versa), they are encapsulated in X.25
packets and sent over the network. There is an experimental
implementation of the X.25 protocol available for Linux.</para><para><indexterm significance="normal"><primary>protocols</primary><secondary>Frame Relay</secondary></indexterm>
<indexterm significance="normal"><primary>FRAD (Frame Relay Access Device)</primary></indexterm>
A more recent protocol commonly offered by telecommunications
companies is called <emphasis>Frame Relay</emphasis>. The Frame Relay
protocol shares a number of technical features with the X.25 protocol,
but is much more like the IP protocol in behavior. Like X.25, Frame
Relay requires special synchronous serial hardware. Because of their
similarities, many cards support both of these protocols. An
alternative is available that requires no special internal hardware,
again relying on an external device called a Frame Relay Access Device
(FRAD) to manage the encapsulation of Ethernet packets into Frame
Relay packets for transmission across a network. Frame Relay is ideal
for carrying TCP/IP between sites. Linux provides drivers that support
some types of internal Frame Relay devices.</para><para><indexterm significance="normal"><primary>protocols</primary><secondary>ATM (Asynchronous Transfer Mode)</secondary></indexterm>
<indexterm significance="normal"><primary>ATM (Asynchronous Transfer Mode)</primary></indexterm>
If you need higher speed networking that can carry many different
types of data, such as digitized voice and video, alongside your usual
data, ATM (Asynchronous Transfer Mode) is probably what you'll be
interested in. ATM is a new network technology that has been
specifically designed to provide a manageable, high-speed, low-latency
means of carrying data, and provide control over the Quality of
Service (Q.S.). Many telecommunications companies are deploying ATM
network infrastructure because it allows the convergence of a number
of different network services into one platform, in the hope of
achieving savings in management and support costs. ATM is often used
to carry TCP/IP.  The Networking-HOWTO offers information on the Linux
support available for ATM.</para><para><indexterm significance="normal"><primary>protocols</primary><secondary>AX.25</secondary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>NetRom</secondary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>Rose</secondary></indexterm>
<indexterm significance="normal"><primary>amateur radio protocols</primary></indexterm>
<indexterm significance="normal"><primary>ham radio</primary></indexterm>
<indexterm significance="normal"><primary>packet radio</primary></indexterm>
<indexterm significance="normal"><primary>AX.25 protocol</primary></indexterm>
<indexterm significance="normal"><primary>NetRom protocol</primary></indexterm>
<indexterm significance="normal"><primary>Rose protocol</primary></indexterm>
<indexterm significance="normal"><primary>TNC (Terminal Node Controller)</primary></indexterm>
<indexterm significance="normal"><primary>AX25 HOWTO</primary></indexterm>
<indexterm significance="normal"><primary>HOWTOs</primary><secondary>AX25</secondary></indexterm>
Frequently, radio amateurs use their radio equipment to network their
computers; this is commonly called <emphasis>packet
radio</emphasis>. One of the protocols used by amateur radio operators
is called AX.25 and is loosely derived from X.25. Amateur radio
operators use the AX.25 protocol to carry TCP/IP and other protocols,
too. AX.25, like X.25, requires serial hardware capable of synchronous
operation, or an external device called a Terminal Node
Controller to convert packets transmitted via an asynchronous
serial link into packets transmitted synchronously. There are a
variety of different sorts of interface cards available to support
packet radio operation; these cards are generally referred to as being
Z8530 SCC based, and are named after the most popular
type of communications controller used in the designs. Two of the
other protocols that are commonly carried by AX.25 are the NetRom and
Rose protocols, which are network layer protocols. Since these
protocols run over AX.25, they have the same hardware
requirements. Linux supports a fully featured implementation of the
AX.25, NetRom, and Rose protocols. The AX25-HOWTO is a good source of
information on the Linux implementation of these protocols.</para><para>Other types of Internet access involve dialing up a central system
over slow but cheap serial lines (telephone, ISDN, and so on).  These
require yet another protocol for transmission of packets, such as SLIP
or PPP, which will be described later.</para></sect2><sect2 id="x-087-2-intro.tcpip.ip"><title>The Internet Protocol</title><para><indexterm significance="normal"><primary>protocols</primary><secondary>Internet (IP)</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary></indexterm>
Of course, you wouldn't want your networking to be limited to one
Ethernet or one point-to-point data link. Ideally, you would want to
be able to communicate with a host computer regardless of what type of
physical network it is connected to. For example, in larger
installations such as Groucho Marx University, you usually have a
number of separate networks that have to be connected in some way. At
GMU, the Math department runs two Ethernets: one with fast machines
for professors and graduates, and another with slow machines for
students. Both are linked to the FDDI campus backbone network.</para><para><indexterm significance="normal"><primary>forwarding</primary><secondary>IP</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>forwarding</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>gateways</secondary></indexterm>
<indexterm significance="normal"><primary>gateways</primary></indexterm>
This connection is handled by a dedicated host called a
<emphasis>gateway</emphasis> that handles incoming and outgoing
packets by copying them between the two Ethernets and the FDDI fiber
optic cable. For example, if you are at the Math department and want
to access <systemitem moreinfo="none" role="sitename">quark</systemitem> on the
Physics department's LAN from your Linux box, the networking software
will not send packets to <systemitem moreinfo="none" role="sitename">quark</systemitem>
directly because it is not on the same Ethernet. Therefore, it has to
rely on the gateway to act as a forwarder. The gateway (named
<systemitem moreinfo="none" role="sitename">sophus</systemitem>) then forwards these
packets to its peer gateway <systemitem moreinfo="none" role="sitename">niels</systemitem> at the Physics department, using
the backbone network, with <systemitem moreinfo="none" role="sitename">niels</systemitem> delivering it to the destination
machine. Data flow between <systemitem moreinfo="none" role="sitename">erdos</systemitem> and <systemitem moreinfo="none" role="sitename">quark</systemitem> is shown in <xref linkend="x-087-2-intro.fig.ip-flow"></xref>.</para><figure float="0" id="x-087-2-intro.fig.ip-flow"><title>The three steps of sending a datagram from erdos to quark</title><graphic fileref="lag2_0101.jpg"></graphic></figure><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>routing</secondary></indexterm>
<indexterm significance="normal"><primary>datagrams</primary></indexterm>
This scheme of directing data to a remote host is called
<emphasis>routing</emphasis>, and packets are often referred to as
<emphasis>datagrams</emphasis> in this context. To facilitate things,
datagram exchange is governed by a single protocol that is independent
of the hardware used: IP, or <emphasis>Internet Protocol</emphasis>.
In <xref linkend="x-087-2-issues"></xref>, we will cover IP and the issues of
routing in greater detail.</para><para><indexterm significance="normal"><primary>internetworking</primary></indexterm>
<indexterm significance="normal"><primary>networks</primary><secondary>interconnecting</secondary></indexterm>
<indexterm significance="normal"><primary>Internet</primary><secondary>versus internetworking</secondary></indexterm>
The main benefit of IP is that it turns physically dissimilar networks into
one apparently homogeneous network. This is called internetworking, and the
resulting meta-network is called an
<emphasis>internet</emphasis>. Note the subtle difference here between
<emphasis>an</emphasis> internet and <emphasis>the</emphasis> Internet.
The latter is the official name of one particular global internet.</para><para><indexterm significance="normal"><primary>addresses</primary><secondary>IP</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>addresses</secondary></indexterm>
<indexterm significance="normal"><primary>dotted quad notation</primary></indexterm>
<indexterm significance="normal"><primary>dotted decimal notation</primary></indexterm>
<indexterm significance="normal"><primary>IPv4 (Internet Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>IPv4</secondary></indexterm>
Of course, IP also requires a hardware-independent addressing
scheme. This is achieved by assigning each host a unique 32-bit number
called the <emphasis>IP address</emphasis>. An IP address is usually
written as four decimal numbers, one for each 8-bit portion, separated
by dots. For example, <systemitem moreinfo="none" role="sitename">quark</systemitem>
might have an IP address of <systemitem moreinfo="none" role="sitename">0x954C0C04</systemitem>, which would be written as
<systemitem moreinfo="none" role="sitename">149.76.12.4</systemitem>. This format is
also called <emphasis>dotted decimal notation</emphasis> and sometimes
<emphasis>dotted quad notation</emphasis>. It is increasingly going
under the name IPv4 (for Internet Protocol, Version 4) because a new
standard called IPv6 offers much more flexible addressing, as well as
other modern features. It will be at least a year after the release of
this edition before IPv6 is in use.</para><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>addresses</secondary><tertiary>versus hostname</tertiary></indexterm>
<indexterm significance="normal"><primary>Ethernet</primary><secondary>addresses</secondary><tertiary>versus IP address</tertiary></indexterm>
You will notice that we now have three different types of addresses:
first there is the host's name, like <systemitem moreinfo="none" role="sitename">quark</systemitem>, then there are IP addresses, and
finally, there are hardware addresses, like the 6-byte Ethernet
address. All these addresses somehow have to match so that when you
type <command moreinfo="none">rlogin quark</command>, the networking software can be
given <systemitem moreinfo="none" role="sitename">quark</systemitem>'s IP address; and
when IP delivers any data to the Physics department's Ethernet, it
somehow has to find out what Ethernet address corresponds to the IP
address.</para><para>We will deal with these situations in <xref linkend="x-087-2-issues"></xref>.
For now, it's enough to remember that these steps of finding addresses are
called <emphasis>hostname resolution</emphasis>, for mapping hostnames onto IP
addresses, and <emphasis>address resolution</emphasis>, for mapping the latter
to hardware addresses.</para></sect2><sect2 id="x-087-2-intro.tcpip.slip"><title>IP Over Serial Lines</title><para><indexterm significance="normal"><primary>protocols</primary><secondary>CSLIP</secondary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>SLIP</secondary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>PPP</secondary></indexterm>
<indexterm significance="normal"><primary>telephones</primary><secondary>sending data over</secondary></indexterm>
<indexterm significance="normal"><primary>SLIP (Serial Line IP) protocol</primary></indexterm>
<indexterm significance="normal"><primary>CSLIP (Compressed Serial Line IP) protocol</primary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary></indexterm>
On serial lines, a de facto standard exists known as SLIP, or
<emphasis>Serial Line IP</emphasis>. A modification of SLIP known as CSLIP,
or <emphasis>Compressed SLIP</emphasis>, performs compression of IP headers
to make better use of the relatively low bandwidth provided by most serial
links. Another serial protocol is PPP, or the
<emphasis>Point-to-Point Protocol</emphasis>. PPP is more modern than
SLIP and includes a number of features that make it more attractive. Its
main advantage over SLIP is that it isn't limited to transporting IP
datagrams, but is designed to allow just about any protocol to be carried
across it.</para></sect2><sect2 id="x-087-2-intro.tcpip.tcp"><title>The Transmission Control Protocol</title><para><indexterm significance="normal"><primary>protocols</primary><secondary>TCP</secondary></indexterm>
<indexterm significance="normal"><primary>TCP (Transmission Control Protocol)</primary></indexterm>
Sending datagrams from one host to another is not the whole story. If you
log in to <systemitem moreinfo="none" role="sitename">quark</systemitem>, you want to have a
reliable connection between your <command moreinfo="none">rlogin</command> process on
<systemitem moreinfo="none" role="sitename">erdos</systemitem> and the shell process on
<systemitem moreinfo="none" role="sitename">quark</systemitem>. Thus, the information sent
to and fro must be split up into packets by the sender and reassembled into
a character stream by the receiver. Trivial as it seems, this involves a
number of complicated tasks.</para><para>A very important thing to know about IP is that, by intent, it is not
reliable.  Assume that ten people on your Ethernet started downloading
the latest release of Netscape's web browser source code from GMU's
FTP server. The amount of traffic generated might be too much for the
gateway to handle, because it's too slow and it's tight on memory. Now
if you happen to send a packet to <systemitem moreinfo="none" role="sitename">quark</systemitem>, <systemitem moreinfo="none" role="sitename">sophus</systemitem> might be out of buffer space for a
moment and therefore unable to forward it. IP solves this problem by
simply discarding it. The packet is irrevocably lost. It is therefore
the responsibility of the communicating hosts to check the integrity
and completeness of the data and retransmit it in case of error.</para><para>This process is performed by yet another protocol, <emphasis>Transmission
Control Protocol</emphasis> (TCP), which builds a reliable service on top of IP. The
essential property of TCP is that it uses IP to give you the illusion of a
simple connection between the two processes on your host and the remote
machine, so you don't have to care about how and along which route your data
actually travels.  A TCP connection works essentially like a two-way pipe that
both processes may write to and read from. Think of it as a telephone
conversation.</para><para><indexterm significance="normal" class="startofrange" id="chit.networks.tcp.ports"><primary>networks</primary><secondary>ports</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="chit.networks.ports"><primary>ports</primary></indexterm>
TCP identifies the end points of such a connection by the IP addresses
of the two hosts involved and the number of a
<emphasis>port</emphasis> on each host. Ports may be viewed as
attachment points for network connections.  If we are to strain the
telephone example a little more, and you imagine that cities are like
hosts, one might compare IP addresses to area codes (where numbers map
to cities), and port numbers to local codes (where numbers map to
individual people's telephones). An individual host may support many
different services, each distinguished by its own port number.</para><para><indexterm significance="normal"><primary>remote</primary><secondary>login</secondary></indexterm>
In the <command moreinfo="none">rlogin</command> example, the client application
(<command moreinfo="none">rlogin</command>) opens a port on <systemitem moreinfo="none" role="sitename">erdos</systemitem> and connects to port 513 on
<systemitem moreinfo="none" role="sitename">quark</systemitem>, to which the
<command moreinfo="none">rlogind</command> server is known to listen. This action
establishes a TCP connection. Using this connection,
<command moreinfo="none">rlogind</command> performs the authorization procedure and
then spawns the shell. The shell's standard input and output are
redirected to the TCP connection, so that anything you type to
<command moreinfo="none">rlogin</command> on your machine will be passed through the
TCP stream and be given to the shell as standard input.</para></sect2><sect2 id="x-087-2-intro.tcpip.udp"><title>The User Datagram Protocol</title><para><indexterm significance="normal"><primary>protocols</primary><secondary>UDP</secondary></indexterm>
<indexterm significance="normal"><primary>UDP (User Datagram Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>User Datagram Protocol (UDP)</primary></indexterm>
Of course, TCP isn't the only user protocol in TCP/IP networking. Although
suitable for applications like <command moreinfo="none">rlogin</command>, the overhead
involved is prohibitive for applications like NFS, which instead uses a
sibling protocol of TCP called UDP, or
<emphasis>User Datagram Protocol</emphasis>. Just like TCP, UDP allows an
application to contact a service on a certain port of the remote machine, but
it doesn't establish a connection for this. Instead, you use it to send single
packets to the destination servicehence its name.</para><para>Assume you want to request a small amount of data from a database
server. It takes at least three datagrams to establish a TCP
connection, another three to send and confirm a small amount of data
each way, and another three to close the connection. UDP provides us
with a means of using only two datagrams to achieve almost the same
result. UDP is said to be connectionless, and it doesn't require us to
establish and close a session. We simply put our data into a datagram
and send it to the server; the server formulates its reply, puts the
data into a datagram addressed back to us, and transmits it
back. While this is both faster and more efficient than TCP for simple
transactions, UDP was not designed to deal with datagram loss. It is
up to the application, a name server for example, to take care of
this.</para></sect2><sect2 id="x-087-2-intro.tcpip.ports"><title>More on Ports</title><para><indexterm significance="normal"><primary>networks</primary><secondary>services</secondary></indexterm>
<indexterm significance="normal"><primary>services</primary></indexterm> Ports may be viewed
as attachment points for network connections. If an application wants
to offer a certain service, it attaches itself to a port and waits for
clients (this is also called <emphasis>listening</emphasis> on the
port). A client who wants to use this service allocates a port on its
local host and connects to the server's port on the remote host. The
same port may be open on many different machines, but on each machine
only one process can open a port at any one time.</para><para>An important property of ports is that once a connection has been
established between the client and the server, another copy of the
server may attach to the server port and listen for more clients.
This property permits, for instance, several concurrent remote logins
to the same host, all using the same port 513. TCP is able to tell
these connections from one another because they all come from
different ports or hosts. For example, if you log in twice to
<systemitem moreinfo="none" role="sitename">quark</systemitem> from <systemitem moreinfo="none" role="sitename">erdos</systemitem>, the first
<command moreinfo="none">rlogin</command> client will use the local port 1023, and the
second one will use port 1022. Both, however, will connect to the same
port 513 on <systemitem moreinfo="none" role="sitename">quark</systemitem>. The two
connections will be distinguished by use of the port numbers used at
<systemitem moreinfo="none" role="sitename">erdos</systemitem>.</para><para><indexterm significance="normal"><primary>services</primary><secondary>well-known</secondary></indexterm>
<indexterm significance="normal"><primary>services</primary><secondary>port numbers and</secondary></indexterm>
<indexterm significance="normal"><primary>IETF (Internet Engineering Task Force)</primary></indexterm>
This example shows the use of ports as rendezvous points, where a client
contacts a specific port to obtain a specific service. In order for a client
to know the proper port number, an agreement has to be reached between the
administrators of both systems on the assignment of these numbers. For
services that are widely used, such as <command moreinfo="none">rlogin</command>, these
numbers have to be administered centrally. This is done by the IETF
(Internet Engineering Task Force), which regularly releases an RFC titled
<emphasis>Assigned Numbers</emphasis> (RFC-1700). It describes, among other
things, the port numbers assigned to well-known services. Linux uses a file
called <filename moreinfo="none">/etc/services</filename> that maps service names to
numbers.</para><para>It is worth noting that although both TCP and UDP connections rely on ports,
these numbers do not conflict. This means that TCP port 513, for example, is
different from UDP port 513. In fact, these ports serve as access points for
two different services, namely <command moreinfo="none">rlogin</command> (TCP) and
<command moreinfo="none">rwho</command> (UDP).
<indexterm significance="normal" class="endofrange" startref="chit.networks.tcp.ports"></indexterm>
<indexterm significance="normal" class="endofrange" startref="chit.networks.ports"></indexterm></para></sect2><sect2 id="x-087-2-intro.tcpip.sockets"><title>The Socket Library</title><para><indexterm significance="normal"><primary>networks</primary><secondary>programming interfaces</secondary></indexterm> <indexterm significance="normal"><primary>Berkeley Socket Library</primary></indexterm>
<indexterm significance="normal"><primary>sockets</primary></indexterm>
<indexterm significance="normal"><primary>bind()</primary></indexterm>
<indexterm significance="normal"><primary>connect()</primary></indexterm>
<indexterm significance="normal"><primary>listen()</primary></indexterm>
<indexterm significance="normal"><primary>accept()</primary></indexterm>
<indexterm significance="normal"><primary>XNS (Xerox Networking System)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>XNS</secondary></indexterm>
In Unix operating systems, the software performing all the tasks and
protocols described above is usually part of the kernel, and so it is
in Linux. The programming interface most common in the Unix world is
the <emphasis>Berkeley Socket Library</emphasis>. Its name derives
from a popular analogy that views ports as sockets and connecting to
a port as plugging in. It provides the <function moreinfo="none">bind</function> call
to specify a remote host, a transport protocol, and a service that a
program can connect or listen to (using <function moreinfo="none">connect</function>,
<function moreinfo="none">listen</function>, and <function moreinfo="none">accept</function>). The
socket library is somewhat more general in that it provides not only a
class of TCP/IP-based sockets (the <function moreinfo="none">AF_INET</function>
sockets), but also a class that handles connections local to the
machine (the <function moreinfo="none">AF_UNIX</function> class). Some implementations
can also handle other classes, like the XNS (<emphasis>Xerox
Networking System</emphasis>) protocol or X.25.</para><para><indexterm significance="normal"><primary>IPX (Internet Packet eXchange)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>Internet Packet eXchange (IPX)</secondary></indexterm>
<indexterm significance="normal"><primary>X.25 protocol</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>X.25</secondary></indexterm>
<indexterm significance="normal"><primary>ATM (Asynchronous Transfer Mode)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>ATM (Asynchronous Transfer Mode)</secondary></indexterm>
<indexterm significance="normal"><primary>AX.25 protocol</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>AX.25</secondary></indexterm>
<indexterm significance="normal"><primary>NetRom protocol</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>NetRom</secondary></indexterm>
<indexterm significance="normal"><primary>Rose protocol</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>Rose</secondary></indexterm>
In Linux, the socket library is part of the standard
<filename moreinfo="none">libc</filename> C library. It supports the
<function moreinfo="none">AF_INET</function> and <function moreinfo="none">AF_INET6</function> sockets
for TCP/IP and <function moreinfo="none">AF_UNIX</function> for Unix domain
sockets. It also supports <function moreinfo="none">AF_IPX</function> for Novell's
network protocols, <function moreinfo="none">AF_X25</function> for the X.25 network
protocol, <function moreinfo="none">AF_ATMPVC</function> and
<function moreinfo="none">AF_ATMSVC</function> for the ATM network protocol and
<function moreinfo="none">AF_AX25</function>, <function moreinfo="none">AF_NETROM</function>, and
<function moreinfo="none">AF_ROSE</function> sockets for Amateur Radio protocol
support. Other protocol families are being developed and will be
added in time.</para><indexterm significance="normal" class="endofrange" startref="chit.networks.tcp-ip"></indexterm></sect2><?troff .Nd 7?></sect1><sect1 id="x-087-2-intro.uucp"><title>UUCP Networks</title><para><indexterm significance="normal"><primary>networks</primary><secondary>UUCP</secondary></indexterm>
<indexterm significance="normal"><primary>UUCP</primary><secondary>networks</secondary></indexterm>
Unix-to-Unix Copy (UUCP) started out as a package of programs that
transferred files over serial lines, scheduled those transfers, and
initiated execution of programs on remote sites. It has undergone major
changes since its first implementation in the late seventies, but it
is still rather spartan in the services it offers. Its main
application is still in Wide Area Networks, based on periodic dialup
telephone links.</para><para>UUCP was first developed by Bell Laboratories in 1977 for
communication between their Unix development sites. In mid-1978, this
network already connected over 80 sites.  It was running email as an
application, as well as remote printing.  However, the system's
central use was in distributing new software and bug fixes. Today, UUCP
is not confined solely to the Unix environment. There are free and
commercial ports available for a variety of platforms, including
AmigaOS, DOS, and Atari's TOS.</para><para>One of the main disadvantages of UUCP networks is that they operate in
batches. Rather than having a permanent connection established between
hosts, it uses temporary connections. A UUCP host machine might dial in to
another UUCP host only once a day, and then only for a short period of time.
While it is connected, it will transfer all of the news, email, and files that
have been queued, and then disconnect. It is this queuing that limits the
sorts of applications that UUCP can be applied to. In the case of email, a
user may prepare an email message and post it. The message will stay queued
on the UUCP host machine until it dials in to another UUCP host to transfer
the message. This is fine for network services such as email, but is no
use at all for services such as <command moreinfo="none">rlogin</command>.</para><para>Despite these limitations, there are still many UUCP networks
operating all over the world, run mainly by hobbyists, which offer
private users network access at reasonable prices. The main reason for
the longtime popularity of UUCP was that it was very cheap compared to
having your computer directly connected to the Internet. To make your
computer a UUCP node, all you needed was a modem, a working UUCP
implementation, and another UUCP node that was willing to feed you
mail and news. Many people were prepared to provide UUCP feeds to
individuals because such connections didn't place much demand on their
existing network.</para><para>We cover the configuration of UUCP in a chapter of its own later in
the book, but we won't focus on it too heavily, as it's being replaced
rapidly with TCP/IP, now that cheap Internet access has become commonly
available in most parts of the world.</para></sect1><sect1><title>Linux Networking</title><para><indexterm significance="normal"><primary>Linux</primary><secondary>networks</secondary></indexterm> 
<indexterm significance="normal"><primary>networks</primary><secondary>Linux</secondary></indexterm> 
<indexterm significance="normal"><primary>Net-1 network version</primary></indexterm>
<indexterm significance="normal"><primary>Net-2d network version</primary></indexterm>
<indexterm significance="normal"><primary>Net-2Debugged network version</primary></indexterm>
<indexterm significance="normal"><primary>Net-3 network version</primary></indexterm>
<indexterm significance="normal"><primary>Biro, Ross</primary></indexterm>
<indexterm significance="normal"><primary>Cox, Alan</primary></indexterm>
<indexterm significance="normal"><primary>Kempen, Fred van</primary></indexterm>
As it is the result of a concerted effort of programmers around
the world, Linux wouldn't have been possible without the global
network. So it's not surprising that in the early stages of
development, several people started to work on providing it with
network capabilities. A UUCP implementation was running on Linux
almost from the very beginning, and work on TCP/IP-based networking
started around autumn 1992, when Ross Biro and others created what has
now become known as Net-1.</para><para>After Ross quit active development in May 1993, Fred van Kempen began
to work on a new implementation, rewriting major parts of the
code. This project was known as Net-2. The first public release, Net-2d, was
made in the summer of 1993 (as part of the 0.99.10 kernel), and has
since been maintained and expanded by several people, most 
notably Alan Cox.<footnote id="x-087-2-fnit04"><para>Alan can be reached at
<systemitem moreinfo="none" role="emailaddr">alan@lxorguk.ukuu.org.uk</systemitem></para></footnote> Alan's original work was known as
Net-2Debugged. After heavy debugging and numerous improvements to the
code, he changed its name to Net-3 after Linux 1.0 was released. The
Net-3 code was further developed for Linux 1.2 and Linux 2.0.  The 2.2
and later kernels use the Net-4 version network support, which remains
the standard official offering today.</para><para><indexterm significance="normal"><primary>Net-4 network version</primary></indexterm> The
Net-4 Linux Network code offers a wide variety of device drivers and
advanced features. Standard Net-4 protocols include SLIP and PPP (for
sending network traffic over serial lines), PLIP (for parallel lines),
IPX (for Novell compatible networks, which we'll discuss in <xref linkend="x-087-2-ipx"></xref>), Appletalk (for Apple networks) and AX.25,
NetRom, and Rose (for amateur radio networks). Other standard Net-4
features include IP firewalling, IP accounting (discussed later in
<xref linkend="x-087-2-firewall"></xref> and <xref linkend="x-087-2-accounting"></xref>), and IP Masquerade (discussed later in
<xref linkend="x-087-2-ipmasq"></xref>. IP tunnelling in a couple of
different flavors and advanced policy routing are supported. A very
large variety of Ethernet devices is supported, in addition to support
for some FDDI, Token Ring, Frame Relay, and ISDN, and ATM cards.</para><para><indexterm significance="normal"><primary>Tridgell, Andrew</primary></indexterm>
Additionally, there are a number of other features that greatly
enhance the flexibility of Linux. These features include an
implementation of the SMB filesystem, which interoperates with
applications like <emphasis>lanmanager</emphasis> and Microsoft
Windows, called Samba, written by Andrew Tridgell, and an
implementation of the Novell NCP (NetWare Core Protocol).<footnote id="x-087-2-fnit05"><para> NCP is the protocol on which Novell file
and print services are based.</para></footnote>
</para><sect2><title>Different Streaks of Development</title><para>There have been, at various times, varying network development efforts active
for Linux.</para><para><indexterm significance="normal"><primary>Net-2e network version</primary></indexterm>
<indexterm significance="normal"><primary>DDI (Device Driver
Interface)</primary></indexterm> <indexterm significance="normal"><primary>Device Driver
Interface (DDI)</primary></indexterm> Fred continued development after
Net-2Debugged was made the official network implementation. This
development led to the Net-2e, which featured a much revised design of
the networking layer. Fred was working toward a standardized Device
Driver Interface (DDI), but the Net-2e work has ended now.</para><para><indexterm significance="normal"><primary>Urlichs, Matthias</primary></indexterm> Yet another 
implementation of TCP/IP networking came from Matthias
Urlichs, who wrote an ISDN driver for Linux and FreeBSD. For this
driver, he integrated some of the BSD networking code in the Linux
kernel.  That project, too is no longer being worked on.</para><para>There has been a lot of rapid change in the Linux kernel networking
implementation, and change is still the watchword as development
continues. Sometimes this means that changes also have to occur in
other software, such as the network configuration tools. While this is
no longer as large a problem as it once was, you may still find that
upgrading your kernel to a later version means that you must upgrade
your network configuration tools, too. Fortunately, with the large
number of Linux distributions available today, this is a quite simple
task.</para><para><indexterm significance="normal"><primary>IPv6 (Internet Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>IPv6</secondary></indexterm>
The Net-4 network implementation is now quite mature and is in use at a
very large number of sites around the world. Much work has been done on
improving the performance of the Net-4 implementation, and it now competes
with the best implementations available for the same hardware platforms.
Linux is proliferating in the Internet Service Provider environment, and is
often used to build cheap and reliable World Wide Web servers, mail servers,
and news servers for these sorts of organizations. There is now sufficient
development interest in Linux that it is managing to keep abreast of
networking technology as it changes, and current releases of the Linux kernel
offer the next generation of the IP protocol, IPv6, as a standard offering.</para></sect2><sect2><title>Where to Get the Code</title><para><indexterm significance="normal"><primary>code, obtaining for</primary><secondary>Linux network</secondary></indexterm>
<indexterm significance="normal"><primary>Linux</primary><secondary>networks</secondary><tertiary>obtaining code for</tertiary></indexterm>
<indexterm significance="normal"><primary>FTP (File Transfer Protocol), location of Linux code</primary></indexterm>
<indexterm significance="normal"><primary>Net-3 network version</primary></indexterm>
It seems odd now to remember that in the early days of the Linux
network code development, the standard kernel required a huge patch
kit to add the networking support to it. Today, network development
occurs as part of the mainstream Linux kernel development process. The
latest stable Linux kernels can be found on <emphasis role="bold">ftp.kernel.org</emphasis> in
<filename moreinfo="none">/pub/linux/kernel/v2.x/</filename>, where
<emphasis>x</emphasis> is an even number. The latest experimental Linux
kernels can be found on <emphasis role="bold">ftp.kernel.org</emphasis>
in <filename moreinfo="none">/pub/linux/kernel/v2.y/</filename>, where
<emphasis>y</emphasis> is an odd number. There are Linux kernel source
mirrors all over the world. It is now hard to imagine Linux without
standard network support.</para></sect2></sect1><sect1><title>Maintaining Your System</title><para><indexterm significance="normal"><primary>maintenance, system</primary></indexterm>
<indexterm significance="normal"><primary>system maintenance</primary></indexterm>
Throughout this book, we will mainly deal with installation and
configuration issues. Administration is, however, much more than
thatafter setting up a service, you have to keep it running, too.
For most services, only a little attendance will be necessary, while some,
like mail and news, require that you perform routine tasks to keep your system
up to date. We will discuss these tasks in later chapters.</para><para><indexterm significance="normal"><primary>cron</primary></indexterm>
<indexterm significance="normal"><primary>errors, checking for</primary></indexterm>
The absolute minimum in maintenance is to check system and per-application
log files regularly for error conditions and unusual events. Often, you
will want to do this by writing a couple of administrative shell scripts
and periodically running them from <command moreinfo="none">cron</command>. The source
distributions of some major applications, like <command moreinfo="none">inn</command> or
C News, contain such scripts. You only have to tailor them to suit your
needs and preferences.</para><para>The output from any of your <command moreinfo="none">cron</command> jobs should be mailed to an
administrative account. By default, many applications will send error
reports, usage statistics, or log file summaries to the
<systemitem moreinfo="none" role="userid">root</systemitem> account. This makes sense only
if you log in as <systemitem moreinfo="none" role="userid">root</systemitem> frequently; a much
better idea is to forward <systemitem moreinfo="none" role="userid">root</systemitem>'s mail to
your personal account by setting up a mail alias as described in
<xref linkend="x-087-2-exim"></xref> or <xref linkend="x-087-2-sendmail"></xref>.</para><para>However carefully you have configured your site, Murphy's law guarantees
that some problem <emphasis>will</emphasis> surface eventually. Therefore,
maintaining a system also means being available for complaints. Usually,
people expect that the system administrator can at least be reached via email
as <systemitem moreinfo="none" role="emailaddr">root</systemitem>, but there are also other
addresses that are commonly used to reach the person responsible for a
specific aspect of maintenence. For instance, complaints about a
malfunctioning mail configuration will usually be addressed to
<systemitem moreinfo="none" role="emailaddr">postmaster</systemitem>, and problems with the
news system may be reported to
<systemitem moreinfo="none" role="emailaddr">newsmaster</systemitem> or
<systemitem moreinfo="none" role="emailaddr">usenet</systemitem>. Mail to
<systemitem moreinfo="none" role="emailaddr">hostmaster</systemitem> should be redirected to
the person in charge of the host's basic network services, and the DNS name
service if you run a name server.</para><sect2 id="x-087-2-intro.security"><title>System Security</title><para><indexterm significance="normal"><primary>system security</primary></indexterm>
<indexterm significance="normal"><primary>security</primary><secondary>system</secondary></indexterm>
Another very important aspect of system administration in a network
environment is protecting your system and users from intruders.
Carelessly managed systems offer malicious people many targets. Attacks
range from password guessing to Ethernet snooping, and the damage caused
may range from faked mail messages to data loss or violation of your
users' privacy. We will mention some particular problems when discussing
the context in which they may occur and some common defenses against them.</para><para>This section will discuss a few examples and basic techniques for
dealing with system security.  Of course, the topics covered cannot
treat all security issues you may be faced with in detail; they merely
serve to illustrate the problems that may arise.  Therefore, reading a
good book on security is an absolute must, especially in a networked
system.</para><para>System security starts with good system administration. This includes
checking the ownership and permissions of all vital files and
directories and monitoring use of privileged accounts. The COPS
program, for instance, will check your file system and common
configuration files for unusual permissions or other anomalies. It is
also wise to use a password suite that enforces certain rules on the
users' passwords that make them hard to guess. The shadow password
suite, for instance, requires a password to have at least five letters
and to contain both upper- and lowercase numbers, as well as
non-alphabetic characters.</para><para><indexterm significance="normal"><primary>services</primary><secondary>restricting access
to</secondary></indexterm> <indexterm significance="normal"><primary>TFTP (Trivial File
Transfer Protocol)</primary></indexterm> When making a service
accessible to the network, make sure to give it least
privilege; don't permit it to do things that aren't required
for it to work as designed. For example, you should make programs
setuid to <systemitem moreinfo="none" role="userid">root</systemitem> or some other
privileged account only when necessary. Also, if you want to use a
service for only a very limited application, don't hesitate to
configure it as restrictively as your special application allows. For
instance, if you want to allow diskless hosts to boot from your
machine, you must provide <emphasis>Trivial File Transfer
Protocol</emphasis> (TFTP) so that they can download basic
configuration files from the <filename moreinfo="none">/boot</filename>
directory. However, when used unrestrictively, TFTP allows users
anywhere in the world to download any world-readable file from your
system. If this is not what you want, restrict TFTP service to the
<filename moreinfo="none">/boot</filename> directory.<footnote id="x-087-2-fnit06"><para> We will come back to this topic in <xref linkend="x-087-2-appl"></xref>.</para></footnote>
</para><para><indexterm significance="normal"><primary>access</primary><secondary>restricting</secondary></indexterm>
You might also want to restrict certain services to users from certain
hosts, say from your local network.  In <xref linkend="x-087-2-appl"></xref>,
we introduce <command moreinfo="none">tcpd</command>, which does this for a variety of
network applications. More sophisticated methods of restricting access
to particular hosts or services will be explored later in <xref linkend="x-087-2-firewall"></xref>.</para><para>Another important point is to avoid dangerous
software. Of course, any software you use can be dangerous because
software may have bugs that clever people might exploit to gain access
to your system. Things like this happen, and there's no complete
protection against it. This problem affects free software and
commercial products alike.<footnote id="x-087-2-fnit07"><para> There
have been commercial Unix systems (that you have to pay lots of money
for) that came with a setuid-<systemitem moreinfo="none" role="userid">root</systemitem> shell script, which allowed users to
gain <systemitem moreinfo="none" role="userid">root</systemitem> privilege using a
simple standard trick.</para></footnote> However, programs that require special privilege are inherently
more dangerous than others, because any loophole can have drastic
consequences.<footnote id="x-087-2-fnit08"><para>In 1988, the RTM worm brought much of the Internet to a grinding halt, partly
by exploiting a gaping hole in some programs including the
<command moreinfo="none">sendmail</command> program. This hole has long since been fixed.</para></footnote>
If you install a setuid program for network purposes, be doubly
careful to check the documentation so that you don't create a security
breach by accident.</para><para><indexterm significance="normal"><primary>ssh tools</primary></indexterm>
<indexterm significance="normal"><primary>authentication</primary><secondary>issues</secondary></indexterm>
Another source of concern should be programs that enable login or
command execution with limited authentication. The
<command moreinfo="none">rlogin</command>, <command moreinfo="none">rsh</command>, and
<command moreinfo="none">rexec</command> commands are all very useful, but offer very
limited authentication of the calling party.  Authentication is based
on trust of the calling host name obtained from a name server (we'll
talk about these later), which can be faked. Today it should be
standard practice to disable the <command moreinfo="none">r</command> commands
completely and replace them with the <command moreinfo="none">ssh</command> suite of
tools. The <command moreinfo="none">ssh</command> tools use a much more reliable
authentication method and provide other services, such as encryption
and compression, as well. </para><para><indexterm significance="normal"><primary>tripwire command</primary></indexterm>
You can never rule out the possibility that your precautions might
fail, regardless of how careful you have been. You should therefore
make sure you detect intruders early. Checking the system log files is
a good starting point, but the intruder is probably clever enough to
anticipate this action and will delete any obvious traces he or she
left. However, there are tools like <command moreinfo="none">tripwire</command>,
written by Gene Kim and Gene Spafford, that allow you to check vital
system files to see if their contents or permissions have been
changed. <command moreinfo="none">tripwire</command> computes various strong
checksums over these files and stores them in a database. During
subsequent runs, the checksums are recomputed and compared to the
stored ones to detect any modifications.

<indexterm significance="normal" class="endofrange" startref="chit.netwks.intro"></indexterm> </para></sect2></sect1></chapter><chapter id="x-087-2-issues"><title>Issues of TCP/IP <?lb?>Networking</title><indexterm significance="normal" class="startofrange" id="chis.tcp.ip.networks"><primary>TCP/IP (Transmission Control Protocol/Internet Protocol)</primary><secondary>networks</secondary></indexterm><indexterm significance="normal" class="startofrange" id="chis.networks.tcp.ip"><primary>networks</primary><secondary>TCP/IP</secondary></indexterm><para>In this chapter we turn to the configuration decisions you'll need to make
when connecting your Linux machine to a TCP/IP network, including dealing 
with IP addresses, hostnames, and routing issues.  This chapter gives you the
background you need in order to understand what your setup requires, while
the next chapters cover the tools you will use.</para><para>To learn more about TCP/IP and the reasons behind it, refer to the
three-volume set <emphasis>Internetworking with TCP/IP</emphasis>, by
Douglas R. Comer (Prentice Hall). For a more detailed guide to managing 
a TCP/IP network, see <emphasis>TCP/IP Network Administration</emphasis> 
by Craig Hunt (O'Reilly).</para><sect1 id="x-087-2-issues.interfaces"><title>Networking Interfaces</title><indexterm significance="normal"><primary>interfaces</primary></indexterm><para>To hide the diversity of equipment that may be used in a networking
environment, TCP/IP defines an abstract <emphasis>interface</emphasis>
through which the hardware is accessed. This interface offers a set of
operations that is the same for all types of hardware and basically deals
with sending and receiving packets.</para><para>For each peripheral networking device, a corresponding interface has
to be present in the kernel. For example, Ethernet interfaces in Linux
are called by such names as <filename moreinfo="none">eth0</filename> and
<filename moreinfo="none">eth1</filename>; PPP (discussed in <xref linkend="x-087-2-ppp"></xref>) interfaces are named <filename moreinfo="none">ppp0</filename>
and <filename moreinfo="none">ppp1</filename>; and FDDI interfaces are given names
like <filename moreinfo="none">fddi0</filename> and <filename moreinfo="none">fddi1</filename>. These
interface names are used for configuration purposes when you want to
specify a particular physical device in a configuration command, and
they have no meaning beyond this use.</para><para>Before being used by TCP/IP networking, an interface must be assigned
an IP address that serves as its identification when communicating
with the rest of the world. This address is different from the
interface name mentioned previously; if you compare an interface to a
door, the address is like the nameplate pinned on it.</para><para><indexterm significance="normal"><primary>Maximum Transfer Unit (MTU)</primary></indexterm>
Other device parameters may be set, like the maximum size of datagrams 
that can be processed by a particular piece of hardware, which is referred
to as <emphasis>Maximum Transfer Unit</emphasis> (MTU). Other attributes 
will be introduced later. Fortunately, most attributes have sensible defaults.</para></sect1><sect1 id="x-087-2-issues.ip-addresses"><title>IP Addresses</title><indexterm significance="normal"><primary>addresses</primary><secondary>IP</secondary></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>addresses</secondary></indexterm><para>As mentioned in <xref linkend="x-087-2-intro"></xref>, the IP networking protocol 
understands addresses as 32-bit numbers. Each machine must be assigned a 
number unique to the networking environment.<footnote id="x-087-2-fnis01"><para>The version of the Internet Protocol most frequently used on the
Internet is Version 4. A lot of effort has been expended in designing
a replacement called IP Version 6. IPv6 uses a different addressing
scheme and larger addresses. Linux has an implementation of IPv6, but
it isn't ready to document it in this book yet. The Linux kernel
support for IPv6 is good, but a large number of network applications
need to be modified to support it as well. Stay tuned.</para></footnote>
If you are running a local network that does not have TCP/IP traffic
with other networks, you may assign these numbers according to your
personal preferences. There are some IP address ranges that have been
reserved for such private networks. These ranges are listed in <xref linkend="x-087-2-issues.reserved.addresses"></xref>.  However, for sites on
the Internet, numbers are assigned by a central authority, the
<emphasis>Network Information Center</emphasis> (NIC).<footnote id="x-087-2-fnis02"><para>Frequently, IP addresses will be assigned to you by the provider from
whom you buy your IP connectivity. However, you may also apply to the
NIC directly for an IP address for your network by sending email to
<systemitem moreinfo="none" role="emailaddr">hostmaster@internic.net</systemitem>, or
by using the form at <systemitem moreinfo="none" role="url">http://www.internic.net/</systemitem>.</para></footnote>
</para><para><indexterm significance="normal"><primary>dotted quad notation</primary></indexterm>
<indexterm significance="normal"><primary>octets</primary></indexterm> 
IP addresses are split up into four eight-bit numbers called
<emphasis>octets</emphasis> for readability.  For example,
<systemitem moreinfo="none" role="sitename">quark.physics.groucho.edu</systemitem> has an
IP address of <systemitem moreinfo="none" role="sitename">0x954C0C04</systemitem>, which is
written as <systemitem moreinfo="none" role="sitename">149.76.12.4</systemitem>. This format
is often referred to as <emphasis>dotted quad notation</emphasis>.</para><para>Another reason for this notation is that IP addresses are split into a
<emphasis>network</emphasis> number, which is contained in the leading
octets, and a <emphasis>host</emphasis> number, which is the remainder.
When applying to the NIC for IP addresses, you are not assigned an address
for each single host you plan to use. Instead, you are given a network
number and allowed to assign all valid IP addresses within this range to
hosts on your network according to your preferences.</para><para>The size of the host part depends on the size of the network. To accommodate
different needs, several classes of networks, defining different places to 
split IP addresses, have been defined. The class networks are described here:</para><para><variablelist><varlistentry><term>Class A</term><listitem><para>Class A comprises networks <systemitem moreinfo="none" role="sitename">1.0.0.0</systemitem>
through <systemitem moreinfo="none" role="sitename">127.0.0.0</systemitem>. The network number
is contained in the first octet. This class provides for a 24-bit host part,
allowing roughly 1.6 million hosts per network.</para></listitem></varlistentry><varlistentry><term>Class B</term><listitem><para>Class B contains networks <systemitem moreinfo="none" role="sitename">128.0.0.0</systemitem>
through <systemitem moreinfo="none" role="sitename">191.255.0.0</systemitem>; the network
number is in the first two octets. This class allows for 16,320 nets with 65,024
hosts each.</para></listitem></varlistentry><varlistentry><term>Class C</term><listitem><para> Class C networks
range from <systemitem moreinfo="none" role="sitename">192.0.0.0</systemitem> through
<systemitem moreinfo="none" role="sitename">223.255.255.0</systemitem>, with the
network number contained in the first three octets. This class allows
for nearly 2 million networks with up to 254 hosts.</para></listitem></varlistentry><varlistentry><term>Classes D, E, and F</term><listitem><para>Addresses falling into the range of
<systemitem moreinfo="none" role="sitename">224.0.0.0</systemitem> through
<systemitem moreinfo="none" role="sitename">254.0.0.0</systemitem> are either experimental or
are reserved for special purpose use and don't specify any network. IP
Multicast, which is a service that allows material to be transmitted to many
points on an internet at one time, has been assigned addresses from within
this range.</para></listitem></varlistentry></variablelist></para><para>If we go back to the example in Chapter 1, we find that
<systemitem moreinfo="none" role="sitename">149.76.12.4</systemitem>, the address of
<systemitem moreinfo="none" role="sitename">quark</systemitem>, refers to host
<systemitem moreinfo="none" role="sitename">12.4</systemitem> on the class B network
<systemitem moreinfo="none" role="sitename">149.76.0.0</systemitem>.</para><para><indexterm significance="normal"><primary>addresses</primary><secondary>broadcast</secondary></indexterm>
You may have noticed that not all possible values in the previous list
were allowed for each octet in the host part. This is because octets
<systemitem moreinfo="none" role="sitename">0</systemitem> and <systemitem moreinfo="none" role="sitename">255</systemitem> are reserved for special purposes.
An address where all host part bits are 0 refers to the network, and
an address where all bits of the host part are 1 is called a
<emphasis>broadcast address</emphasis>.  This refers to all hosts on
the specified network simultaneously.  Thus, <systemitem moreinfo="none" role="sitename">149.76.255.255</systemitem> is not a valid host
address, but refers to all hosts on network <systemitem moreinfo="none" role="sitename">149.76.0.0</systemitem>.</para><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>default
route</secondary></indexterm>
<indexterm significance="normal"><primary>route, default</primary></indexterm>
<indexterm significance="normal"><primary>loopback</primary><secondary>address</secondary></indexterm>
<indexterm significance="normal"><primary>addresses</primary><secondary>loopback</secondary></indexterm>
A number of network addresses are reserved for special purposes.
<systemitem moreinfo="none" role="sitename">0.0.0.0</systemitem> and <systemitem moreinfo="none" role="sitename">127.0.0.0</systemitem> are two such addresses. The
first is called the <emphasis>default route</emphasis>, and the latter
is the <emphasis>loopback address</emphasis>. The default route has to
do with the way the IP routes datagrams.</para><para>Network <systemitem moreinfo="none" role="sitename">127.0.0.0</systemitem> is reserved for
IP traffic local to your host. Usually, address
<systemitem moreinfo="none" role="sitename">127.0.0.1</systemitem> will be assigned to a special
interface on your host, the <emphasis>loopback interface</emphasis>, which
acts like a closed circuit. Any IP packet handed to this interface from 
TCP or UDP will be returned to them as if it had just arrived from some 
network. This allows you to develop and test networking software without 
ever using a real network. The loopback network also allows
you to use networking software on a standalone host. This may not be as 
uncommon as it sounds; for instance, many UUCP sites don't have IP 
connectivity at all, but still want to run the INN news system. For 
proper operation on Linux, INN requires the loopback interface.</para><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>private addresses</secondary></indexterm>
Some address ranges from each of the network classes have been set
aside and designated reserved or private
address ranges.  These addresses are reserved for use by private
networks and are not routed on the Internet. They are commonly used by
organizations building their own intranet, but even small networks
often find them useful. The reserved network addresses appear in <xref linkend="x-087-2-issues.reserved.addresses"></xref>.</para><table id="x-087-2-issues.reserved.addresses"><title>IP Address Ranges Reserved for Private Use</title><tgroup cols="2"><thead><row><entry>Class</entry><entry>Networks</entry></row></thead><tbody><row><entry>A</entry><entry>10.0.0.0 through 10.255.255.255</entry></row><row><entry>B</entry><entry>172.16.0.0 through 172.31.0.0</entry></row><row><entry>C</entry><entry>192.168.0.0 through 192.168.255.0</entry></row></tbody></tgroup></table><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>addresses</secondary></indexterm></para></sect1><sect1 id="x-087-2-issues.arp"><title>Address Resolution</title><indexterm significance="normal" class="startofrange" id="chis.arp1"><primary>ARP (Address Resolution Protocol)</primary></indexterm><indexterm significance="normal"><primary>Ethernet</primary><secondary>addresses</secondary></indexterm><para>Now that you've seen how IP addresses are composed, you may be wondering
how they are used on an Ethernet or Token Ring network to address different
hosts. After all, these protocols have their own addresses to identify hosts
that have absolutely nothing in common with an IP address, don't they? Right.</para><para><indexterm significance="normal"><primary>ham radio</primary></indexterm>
<indexterm significance="normal"><primary>Token Ring</primary><secondary>ARP and</secondary></indexterm>
A mechanism is needed to map IP addresses onto the addresses of the
underlying network. The mechanism used is the <emphasis>Address
Resolution Protocol</emphasis> (ARP). In fact, ARP is not confined to
Ethernet or Token Ring, but is used on other types of networks, such
as the amateur radio AX.25 protocol. The idea underlying ARP is
exactly what most people do when they have to find Mr. X in a throng
of 150 people: the person who wants him calls out loudly enough that
everyone in the room can hear them, expecting him to respond if he is
there. When he responds, we know which person he is.</para><para>When ARP wants to find the Ethernet address corresponding to a given
IP address, it uses an Ethernet feature called <emphasis>broadcasting</emphasis>, in which a datagram is addressed to
all stations on the network simultaneously. The broadcast datagram
sent by ARP contains a query for the IP address. Each receiving host
compares this query to its own IP address and if it matches, returns
an ARP reply to the inquiring host.  The inquiring host can now
extract the sender's Ethernet address from the reply.</para><para>You may wonder how a host can reach an Internet address that may be on
a different network halfway around the world. The answer to this
question involves <emphasis>routing</emphasis>, namely finding the
physical location of a host in a network. We will discuss this issue
further in the next section.</para><?troff .Nd 15?><para>Let's talk a little more about ARP. Once a host has discovered an
Ethernet address, it stores it in its ARP cache so that it doesn't
have to query for it again the next time it wants to send a datagram
to the host in question.  However, it is unwise to keep this
information forever; the remote host's Ethernet card may be replaced
because of technical problems, so the ARP entry becomes
invalid. Therefore, entries in the ARP cache are discarded after some
time to force another query for the IP address.</para><para><indexterm significance="normal"><primary>diskless clients</primary></indexterm>
<indexterm significance="normal"><primary>BOOTP</primary></indexterm>
<indexterm significance="normal"><primary>RARP (Reverse Address Resolution Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>RARP (Reverse Address Resolution Protocol)</primary></indexterm>
Sometimes it is also necessary to find the IP address associated with
a given Ethernet address. This happens when a diskless machine wants
to boot from a server on the network, which is a common situation on
Local Area Networks. A diskless client, however, has virtually no
information about itselfexcept for its Ethernet address! So it
broadcasts a message containing a request asking a boot server to
provide it with an IP address. There's another protocol for this
situation named <emphasis>Reverse Address Resolution
Protocol</emphasis> (RARP). Along with the BOOTP protocol, it serves
to define a procedure for bootstrapping diskless clients over the
network.</para><para><indexterm significance="normal" class="endofrange" startref="chis.arp1"></indexterm></para></sect1><sect1 id="x-087-2-issues.routing"><title>IP Routing</title><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>routing</secondary></indexterm><indexterm significance="normal"><primary>routing</primary><secondary>IP</secondary></indexterm><para>We now take up the question of finding the host that datagrams go to
based on the IP address. Different parts of the address are handled in
different ways; it is your job to set up the files that indicate how to treat
each part.</para><sect2 id="x-087-2-issues.routing.networks"><title>IP Networks</title><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>networks</secondary></indexterm><para>When you write a letter to someone, you usually put a complete address
on the envelope specifying the country, state, and Zip Code. After you
put it in the mailbox, the post office will deliver it to its
destination: it will be sent to the country indicated, where the
national service will dispatch it to the proper state and region. The
advantage of this hierarchical scheme is obvious: wherever you
post the letter, the local postmaster knows roughly which direction to
forward the letter, but the postmaster doesn't care which way the
letter will travel once it reaches its country of destination.</para><para>IP networks are structured similarly. The whole Internet consists of a
number of proper networks, called <emphasis>autonomous
systems</emphasis>. Each system performs routing between its member
hosts internally so that the task of delivering a datagram is reduced
to finding a path to the destination host's network. As soon as the
datagram is handed to <emphasis>any</emphasis> host on that particular
network, further processing is done exclusively by the network itself.</para><?troff .Nd 10?></sect2><sect2 id="x-087-2-issues.routing.subnets"><title>Subnetworks</title><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>subnets</secondary></indexterm><indexterm significance="normal"><primary>subnets</primary><secondary>IP</secondary></indexterm><para>This structure is reflected by splitting IP addresses into a host and
network part, as explained previously. By default, the destination network is
derived from the network part of the IP address. Thus, hosts with identical
IP <emphasis>network</emphasis> numbers should be found within the same
network.<footnote id="x-087-2-fnis03"><para>Autonomous systems are slightly more general. They may comprise more than
one IP network.</para></footnote>
</para><para>It makes sense to offer a similar scheme <emphasis>inside</emphasis> the
network, too, since it may consist of a collection of hundreds of smaller
networks, with the smallest units being physical networks like Ethernets.
Therefore, IP allows you to subdivide an IP network into several
<emphasis>subnets</emphasis>.</para><para><indexterm significance="normal"><primary>interfaces</primary><secondary>netmask</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>netmask</secondary></indexterm>
A subnet takes responsibility for delivering datagrams to a certain range
of IP addresses. It is an extension of the concept of splitting bit fields,
as in the A, B, and C classes. However, the network part is now extended 
to include some bits from the host part. The number of bits that are 
interpreted as the subnet number is given by the so-called 
<emphasis>subnet mask</emphasis>, or <emphasis>netmask</emphasis>. This is a
32-bit number too, which specifies the bit mask for the network part of the
IP address.</para><para><indexterm significance="normal"><primary>Groucho Marx University (GMU)</primary></indexterm>
The campus network of Groucho Marx University is an example of such a
network. It has a class B network number of
<systemitem moreinfo="none" role="sitename">149.76.0.0</systemitem>, and its
netmask is therefore <systemitem moreinfo="none" role="sitename">255.255.0.0</systemitem>.</para><para>Internally, GMU's campus network consists of several smaller networks,
such various departments' LANs. So the range of IP addresses is broken
up into 254 subnets, <systemitem moreinfo="none" role="sitename">149.76.1.0</systemitem> through <systemitem moreinfo="none" role="sitename">149.76.254.0</systemitem>. For example, the department
of Theoretical Physics has been assigned <systemitem moreinfo="none" role="sitename">149.76.12.0</systemitem>. The campus backbone is a
network in its own right, and is given <systemitem moreinfo="none" role="sitename">149.76.1.0</systemitem>.  These subnets share the same
IP network number, while the third octet is used to distinguish
between them. They will thus use a subnet mask of <systemitem moreinfo="none" role="sitename">255.255.255.0</systemitem>.</para><para><xref linkend="x-087-2-issues.fig.subnet"></xref> shows how <systemitem moreinfo="none" role="sitename">149.76.12.4</systemitem>, the address of <systemitem moreinfo="none" role="sitename">quark</systemitem>, is interpreted differently when
the address is taken as an ordinary class B network and when used with 
subnetting.</para><figure float="0" id="x-087-2-issues.fig.subnet"><title>Subnetting a class B network</title><graphic fileref="lag2_0201.jpg"></graphic></figure><para><indexterm significance="normal"><primary>delegating</primary><secondary>IP subnets</secondary></indexterm>
<indexterm significance="normal"><primary>subnets</primary><secondary>IP</secondary></indexterm>
It is worth noting that <emphasis>subnetting</emphasis> (the technique
of generating subnets) is only an <emphasis>internal
division</emphasis> of the network. Subnets are generated by the
network owner (or the administrators). Frequently, subnets are created
to reflect existing boundaries, be they physical (between two
Ethernets), administrative (between two departments), or geographical
(between two locations), and authority over each subnet is delegated
to some contact person. However, this structure affects only the
network's internal behavior, and is completely invisible to the
outside world.</para></sect2><sect2 id="x-087-2-issues.routing.gateway"><title>Gateways</title><indexterm significance="normal"><primary>internetworking</primary></indexterm><indexterm significance="normal"><primary>gateways</primary></indexterm><para>Subnetting is not only a benefit to the organization; it is frequently
a natural consequence of hardware boundaries. The viewpoint of a host
on a given physical network, such as an Ethernet, is a very limited
one: it can only talk to the host of the network it is on.  All other
hosts can be accessed only through special-purpose machines called
<emphasis>gateways</emphasis>. A gateway is a host that is connected
to two or more physical networks simultaneously and is configured to
switch packets between them.</para><para><xref linkend="x-087-2-issues.fig.ip"></xref> shows part of the network topology at
Groucho Marx University (GMU).  Hosts that are on two subnets at the same
time are shown with both addresses.</para><figure float="0" id="x-087-2-issues.fig.ip"><title>A part of the net topology at Groucho Marx University</title><graphic fileref="lag2_0202.jpg"></graphic></figure><para>Different physical networks have to belong to different IP networks for IP to 
be able to recognize if a host is on a local network. For example, the 
network number
<systemitem moreinfo="none" role="sitename">149.76.4.0</systemitem> is reserved for hosts on
the mathematics LAN. When sending a datagram to
<systemitem moreinfo="none" role="sitename">quark</systemitem>, the network software on
<systemitem moreinfo="none" role="sitename">erdos</systemitem> immediately sees from the IP
address <systemitem moreinfo="none" role="sitename">149.76.12.4</systemitem> that the
destination host is on a different physical network, and therefore can be
reached only through a gateway (<systemitem moreinfo="none" role="sitename">sophus</systemitem>
by default).</para><para><systemitem moreinfo="none" role="sitename">sophus</systemitem> itself is connected to two
distinct subnets: the Mathematics department and the campus backbone. It
accesses each through a different interface, <filename moreinfo="none">eth0</filename> and
<filename moreinfo="none">fddi0</filename>, respectively.  Now, what IP address do we assign
it? Should we give it one on subnet
<systemitem moreinfo="none" role="sitename">149.76.1.0</systemitem>, or on
<systemitem moreinfo="none" role="sitename">149.76.4.0</systemitem>?</para><para>The answer is: both.
<systemitem moreinfo="none" role="sitename">sophus</systemitem> has been assigned the address
<systemitem moreinfo="none" role="sitename">149.76.1.1</systemitem> for use on the
<systemitem moreinfo="none" role="sitename">149.76.1.0</systemitem> network and address
<systemitem moreinfo="none" role="sitename">149.76.4.1</systemitem> for use on the
<systemitem moreinfo="none" role="sitename">149.76.4.0</systemitem> network. A gateway must be
assigned one IP address for each network it belongs to. These<?troff .nD 10?> addressesalong with the corresponding netmaskare tied to
the interface through which the subnet is accessed. Thus, the interface and 
address mapping for <systemitem moreinfo="none" role="sitename">sophus</systemitem>
would look like this:</para><informaltable><tgroup cols="3"><thead><row><entry>Interface</entry><entry>Address</entry><entry>Netmask</entry></row></thead><tbody><row><entry><filename moreinfo="none">eth0</filename></entry><entry>149.76.4.1</entry><entry>255.255.255.0</entry></row><row><entry><filename moreinfo="none">fddi0</filename></entry><entry>149.76.1.1</entry><entry>255.255.255.0</entry></row><row><entry><filename moreinfo="none">lo</filename></entry><entry>127.0.0.1</entry><entry>255.0.0.0</entry></row></tbody></tgroup></informaltable><?troff .Nd 7?><para>The last entry describes the loopback interface <filename moreinfo="none">lo</filename>, which
we talked about earlier.</para><para><indexterm significance="normal"><primary>gateways</primary></indexterm>
Generally, you can ignore the subtle difference between attaching an
address to a host or its interface. For hosts that are on one network
only, like <systemitem moreinfo="none" role="sitename">erdos</systemitem>, you would generally
refer to the host as having this-and-that IP address, although strictly
speaking, it's the Ethernet interface that has this IP address. The
distinction is really important only when you refer to a gateway.</para></sect2><sect2 id="x-087-2-issues.routing.table"><title>The Routing Table</title><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>routing</secondary><tertiary>table</tertiary></indexterm><indexterm significance="normal"><primary>routing table</primary></indexterm><para>We now focus our attention on how IP chooses a gateway to use to deliver 
a datagram to a remote network.</para><para>We have seen that <systemitem moreinfo="none" role="sitename">erdos</systemitem>, when
given a datagram for <systemitem moreinfo="none" role="sitename">quark</systemitem>,
checks the destination address and finds that it is not on the local
network.  <systemitem moreinfo="none" role="sitename">erdos</systemitem> therefore
sends the datagram to the default gateway <systemitem moreinfo="none" role="sitename">sophus</systemitem>, which is now faced with the same
task.  <systemitem moreinfo="none" role="sitename">sophus</systemitem> recognizes that
<systemitem moreinfo="none" role="sitename">quark</systemitem> is not on any of the
networks it is connected to directly, so it has to find yet another
gateway to forward it through. The correct choice would be <systemitem moreinfo="none" role="sitename">niels</systemitem>, the gateway to the Physics
department. <systemitem moreinfo="none" role="sitename">sophus</systemitem> thus 
needs information to associate a destination network with a
suitable gateway.</para><para>IP uses a table for this task that associates networks with the
gateways by which they may be reached. A catch-all entry (the
<emphasis>default route</emphasis>) must generally be supplied too;
this is the gateway associated with network <systemitem moreinfo="none" role="sitename">0.0.0.0</systemitem>. All destination addresses match
this route, since none of the 32 bits are required to match, and
therefore packets to an unknown network are sent through the default
route.  On <systemitem moreinfo="none" role="sitename">sophus</systemitem>, the table
might look like this:</para><informaltable><tgroup cols="4"><thead><row><entry>Network</entry><entry>Netmask</entry><entry>Gateway</entry><entry>Interface</entry></row></thead><tbody><row><entry>149.76.1.0</entry><entry>255.255.255.0</entry><entry>-</entry><entry><filename moreinfo="none">fddi0</filename></entry></row><row><entry>149.76.2.0</entry><entry>255.255.255.0</entry><entry>149.76.1.2</entry><entry><filename moreinfo="none">fddi0</filename></entry></row><row><entry>149.76.3.0</entry><entry>255.255.255.0</entry><entry>149.76.1.3</entry><entry><filename moreinfo="none">fddi0</filename></entry></row><row><entry>149.76.4.0</entry><entry>255.255.255.0</entry><entry>-</entry><entry><filename moreinfo="none">eth0</filename></entry></row><row><entry>149.76.5.0</entry><entry>255.255.255.0</entry><entry>149.76.1.5</entry><entry><filename moreinfo="none">fddi0</filename></entry></row><row><entry></entry><entry></entry><entry></entry><entry></entry></row><row><entry>0.0.0.0</entry><entry>0.0.0.0</entry><entry>149.76.1.2</entry><entry><filename moreinfo="none">fddi0</filename></entry></row></tbody></tgroup></informaltable><para>If you need to use a route to a network that <systemitem moreinfo="none" role="sitename">sophus</systemitem> is directly connected to, you
don't need a gateway; the gateway column here contains a hyphen.</para><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>routing</secondary><tertiary>effect of netmask</tertiary></indexterm>
The process for identifying whether a particular destination address
matches a route is a mathematical operation. The process is quite
simple, but it requires an understanding of binary arithmetic and
logic: A route matches a destination if the network
address logically ANDed with the netmask precisely equals the
destination address logically ANDed with the
netmask. </para><para>Translation: a route matches if the
number of bits of the network address specified by the netmask
(starting from the left-most bit, the high order bit of byte one of
the address) match that same number of bits in the destination
address.</para><para>When the IP implementation is searching for the best route to a
destination, it may find a number of routing entries that match the
target address. For example, we know that the default route matches
every destination, but datagrams destined for locally attached
networks will match their local route, too. How does IP know which
route to use? It is here that the netmask plays an important
role. While both routes match the destination, one of the routes has a
larger netmask than the other. We previously mentioned that the
netmask was used to break up our address space into smaller
networks. The larger a netmask is, the more specifically a target
address is matched; when routing datagrams, we should always choose
the route that has the largest netmask. The default route has a
netmask of zero bits, and in the configuration presented above, the
locally attached networks have a 24-bit netmask. If a datagram matches
a locally attached network, it will be routed to the appropriate device
in preference to following the default route because the local network
route matches with a greater number of bits. The only datagrams that
will be routed via the default route are those that don't match any
other route.</para><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>dynamic
routing</secondary></indexterm>
<indexterm significance="normal"><primary>dynamic routing</primary></indexterm>
<indexterm significance="normal"><primary>routing</primary><secondary>daemon</secondary></indexterm>
<indexterm significance="normal"><primary>routing</primary><secondary>dynamic</secondary></indexterm>
You can build routing tables by a variety of means. For small LANs, it
is usually most efficient to construct them by hand and feed them to
IP using the <command moreinfo="none">route</command> command at boot time (see <xref linkend="x-087-2-iface"></xref>). For larger networks, they are built and
adjusted at runtime by <emphasis>routing daemons</emphasis>; these
daemons run on central hosts of the network and exchange routing
information to compute optimal routes between the member
networks.</para><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>routing</secondary><tertiary>protocols</tertiary></indexterm>
<indexterm significance="normal"><primary>routing</primary><secondary>protocols</secondary></indexterm>
<indexterm significance="normal"><primary>Routing Information Protocol (RIP)</primary></indexterm>
<indexterm significance="normal"><primary>RIP (Routing Information Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>routed command</primary></indexterm>
<indexterm significance="normal"><primary>gated command</primary></indexterm>
Depending on the size of the network, you'll need to use different
routing protocols. For routing inside autonomous systems (such as the
Groucho Marx campus), the <emphasis>internal routing
protocols</emphasis> are used. The most prominent one of these is the
<emphasis>Routing Information Protocol</emphasis> (RIP), which is
implemented by the BSD <command moreinfo="none">routed</command> daemon. For routing
between autonomous systems, <emphasis>external routing
protocols</emphasis> like <emphasis>External Gateway
Protocol</emphasis> (EGP) or <emphasis>Border Gateway
Protocol</emphasis> (BGP) have to be used; these protocols, including
RIP, have been implemented in the University of Cornell's
<command moreinfo="none">gated</command> daemon.</para></sect2><sect2 id="x-087-2-issues.routing.metric"><title>Metric Values</title><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>metric</secondary><tertiary>values</tertiary></indexterm><indexterm significance="normal"><primary>routing</primary><secondary>metric</secondary></indexterm><indexterm significance="normal"><primary>metric values (for routing table entries)</primary></indexterm><para><?troff .hw discarded?>We depend on dynamic routing to choose the best route to a destination
host or network based on the number of <emphasis>hops</emphasis>. Hops
are the gateways a datagram has to pass before reaching a host or
network. The shorter a route is, the better RIP rates it. Very long
routes with 16 or more hops are regarded as unusable and are
discarded.</para><para>RIP manages routing information internal to your local network, but
you have to run <command moreinfo="none">gated</command> on all hosts. At boot time,
<command moreinfo="none">gated</command> checks for all active network interfaces.  If
there is more than one active interface (not counting the loopback
interface), it assumes the host is switching packets between several
networks and will actively exchange and broadcast routing
information. Otherwise, it will only passively receive RIP updates and
update the local routing table.</para><para>When broadcasting information from the local routing table,
<command moreinfo="none">gated</command> computes the length of the route from the
so-called <emphasis>metric value</emphasis> associated with the
routing table entry. This metric value is set by the system
administrator when configuring the route, and should reflect the
actual route cost.<footnote id="x-087-2-fnis05"><para> The cost of a
route can be thought of, in a simple case, as the number of hops
required to reach the destination. Proper calculation of route costs
can be a fine art in complex network designs.</para></footnote> Therefore, the metric of a route to a subnet that the host
is directly connected to should always be zero, while a route going
through two gateways should have a metric of two. You don't have to bother
with metrics if you don't use <command moreinfo="none">RIP</command> or
<command moreinfo="none">gated</command>.
</para></sect2></sect1><sect1 id="x-087-2-issues.icmp"><title>The Internet Control Message Protocol</title><para><indexterm significance="normal"><primary>protocols</primary><secondary>ICMP</secondary></indexterm>
<indexterm significance="normal"><primary>ICMP (Internet Control Message Protocol)</primary><secondary>Port Unreachable message</secondary></indexterm>
IP has a companion protocol that we haven't talked about yet. This is
the <emphasis>Internet Control Message Protocol</emphasis> (ICMP),
used by the kernel networking code to communicate error messages to
other hosts. For instance, assume that you are on <systemitem moreinfo="none" role="sitename">erdos</systemitem> again and want to
<command moreinfo="none">telnet</command> to port 12345 on <systemitem moreinfo="none" role="sitename">quark</systemitem>, but there's no process listening
on that port. When the first TCP packet for this port arrives on
<systemitem moreinfo="none" role="sitename">quark</systemitem>, the networking layer
will recognize this arrival and immediately return an ICMP message to
<systemitem moreinfo="none" role="sitename">erdos</systemitem> stating Port
Unreachable.</para><para><indexterm significance="normal"><primary>ICMP (Internet Control Message Protocol)</primary><secondary>Redirect message</secondary></indexterm>
<indexterm significance="normal"><primary>routing</primary><secondary>ICMP Redirect</secondary></indexterm>
<indexterm significance="normal"><primary>routing</primary><secondary>dynamic</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>routing</secondary><tertiary>Redirect message (ICMP)</tertiary></indexterm>
The ICMP protocol provides several different messages, many of which
deal with error conditions. However, there is one very interesting
message called the Redirect message. It is generated by the routing
module when it detects that another host is using it as a gateway,
even though a much shorter route exists. For example, after booting, the
routing table of <systemitem moreinfo="none" role="sitename">sophus</systemitem> may be
incomplete. It might contain the routes to the Mathematics network, to the
FDDI backbone, and the default route pointing at the Groucho Computing
Center's gateway (gcc1). Thus, packets for <systemitem moreinfo="none" role="sitename">quark</systemitem> would be sent
to <systemitem moreinfo="none" role="sitename">gcc1</systemitem> rather than to
<systemitem moreinfo="none" role="sitename">niels</systemitem>, the gateway to the Physics
department. When receiving such a datagram,
<systemitem moreinfo="none" role="sitename">gcc1</systemitem> will notice that this is a poor
choice of route and will forward the packet to
<systemitem moreinfo="none" role="sitename">niels</systemitem>, meanwhile returning an
ICMP Redirect message to <systemitem moreinfo="none" role="sitename">sophus</systemitem> telling it of the superior route.</para><para>This seems to be a very clever way to avoid manually setting up any
but the most basic routes. However, be warned that relying on dynamic
routing schemes, be it RIP or ICMP Redirect messages, is not always a
good idea. ICMP Redirect and RIP offer you little or no choice in
verifying that some routing <?troff .ne 10?>information is indeed authentic. This
situation allows malicious good-for-nothings to disrupt your entire
network traffic, or even worse. Consequently, the Linux networking
code treats Network Redirect messages as if they were Host Redirects.
This minimizes the damage of an attack by restricting it to just one
host, rather than the whole network. On the flip side, it means that a
little more traffic is generated in the event of a legitimate
condition, as each host causes the generation of an ICMP Redirect
message. It is generally considered bad practice to rely on ICMP
redirects for anything these days.</para></sect1><sect1 id="x-087-2-issues.resolving"><title>Resolving Host Names</title><indexterm significance="normal" class="startofrange" id="chis.dns.1"><primary>DNS (Domain Name System)</primary></indexterm><indexterm significance="normal"><primary>hostname</primary><secondary>resolution</secondary></indexterm><indexterm significance="normal"><primary>hostname</primary><secondary>mapping to addresses</secondary></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>addresses</secondary><tertiary>hostname and</tertiary></indexterm><para>As described previously, addressing in TCP/IP networking, at least for
IP Version 4, revolves around 32-bit numbers. However, you will have a
hard time remembering more than a few of these numbers. Therefore,
hosts are generally known by ordinary names such as
<systemitem moreinfo="none" role="sitename">gauss</systemitem> or <systemitem moreinfo="none" role="sitename">strange</systemitem>. It becomes the application's
duty to find the IP address corresponding to this name.  This process
is called <emphasis>hostname resolution</emphasis>.</para><indexterm significance="normal"><primary>gethostbyname()</primary></indexterm><indexterm significance="normal"><primary>gethostbyaddr()</primary></indexterm><para>When an application needs to find the IP address of a given host, it
relies on the library functions <function moreinfo="none">gethostbyname(3)</function>
and <function moreinfo="none">gethostbyaddr(3)</function>. Traditionally, these and a
number of related procedures were grouped in a separate library called
the <emphasis>resolverlibrary</emphasis>; on Linux, these functions
are part of the standard <filename moreinfo="none">libc</filename>. Colloquially, this
collection of functions is therefore referred to as the
resolver. Resolver name configuration is detailed in <xref linkend="x-087-2-resolv"></xref>.</para><para>On a small network like an Ethernet or even a cluster of Ethernets, it
is not very difficult to maintain tables mapping hostnames to
addresses. This information is usually kept in a file named
<filename moreinfo="none">/etc/hosts</filename>. When adding or removing hosts, or
reassigning addresses, all you have to do is update the
<filename moreinfo="none">hosts</filename> file on all hosts. Obviously, this will
become burdensome with networks that comprise more than a handful of
machines.</para><indexterm significance="normal"><primary>NIS (Network Information System)</primary></indexterm><indexterm significance="normal"><primary>Yellow Pages (YP)</primary></indexterm><para>One solution to this problem is the <emphasis>Network Information
System</emphasis> (NIS), developed by Sun Microsystems, colloquially 
called YP or Yellow Pages. NIS stores the <filename moreinfo="none">hosts</filename>
file (and other information) in a database on a master host from which clients
may retrieve it as needed. Still, this approach is suitable only for
medium-sized networks such as LANs, because it involves maintaining
the entire <filename moreinfo="none">hosts</filename> database centrally and distributing
it to all servers. NIS installation and configuration is discussed in
detail in <xref linkend="x-087-2-nis"></xref>.</para><para>On the Internet, address information was initially stored in a single
<filename moreinfo="none">HOSTS.TXT</filename> database, too. This file was maintained at
the <emphasis>Network Information Center</emphasis> (NIC), and had to 
be downloaded and installed by all participating sites. When the network 
grew, several problems with this scheme arose. Besides the administrative 
overhead involved in installing <filename moreinfo="none">HOSTS.TXT</filename> regularly, 
the load on the servers that distributed it became too high. Even more 
severe, all names had to be registered with the NIC, which made sure that 
no name was issued twice.</para><para>This is why a new name resolution scheme was adopted in 1994: the
<emphasis>Domain Name System</emphasis>. DNS was designed by Paul
Mockapetris and addresses both problems simultaneously. We discuss the
Domain Name System in detail in <xref linkend="x-087-2-resolv"></xref>.</para><indexterm significance="normal" class="endofrange" startref="chis.dns.1"></indexterm></sect1><indexterm significance="normal" class="endofrange" startref="chis.tcp.ip.networks"></indexterm><indexterm significance="normal" class="endofrange" startref="chis.networks.tcp.ip"></indexterm></chapter><chapter id="x-087-2-hardware"><title>Configuring<?lb?>the Networking<?lb?>Hardware</title><indexterm significance="normal" class="startofrange" id="idx-configuringnetworkhardware-1"><primary>configuring</primary><secondary>networks</secondary><tertiary>hardware</tertiary></indexterm><indexterm significance="normal" class="startofrange" id="idx-hardwarenetworking-1"><primary>hardware</primary><secondary>configuration
of networking</secondary></indexterm><indexterm significance="normal" class="startofrange" id="ch03.net.hw.config"><primary>networks</primary><secondary>hardware,
configuring</secondary></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>devices</secondary></indexterm><indexterm significance="normal"><primary>interfaces</primary></indexterm><para>We've been talking quite a bit about network interfaces and general
TCP/IP issues, but we haven't really covered what happens when the
networking code in the kernel accesses a piece of
hardware.  In order to describe this accurately, we have to talk a
little about the concept of interfaces and drivers.</para><para>First, of course, there's the hardware itself, for example an
Ethernet, FDDI or Token Ring card: this is a slice of Epoxy cluttered
with lots of tiny chips with strange numbers on them, sitting in a
slot of your PC. This is what we generally call a physical device.</para><para><indexterm significance="normal"><primary>Ethernet</primary><secondary>cards</secondary></indexterm>
<indexterm significance="normal"><primary>device drivers</primary></indexterm> For you to
use a network card, special functions have to be present in your Linux
kernel that understand the particular way this device is accessed. The
software that implements these functions is called a <emphasis>device
driver</emphasis>. Linux has device drivers for many different types
of network interface cards: ISA, PCI, MCA, EISA, Parallel port, PCMCIA,
and more recently, USB.</para><para>But what do we mean when we say a driver handles a device? Let's
consider an Ethernet card. The driver has to be able to communicate with the
peripheral's on-card logic somehow: it has to send commands and data to the
card, while the card should deliver any data received to the driver.</para><para>In IBM-style personal computers, this communication takes place through a
cluster of I/O addresses that are mapped to registers on the card and/or
through shared or direct memory transfers. All commands and data the kernel
sends to the card have to go to these addresses. I/O and memory addresses are
generally described by providing the starting or
<emphasis>base address</emphasis>. Typical base addresses for ISA bus Ethernet
cards are <literal moreinfo="none">0x280</literal> or <literal moreinfo="none">0x300</literal>. PCI bus
network cards generally have their I/O address automatically assigned.</para><para>Usually you don't have to worry about any hardware issues such as the
base address because the kernel makes an attempt at boot time to
detect a card's location. This is called <emphasis>auto
probing</emphasis>, which means that the kernel reads several memory
or I/O locations and compares the data it reads there with what it
would expect to see if a certain network card were installed at that
location. However, there may be network cards it cannot detect
automatically; this is sometimes the case with cheap network cards
that are not-quite clones of standard cards from other
manufacturers. Also, the kernel will normally attempt to detect only
one network device when booting. If you're using more than one card,
you have to tell the kernel about the other cards explicitly.</para><para><indexterm significance="normal"><primary>IRQ (Interrupt Request)</primary></indexterm>
Another parameter that you might have to tell the kernel about is the
interrupt request line. Hardware components usually interrupt the
kernel when they need to be taken care offor example, when data
has arrived or a special condition occurs. In an ISA bus PC,
interrupts may occur on one of 15 interrupt channels numbered 0, 1,
and 3 through 15. The interrupt number assigned to a hardware
component is called its <emphasis>interrupt request
number</emphasis> (IRQ).<footnote id="x-087-2-fnhw01"><para> IRQs 2 and
9 are the same because the IBM PC design has two cascaded interrupt
processors with eight IRQs each; the secondary processor is connected
to IRQ 2 of the primary one.</para></footnote>
</para><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>interface</secondary></indexterm>
<indexterm significance="normal"><primary>interfaces</primary></indexterm>
As described in <xref linkend="x-087-2-issues"></xref>, the kernel accesses a piece
of network hardware through a software construct called an 
<emphasis>interface</emphasis>.
Interfaces offer an abstract set of functions that are the same across all
types of hardware, such as sending or receiving a datagram.</para><para><indexterm significance="normal"><primary>device files</primary></indexterm>
<indexterm significance="normal"><primary>devices</primary><secondary>major/minor
numbers</secondary></indexterm> Interfaces are identified by means of
names. In many other Unix-like operating systems, the network
interface is implemented as a special device file in the
<filename moreinfo="none">/dev/</filename> directory. If you type the <literal moreinfo="none">ls -las
/dev/</literal> command, you will see what these device files look
like. In the file permissions (second) column you will see that device
files begin with a letter rather than the hyphen seen for normal
files. This character indicates the device type. The most common
device types are <literal moreinfo="none">b</literal>, which indicates the device is a
<emphasis>block</emphasis> device and handles whole blocks of data
with each read and write, and <literal moreinfo="none">c</literal>, which indicates
the device is a <emphasis>character</emphasis> device and handles data
one character at a time. Where you would normally see the file length
in the <command moreinfo="none">ls</command> output, you instead see two numbers,
called the major and minor device numbers. These numbers indicate the
actual device with which the device file is associated.</para><para>Each device driver registers a unique major number with the kernel.
Each <emphasis>instance</emphasis> of that device registers a unique
minor number for that major device. The <literal moreinfo="none">tty</literal>
interfaces,<filename moreinfo="none">/dev/tty*</filename>, are a character
mode device indicated by the <literal moreinfo="none">c</literal>, and
each have a major number of <literal moreinfo="none">4</literal>, but
<filename moreinfo="none">/dev/tty1</filename> has a minor number of
<literal moreinfo="none">1</literal>, and <filename moreinfo="none">/dev/tty2</filename> has a minor
number of <literal moreinfo="none">2</literal>. Device files are very useful for
many types of devices, but can be clumsy to use when trying to find an
unused device to open.</para><para>Linux interface names are defined internally in the kernel and are not
device files in the <filename moreinfo="none">/dev</filename> directory. Some typical
device names are listed later in <xref linkend="x-087-2-hwconfig.tour"></xref>. The assignment of interfaces to
devices usually depends on the order in which devices are
configured. For instance, the first Ethernet card installed will
become <filename moreinfo="none">eth0</filename>, and the next will be
<filename moreinfo="none">eth1</filename>. SLIP interfaces are handled differently
from others because they are assigned dynamically. Whenever a SLIP
connection is established, an interface is assigned to the serial
port.</para><para><xref linkend="x-087-2-hardware.fig.drivers"></xref> illustrates the relationship
between the hardware, device drivers, and interfaces.</para><figure float="0" id="x-087-2-hardware.fig.drivers"><title>The relationship between drivers, interfaces, and hardware</title><graphic fileref="lag2_0301.jpg"></graphic></figure><para>When booting, the kernel displays the devices it detects and the
interfaces it installs. The following is an excerpt from typical
boot messages:
<screen format="linespecific"> .
 .  This processor honors the WP bit even when in supervisor mode./ 
    Good. 
Swansea University Computer Society NET3.035 for Linux 2.0 
NET3: Unix domain sockets 0.13 for Linux NET3.035.
Swansea University Computer Society TCP/IP for NET3.034 
IP Protocols: IGMP,ICMP, UDP, TCP 
Swansea University Computer Society IPX 0.34 for NET3.035 
IPX Portions Copyright (c) 1995 Caldera, Inc.
Serial driver version 4.13 with no serial options enabled 
tty00 at 0x03f8 (irq = 4) is a 16550A
tty01 at 0x02f8 (irq = 3) is a 16550A
CSLIP: code copyright 1989 Regents of the University of California 
PPP: Version 2.2.0 (dynamic channel allocation) 
PPP Dynamic channel allocation code copyright 1995 Caldera, Inc. 
PPP line discipline registered.  
eth0: 3c509 at 0x300 tag 1, 10baseT port, address 00 a0 24 0e e4 e0,/ 
    IRQ 10.
3c509.c:1.12 6/4/97 becker@cesdis.gsfc.nasa.gov 
Linux Version 2.0.32 (root@perf) (gcc Version 2.7.2.1) 
#1 Tue Oct 21 15:30:44 EST 1997
 .
 .</screen></para><para>This example shows that the kernel has been compiled with TCP/IP
enabled, and it includes drivers for SLIP, CSLIP, and PPP. The third
line from the bottom says that a 3C509 Ethernet card was detected and
installed as interface <filename moreinfo="none">eth0</filename>. If you have some
other type of network cardperhaps a D-Link pocket adaptor, for
examplethe kernel will usually print a line starting with its
device name<filename moreinfo="none">dl0</filename> in the D-Link
examplefollowed by the type of card detected. If you have a
network card installed but don't see any similar message, the kernel
is unable to detect your card properly. This situation will be
discussed later in the section Ethernet Autoprobing.</para><sect1 id="x-087-2-hardware.kernel.config"><title>Kernel Configuration</title><indexterm significance="normal" class="startofrange" id="ch03.kernel.config"><primary>kernels</primary><secondary>configuration</secondary></indexterm><para>Most Linux distributions are supplied with boot disks that work for
all common types of PC hardware. Generally, the supplied kernel is
highly modularized and includes nearly every possible driver. This is
a great idea for boot disks, but is probably not what you'd want for
long-term use. There isn't much point in having drivers cluttering up
your disk that you will never use. Therefore, you will generally roll
your own kernel and include only those drivers you actually need or
want; that way you save a little disk space and reduce the time it
takes to compile a new kernel.</para><para>In any case, when running a Linux system, you should be familiar with 
building a kernel. Think of it as a right of passage, an affirmation of 
the one thing that makes free software as powerful as it isyou have 
the source. It isn't a case of, I have to compile a kernel, 
rather it's a case of, I <emphasis>can</emphasis> compile a 
kernel. The basics of compiling a Linux kernel are explained in Matt 
Welsh's book, <emphasis>Running Linux</emphasis> (O'Reilly). Therefore, we 
will discuss only configuration options that affect networking in this 
section.</para><para><indexterm significance="normal"><primary>kernel version numbering</primary></indexterm>
<indexterm significance="normal"><primary>Linux kernel</primary><secondary>version numbering
of</secondary></indexterm> One important point that does bear
repeating here is the way the kernel version numbering scheme
works. Linux kernels are numbered in the following format:
<literal moreinfo="none">2.2.14</literal>. The first digit indicates the
<emphasis>major</emphasis> version number. This digit changes when
there are large and significant changes to the kernel design. For
example, the kernel changed from major 1 to 2 when the kernel obtained
support for machines other than Intel machines. The second number is
the <emphasis>minor</emphasis> version number. In many respects, this
number is the most important number to look at. The Linux development
community has adopted a standard at which <emphasis>even</emphasis> minor
version numbers indicate <emphasis>production</emphasis>, or
<emphasis>stable</emphasis>, kernels and <emphasis>odd</emphasis>
minor version numbers indicate <emphasis>development</emphasis>, or
<emphasis>unstable</emphasis>, kernels. The stable kernels are what
you should use on a machine that is important to you, as they have
been more thoroughly tested. The development kernels are what you
should use if you are interested in experimenting with the newest
features of Linux, but they may have problems that haven't yet been
found and fixed. The third number is simply incremented for each
release of a minor version.<footnote id="x-087-2-fnhw02"><para><?troff .hw REPORTING?>People should use development kernels and report bugs if they are
found; this is a very useful thing to do if you have a machine you can use 
as a test machine. Instructions on how to report bugs are detailed in
<filename moreinfo="none">/usr/src/linux/REPORTING-BUGS</filename> in the Linux kernel
source.</para></footnote></para><para>When running <command moreinfo="none">make menuconfig</command>, you are presented with
a text-based menu that offers lists of configuration questions, such as
whether you want kernel math emulation. One of these queries asks you
whether you want TCP/IP networking support. You must answer this with
<literal moreinfo="none">y</literal> to get a kernel capable of networking.</para><sect2><title>Kernel Options in Linux 2.0 and Higher</title><indexterm significance="normal"><primary>configuring</primary><secondary>kernel</secondary></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>kernel options</secondary></indexterm><indexterm significance="normal"><primary>configuring</primary><secondary>Ethernet</secondary></indexterm><indexterm significance="normal"><primary>configuring</primary><secondary>SLIP</secondary></indexterm><indexterm significance="normal"><primary>configuring</primary><secondary>PLIP</secondary></indexterm><indexterm significance="normal"><primary>configuring</primary><secondary>PPP</secondary></indexterm><para>
After the general option section is complete, the configuration will
go on to ask whether you want to include support for various features,
such as SCSI drivers or sound cards. The prompt will indicate what
options are available. You can press <prompt moreinfo="none">?</prompt> to obtain a
description of what the option is actually offering. You'll always
have the option of yes (<prompt moreinfo="none">y</prompt>) to statically include the
component in the kernel, or no (<prompt moreinfo="none">n</prompt>) to exclude the
component completely. You'll also see the module (<prompt moreinfo="none">m</prompt>)
option for those components that may be compiled as a run-time
loadable module. Modules need to be loaded before they can be used,
and are useful for drivers of components that you use infrequently.</para><para>The subsequent list of questions deal with networking support. 
The exact set of configuration options is in constant flux due to ongoing 
development. A typical list of options offered by most kernel versions 
around 2.0 and 2.1 looks like this:

<screen format="linespecific">*
* Network device support
*
Network device support (CONFIG_NETDEVICES) [Y/n/?] </screen></para><para>You must answer this question with <literal moreinfo="none">y</literal> if you want to 
use <emphasis>any</emphasis> type of networking devices, whether 
they are Ethernet, SLIP, PPP, or whatever. When you answer the 
question with <literal moreinfo="none">y</literal>, support for Ethernet-type devices 
is enabled automatically. You must answer additional questions if 
you want to enable support for other types of network drivers:</para><para><screen format="linespecific">PLIP (parallel port) support (CONFIG_PLIP) [N/y/m/?] y
PPP (point-to-point) support (CONFIG_PPP) [N/y/m/?] y
*
* CCP compressors for PPP are only built as modules.
*
SLIP (serial line) support (CONFIG_SLIP) [N/y/m/?] m
 CSLIP compressed headers (CONFIG_SLIP_COMPRESSED) [N/y/?] (NEW) y
 Keepalive and linefill (CONFIG_SLIP_SMART) [N/y/?] (NEW) y
 Six bit SLIP encapsulation (CONFIG_SLIP_MODE_SLIP6) [N/y/?] (NEW) y</screen></para><para><indexterm significance="normal"><primary>IPX (Internet Packet eXchange)</primary><secondary>PPP network protocol</secondary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>carrying IPX</secondary></indexterm>
These questions concern the various link layer protocols that Linux
supports.  Both PPP and SLIP allow you to transport IP datagrams
across serial lines.  PPP is actually a suite of protocols used to
send network traffic across serial lines. Some of the protocols that
form PPP manage the way that you authenticate yourself to the dial-in
server, while others manage the way certain protocols are carried
across the linkPPP is not limited to carrying TCP/IP datagrams;
it may also carry other protocol such as IPX.</para><para>If you answer <literal moreinfo="none">y</literal> or <literal moreinfo="none">m</literal> to SLIP 
support, you will be prompted to answer the three questions that appear 
below it. The compressed header option provides support for CSLIP, a 
technique that compresses TCP/IP headers to as little as three bytes. Note 
that this kernel option does not turn on CSLIP automatically; it merely 
provides the necessary kernel functions for it. The <literal moreinfo="none">Keepalive and 
linefill</literal> option causes the SLIP support to periodically generate 
activity on the SLIP line to avoid it being dropped by an inactivity timer. The
<literal moreinfo="none">Six bit SLIP encapsulation</literal> option allows you to run
SLIP over lines and circuits that are not capable of transmitting the
whole 8-bit data set cleanly. This is similar to the uuencoding or binhex 
technique used to send binary files by electronic mail.</para><para>PLIP provides a way to send IP datagrams across a parallel port connection.
It is mostly used to communicate with PCs running DOS. On typical PC hardware,
PLIP can be faster than PPP or SLIP, but it requires much more CPU overhead to
perform, so while the transfer rate might be good, other tasks on the machine
may be slow. </para><para>The following questions address network cards from various vendors.
As more drivers are being developed, you are likely to see questions added
to this section.  If you want to build a kernel you can use on a number of
different machines, or if your machine has more than one type of network
card installed, you can enable more than one driver:</para><para><screen format="linespecific"> .
 .
Ethernet (10 or 100Mbit) (CONFIG_NET_ETHERNET) [Y/n/?] 
3COM cards (CONFIG_NET_VENDOR_3COM) [Y/n/?] 
3c501 support (CONFIG_EL1) [N/y/m/?]
3c503 support (CONFIG_EL2) [N/y/m/?]
3c509/3c579 support (CONFIG_EL3) [Y/m/n/?]
3c590/3c900 series (592/595/597/900/905) "Vortex/Boomerang" support/
    (CONFIG_VORTEX) [N/y/m/?]
AMD LANCE and PCnet (AT1500 and NE2100) support (CONFIG_LANCE) [N/y/?]
AMD PCInet32 (VLB and PCI) support (CONFIG_LANCE32) [N/y/?] (NEW)
Western Digital/SMC cards (CONFIG_NET_VENDOR_SMC) [N/y/?]
WD80*3 support (CONFIG_WD80x3) [N/y/m/?] (NEW)
SMC Ultra support (CONFIG_ULTRA) [N/y/m/?] (NEW)
SMC Ultra32 support (CONFIG_ULTRA32) [N/y/m/?] (NEW)
SMC 9194 support (CONFIG_SMC9194) [N/y/m/?] (NEW)
Other ISA cards (CONFIG_NET_ISA) [N/y/?]
Cabletron E21xx support (CONFIG_E2100) [N/y/m/?] (NEW)
DEPCA, DE10x, DE200, DE201, DE202, DE422 support (CONFIG_DEPCA) [N/y/m/?]/ 
    (NEW)
EtherWORKS 3 (DE203, DE204, DE205) support (CONFIG_EWRK3) [N/y/m/?] (NEW)
EtherExpress 16 support (CONFIG_EEXPRESS) [N/y/m/?] (NEW)
HP PCLAN+ (27247B and 27252A) support (CONFIG_HPLAN_PLUS) [N/y/m/?] (NEW)
HP PCLAN (27245 and other 27xxx series) support (CONFIG_HPLAN) [N/y/m/?]/ 
    (NEW)
HP 10/100VG PCLAN (ISA, EISA, PCI) support (CONFIG_HP100) [N/y/m/?] (NEW)
NE2000/NE1000 support (CONFIG_NE2000) [N/y/m/?] (NEW)
SK_G16 support (CONFIG_SK_G16) [N/y/?] (NEW)
EISA, VLB, PCI and on card controllers (CONFIG_NET_EISA) [N/y/?]
Apricot Xen-II on card ethernet (CONFIG_APRICOT) [N/y/m/?] (NEW)
Intel EtherExpress/Pro 100B support (CONFIG_EEXPRESS_PRO100B) [N/y/m/?]/ 
    (NEW)
DE425, DE434, DE435, DE450, DE500 support (CONFIG_DE4X5) [N/y/m/?] (NEW)
DECchip Tulip (dc21x4x) PCI support (CONFIG_DEC_ELCP) [N/y/m/?] (NEW)
Digi Intl. RightSwitch SE-X support (CONFIG_DGRS) [N/y/m/?] (NEW)
Pocket and portable adaptors (CONFIG_NET_POCKET) [N/y/?]
AT-LAN-TEC/RealTek pocket adaptor support (CONFIG_ATP) [N/y/?] (NEW)
D-Link DE600 pocket adaptor support (CONFIG_DE600) [N/y/m/?] (NEW)
D-Link DE620 pocket adaptor support (CONFIG_DE620) [N/y/m/?] (NEW)
Token Ring driver support (CONFIG_TR) [N/y/?]
IBM Tropic chipset based adaptor support (CONFIG_IBMTR) [N/y/m/?] (NEW)
FDDI driver support (CONFIG_FDDI) [N/y/?]
Digital DEFEA and DEFPA adapter support (CONFIG_DEFXX) [N/y/?] (NEW)
ARCnet support (CONFIG_ARCNET) [N/y/m/?]
  Enable arc0e (ARCnet "Ether-Encap" packet format) (CONFIG_ARCNET_ETH)/ 
      [N/y/?] (NEW)
  Enable arc0s (ARCnet RFC1051 packet format) (CONFIG_ARCNET_1051)/ 
      [N/y/?] (NEW)
 .
 .</screen></para><para><indexterm significance="normal"><primary>configuring</primary><secondary>NFS</secondary></indexterm>
Finally, in the file system section, the configuration script will ask you
whether you want support for NFS, the networking file system. NFS lets you
export file systems to several hosts, which makes the files appear as if they
were on an ordinary hard disk attached to the host:</para><para><screen format="linespecific">NFS file system support (CONFIG_NFS_FS) [y]</screen>

We describe NFS in detail in <xref linkend="x-087-2-nfs"></xref>.</para></sect2><sect2><title>Kernel Networking Options in Linux 2.0.0 <?lb?>and Higher</title><para><indexterm significance="normal"><primary>Networking HOWTO</primary></indexterm>
<indexterm significance="normal"><primary>HOWTOs</primary><secondary>Networking</secondary></indexterm>
Linux 2.0.0 marked a significant change in Linux Networking. Many 
features were made a standard part of the Kernel, such as support
for IPX.  A number of options were also added and made
configurable. Many of these options are used only in very special
circumstances and we won't cover them in detail. The Networking HOWTO
probably addresses what is not covered here. We'll list a number of
useful options in this section, and explain when you'd want to use
each one:</para><variablelist><varlistentry><term>Basics</term><listitem><para> To use TCP/IP networking, you must answer this question with
<literal moreinfo="none">y</literal>. If you answer with <literal moreinfo="none">n</literal>, however, you
will still be able to compile the kernel with IPX support:</para></listitem></varlistentry></variablelist><para><screen format="linespecific">Networking options  ---
    [*] TCP/IP networking</screen></para><variablelist><varlistentry><term>Gateways</term><listitem><para><indexterm significance="normal"><primary>forwarding</primary><secondary>IP</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet
Protocol)</primary><secondary>forwarding</secondary></indexterm> You
have to enable this option if your system acts as a gateway between
two networks or between a LAN and a SLIP link, etc.  It
doesn't hurt to enable this by default, but you may want to disable it to
configure a host as a so-called
<emphasis>firewall</emphasis>. Firewalls are hosts that are connected
to two or more networks, but don't route traffic between them.  They're 
commonly used to provide users with Internet access at minimal
risk to the internal network. Users are allowed to log in to the
firewall and use Internet services, but the company's machines are
protected from outside attacks because incoming connections can't
cross the firewall (firewalls are covered in detail in
<xref linkend="x-087-2-firewall"></xref>):</para></listitem></varlistentry></variablelist><para><screen format="linespecific">    [*] IP: forwarding/gatewaying</screen></para><variablelist><varlistentry><term>Virtual hosting</term><listitem><para>
<indexterm significance="normal"><primary>IP (Internet
Protocol)</primary><secondary>aliasing</secondary></indexterm>
<indexterm significance="normal"><primary>aliasing, IP (Internet
Protocol)</primary></indexterm> These options together allow to you
configure more than one IP address onto an interface. This is
sometimes useful if you want to do virtual hosting,
through which a single machine can be configured to look and act as
though it were actually many separate machines, each with its own
network personality. We'll talk more about IP aliasing in a moment:</para></listitem></varlistentry></variablelist><para><screen format="linespecific">    [*] Network aliasing
	* IP: aliasing support</screen></para><variablelist><varlistentry><term>Accounting</term><listitem><para><indexterm significance="normal"><primary>IP accounting</primary></indexterm>
This option enables you to collect data on the volume of IP traffic leaving
and arriving at your machine (we cover this is detail in
<xref linkend="x-087-2-accounting"></xref>):</para></listitem></varlistentry></variablelist><para><screen format="linespecific">    [*] IP: accounting</screen></para><variablelist><varlistentry><term>PC hug</term><listitem><para><indexterm significance="normal"><primary>PC/TCP compatibility</primary></indexterm>
This option works around an incompatibility with some versions of PC/TCP, a
commercial TCP/IP implementation for DOS-based PCs. If you enable this option,
you will still be able to communicate with normal Unix machines, but
performance may be hurt over slow links:</para></listitem></varlistentry></variablelist><para><screen format="linespecific">    --- (it is safe to leave these untouched)
    [*] IP: PC/TCP compatibility mode</screen></para><variablelist><varlistentry><term>Diskless booting</term><listitem><para><indexterm significance="normal"><primary>RARP (Reverse Address Resolution Protocol)</primary></indexterm>
This function enables <emphasis>Reverse Address Resolution
Protocol</emphasis> (RARP). RARP is used by diskless clients and X terminals to
request their IP address when booting. You should enable RARP if you plan to
serve this sort of client. A small program called <command moreinfo="none">rarp</command>,
included with the standard networking utilities, is used to add entries
to the kernel RARP table:</para></listitem></varlistentry></variablelist><para><screen format="linespecific">    * IP: Reverse ARP</screen></para><variablelist><varlistentry><term>MTU</term><listitem><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>routing</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>subnets</secondary></indexterm>
<indexterm significance="normal"><primary>subnets</primary><secondary>IP</secondary></indexterm>
<indexterm significance="normal"><primary>Maximum Transmission Unit (MTU)</primary><secondary>IP</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>MTU</secondary></indexterm>
When sending data over TCP, the kernel has to break up the stream into blocks
of data to pass to IP. The size of the block is called the <emphasis>Maximum 
Transmission Unit</emphasis>, or MTU. For hosts that can be reached over a 
local network such as an
Ethernet, it is typical to use an MTU as large as the maximum length of an
Ethernet packet1,500 bytes. When routing IP over a Wide Area Network 
like the Internet, it is preferable to use smaller-sized datagrams to ensure 
that they don't need to be further broken down along the route through a 
process called <emphasis>IP fragmentation</emphasis>.<footnote id="x-087-2-fnhw03"><para>Remember, the IP protocol can be carried over many different types of
network, and not all network types will support packet sizes as large
as Ethernet.</para></footnote> The kernel is
able to automatically determine the smallest MTU of an IP route and to
automatically configure a TCP connection to use it. This behavior is on by
default. If you answer <literal moreinfo="none">y</literal> to this option this feature 
will be disabled.</para><para>If you do want to use smaller packet sizes for data sent to specific hosts
(because, for example, the data goes through a SLIP link), you can do so using
the <command moreinfo="none">mss</command> option of the <command moreinfo="none">route</command> command,
which is briefly discussed at the end of this chapter:</para></listitem></varlistentry></variablelist><para><screen format="linespecific">    [ ] IP: Disable Path MTU Discovery (normally enabled)</screen></para><variablelist><varlistentry><term>Security feature</term><listitem><para><indexterm significance="normal"><primary>source routing</primary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>source routing</secondary></indexterm>
<indexterm significance="normal"><primary>RIP (Routing Information Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>Routing Information Protocol (RIP)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>Routing Information
Protocol (RIP)</secondary></indexterm>
<indexterm significance="normal"><primary>OSPF (Open Shortest Path First) protocol</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>OSPF</secondary></indexterm>
The IP protocol supports a feature called <emphasis>Source
Routing</emphasis>.  Source routing allows you to specify the route a
datagram should follow by coding the route into the datagram
itself. This was once probably useful before routing protocols such as
RIP and OSPF became commonplace. But today it's considered a security
threat because it can provide clever attackers with a way of
circumventing certain types of firewall protection by bypassing the
routing table of a router. You would normally want to filter out
source routed datagrams, so this option is normally enabled:</para></listitem></varlistentry></variablelist><para><screen format="linespecific">    [*] IP: Drop source routed frames</screen></para><variablelist><varlistentry><term>Novell support</term><listitem><para><indexterm significance="normal"><primary>configuring</primary><secondary>IPX</secondary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>Internet Packet eXchange (IPX)</secondary></indexterm>
<indexterm significance="normal"><primary>IPX (Internet Packet eXchange)</primary><secondary>routing</secondary></indexterm>
This option enables support for IPX, the transport protocol Novell
Networking uses.  Linux will function quite happily as an IPX router
and this support is useful in environments where you have Novell
fileservers. The NCP filesystem also requires IPX support enabled in
your kernel; if you wish to attach to and mount your Novell
filesystems you must have this option enabled (we'll dicuss IPX and
the NCP filesystem in <xref linkend="x-087-2-ipx"></xref>):</para></listitem></varlistentry></variablelist><para><screen format="linespecific">    * The IPX protocol</screen></para><variablelist><varlistentry><term>Amateur radio</term><listitem><para><indexterm significance="normal"><primary>amateur radio protocols</primary></indexterm>
<indexterm significance="normal"><primary>AX.25 protocol</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>AX.25</secondary></indexterm>
<indexterm significance="normal"><primary>NetRom protocol</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>NetRom</secondary></indexterm>
<indexterm significance="normal"><primary>Rose protocol</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>Rose</secondary></indexterm>
<indexterm significance="normal"><primary>AX25 HOWTO</primary></indexterm>
<indexterm significance="normal"><primary>HOWTOs</primary><secondary>AX25</secondary></indexterm>
These three options select support for the three Amateur Radio protocols
supported by Linux: AX.25, NetRom and Rose (we don't describe them in this
book, but they are covered in detail in the AX25 HOWTO):

<screen format="linespecific">    * Amateur Radio AX.25 Level 2
    * Amateur Radio NET/ROM
    * Amateur Radio X.25 PLP (Rose)</screen></para><para> Linux supports another driver type: the dummy driver. The following
question appears toward the start of the device-driver section:
<screen format="linespecific">    * Dummy net driver support</screen></para><para>The dummy driver doesn't really do much, but it is quite useful on standalone
or PPP/SLIP hosts.  It is basically a masqueraded loopback interface. On 
hosts that offer PPP/SLIP but have no
other network interface, you want to have an interface that bears your IP
address all the time. This is discussed in a little more detail in 
<xref linkend="x-087-2-iface.interface.dummy"></xref>" in
<xref linkend="x-087-2-iface"></xref>. Note that today you can achieve the same
result by using the IP alias feature and configuring your IP address as an
alias on the loopback interface.
<indexterm significance="normal" class="endofrange" startref="ch03.kernel.config"></indexterm> </para></listitem></varlistentry></variablelist></sect2></sect1><sect1 id="x-087-2-hwconfig.tour"><title>A Tour of Linux Network Devices</title><indexterm significance="normal"><primary>devices</primary><secondary>Linux network</secondary></indexterm><indexterm significance="normal"><primary>networks</primary></indexterm><para>The Linux kernel supports a number of hardware drivers for various
types of equipment. This section gives a short overview of the driver
families available and the interface names they use.</para><para><indexterm significance="normal"><primary>interfaces</primary></indexterm> There is a number
of standard names for interfaces in Linux, which are listed here. Most
drivers support more than one interface, in which case the interfaces
are numbered, as in <filename moreinfo="none">eth0</filename> and
<filename moreinfo="none">eth1</filename>:</para><para><variablelist><varlistentry><term><filename moreinfo="none">lo</filename></term><listitem><para><indexterm significance="normal"><primary>interfaces</primary><secondary>loopback</secondary></indexterm>
<indexterm significance="normal"><primary>loopback</primary><secondary>interface device</secondary></indexterm> 
This is the local loopback interface. It is used for testing purposes, as 
well as a couple of network applications. It works like a closed circuit in 
that any datagram written to it will immediately be returned to the host's
networking layer.  There's always one loopback device present in the kernel,
and there's little sense in having more.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">eth0</filename>, <filename moreinfo="none">eth1</filename>, </term><listitem><para><indexterm significance="normal"><primary>eth1 device</primary></indexterm> 
<indexterm significance="normal"><primary>interfaces</primary><secondary>Ethernet</secondary></indexterm>
These are the Ethernet card interfaces. They are used for most Ethernet cards,
including many of the parallel port Ethernet cards.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">tr0</filename>, <filename moreinfo="none">tr1</filename>, </term><listitem><para><indexterm significance="normal"><primary>tr0 device</primary></indexterm> 
<indexterm significance="normal"><primary>interfaces</primary><secondary>Token Ring</secondary></indexterm>
These are the Token Ring card interfaces. They are used for most Token Ring 
cards, including non-IBM manufactured cards.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">sl0</filename>, <filename moreinfo="none">sl1</filename>, </term><listitem><para><indexterm significance="normal"><primary>sl1 device</primary></indexterm> 
<indexterm significance="normal"><primary>interfaces</primary><secondary>SLIP</secondary></indexterm>
These are the SLIP interfaces. SLIP interfaces are associated with serial 
lines in the order in which they are allocated for SLIP.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">ppp0</filename>, <filename moreinfo="none">ppp1</filename>, </term><listitem><para><indexterm significance="normal"><primary>ppp1 device</primary></indexterm> 
<indexterm significance="normal"><primary>interfaces</primary><secondary>PPP</secondary></indexterm>
These are the PPP interfaces. Just like SLIP interfaces, a PPP interface is 
associated with a serial line once it is converted to PPP mode.</para></listitem></varlistentry><varlistentry><term> <filename moreinfo="none">plip0</filename>,
<filename moreinfo="none">plip1</filename>, </term><listitem><para><indexterm significance="normal"><primary>plip1 device</primary></indexterm>
<indexterm significance="normal"><primary>interfaces</primary><secondary>PLIP</secondary></indexterm>
These are the PLIP interfaces. PLIP transports IP datagrams over
parallel lines. The interfaces are allocated by the PLIP driver at
system boot time and are mapped onto parallel ports. In the
<emphasis>2.0.x</emphasis> kernels there is a direct relationship
between the device name and the I/O port of the parallel port, but in
later kernels the device names are allocated sequentially, just as for
SLIP and PPP devices.</para></listitem></varlistentry><varlistentry><term> <filename moreinfo="none">ax0</filename>,
<filename moreinfo="none">ax1</filename>, </term><listitem><para><indexterm significance="normal"><primary>AX.25 device</primary></indexterm>
<indexterm significance="normal"><primary>interfaces</primary><secondary>AX.25</secondary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>AX.25</secondary></indexterm>
These are the AX.25 interfaces. AX.25 is the primary protocol used by
amateur radio operators. AX.25 interfaces are allocated and mapped in
a similar fashion to SLIP devices.</para></listitem></varlistentry></variablelist></para><para>There are many other types of interfaces available for other network
drivers. We've listed only the most common ones.</para><para>During the next few sections, we will discuss the details of using
the drivers described previously. The Networking HOWTO provides details on 
how to configure most of the others, and the AX25 HOWTO explains how to 
configure the Amateur Radio network devices.</para></sect1><sect1 id="x-087-2-hardware.drivers.ethernet"><title>Ethernet Installation</title><indexterm significance="normal" class="startofrange" id="idx-configuringethernet-1"><primary>configuring</primary><secondary>Ethernet</secondary></indexterm><indexterm significance="normal"><primary>Ethernet</primary><secondary>Becker drivers</secondary></indexterm><indexterm significance="normal" class="startofrange" id="ch03.ethernet.install"><primary>Ethernet</primary><secondary>installation</secondary></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>Ethernet</secondary></indexterm><indexterm significance="normal"><primary>Becker, Donald</primary></indexterm><indexterm significance="normal"><primary>drivers</primary><secondary>Ethernet</secondary></indexterm><indexterm significance="normal"><primary>Ekwall, Bjrn</primary></indexterm><indexterm significance="normal"><primary>Davies, David C.</primary></indexterm><indexterm significance="normal"><primary>Ethernet</primary><secondary>through parallel port</secondary></indexterm><indexterm significance="normal"><primary>parallel port</primary><secondary>Ethernet</secondary></indexterm><indexterm significance="normal"><primary>D-Link pocket adaptor</primary></indexterm><indexterm significance="normal"><primary>drivers</primary><secondary>Ethernet</secondary></indexterm><indexterm significance="normal"><primary>drivers</primary><secondary>D-Link</secondary></indexterm><para>The current Linux network code supports a large variety of Ethernet
cards.  Most drivers were written by Donald Becker, who authored a
family of drivers for cards based on the National Semiconductor 8390
chip; these have become known as the Becker Series Drivers. Many other
developers have contributed drivers, and today there are few common
Ethernet cards that aren't supported by Linux. The list of supported
Ethernet cards is growing all the time, so if your card isn't
supported yet, chances are it will be soon.</para><para>Sometime earlier in Linux's history we would have attempted to list
all supported Ethernet cards, but that would now take too much time
and space.  Fortunately, Paul Gortmaker maintains the Ethernet HOWTO,
which lists each of the supported cards and provides useful
information about getting each of them running under Linux.<footnote id="x-087-2-fnhw04"><para> Paul can be reached at <systemitem moreinfo="none" role="emailaddr">gpg109@rsphy1.anu.edu.au</systemitem>.</para></footnote> It is posted monthly to the <systemitem moreinfo="none" role="newsgroup">comp.os.linux.answers</systemitem> newsgroup, and is
also available on any of the Linux Documentation Project mirror sites.
</para><para>Even if you are confident you know how to install a particular type of
Ethernet card in your machine, it is often worthwhile taking a look at
what the Ethernet HOWTO has to say about it. You will find information
that extends beyond simple configuration issues. For example, it could 
save you a lot of headaches to know the
behavior of some DMA-based Ethernet cards that use the same DMA
channel as the Adaptec 1542 SCSI controller by default. Unless you move
one of them to a different DMA channel, you will wind up with the 
Ethernet card writing packet data to arbitrary locations on your hard
disk.</para><para>To use any of the supported Ethernet cards with Linux, you may use a
precompiled kernel from one of the major Linux distributions. These generally
have modules available for all of the supported drivers, and the installation
process usually allows you to select which drivers you want loaded. In the
long term, however, it's better to build your own kernel and compile only
those drivers you actually need; this saves disk space and memory.</para><sect2><title>Ethernet Autoprobing</title><indexterm significance="normal" class="startofrange" id="idx-ethernetautoprobing-1"><primary>Ethernet</primary><secondary>autoprobing</secondary></indexterm><indexterm significance="normal"><primary>autoprobing</primary><secondary>Ethernet</secondary></indexterm><para>Many of the Linux Ethernet drivers are smart enough to know how to
search for the location of your Ethernet card. This saves you having
to tell the kernel where it is manually. The Ethernet HOWTO lists
whether a particular driver uses autoprobing and in which order it
searches the I/O address for the card.</para><para>There are three limitations to the autoprobing code. First, it may not
recognize all cards properly. This is especially true for some of the cheaper
clones of common cards. Second, the kernel won't
autoprobe for more than one card unless specifically instructed. This was
a conscious design decision, as it is assumed you will want to have control
over which card is assigned to which interface. The best way to do this
reliably is to manually configure the Ethernet cards in your machine. Third,
the driver may not probe at the address that your card is configured for.
Generally speaking, the drivers will autoprobe at the addresses that the
particular device is capable of being configured for, but sometimes certain
addresses are ignored to avoid hardware conflicts with other types of cards
that commonly use that same address.</para><para>PCI network cards should be reliably detected. But if you are using more 
than one card, or if the autoprobe should fail to detect your card, you 
have a way to explicitly tell the kernel about the card's base address and 
name.</para><para><indexterm significance="normal"><primary>configuring</primary><secondary>Ethernet</secondary></indexterm>
<indexterm significance="normal"><primary>manual configuration</primary><secondary>Ethernet</secondary></indexterm>
<indexterm significance="normal"><primary>autoprobing</primary><secondary>failure</secondary></indexterm>
<indexterm significance="normal"><primary>lilo command</primary></indexterm>
At boot time you can supply arguments and information to the kernel that any 
of the kernel components may read. This mechanism allows you
to pass information to the kernel that Ethernet drivers can use to locate your
Ethernet hardware without making the driver probe.</para><para>If you use lilo to boot your system, you can pass parameters
to the kernel by specifying them through the
<systemitem moreinfo="none" role="keyword">append</systemitem> option in the
<filename moreinfo="none">lilo.conf</filename> file. To inform the kernel about an
Ethernet device, you can pass the following parameters:</para><para><screen format="linespecific">ether=<replaceable>irq</replaceable>,<replaceable>base_addr</replaceable>,[<replaceable>param1</replaceable>,][<replaceable>param2</replaceable>,]<replaceable>name</replaceable></screen></para><para>The first four parameters are numeric, while the last is the device
name. The <replaceable>irq</replaceable>,
<replaceable>base_addr</replaceable>, and
<replaceable>name</replaceable> parameters are required, but the two
<replaceable>param</replaceable> parameters are optional. Any of the
numeric values may be set to zero, which causes the kernel to
determine the value by probing.</para><para><indexterm significance="normal"><primary>auto-IRQ</primary></indexterm>
<indexterm significance="normal"><primary>IRQ (Interrupt Request)</primary></indexterm>
The first parameter sets the IRQ assigned to the device. By default, the
kernel will try to autodetect the device's IRQ channel. The 3c503 driver,
for example, has a special feature that selects a free IRQ from the list
5, 9, 3, 4 and configures the card to use this line.
The <replaceable>base_addr</replaceable> parameter gives the I/O base address
of the card; a value of zero tells the kernel to probe the addresses listed
above.</para><para>Different drivers use the next two parameters differently. For shared-memory cards, such as the WD80x3, they specify starting and ending
addresses of the shared memory area. Other cards commonly use
<replaceable>param1</replaceable> to set the level at which debugging 
information is displayed. Values of 1 through 7 denote increasing levels of
verbosity, while 8 turns them off altogether; 0 denotes the default.
The 3c503 driver uses <replaceable>param2</replaceable> to choose between the
internal transceiver (default) or an external transceiver (a value of 1).
The former uses the card's BNC connector; the latter uses its AUI port.
The <replaceable>param</replaceable> arguments need not be included at all
if you don't have anything special to configure.</para><para>The first non-numeric argument is interpreted by the kernel as the
device name. You must specify a device name for each Ethernet card you
describe.</para><para>If you have two Ethernet cards, you can have Linux autodetect one card
and pass the second card's parameters with <command moreinfo="none">lilo</command>,
but you'll probably want to manually configure both cards. If you
decide to have the kernel probe for one and manually configure the
second, you must make sure the kernel doesn't accidentally find the
second card first, or else the other one won't be registered at
all. You do this by passing <command moreinfo="none">lilo</command> a <systemitem moreinfo="none" role="keyword">reserve</systemitem> option, which explicitly tells the
kernel to avoid probing the I/O space taken up by the second card. For
instance, to make Linux install a second Ethernet card at
<literal moreinfo="none">0x300</literal> as <filename moreinfo="none">eth1</filename>, you would pass
the following parameters to the kernel:</para><?troff .wcon_off?><para><screen format="linespecific">reserve=0x300,32 ether=0,0x300,eth1</screen></para><?troff .Nd 10?><para>The <emphasis>reserve</emphasis> option makes sure no driver
accesses the second card's I/O space when probing for some device. You may 
also use the kernel parameters to override autoprobing for 
<filename moreinfo="none">eth0</filename>:</para><para><screen format="linespecific">reserve=0x340,32 ether=0,0x340,eth0</screen></para><para>You can turn off autoprobing altogether. You might do this, for example, to
stop a kernel probing for an Ethernet card you might have temporarily removed.
Disabling autoprobing is as simple as specifying a
<replaceable>base_addr</replaceable> argument of 1:</para><para><screen format="linespecific">ether=0,-1,eth0</screen></para><para>To supply these parameters to the kernel at boot time, you enter the
parameters at the lilo "boot:" prompt. To have <command moreinfo="none">lilo</command>
give you the "<prompt moreinfo="none">boot:</prompt>" at the prompt, you must press
any one of the Control, Alt or Shift keys while
<command moreinfo="none">lilo</command> is booting. If you press the Tab key at the
prompt, you will be presented with a list of kernels that you may
boot. To boot a kernel with parameters supplied, enter the name of the
kernel you wish to boot, followed by a space, then followed by the
parameters you wish to supply. When you press the Enter key,
<command moreinfo="none">lilo</command> will load that kernel and boot it with the
parameters you've supplied.</para><para>To make this change occur automatically on each reboot, enter the parameters
into the <filename moreinfo="none">/etc/lilo.conf</filename> using the
<literal moreinfo="none">append=</literal> keyword. An example might look like this:

<screen format="linespecific">boot=/dev/hda
root=/dev/hda2
install=/boot/boot.b
map=/boot/map
vga=normal
delay=20
append="ether=10,300,eth0"

image=/boot/vmlinuz-2.2.14
label=2.2.14
read-only</screen></para><para>After you've edited <filename moreinfo="none">lilo.conf</filename>, you must rerun
the <command moreinfo="none">lilo</command> command to activate the change.</para><para><indexterm significance="normal" class="endofrange" startref="idx-ethernetautoprobing-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-configuringethernet-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="ch03.ethernet.install"></indexterm> </para></sect2></sect1><sect1 id="x-087-2-hardware.drivers.plip"><title>The PLIP Driver</title><indexterm significance="normal"><primary>configuring</primary><secondary>PLIP</secondary></indexterm><indexterm significance="normal"><primary>parallel port</primary><secondary>IP</secondary></indexterm><indexterm significance="normal"><primary>drivers</primary><secondary>PLIP</secondary></indexterm><indexterm significance="normal"><primary>PLIP (Parallel Line IP) protocol</primary><secondary>driver</secondary></indexterm><indexterm significance="normal"><primary>protocols</primary><secondary>PLIP</secondary></indexterm><para><emphasis>Parallel Line IP</emphasis> (PLIP) is a cheap way to
network when you want to connect only two machines. It uses a parallel port
and a special cable, achieving speeds of 10 kilobytes per second to 20 kilobytes per second.</para><para>PLIP was originally developed by Crynwr, Inc. Its design at the time was
rather ingenious (or, if you prefer, a
hack), because the original parallel ports on
IBM PCs were designed to spend their time being unidirectional printer ports;
the eight data lines could be used only to send data from the PC to the
peripheral device, but not the other way around.<footnote id="x-087-2-fnhw05"><para>Fight to clear the hacking name! Always use cracker when
you are referring to people who are consciously trying to defeat the
security of a system, and hacker when you are referring
to people who have found a clever way of solving a problem. Hackers
can be crackers, but the two should never be confused. Consult the New
Hackers Dictionary (popularly found as the Jargon file) for a more
complete understanding of the terms.  </para></footnote> The Cyrnwr
PLIP design worked around this limitation by using the port's five
status lines for input, which limited it to transferring all data as
nibbles (half bytes) only, but allowed for bidirectional
transfer. This mode of operation was called PLIP mode 0.
Today, the parallel ports supplied on PC hardware cater to full
bidirectional 8-bit data transfer, and PLIP has been extended to
accomodate this with the addition of PLIP mode 1.</para><para><indexterm significance="normal"><primary>NCSA telnet</primary></indexterm> <?troff .ffn?>
Linux kernels up to and including Version 2.0 support PLIP mode 0 only,
and an enhanced parallel port driver exists as a
patch against the 2.0 kernel and as a 
standard part of the 2.2 kernel code to provide PLIP mode 1 operation, too.
<footnote id="x-087-2-fnhw06"><para>The enhanced parallel port adaptor patch for 2.0 kernel is available from
<systemitem moreinfo="none" role="url">http://www.cyberelk.demon.co.uk/parport.html</systemitem>.</para></footnote>
Unlike earlier versions of the PLIP code, the driver now attempts to be
compatible with the PLIP implementations from Crynwr, as well as the PLIP
driver in NCSA <command moreinfo="none">telnet</command>.<footnote id="x-087-2-fnhw07"><para>NCSA <command moreinfo="none">telnet</command> is a popular program for DOS that runs TCP/IP
over Ethernet or PLIP, and supports <command moreinfo="none">telnet</command> and FTP.</para></footnote>
To connect two machines using PLIP, you need a special cable sold at some
shops as a Null Printer or Turbo Laplink cable.
You can, however, make one yourself fairly easily;
<xref linkend="x-087-2-appendix.cables"></xref> shows you how.</para><para><indexterm significance="normal"><primary>Yutaka, Niibe</primary></indexterm>
The PLIP driver for Linux is the work of almost countless persons. It is
currently maintained by Niibe Yutaka.<footnote id="x-087-2-fnhw08"><para>Niibe can be reached at
<systemitem moreinfo="none" role="emailaddr">gniibe@mri.co.jp</systemitem>.</para></footnote>
If compiled into the kernel, it sets up a network interface for each of the
possible printer ports, with <filename moreinfo="none">plip0</filename> corresponding to
parallel port <filename moreinfo="none">lp0</filename>, <filename moreinfo="none">plip1</filename><?troff .endwcd?>
corresponding to <filename moreinfo="none">lp1</filename>, etc. The mapping of interfaces to
ports differs in the 2.0 kernels and the 2.2<?troff .hw hardwired?>
kernels. In the 2.0 kernels, the mapping was hardwired in the
<filename moreinfo="none">drivers/net/Spacd.c</filename> file in the kernel<?troff .hw hard-wired?><?troff .ne 10?>
source. The default mappings in this file are:</para><informaltable><tgroup cols="3"><thead><row><entry>Interface</entry><entry>I/O Port</entry><entry>IRQ</entry></row></thead><tbody><row><entry><filename moreinfo="none">plip0</filename></entry><entry><literal moreinfo="none">0x3BC</literal></entry><entry>7</entry></row><row><entry><filename moreinfo="none">plip1</filename></entry><entry><literal moreinfo="none">0x378</literal></entry><entry>7</entry></row><row><entry><filename moreinfo="none">plip2</filename></entry><entry><literal moreinfo="none">0x278</literal></entry><entry>5</entry></row></tbody></tgroup></informaltable><para><indexterm significance="normal"><primary>manual configuration</primary><secondary>PLIP</secondary></indexterm>
If you configured your printer port in a different way, you
must change these values in <filename moreinfo="none">drivers/net/Space.c</filename> in
the Linux kernel source and build a new kernel.</para><para>In the 2.2 kernels, the PLIP driver uses the parport parallel port
sharing driver developed by Philip Blundell.<footnote id="x-087-2-fnhw09"><para>You can reach Philip at <systemitem moreinfo="none" role="emailadd"><emphasis>Philip.Blundell@pobox.com</emphasis></systemitem>.</para></footnote> The new driver allocates the PLIP network device names serially,
just as for the Ethernet or PPP drivers, so the first PLIP device created is
<filename moreinfo="none">plip0</filename>, the second is <filename moreinfo="none">plip1</filename>, and so on.
The physical parallel port hardware is also allocated serially. By default, the
parallel port driver will attempt to detect your parallel port hardware with an
autoprobe routine, recording the physical device information in the order found. It is better practice to explicitly tell the kernel the physical I/O
parameters. You can do this by supplying arguments to the
<filename moreinfo="none">parport_pc.o</filename> module as you load it, or if you have
compiled the driver into your kernel, using lilo to supply
arguments to the kernel at boot time. The IRQ setting of any device may be
changed later by writing the new IRQ value to the related
<filename moreinfo="none">/proc/parport/*/irq</filename> file.</para><para>Configuring the physical I/O parameters in a 2.2 kernel when loading the
module is straightforward. For instance, to tell the driver that you have
two PC-style parallel ports at I/O addresses <literal moreinfo="none">0x278</literal> and
<literal moreinfo="none">0c378</literal> and IRQs 5 and 7, respectively, you would load the
module with the following arguments:

<screen format="linespecific">modprobe parport_pc io=0x278,0x378 irq=5,7</screen>

The corresponding arguments to pass to the kernel for a compiled-in driver are:

<screen format="linespecific">parport=0x278,5 parport=0x378,7</screen>

You would use the lilo <systemitem moreinfo="none" role="keyword">append</systemitem> 
keyword to have these arguments
passed to the kernel automatically at boot time.</para><para>When the PLIP driver is initialized, either at boot time if it is
built-in, or when the <filename moreinfo="none">plip.o</filename> module is loaded,
each of the parallel ports will have a <filename moreinfo="none">plip</filename>
network device associated with it. <filename moreinfo="none">plip0</filename> will be
assigned to the first parallel port device, <filename moreinfo="none">plip1</filename>
the second, and so on.  You can manually override this automatic
assignment using another set of kernel arguments. For instance, to
assign <literal moreinfo="none">parport0</literal> to network device<?troff .ne 10?>
<literal moreinfo="none">plip0</literal>, and <literal moreinfo="none">parport1</literal> to network
device <literal moreinfo="none">plip1</literal>, you would use kernel arguments of:

<screen format="linespecific">plip=parport1 plip=parport0</screen>
</para><para>This mapping does not mean, however, that you cannot use these parallel ports
for printing or other purposes. The physical parallel port devices are used
by the PLIP driver only when the corresponding interface is configured
<systemitem moreinfo="none" role="keyword">up</systemitem>.</para></sect1><sect1 id="x-087-2-hardware.drivers.slip"><title>The PPP and SLIP Drivers</title><indexterm significance="normal"><primary>drivers</primary><secondary>SLIP</secondary></indexterm><indexterm significance="normal"><primary>drivers</primary><secondary>PPP</secondary></indexterm><indexterm significance="normal"><primary>SLIP (Serial Line IP) protocol</primary><secondary>driver</secondary></indexterm><indexterm significance="normal"><primary>PLIP (Parallel Line IP) protocol</primary><secondary>driver</secondary></indexterm><para>Point-to-Point Protocol (PPP) and Serial Line IP (SLIP) are widely used
protocols for carrying IP packets over a serial link. A number of institutions
offer dialup PPP and SLIP access to machines that are on the Internet, thus
providing IP connectivity to private persons (something that's otherwise
hardly affordable).</para><para>No hardware modifications are necessary to run PPP or SLIP; you can use
any serial port. Since serial port configuration is not specific to
TCP/IP networking, we have devoted a separate chapter to this.  Please
refer to <xref linkend="x-087-2-serial"></xref>, for more information. We cover
PPP in detail in <xref linkend="x-087-2-ppp"></xref>, and SLIP in
<xref linkend="x-087-2-slip"></xref>.</para></sect1><sect1 id="x-087-2-hardware.other"><title>Other Network Types</title><para><indexterm significance="normal"><primary>drivers</primary><secondary>Token Ring</secondary></indexterm>
<indexterm significance="normal"><primary>drivers</primary><secondary>ArcNet</secondary></indexterm>
<indexterm significance="normal"><primary>drivers</primary><secondary>FDDI</secondary></indexterm>
<indexterm significance="normal"><primary>Token Ring</primary><secondary>driver</secondary></indexterm>
<indexterm significance="normal"><primary>ArcNet protocol driver</primary></indexterm>
<indexterm significance="normal"><primary>FDDI (Fiber Distributed Data Interface)</primary></indexterm>
<indexterm significance="normal"><primary>Fiber Distributed Data Interface (FDDI)</primary></indexterm>
Most other network types are configured similarly to Ethernet. The arguments 
passed to the loadable modules will be different
and some drivers may not support more than one card, but just about everything
else is the same. Documentation for these cards is generally available in the
<filename moreinfo="none">/usr/src/linux/Documentation/networking/</filename> directory of
the Linux kernel source.</para><para><indexterm significance="normal" class="endofrange" startref="idx-configuringnetworkhardware-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-hardwarenetworking-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="ch03.net.hw.config"></indexterm> </para></sect1></chapter><chapter id="x-087-2-serial"><title>Configuring the Serial Hardware</title><indexterm significance="normal" class="startofrange" id="idx-hardwareserial-1"><primary>hardware</primary><secondary>configuring serial</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-deviceserial-1"><primary>devices</primary><secondary>serial</secondary></indexterm><indexterm significance="normal" class="startofrange" id="ch04.serdev.setup"><primary>serial devices</primary><secondary>configuring</secondary></indexterm><para>The Internet is growing at an incredible rate. Much of this growth is
attributed to Internet users who can't afford high-speed permanent
network connections and who use protocols such as SLIP, PPP, or UUCP
to dial in to a network provider to retrieve their daily dose of email
and news.</para><para><indexterm significance="normal"><primary>Hankins, Greg</primary></indexterm>
<indexterm significance="normal"><primary>HOWTOs</primary><secondary>Serial</secondary></indexterm>
This chapter is intended to help all people who rely on modems
to maintain their link to the outside world. We won't cover the
mechanics of how to configure your modem (the manual that came with it
will tell you more about it than we can), but we will cover most of
the Linux-specific aspects of managing devices that use serial
ports. Topics include serial communications software, creating the
serial device files, serial hardware, and configuring serial devices
using the <command moreinfo="none">setserial</command> and <command moreinfo="none">stty</command>
commands. Many other related topics are covered in the Serial HOWTO
by David Lawyer.<footnote id="x-087-2-fnse1"><para>David can be reached at
<systemitem moreinfo="none" role="emailaddr">bf347@lafn.org</systemitem>.</para></footnote>
</para><sect1 id="x-087-2-serial.software"><title>Communications Software<?lb?>
for Modem Links</title><indexterm significance="normal"><primary>terminal
programs</primary></indexterm><indexterm significance="normal"><primary>kermit (terminal
program)</primary></indexterm><indexterm significance="normal"><primary>minicom (terminal
program)</primary></indexterm><indexterm significance="normal"><primary>BBS (Bulletin Board
System)</primary></indexterm><indexterm significance="normal"><primary>bulletin
board</primary></indexterm><indexterm significance="normal" class="startofrange" id="ch03.modem.comm.sw"><primary>modems</primary><secondary>links</secondary><tertiary>communication
software for</tertiary></indexterm><para>There are a number of communications packages available for
Linux. Many of these packages are <emphasis>terminal
programs</emphasis>, which allow a user to dial in to another computer
as if she were sitting in front of a simple terminal. The traditional
terminal program for Unix-like environments is
<command moreinfo="none">kermit</command>. It is, however, fairly ancient now, and
would probably be considered difficult to use. There are more
comfortable programs available that support features, like
telephone-dialing dictionaries, script languages to automate dialing
and logging in to remote computer systems, and a variety of file
exchange protocols. One of these programs is <command moreinfo="none">minicom</command>,
which was modeled after some of the most popular DOS terminal
programs. X11 users are accommodated, too. <command moreinfo="none">seyon</command> is
a fully featured X11-based communications program.</para><para>Terminal programs aren't the only type of serial communication
programs available. Other programs let you connect to a host and
download news and email in a single bundle, to read and reply later at
your leisure. This can save a lot of time, and is especially useful if
you are unfortunate enough to live in an area where your local calls
are time-charged. All of the reading and replying time can be spent
offline, and when you are ready, you can redial and upload your
responses in a single bundle. This all consumes a bit more hard disk
because all of the messages have to be stored to your disk before you
can read them, but this could be a reasonable trade-off at today's
hard drive prices.</para><para><indexterm significance="normal"><primary>UUCP</primary></indexterm>
<indexterm significance="normal"><primary>FidoNet</primary></indexterm> UUCP epitomizes this
communication software style. It is a program suite that copies files
from one host to another and executes programs on a remote host. It is
frequently used to transport mail or news in private networks. Ian
Taylor's UUCP package, which also runs under Linux, is described in
detail in <xref linkend="x-087-2-uucp"></xref>. Other noninteractive
communications software is used throughout networks such as
Fidonet. Fidonet application ports like <command moreinfo="none">ifmail</command> are
also available, although we expect that not many people still use
them.</para><para><indexterm significance="normal"><primary>SLIP (Serial Line IP)
protocol</primary></indexterm> <indexterm significance="normal"><primary>PPP (Point-to-Point
Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>SLIP</secondary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>PPP</secondary></indexterm>
PPP and SLIP are in between, allowing both interactive and
noninteractive use. Many people use PPP or SLIP to dial in to their
campus network or other Internet Service Provider to run FTP and read
web pages. PPP and SLIP are also, however, commonly used over
permanent or semipermanent connections for LAN-to-LAN coupling,
although this is really only interesting with ISDN or other high-speed
network connections.</para><indexterm significance="normal" class="endofrange" startref="ch03.modem.comm.sw"></indexterm></sect1><sect1 id="x-087-2-serial.ttys"><title>Introduction to Serial Devices</title><indexterm significance="normal" class="startofrange" id="idx-tty-1"><primary>ttys</primary></indexterm><para>The Unix kernel provides devices for accessing serial hardware,
typically called <emphasis>tty</emphasis> devices (pronounced as it is
spelled: T-T-Y). This is an abbreviation for <emphasis>Teletype
device</emphasis>, which used to be one of the major manufacturers of
terminal devices in the early days of Unix. The term is used now for
any character-based data terminal. Throughout this chapter, we use the
term to refer exclusively to the Linux device files rather than the
physical terminal.</para><para>Linux provides three classes of tty devices: serial devices, virtual
terminals (all of which you can access in turn by pressing Alt-F1
through Alt-F<emphasis>nn</emphasis> on the local console), and
pseudo-terminals (similar to a two-way pipe, used by applications such
as X11). The former were called tty devices because the original
character-based terminals were connected to the Unix machine by a
serial cable or telephone line and modem. The latter two were
named after the tty device because they were created to behave in a
similar fashion from the programmer's perspective.</para><para><indexterm significance="normal"><primary>line discipline</primary></indexterm>
<indexterm significance="normal"><primary>ttys</primary><secondary>line
discipline</secondary></indexterm> SLIP and PPP are most commonly
implemented in the kernel. The kernel doesn't really treat the
<emphasis>tty</emphasis> device as a network device that you can
manipulate like an Ethernet device, using commands such as
<command moreinfo="none">ifconfig</command>. However, it does treat tty devices as
places where network devices can be bound. To do this, the kernel
changes what is called the line discipline of the tty
device. Both SLIP and PPP are line disciplines that may be enabled on
tty devices. The general idea is that the serial driver handles data
given to it differently, depending on the line discipline it is
configured for. In its default line discipline, the driver simply
transmits each character it is given in turn. When the SLIP or PPP
line discipline is selected, the driver instead reads a block of data,
wraps a special header around it that allows the remote end to
identify that block of data in a stream, and transmits the new data
block. It isn't too important to understand this yet; we'll cover both
SLIP and PPP in later chapters, and it all happens automatically for
you anyway.</para></sect1><sect1 id="x-087-2-serial.devices"><title>Accessing Serial Devices</title><para>Like all devices in a Unix system, serial ports are accessed through
device special files, located in the <filename moreinfo="none">/dev</filename>
directory.  There are two varieties of device files related to serial
drivers, and there is one device file of each type for each port. The
device will behave slightly differently, depending on which of its
device files we open.  We'll cover the differences because it will help you
understand some of the configurations and advice that you might see
relating to serial devices, but in practice you need to use only
one of these. At some point in the future, one of them may even
disappear completely.</para><para><indexterm significance="normal" class="startofrange" id="idx-filenamedevcuafilename-1"><primary sortas="dev/cua*">/dev/cua*</primary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-filenamedevttysfilename-1"><primary sortas="dev/ttyS*">/dev/ttyS*</primary></indexterm>
<indexterm significance="normal"><primary>serial devices</primary><secondary>accessing</secondary></indexterm> 
<indexterm significance="normal"><primary>serial line</primary><secondary>device file</secondary></indexterm>
<indexterm significance="normal"><primary>dialout device</primary></indexterm>
<indexterm significance="normal"><primary>dialin device</primary></indexterm>
The most important of the two classes of serial device has a major
number of 4, and its device special files are named
<filename moreinfo="none">ttyS0</filename>, <filename moreinfo="none">ttyS1</filename>, etc. The
second variety has a major number of 5, and was designed for use when
dialing out (calling out) through a port; its device special files are
called <filename moreinfo="none">cua0</filename>, <filename moreinfo="none">cua1</filename>, etc. In
the Unix world, counting generally starts at zero, while laypeople
tend to start at one. This creates a small amount of confusion for
people because <literal moreinfo="none">COM1:</literal> is represented by
<filename moreinfo="none">/dev/ttyS0</filename>, <literal moreinfo="none">COM2:</literal> by
<filename moreinfo="none">/dev/ttyS1</filename>, etc. Anyone familiar with IBM PC-style
hardware knows that <literal moreinfo="none">COM3:</literal> and greater were never
really standardized anyway.</para><para>The <emphasis>cua</emphasis>, or callout, devices were
created to solve the problem of avoiding conflicts on serial devices
for modems that have to support both incoming and outgoing
connections.  Unfortunately, they've created their own problems and
are now likely to be discontinued. Let's briefly look at the problem.</para><para>Linux, like Unix, allows a device, or any other file, to be opened by
more than one process simultaneously. Unfortunately, this is rarely
useful with tty devices, as the two processes will almost certainly
interfere with each other. Luckily, a mechanism was devised to allow a
process to check if a tty device had already been opened by another
device before opening it. The mechanism uses what are called
<emphasis>lock files</emphasis>. The idea was that when a process
wanted to open a tty device, it would check for the existence of a
file in a special location, named similarly to the device it intends
to open. If the file does not exist, the process creates it and opens
the tty device. If the file does exist, the process assumes another
process already has the tty device open and takes appropriate
action. One last clever trick to make the lock file management system
work was writing the process ID (pid) of the process that had created
the lock file into the lock file itself; we'll talk more about that in
a moment.</para><para>The lock file mechanism works perfectly well in circumstances in which
you have a defined location for the lock files and all programs know
where to find them. Alas, this wasn't always the case for Linux. It
wasn't until the Linux Filesystem Standard defined a standard location
for lock files when <filename moreinfo="none">tty</filename> lock files began to work
correctly. At one time there were at least four, and possibly more
locations chosen by software developers to store lock files:
<filename moreinfo="none">/usr/spool/locks/</filename>,
<filename moreinfo="none">/var/spool/locks/</filename>,
<filename moreinfo="none">/var/lock/</filename>, and
<filename moreinfo="none">/usr/lock/</filename>. Confusion caused chaos. Programs were
opening lock files in different locations that were meant to control a
single tty device; it was as if lock files weren't being used at all.</para><para>The <filename moreinfo="none">cua</filename> devices were created to provide a
solution to this problem. Rather than relying on the use of lock files
to prevent clashes between programs wanting to use the serial devices,
it was decided that the kernel could provide a simple means of
arbitrating who should be given access. If the
<filename moreinfo="none">ttyS</filename> device were already opened, an attempt to
open the <filename moreinfo="none">cua</filename> would result in an error that a
program could interpret to mean the device was already being used. If
the <filename moreinfo="none">cua</filename> device were already open and an attempt
was made to open the <filename moreinfo="none">ttyS</filename>, the request would
block; that is, it would be put on hold and wait until the
<filename moreinfo="none">cua</filename> device was closed by the other process. This
worked quite well if you had a single modem that you had configured
for dial-in access and you occasionally wanted to dial out on the same
device. But it did not work very well in environments where you had
multiple programs wanting to call out on the same device. The only way
to solve the contention problem was to use lock files! Back to square
one.</para><para>Suffice it to say that the Linux Filesystem Standard came to the
rescue and now mandates that lock files be stored in the
<filename moreinfo="none">/var/lock</filename> directory, and that by convention, the
lock file name for the <filename moreinfo="none">ttyS1</filename> device, for
instance, is <filename moreinfo="none">LCK..ttyS1</filename>. The
<filename moreinfo="none">cua</filename> lock files should also go in this directory,
but use of <filename moreinfo="none">cua</filename> devices is now discouraged.</para><para>The <filename moreinfo="none">cua</filename> devices will probably still be around for
some time to provide a period of backward compatibility, but in time
they will be retired. If you are wondering what to use, stick to the
<filename moreinfo="none">ttyS</filename> device and make sure that your system is
Linux FSSTND compliant, or at the very least that all programs using
the serial devices agree on where the lock files are located. Most
software dealing with serial tty devices provides a compile-time
option to specify the location of the lock files. More often than not,
this will appear as a variable called something like
<literal moreinfo="none">LOCKDIR</literal> in the <filename moreinfo="none">Makefile</filename> or in
a configuration header file. If you're compiling the software
yourself, it is best to change this to agree with the FSSTND-specified
location. If you're using a precompiled binary and you're not sure
where the program will write its lock files, you can use the following
command to gain a hint:
<screen format="linespecific"><command moreinfo="none">strings</command> <filename moreinfo="none">binaryfile</filename> | <command moreinfo="none">grep</command> lock</screen>
If the location found does not agree with the rest of your system, you
can try creating a symbolic link from the lock directory that the
foreign executable wants to use back to
<filename moreinfo="none">/var/lock/</filename>. This is ugly, but it will work.</para><sect2 id="x-087-2-serial.devicefiles"><title>The Serial Device Special Files</title><para><indexterm significance="normal"><primary>COM port</primary></indexterm>
<indexterm significance="normal"><primary>ports</primary><secondary>COM</secondary></indexterm>
Minor numbers are identical for both types of serial devices. If you
have your modem on one of the ports COM1: through COM4:, its minor
number will be the COM port number plus 63.  If you are using special
serial hardware, such as a high-performance multiple port serial
controller, you will probably need to create special device files for
it; it probably won't use the standard device driver. The Serial-HOWTO
should be able to assist you in finding the appropriate details.</para><para>Assume your modem is on COM2:. Its minor number will be 65, and its
major number will be 4 for normal use. There should be a device called
<filename moreinfo="none">ttyS1</filename> that has these numbers. List the serial
ttys in the <filename moreinfo="none">/dev/</filename> directory. The fifth and sixth
columns show the major and minor numbers, respectively:</para><para><screen format="linespecific">$ <userinput moreinfo="none">ls -l /dev/ttyS*</userinput>
0 crw-rw----   1 uucp     dialout    4,  64 Oct 13  1997 /dev/ttyS0
0 crw-rw----   1 uucp     dialout    4,  65 Jan 26 21:55 /dev/ttyS1
0 crw-rw----   1 uucp     dialout    4,  66 Oct 13  1997 /dev/ttyS2
0 crw-rw----   1 uucp     dialout    4,  67 Oct 13  1997 /dev/ttyS3</screen></para><para>If there is no device with major number 4 and minor number 65, you
will have to create one. Become the superuser and type:</para><para><screen format="linespecific"># <userinput moreinfo="none">mknod -m 666 /dev/ttyS1 c 4 65</userinput>
# <userinput moreinfo="none">chown uucp.dialout /dev/ttyS1</userinput></screen>
The various Linux distributions use slightly differing strategies for
who should own the serial devices. Sometimes they will be owned by
<emphasis>root</emphasis>, and other times they will be owned by
another user, such as <userinput moreinfo="none">uucp</userinput> in our example.
Modern distributions have a group specifically for dial-out devices,
and any users who are allowed to use them are added to this group.</para><para><indexterm significance="normal"><primary sortas="dev/modem">/dev/modem</primary></indexterm>
Some people suggest making <filename moreinfo="none">/dev/modem</filename> a symbolic
link to your modem device so that casual users don't have to remember
the somewhat unintuitive <filename moreinfo="none">ttyS1</filename>. However, you
cannot use <filename moreinfo="none">modem</filename> in one program and the real
device file name in another. Their lock files would have different
names and the locking mechanism wouldn't work.</para><para><indexterm significance="normal" class="endofrange" startref="idx-filenamedevcuafilename-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-filenamedevttysfilename-1"></indexterm></para></sect2></sect1><sect1 id="x-087-2-serial.hardware"><title>Serial Hardware</title><indexterm significance="normal"><primary>RS-232 serial interface</primary></indexterm><para>RS-232 is currently the most common standard for serial communications
in the PC world. It uses a number of circuits for transmitting single
bits, as well as for synchronization. Additional lines may be used for
signaling the presence of a carrier (used by modems) and for
handshaking. Linux supports a wide variety of serial cards that use
the RS-232 standard.</para><para><indexterm significance="normal"><primary>serial line</primary><secondary>hardware
handshake</secondary></indexterm> <indexterm significance="normal"><primary>handshake,
hardware</primary></indexterm>
<indexterm significance="normal"><primary>hardware</primary><secondary>handshake</secondary></indexterm>
<indexterm significance="normal"><primary>RTS/CTS (Ready to Send/Clear to
Send)</primary></indexterm> Hardware handshake is optional, but very
useful. It allows either of the two stations to signal whether it is
ready to receive more data, or if the other station should pause until
the receiver is done processing the incoming data.  The lines used for
this are called Clear to Send (CTS) and Ready to
Send (RTS), respectively, which explains the colloquial name
for hardware handshake: RTS/CTS. The other type of
handshake you might be familiar with is called XON/XOFF
handshaking. XON/XOFF uses two nominated characters, conventionally
Ctrl-S and Ctrl-Q, to signal to the remote end that it should stop and
start transmitting data, respectively. While this method is simple to
implement and okay for use by dumb terminals, it causes great
confusion when you are dealing with binary data, as you may want to
transmit those characters as part of your data stream, and not have
them interpreted as flow control characters. It is also somewhat
slower to take effect than hardware handshake. Hardware handshake is
clean, fast, and recommended in preference to XON/XOFF when you have a
choice.</para><para><indexterm significance="normal"><primary>8250 UART</primary></indexterm>
<indexterm significance="normal"><primary>16450 UART</primary></indexterm>
<indexterm significance="normal"><primary>16550 UART</primary></indexterm>
<indexterm significance="normal"><primary>UART</primary></indexterm>
In the original IBM PC, the RS-232 interface was driven by a UART chip
called the 8250. PCs around the time of the 486 used a newer version
of the UART called the 16450. It was slightly faster than the
8250. Nearly all Pentium-based machines have been supplied with an
even newer version of the UART called the 16550. Some brands (most
notably internal modems equipped with the Rockwell chip set) use
completely different chips that emulate the behavior of the 16550 and
can be treated similarly. Linux supports all of these in its standard
serial port driver.<footnote id="x-087-2-serial-fixme"><para>Note that we are not talking about WinModem here! WinModems
have very simple hardware and rely completely on the main CPU of your
computer instead of dedicated hardware to do all of the hard work. If
you're purchasing a modem, it is our strongest recommendation to
<emphasis>not</emphasis> purchase such a modem; get a real modem. You
may find Linux support for WinModems, but that makes them only a
marginally more attractive solution.</para></footnote>
</para><para>The 16550 was a significant improvement over the 8250 and the 16450
because it offered a 16-byte FIFO buffer. The 16550 is actually a
family of UART devices, comprising the 16550, the 16550A, and the
16550AFN (later renamed PC16550DN). The differences relate to whether
the FIFO actually works; the 16550AFN is the one that is sure to
work. There was also an NS16550, but its FIFO never really worked
either.</para><para>The 8250 and 16450 UARTs had a simple 1-byte buffer. This means that a
16450 generates an interrupt for every character transmitted or
received. Each interrupt takes<?troff .ne 10?> a short period of time to service, and
this small delay limits 16450s to a reliable maximum bit speed of
about 9,600 bps in a typical ISA bus machine.</para><para>In the default configuration, the kernel checks the four standard
serial ports, COM1: through COM4:. The kernel is also able to
automatically detect what UART is used for each of the standard serial
ports, and will make use of the enhanced FIFO buffer of the 16550, if
it is available.</para></sect1><sect1 id="x-087-2-serial-configuration"><title>Using the Configuration Utilities</title><para><indexterm significance="normal" class="startofrange" id="idx-configuringserialport-1"><primary>configuring</primary><secondary>serial port</secondary></indexterm></para><para>Now let's spend some time looking at the two most useful serial device
configuration utilities: <command moreinfo="none">setserial</command> and
<command moreinfo="none">stty</command>.</para><sect2 id="x-087-2-serial-setserial"><title>The setserial Command</title><indexterm significance="normal"><primary sortas="setserial">setserial command</primary></indexterm><indexterm significance="normal"><primary sortas="Tso, Theodore">T'so, Theodore</primary></indexterm><para>The kernel will make its best effort to correctly determine how your
serial hardware is configured, but the variations on serial device
configuration makes this determination difficult to achieve 100
percent reliably in practice. A good example of where this is a
problem is the internal modems we talked about earlier. The UART they
use has a 16-byte FIFO buffer, but it looks like a 16450 UART to the
kernel device driver: unless we specifically tell the driver that this
port is a 16550 device, the kernel will not make use of the extended
buffer. Yet another example is that of the dumb 4-port cards that
allow sharing of a single IRQ among a number of serial devices. We may
have to specifically tell the kernel which IRQ port it's supposed to
use, and that IRQs may be shared.</para><para><command moreinfo="none">setserial</command> was created to configure the serial driver
at runtime. The <command moreinfo="none">setserial</command> command is most commonly
executed at boot time from a script called <filename moreinfo="none">0setserial</filename>
on some distributions, and <filename moreinfo="none">rc.serial</filename> on others. This
script is charged with the responsibility of initializing the serial driver
to accommodate any nonstandard or unusual serial hardware in the machine.</para><para>The general syntax for the <command moreinfo="none">setserial</command> command is:

<screen format="linespecific">setserial <replaceable>device</replaceable> [<replaceable>parameters</replaceable>]</screen>
in which the device is one of the serial devices, such as
<emphasis>ttyS0</emphasis>.</para><para>The <command moreinfo="none">setserial</command> command has a large number of
parameters.  The most common of these are described in <xref linkend="x-087-2-serial-setserial-parameters"></xref>. For information on the
remainder of the parameters, you should refer to the
<command moreinfo="none">setserial</command> manual page.</para><table id="x-087-2-serial-setserial-parameters"><title>setserial Command-Line Parameters</title><tgroup cols="2"><colspec colnum="2" colwidth="3.57i"></colspec><thead><row><entry>Parameter</entry><entry>Description</entry></row></thead><tbody><row><entry><literal moreinfo="none">port</literal> <replaceable>port_number</replaceable></entry><entry><para>	Specify the I/O port address of the serial device. Port numbers
	should be specified in hexadecimal notation, e.g., <literal moreinfo="none">0x2f8</literal>.
	</para></entry></row><row><entry><literal moreinfo="none">irq</literal> <replaceable>num</replaceable></entry><entry><para>	Specify the interrupt request line the serial device is
	using.
	</para></entry></row><row><entry><literal moreinfo="none">uart</literal> <replaceable>uart_type</replaceable></entry><entry><para>	Specify the UART type of the serial device. Common values are
	<literal moreinfo="none">16450</literal>, <literal moreinfo="none">16550</literal>, etc. Setting this
	value to <literal moreinfo="none">none</literal> will disable this serial device.</para></entry></row><row><entry><literal moreinfo="none">fourport</literal></entry><entry><para>	Specifying this parameter instructs the kernel serial driver that
	this port is one port of an AST Fourport card.</para></entry></row><row><entry><literal moreinfo="none">spd_hi</literal></entry><entry><para>	Program the UART to use a speed of 57.6 kbps when a process
	requests 38.4 kbps.
	</para></entry></row><row><entry><literal moreinfo="none">spd_vhi</literal></entry><entry><para>	Program the UART to use a speed of 115 kbps when a process
	requests 38.4 kbps.
	</para></entry></row><row><entry><literal moreinfo="none">spd_normal</literal></entry><entry><para>	Program the UART to use the default speed of 38.4 kbps when
	requested. This parameter is used to reverse the effect of a
	<literal moreinfo="none">spd_hi</literal> or <literal moreinfo="none">spd_vhi</literal> performed on
	the specified serial device.
	</para></entry></row><row><entry><literal moreinfo="none">auto_irq</literal></entry><entry><para>	This parameter will cause the kernel to attempt to automatically
	determine the IRQ of the specified device. This attempt may not be 
        completely reliable, so it is probably better to think of this as a 
        request for the kernel to guess the IRQ. If you know the IRQ of the 
        device, you should specify that it use the <literal moreinfo="none">irq</literal> 
        parameter instead.
	</para></entry></row><row><entry><literal moreinfo="none">autoconfig</literal></entry><entry><para>	This parameter must be specified in conjunction with the
	<literal moreinfo="none">port</literal> parameter. When this parameter is supplied,
	<command moreinfo="none">setserial</command> instructs the kernel to attempt to
	automatically determine the UART type located at the supplied port
	address. If the <literal moreinfo="none">auto_irq</literal> parameter is also 
        supplied, the kernel attempts to automatically determine the IRQ,
	too.
	</para></entry></row><row><entry><literal moreinfo="none">skip_test</literal></entry><entry><para>	This parameter instructs the kernel not to bother performing
	the UART type test during auto-configuration. This is necessary when
	the UART is incorrectly detected by the kernel.</para></entry></row></tbody></tgroup></table><para>A typical and simple <filename moreinfo="none">rc</filename> file to configure your serial
ports at boot time might look something like that shown in
<xref linkend="x-087-2-serial-rc.serial.setserial"></xref>. Most Linux distributions
will include something slightly more sophisticated than this one.</para><example id="x-087-2-serial-rc.serial.setserial"><title>Example rc.serial setserial Commands</title><screen format="linespecific"># /etc/rc.serial - serial line configuration script.
#
# Configure serial devices
/sbin/setserial /dev/ttyS0 auto_irq skip_test autoconfig
/sbin/setserial /dev/ttyS1 auto_irq skip_test autoconfig
/sbin/setserial /dev/ttyS2 auto_irq skip_test autoconfig
/sbin/setserial /dev/ttyS3 auto_irq skip_test autoconfig
#
# Display serial device configuration
/sbin/setserial -bg /dev/ttyS*</screen></example><para>The <literal moreinfo="none">-bg /dev/ttyS*</literal> argument in the last
command will print a neatly formatted summary of the hardware configuration
of all active serial devices. The output will look like that shown in
<xref linkend="x-087-2-serial.setserial.output"></xref>.</para><example id="x-087-2-serial.setserial.output"><title>Output of setserial -bg /dev/ttyS Command</title><screen format="linespecific">/dev/ttyS0 at 0x03f8 (irq = 4) is a 16550A
/dev/ttyS1 at 0x02f8 (irq = 3) is a 16550A</screen></example></sect2><sect2 id="x-087-2-serial-stty"><title>The stty Command</title><para><indexterm significance="normal"><primary sortas="stty">stty command</primary></indexterm>
<indexterm significance="normal"><primary>serial line</primary><secondary>hardware handshake</secondary></indexterm>
<indexterm significance="normal"><primary>handshake, hardware</primary></indexterm>
<indexterm significance="normal"><primary>hardware</primary><secondary>handshake</secondary></indexterm></para><para>The name <command moreinfo="none">stty</command> probably means set tty,
but the <command moreinfo="none">stty</command> command can also be used to display a
terminal's configuration. Perhaps even more so than
<command moreinfo="none">setserial</command>, the <command moreinfo="none">stty</command> command
provides a bewildering number of characteristics you can
configure. We'll cover the most important of these in a moment. You
can find the rest described in the <command moreinfo="none">stty</command> manual
page.</para><para>The <command moreinfo="none">stty</command> command is most commonly used to configure
terminal parameters, such as whether characters will be echoed or what
key should generate a break signal. We explained earlier that serial
devices are tty devices and the <command moreinfo="none">stty</command> command is therefore
equally applicable to them.</para><para>One of the more important uses of the <command moreinfo="none">stty</command> for
serial devices is to enable hardware handshaking on the device. We
talked briefly about hardware handshaking earlier. The default
configuration for serial devices is for hardware handshaking to be
disabled. This setting allows three wire serial cables to work;
they don't support the necessary signals for hardware handshaking, and
if it were enabled by default, they'd be unable to transmit any
characters to change it.</para><para>Surprisingly, some serial communications programs don't enable
hardware handshaking, so if your modem supports hardware handshaking,
you should configure the modem to use it (check your modem manual for
what command to use), and also configure your serial device to use
it. The <command moreinfo="none">stty</command> command has a
<literal moreinfo="none">crtscts</literal> flag that enables hardware handshaking on a
device; you'll need to use this. The command is probably best issued
from the <filename moreinfo="none">rc.serial</filename> file (or equivalent) at boot
time using commands like those shown in <xref linkend="x-087-2-serial-rc.serial.stty"></xref>.</para><example id="x-087-2-serial-rc.serial.stty"><title>Example rc.serial stty Commands</title><screen format="linespecific">#
stty crtscts  /dev/ttyS0
stty crtscts  /dev/ttyS1
stty crtscts  /dev/ttyS2
stty crtscts  /dev/ttyS3
#</screen></example><para>The <command moreinfo="none">stty</command> command works on the current terminal by
default, but by using the input redirection ()
feature of the shell, we can have <command moreinfo="none">stty</command> manipulate
any tty device. It's a common mistake to forget whether you are
supposed to use  or ; modern
versions of the <command moreinfo="none">stty</command> command have a much cleaner
syntax for doing this. To use the new syntax, we'd rewrite our sample
configuration to look like that shown in <xref linkend="x-087-2-serial-rc.serial.stty.new"></xref>.</para><example id="x-087-2-serial-rc.serial.stty.new"><title>Example rc.serial stty Commands Using Modern Syntax</title><screen format="linespecific">#
stty crtscts -F /dev/ttyS0
stty crtscts -F /dev/ttyS1
stty crtscts -F /dev/ttyS2
stty crtscts -F /dev/ttyS3
#</screen></example><para>We mentioned that the <command moreinfo="none">stty</command> command can be used to display
the terminal configuration parameters of a tty device. To display all of
the active settings on a tty device, use:</para><para><screen format="linespecific">$ <userinput moreinfo="none">stty -a -F /dev/ttyS1</userinput></screen></para><para>The output of this command, shown in
<xref linkend="x-087-2-serial.stty.output"></xref>, gives you the status of all flags
for that device; a flag shown with a preceding minus, as in
<option>crtscts</option>, means that the flag has been
turned off.</para><example id="x-087-2-serial.stty.output"><title>Output of stty -a Command</title><screen format="linespecific">speed 19200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = undef; 
         eol2 = undef; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
         werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon
        -ixoff -iuclc -ixany -imaxbel
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0
         bs0 vt0 ff0
-isig -icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop
         -echoprt echoctl echoke</screen></example><para>A description of the most important of these flags is given in <xref linkend="x-087-2-serial.stty.flags"></xref>. Each of these flags is enabled
by supplying it to <command moreinfo="none">stty</command> and disabled by supplying
it to <command moreinfo="none">stty</command> with the  character in front of
it. Thus, to disable hardware handshaking on the
<literal moreinfo="none">ttyS0</literal> device, you would use:
<screen format="linespecific">$ <userinput moreinfo="none">stty -crtscts -F /dev/ttyS0</userinput></screen></para><table id="x-087-2-serial.stty.flags"><title>stty Flags Most Relevant to Configuring Serial Devices</title><tgroup cols="2"><colspec colnum="2" colwidth="3.57i"></colspec><thead><row><entry>Flags</entry><entry>Description</entry></row></thead><tbody><row><entry><literal moreinfo="none">N</literal></entry><entry><para>	Set the line speed to <literal moreinfo="none">N</literal> bits per second.
	</para></entry></row><row><entry><literal moreinfo="none">crtsdts</literal></entry><entry><para>	Enable/Disable hardware handshaking.
	</para></entry></row><row><entry><literal moreinfo="none">ixon</literal></entry><entry><para>	Enable/Disable XON/XOFF flow control.
	</para></entry></row><row><entry><literal moreinfo="none">clocal</literal></entry><entry><para>	Enable/Disable modem control signals such as DTR/DTS and DCD. This
	is necessary if you are using a three wire serial cable because it does not supply these signals.
	</para></entry></row><row><entry><literal moreinfo="none">cs5 cs6 cs7 cs8</literal></entry><entry><para>	Set number of data bits to 5, 6, 7, or 8, respectively.
	</para></entry></row><row><entry><literal moreinfo="none">parodd</literal></entry><entry><para>	Enable odd parity. Disabling this flag enables even parity.
	</para></entry></row><row><entry><literal moreinfo="none">parenb</literal></entry><entry><para>	Enable parity checking. When this flag is negated, no parity is used.
	</para></entry></row><row><entry><literal moreinfo="none">cstopb</literal></entry><entry><para>	Enable use of two stop bits per character. When this flag is
	negated, one stop bit per character is used.
	</para></entry></row><row><entry><literal moreinfo="none">echo</literal></entry><entry><para>	Enable/Disable echoing of received characters back to sender.
	</para></entry></row></tbody></tgroup></table><para>The next example combines some of these flags and sets the
<filename moreinfo="none">ttyS0</filename> device to 19,200 bps, 8 data bits, no
parity, and hardware handshaking with echo disabled:

<screen format="linespecific">$ <userinput moreinfo="none">stty 19200 cs8 -parenb crtscts -echo -F /dev/ttyS0</userinput></screen>
</para><para><indexterm significance="normal" class="endofrange" startref="idx-configuringserialport-1"></indexterm></para></sect2></sect1><sect1 id="x-087-2-serial.getty"><title>Serial Devices and the login: Prompt</title><para>It was once very common that a Unix installation involved one server
machine and many dumb character mode terminals or
dial-up modems.  Today that sort of installation is less common, which
is good news for many people interested in operating this way, because
the dumb terminals are now very cheap to
acquire. Dial-up modem configurations are no less common, but these
days they would probably be used to support a SLIP or PPP login
(discussed in <xref linkend="x-087-2-slip"></xref> and <xref linkend="x-087-2-ppp"></xref>) than to be used for a simple login.
Nevertheless, each of these configurations can make use of a simple
program called a <command moreinfo="none">getty</command> program.</para><para>The term <command moreinfo="none">getty</command> is probably a contraction of
get tty. A <command moreinfo="none">getty</command> program opens a
serial device, configures it appropriately, optionally configures a
modem, and waits for a connection to be made. An active connection on
a serial device is usually indicated by the Data Carrier Detect (DCD)
pin on the serial device being raised. When a connection is detected,
the <command moreinfo="none">getty</command> program issues a
<literal moreinfo="none">login:</literal> prompt, and then invokes the
<command moreinfo="none">login</command> program to handle the actual system
login. Each of the virtual terminals (e.g.,
<filename moreinfo="none">/dev/tty1</filename>) in Linux has a
<command moreinfo="none">getty</command> running against it.</para><para>There are a number of different <command moreinfo="none">getty</command>
implementations, each designed to suit some configurations better than
others.  The <command moreinfo="none">getty</command> that we'll describe here is
called <command moreinfo="none">mgetty</command>. It is quite popular because it has
all sorts of features that make it especially modem-friendly,
including support for automatic fax programs and voice modems. We'll
concentrate on configuring <command moreinfo="none">mgetty</command> to answer
conventional data calls and leave the rest for you to explore at your
convenience.</para><sect2 id="x-087-2-serial.getty.mgetty"><title>Configuring the mgetty Daemon</title><para>The <command moreinfo="none">mgetty</command> daemon is available in source form from
<systemitem moreinfo="none" role="url">ftp://alpha.greenie.net/pub/mgetty/source/</systemitem>,
and is available in just about all Linux distributions in prepackaged
form.  The <command moreinfo="none">mgetty</command> daemon differs from most other
<command moreinfo="none">getty</command> implementations in that it has been designed
specifically for Hayes-compatible modems. It still supports direct
terminal connections, but is best suited for dialup
applications. Rather than using the DCD line to detect an incoming
call, it listens for the <literal moreinfo="none">RING</literal> message generated by
modern modems when they detect an incoming call and are not configured
for auto-answer.</para><para>The main executable program is called
<filename moreinfo="none">/usr/sbin/mgetty</filename>, and its main configuration file
is called <filename moreinfo="none">/etc/mgetty/mgetty.config</filename>. There are a
number of other binary programs and configuration files that cover
other <command moreinfo="none">mgetty</command> features.</para><para>For most installations, configuration is a matter of editing the
<filename moreinfo="none">/etc/mgetty/ mgetty.config</filename> file and adding
appropriate entries to the <filename moreinfo="none">/etc/inittab</filename> file to
execute <command moreinfo="none">mgetty</command> automatically.</para><para><xref linkend="x-087-2-serial.mgetty.conf"></xref> shows a very simple
<command moreinfo="none">mgetty</command> configuration file. This example configures
two serial devices. The first, <filename moreinfo="none">/dev/ttyS0</filename>,
supports a Hayes-compatible modem at 38,400 bps. The second,
<filename moreinfo="none">/dev/ttyS0</filename>, supports a directly connected VT100
terminal at 19,200 bps.</para><para><example id="x-087-2-serial.mgetty.conf"><title>Sample /etc/mgetty/mgetty.config File</title><screen format="linespecific">#
# mgetty configuration file
#
# this is a sample configuration file, see mgetty.info for details
#
# comment lines start with a "#", empty lines are ignored
#
# ----- global section -----
#
# In this section, you put the global defaults, per-port stuff is below
#
# access the modem(s) with 38400 bps
speed 38400
#
# set the global debug level to "4" (default from policy.h)
debug 4
#

# ----- port specific section -----
# 
# Here you can put things that are valid only for one line, not the others
#
#
# Hayes modem connected to ttyS0: don't do fax, less logging
#
port ttyS0
  debug 3
  data-only y
#
# direct connection of a VT100 terminal which doesn't like DTR drops
#
port ttyS1
  direct y
  speed 19200
  toggle-dtr n
#</screen></example></para><para>The configuration file supports global and port-specific options.
In our example we used a global option to set the speed to 38,400 bps. This
value is inherited by the <filename moreinfo="none">ttyS0</filename> port. Ports we apply
<command moreinfo="none">mgetty</command> to use this speed setting unless it is
overwritten by a port-specific speed setting, as we have done in the
<filename moreinfo="none">ttyS1</filename> configuration.</para><para>The <literal moreinfo="none">debug</literal> keyword controls the verbosity of
<command moreinfo="none">mgetty</command> logging. The <literal moreinfo="none">data-only</literal>
keyword in the <filename moreinfo="none">ttyS0</filename> configuration causes
<command moreinfo="none">mgetty</command> to ignore any modem fax features, to operate
just as a data modem. The <literal moreinfo="none">direct</literal> keyword in the
<filename moreinfo="none">ttyS1</filename> configuration instructs
<command moreinfo="none">mgetty</command> not to attempt any modem initialization on
the port. Finally, the <literal moreinfo="none">toggle-dtr</literal> keyword instructs
<command moreinfo="none">mgetty</command> not to attempt to hang up the line by
dropping the DTR (Data Terminal Ready) pin on the serial interface;
some terminals don't like this to happen.</para><para>You can also choose to leave the <filename moreinfo="none">mgetty.config</filename>
file empty and use command-line arguments to specify most of the same
parameters. The documentation accompanying the application includes a
complete description of the <command moreinfo="none">mgetty</command> configuration
file parameters and command-line arguments. See the following example.</para><para>We need to add two entries to the <filename moreinfo="none">/etc/inittab</filename>
file to activate this configuration. The <filename moreinfo="none">inittab</filename>
file is the configuration file of the Unix System V
<command moreinfo="none">init</command> command. The <command moreinfo="none">init</command> command
is responsible for system initialization; it provides a means of
automatically executing programs at boot time and re-executing them
when they terminate. This is ideal for the goals of running a
<command moreinfo="none">getty</command> program.</para><para><screen format="linespecific">T0:23:respawn:/sbin/mgetty ttyS0
T1:23:respawn:/sbin/mgetty ttyS1</screen></para><para>Each line of the <filename moreinfo="none">/etc/inittab</filename> file contains four
fields, separated by colons. The first field is an identifier that
uniquely labels an entry in the file; traditionally it is two
characters, but modern versions allow four. The second field is the
list of run levels at which this entry should be active. A run level
is a means of providing alternate machine configurations and is
implemented using trees of startup scripts stored in directories
called <filename moreinfo="none">/etc/rc1.d</filename>,
<filename moreinfo="none">/etc/rc2.d</filename>, etc. This feature is typically
implemented very simply, and you should model your entries on others
in the file or refer to your system documentation for more
information. The third field describes when to take action. For the
purposes of running a <command moreinfo="none">getty</command> program, this field
should be set to <literal moreinfo="none">respawn</literal>, meaning that the command
should be re-executed automatically when it dies. There are several
other options, as well, but they are not useful for our purposes
here. The fourth field is the actual command to execute; this is where
we specify the <command moreinfo="none">mgetty</command> command and any arguments we
wish to pass it. In our simple example we're starting and restarting
<command moreinfo="none">mgetty</command> whenever the system is operating at either
of run levels two or three, and are supplying as an argument just the
name of the device we wish it to use.  The <command moreinfo="none">mgetty</command>
command assumes the <filename moreinfo="none">/dev/</filename>, so we don't need to
supply it.</para><para>This chapter was a quick introduction to <command moreinfo="none">mgetty</command>
and how to offer login prompts to serial devices. You can find more
extensive information in the Serial-HOWTO.</para><para>After you've edited the configuration files, you need to reload
<command moreinfo="none">init</command> to make the changes take effect. Simply send a
hangup signal to the <command moreinfo="none">init</command> process; it always has a
process ID of one, so you can use the following command safely:</para><screen format="linespecific"># <userinput moreinfo="none">kill -HUP 1</userinput></screen></sect2><indexterm significance="normal" class="endofrange" startref="ch04.serdev.setup"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-tty-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-deviceserial-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-hardwareserial-1"></indexterm></sect1></chapter><chapter id="x-087-2-iface"><title>Configuring <?lb?>TCP/IP Networking</title><para><indexterm significance="normal"><primary>bootup sequence</primary></indexterm>
<indexterm significance="normal"><primary>initializing networking</primary></indexterm>
<indexterm significance="normal"><primary>networks</primary><secondary>booting</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="chtc.tcpip.config.netwks"><primary>TCP/IP (Transmission Control Protocol/Internet Protocol)</primary><secondary>configuring networks</secondary></indexterm> 
In this chapter, we walk you through all the necessary steps to set up
TCP/IP networking on your machine. Starting with the assignment of IP
addresses, we slowly work our way through the configuration of TCP/IP
network interfaces and introduce a few tools that come in handy when
hunting down network installation problems.</para><para>Most of the tasks covered in this chapter will generally have to be
done only once. Afterward, you have to touch most configuration files
only when adding a new system to your network or when you reconfigure
your system entirely. Some of the commands used to configure TCP/IP,
however, have to be executed each time the system is booted. This is
usually done by invoking them from the system
<filename moreinfo="none">/etc/rc*</filename> scripts.</para><para><indexterm significance="normal"><primary>rc script</primary></indexterm>
Commonly, the network-specific part of this procedure is contained in
a script. The name of this script varies in different Linux
distributions. In many older Linux distributions, it is known as
<filename moreinfo="none">rc.net</filename> or <filename moreinfo="none">rc.inet</filename>. Sometimes
you will also see two scripts named <filename moreinfo="none">rc.inet1</filename> and
<filename moreinfo="none">rc.inet2</filename>; the former initializes the
kernel part of networking and the latter starts basic networking
services and applications. In modern distributions, the
<filename moreinfo="none">rc</filename> files are structured in a more sophisticated
arrangement; here you may find scripts in the
<filename moreinfo="none">/etc/init.d/</filename> (or
<filename moreinfo="none">/etc/rc.d/init.d/</filename>) directory that create
the network devices and other <filename moreinfo="none">rc</filename> files that run
the network application programs. This book's examples are based on
the latter arrangement.</para><para>This chapter discusses parts of the script that configure your network
interfaces, while applications will be covered in later chapters.
After finishing this chapter, you should have established a sequence
of commands that properly configure TCP/IP networking on your
computer. You should then replace any sample commands in your
configuration scripts with your commands, make sure the script is
executed from the basic <filename moreinfo="none">rc</filename> script at startup
time, and reboot your machine. The networking <filename moreinfo="none">rc</filename>
scripts that come along with your favorite Linux distribution should
provide a solid example from which to work.</para><sect1 id="x-087-2-iface.procfs"><title>Mounting the /proc Filesystem</title><indexterm significance="normal"><primary>mounting</primary><secondary>the proc filesystem</secondary></indexterm><indexterm significance="normal"><primary>proc filesystem, mounting</primary></indexterm><para>Some of the configuration tools of the Linux NET-2 and NET-3 release
rely on the <filename moreinfo="none">/proc</filename> filesystem for communicating
with the kernel. This interface permits access to kernel runtime
information through a filesystem-like mechanism. When mounted, you can
list its files like any other filesystem, or display their contents.
Typical items include the <filename moreinfo="none">loadavg</filename> file, which
contains the system load average, and <filename moreinfo="none">meminfo</filename>,
which shows current core memory and swap usage.</para><para><indexterm significance="normal"><primary sortas="proc/net file">/proc/net file</primary></indexterm>
To this, the networking code adds the <filename moreinfo="none">net</filename> directory.
It contains a number of files that show things like the kernel ARP tables,
the state of TCP connections, and the routing tables. Most network
administration tools get their information from these files.</para><para><indexterm significance="normal"><primary sortas="etc/fstab file">/etc/fstab file</primary></indexterm>
The <filename moreinfo="none">proc</filename> filesystem (or <filename moreinfo="none">procfs</filename>, as
it is also known) is usually mounted on <filename moreinfo="none">/proc</filename> at system
boot time. The best method is to add the following line to
<filename moreinfo="none">/etc/fstab</filename>:

<screen format="linespecific"># procfs mount point:
none		/proc		proc	defaults</screen>

Then execute <command moreinfo="none">mount /proc</command> from your
<filename moreinfo="none">/etc/rc</filename> script.</para><para>The <filename moreinfo="none">procfs</filename> is now configured into most kernels by
default. If the <filename moreinfo="none">procfs</filename> is not in your kernel, you
will get a message such as: <literal moreinfo="none">mount: fs type procfs not
supported by kernel</literal>. You will then have to recompile the
kernel and answer yes when asked for
<filename moreinfo="none">procfs</filename> support.</para></sect1><sect1 id="x-087-2-iface.binaries"><title>Installing the Binaries</title><indexterm significance="normal"><primary>installing</primary><secondary>network binaries</secondary></indexterm><indexterm significance="normal"><primary>binaries, installing</primary></indexterm><para>If you are using one of the prepackaged Linux distributions, it will
contain the major networking applications and utilities along with a
coherent set of sample files. The only case in which you might have to
obtain and install new utilities is when you install a new kernel
release. As they occasionally involve changes in the kernel networking
layer, you will need to update the basic configuration tools. This
update at least involves recompiling, but sometimes you may also be
required to obtain the latest set of binaries. These binaries are
available at their official home site at <emphasis>ftp.inka.de/pub/comp/Linux/networking/NetTools/</emphasis>,
packaged in an archive called
<filename moreinfo="none">net-tools-XXX.tar.gz</filename>, where
<filename moreinfo="none">XXX</filename> is the version number. The release matching
Linux 2.0 is <filename moreinfo="none">net-tools-1.45</filename>.</para><para>If you want to compile and install the standard TCP/IP network applications
yourself, you can obtain the sources from most Linux FTP servers. All modern
Linux distributions include a fairly comprehensive range of TCP/IP network
applications, such as World Wide Web browsers, <command moreinfo="none">telnet</command> and
<command moreinfo="none">ftp</command> programs, and other network applications, such as
<command moreinfo="none">talk</command>. If you do find something that you do need to compile
yourself, the chances are good that it will compile under Linux from
source quite simply if you follow the instructions included in the source
package.</para></sect1><sect1 id="x-087-2-iface.hostname"><title>Setting the Hostname</title><indexterm significance="normal"><primary>hostname</primary><secondary>setting</secondary></indexterm><indexterm significance="normal"><primary>configuring</primary><secondary>hostname</secondary></indexterm><indexterm significance="normal"><primary>setting</primary><secondary>hostname</secondary></indexterm><para>Most, if not all, network applications rely on you to set the local
host's name to some reasonable value. This setting is usually made
during the boot procedure by executing the <command moreinfo="none">hostname</command>
command. To set the hostname to <replaceable>name</replaceable>, enter:

<screen format="linespecific"># <userinput moreinfo="none">hostname</userinput> <replaceable>name</replaceable></screen></para><para>It is common practice to use the unqualified hostname without
specifying the domain name. For instance, hosts at the Virtual Brewery
(described in <xref linkend="x-087-2-appendix.brewery"></xref>) might be
called <systemitem moreinfo="none" role="sitename">vale.vbrew.com</systemitem> or
<systemitem moreinfo="none" role="sitename">vlager.vbrew.com</systemitem>. These are
their official <emphasis>fully qualified domain names</emphasis>
(FQDNs). Their local hostnames would be the first component of the
name, such as <systemitem moreinfo="none" role="sitename">vale</systemitem>. However,
as the local hostname is frequently used to look up the host's IP
address, you have to make sure that the resolver library is able to
look up the host's IP address. This usually means that you have to
enter the name in <filename moreinfo="none">/etc/hosts</filename>.</para><para><indexterm significance="normal"><primary>domains</primary><secondary>names</secondary><tertiary>NIS versus DNS</tertiary></indexterm>
<indexterm significance="normal"><primary>domainname command</primary></indexterm>
<indexterm significance="normal"><primary>setting</primary><secondary>domain name</secondary></indexterm>
Some people suggest using the <command moreinfo="none">domainname</command> command to
set the kernel's idea of a domain name to the remaining part of the
FQDN. This way you could combine the output from
<command moreinfo="none">hostname</command> and <command moreinfo="none">domainname</command> to get
the FQDN again. However, this is at best only half
correct. <command moreinfo="none">domainname</command> is generally used to set the
host's NIS domain, which may be entirely different from the DNS domain
to which your host belongs. Instead, to ensure that the short form of
your hostname is resolvable with all recent versions of the
<command moreinfo="none">hostname</command> command, either add it as an entry in your
local Domain Name Server or place the fully qualified domain name in
the <filename moreinfo="none">/etc/hosts</filename> file. You may then use the
<parameter moreinfo="none">--fqdn</parameter> argument to the
<command moreinfo="none">hostname</command> command, and it will print the fully
qualifed domain name.</para></sect1><sect1 id="x-087-2-iface.addresses"><title>Assigning IP Addresses</title><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>addresses</secondary><tertiary>assigning</tertiary></indexterm><indexterm significance="normal"><primary>addresses</primary><secondary>choosing (IP)</secondary></indexterm><indexterm significance="normal"><primary>choosing</primary><secondary>IP addresses</secondary></indexterm><indexterm significance="normal"><primary>private IP addresses</primary></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>addresses</secondary><tertiary>private</tertiary></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>IP address</secondary></indexterm><para>If you configure the networking software on your host for standalone
operation (for instance, to be able to run the INN Netnews software),
you can safely skip this section, because the only IP address
you will need is for the loopback interface, which is always
<systemitem moreinfo="none" role="sitename">127.0.0.1</systemitem>.</para><para>Things are a little more complicated with real networks like Ethernets.
If you want to connect your host to an existing network, you have to ask
its administrators to give you an IP address on this network.  When
setting up a network all by yourself, you have to assign IP addresses
yourself.</para><para>Hosts within a local network should usually share addresses from the
same logical IP network. Hence, you have to assign an IP network address.
If you have several physical networks, you have to either assign them
different network numbers, or use subnetting to split your IP address
range into several subnetworks. Subnetting will be revisited in the
next section, <xref linkend="x-087-2-create.subnets"></xref>.</para><para>When picking an IP network number, much depends on whether you intend
to get on the Internet in the near future. If so, you should obtain an
official IP address <emphasis>now</emphasis>. Ask your network service
provider to help you. If you want to obtain a network number, just in
case you might get on the Internet someday, request a Network Address
Application Form from <systemitem moreinfo="none" role="emailaddr">hostmaster@internic.net</systemitem>, or your
country's own Network Information Center, if there is one.</para><para>If your network is not connected to the Internet and won't be in the
near future, you are free to choose any legal network address. Just
make sure no packets from your internal network escape to the real
Internet. To make sure no harm can be done even if packets
<emphasis>did</emphasis> escape, you should use one of the network
numbers reserved for private use. The Internet Assigned Numbers
Authority (IANA) has set aside several network numbers from classes A,
B, and C that you can use without registering. These addresses are
valid only within your private network and are not routed between real
Internet sites. The numbers are defined by RFC 1597 and are listed in
<xref linkend="x-087-2-issues.reserved.addresses"></xref> in <xref linkend="x-087-2-issues"></xref>. Note that the second and third blocks
contain 16 and 256 networks, respectively.</para><para>Picking your addresses from one of these network numbers is not
only useful for networks completely unconnected to the Internet; you can
still implement a slightly more restricted access using a single
host as a gateway. To your local network, the gateway is accessible by its
internal IP address, while the outside world knows it by an officially
registered address (assigned to you by your provider). We come back to
this concept in connection with the IP masquerade facility in
<xref linkend="x-087-2-ipmasq"></xref>.</para><para>Throughout the remainder of the book, we will assume that the brewery's
network manager uses a class B network number, say
<systemitem moreinfo="none" role="sitename">172.16.0.0</systemitem>. Of course, a class C
network number would definitely suffice to accommodate both the Brewery's and
the Winery's networks. We'll use a class B network here for the sake of
simplicity; it will make the subnetting examples in the next section
of this chapter a little more intuitive.</para></sect1><sect1 id="x-087-2-create.subnets"><title>Creating Subnets</title><indexterm significance="normal"><primary>creating</primary><secondary>subnets</secondary></indexterm><indexterm significance="normal"><primary>subnets</primary><secondary>DNS, creating</secondary></indexterm><indexterm significance="normal"><primary>interfaces</primary><secondary>netmask</secondary></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>netmask</secondary></indexterm><para>To operate several Ethernets (or other networks, once a driver is
available), you have to split your network into subnets. Note that
subnetting is required only if you have more than one
<emphasis>broadcast network</emphasis>point-to-point links
don't count. For instance, if you have one Ethernet, and one or more
SLIP links to the outside world, you don't need to subnet your
network. This is explained in more detail in <xref linkend="x-087-2-slip"></xref>.</para><para>To accommodate the two Ethernets, the Brewery's network manager decides
to use 8 bits of the host part as additional subnet bits. This
leaves another 8 bits for the host part, allowing for 254 hosts on
each of the subnets. She then assigns subnet number 1 to the brewery,
and gives the winery number 2. Their respective network addresses are
thus <systemitem moreinfo="none" role="sitename">172.16.1.0</systemitem> and
<systemitem moreinfo="none" role="sitename">172.16.2.0</systemitem>. The subnet mask is
<systemitem moreinfo="none" role="sitename">255.255.255.0</systemitem>.</para><para><systemitem moreinfo="none" role="sitename">vlager</systemitem>, which is the gateway between
the two networks, is assigned a host number of 1 on both of them, which gives
it the IP addresses <systemitem moreinfo="none" role="sitename">172.16.1.1</systemitem> and
<systemitem moreinfo="none" role="sitename">172.16.2.1</systemitem>, respectively.</para><para>Note that in this example we are using a class B network to keep things
simple, but a class C network would be more realistic. With the new networking
code, subnetting is not limited to byte boundaries, so even a class C
network may be split into several subnets. For instance, you could use two
bits of the host part for the netmask, giving you 4 possible subnets
with 64 hosts on each.<footnote id="x-087-2-fntc02"><para>The first number on each subnet is the subnetwork address, and the last number
on each subnet is reserved as the broadcast address, so it's actually 62 hosts
per subnet.</para></footnote></para></sect1><sect1 id="x-087-2-iface.simple-resolv"><title>Writing hosts and networks Files</title><indexterm significance="normal"><primary>configuring</primary><secondary>hostname</secondary><tertiary>resolution</tertiary></indexterm><indexterm significance="normal"><primary>hosts file</primary></indexterm><indexterm significance="normal"><primary sortas="etc/hosts file">/etc/hosts file</primary></indexterm><indexterm significance="normal"><primary>hostname</primary><secondary>resolution</secondary></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>names of</secondary></indexterm><indexterm significance="normal"><primary>hosts file</primary></indexterm><para>After you have subnetted your network, you should prepare for some simple
sort of hostname resolution using the <filename moreinfo="none">/etc/hosts</filename> file.
If you are not going to use DNS or NIS for address resolution, you have to put
all hosts in the <filename moreinfo="none">hosts</filename> file.</para><para>Even if you want to run DNS or NIS during normal operation, you should
have some subset of all hostnames in
<filename moreinfo="none">/etc/hosts</filename>. You should have some sort of name
resolution, even when no network interfaces are running, for example,
during boot time. This is not only a matter of convenience, but it
allows you to use symbolic hostnames in your network
<filename moreinfo="none">rc</filename> scripts. Thus, when changing IP addresses, you
only have to copy an updated <filename moreinfo="none">hosts</filename> file to all
machines and reboot, rather than edit a large number of
<filename moreinfo="none">rc</filename> files separately. Usually you put all local
hostnames and addresses in <filename moreinfo="none">hosts</filename>, adding those of
any gateways and NIS servers used.<footnote id="x-087-2-fntc03"><para>You need the address of an NIS server only if you use Peter Eriksson's
NYS. Other NIS implementations locate their servers only at runtime by
using <command moreinfo="none">ypbind</command>.</para></footnote></para><para>You should make sure your resolver only uses information from the
<filename moreinfo="none">hosts</filename> file during initial testing. Sample files
that come with your DNS or NIS software may produce strange
results. To make all applications use <filename moreinfo="none">/etc/hosts</filename>
exclusively when looking up the IP address of a host, you have to edit
the <filename moreinfo="none">/etc/host.conf</filename> file. Comment out any lines
that begin with the keyword <systemitem moreinfo="none" role="keyword">order</systemitem> by preceding them with a hash sign,
and insert the line:

<screen format="linespecific">order hosts</screen></para><para>The configuration of the resolver library is covered in detail in
<xref linkend="x-087-2-resolv"></xref>.</para><para>The <filename moreinfo="none">hosts</filename> file contains one entry per line, consisting
of an IP address, a hostname, and an optional list of aliases for the
hostname. The fields are separated by spaces or tabs, and the address
field must begin in the first column. Anything following a hash sign (#) is
regarded as a comment and is ignored.</para><para>Hostnames can be either fully qualified or relative to the local domain.
For <systemitem moreinfo="none" role="sitename">vale</systemitem>, you would usually enter the
fully qualified name, <systemitem moreinfo="none" role="sitename">vale.vbrew.com</systemitem>,
and <systemitem moreinfo="none" role="sitename">vale</systemitem> by itself in the
<filename moreinfo="none">hosts</filename> file, so that it is known by both its official name
and the shorter local name.</para><para>This is an example how a <filename moreinfo="none">hosts</filename> file at the Virtual
Brewery might look. Two special names are included,
<systemitem moreinfo="none" role="sitename">vlager-if1</systemitem> and
<systemitem moreinfo="none" role="sitename">vlager-if2</systemitem>, which give the addresses
for both interfaces used on <systemitem moreinfo="none" role="sitename">vlager</systemitem>:</para><para><screen format="linespecific">#
# Hosts file for Virtual Brewery/Virtual Winery
#
# IP            FQDN                 aliases
#
127.0.0.1       localhost
#
172.16.1.1      vlager.vbrew.com      vlager vlager-if1
172.16.1.2      vstout.vbrew.com      vstout
172.16.1.3      vale.vbrew.com        vale
#
172.16.2.1      vlager-if2
172.16.2.2      vbeaujolais.vbrew.com vbeaujolais
172.16.2.3      vbardolino.vbrew.com  vbardolino
172.16.2.4      vchianti.vbrew.com    vchianti</screen></para><para><indexterm significance="normal"><primary>networks file</primary></indexterm>
<indexterm significance="normal"><primary sortas="etc/networks file">/etc/networks file</primary></indexterm>
Just as with a host's IP address, you should sometimes use a symbolic
name for network numbers, too. Therefore, the
<filename moreinfo="none">hosts</filename> file has a companion called
<filename moreinfo="none">/etc/networks</filename> that maps network names to network
numbers, and vice versa. At the Virtual Brewery, we might install a
<filename moreinfo="none">networks</filename> file like this:<footnote id="x-087-2-fntc04"><para> Note that names in
<filename moreinfo="none">networks</filename> must not collide with hostnames from the
<filename moreinfo="none">hosts</filename> file, or else some programs may produce
strange results.</para></footnote>

<screen format="linespecific"># /etc/networks for the Virtual Brewery
brew-net      172.16.1.0
wine-net      172.16.2.0</screen></para></sect1><sect1 id="x-087-2-iface.interface"><title>Interface Configuration for IP</title><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>interface</secondary><tertiary>configuration</tertiary></indexterm><indexterm significance="normal"><primary>interfaces</primary><secondary>configuration of</secondary></indexterm><indexterm significance="normal"><primary>configuring</primary><secondary>networks</secondary><tertiary>interfaces</tertiary></indexterm><indexterm significance="normal"><primary>ifconfig command</primary></indexterm><para>After setting up your hardware as explained in <xref linkend="x-087-2-serial"></xref>, you have to make these devices known to the
kernel networking software. A couple of commands are used to configure
the network interfaces and initialize the routing table. These tasks
are usually performed from the network initialization script each time
you boot the system. The basic tools for this process are called
<command moreinfo="none">ifconfig</command> (where if stands for
interface) and <command moreinfo="none">route</command>.</para><para><command moreinfo="none">ifconfig</command> is used to make an interface accessible to
the kernel networking layer. This involves the assignment of an IP
address and other parameters, and activation of the interface, also
known as bringing up the interface. Being active here
means that the kernel will send and receive IP datagrams through the
interface. The simplest way to invoke it is with:

<screen format="linespecific">ifconfig <replaceable>interface</replaceable> <replaceable>ip-address</replaceable></screen></para><para>This command assigns <replaceable>ip-address</replaceable> to
<replaceable>interface</replaceable> and activates it. All other
parameters are set to default values. For instance, the default
network mask is derived from the network class of the IP address, such
as <systemitem moreinfo="none" role="sitename">255.255.0.0</systemitem> for a class B
address.  <command moreinfo="none">ifconfig</command> is described in detail in the
section <xref linkend="x-087-2-iface.ifconfig"></xref>.</para><indexterm significance="normal"><primary>route command</primary></indexterm><para><command moreinfo="none">route</command> allows you to add or remove routes from the kernel
routing table. It can be invoked as:

<screen format="linespecific">route [add|del] [-net|-host] <replaceable>target</replaceable> [<replaceable>if</replaceable>]</screen></para><para>The <option>add</option> and <option>del</option> arguments determine
whether to add or delete the route to
<replaceable>target</replaceable>. The <option>-net</option> and
<option>-host</option> arguments tell the route command whether the
target is a network or a host (a host is assumed if you don't
specify). The <option>if</option> argument is again optional, and
allows you to specify to which network interface the route should be
directedthe Linux kernel makes a sensible guess if you don't
supply this information. This topic will be explained in more detail
in succeeding sections.</para><sect2 id="x-087-2-iface.interface.loopback"><title>The Loopback Interface</title><indexterm significance="normal"><primary>configuring</primary><secondary>loopback interface device</secondary></indexterm><indexterm significance="normal"><primary>loopback</primary><secondary>interface device</secondary><tertiary>configuring</tertiary></indexterm><indexterm significance="normal"><primary>interfaces</primary><secondary>loopback</secondary></indexterm><indexterm significance="normal"><primary>lo (loopback interface)</primary></indexterm><para>The very first interface to be activated is the loopback interface:

<screen format="linespecific"># <userinput moreinfo="none">ifconfig lo 127.0.0.1</userinput></screen></para><para><indexterm significance="normal"><primary>localhost (dummy hostname)</primary></indexterm>
Occasionally, you will see the dummy hostname
<systemitem moreinfo="none" role="sitename">localhost</systemitem> being used instead of the
IP address. <command moreinfo="none">ifconfig</command> will look up the name in the
<filename moreinfo="none">hosts</filename> file, where an entry should declare
it as the hostname for <systemitem moreinfo="none" role="sitename">127.0.0.1</systemitem>:

<screen format="linespecific"># Sample /etc/hosts entry for localhost
localhost     127.0.0.1</screen></para><para><indexterm significance="normal"><primary>checking</primary><secondary>network</secondary><tertiary>interface</tertiary></indexterm>
To view the configuration of an interface, you invoke
<command moreinfo="none">ifconfig</command>, giving it only the interface name as argument:

<screen format="linespecific">$ <userinput moreinfo="none">ifconfig lo</userinput>
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:3924  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          Collisions:0 </screen></para><para>As you can see, the loopback interface has been assigned a netmask
of <systemitem moreinfo="none" role="sitename">255.0.0.0</systemitem>, since
<systemitem moreinfo="none" role="sitename">127.0.0.1</systemitem> is a class A address.</para><para>Now you can almost start playing with your mini-network. What is still
missing is an entry in the routing table that tells IP that it may use
this interface as a route to destination <systemitem moreinfo="none" role="sitename">127.0.0.1</systemitem>. This is accomplished by using:

<screen format="linespecific"># route add 127.0.0.1</screen></para><para>Again, you can use <systemitem moreinfo="none" role="sitename">localhost</systemitem> instead
of the IP address, provided you've entered it into your
<filename moreinfo="none">/etc/hosts</filename>.</para><para><indexterm significance="normal"><primary>testing</primary><secondary>network configuration</secondary></indexterm>
<indexterm significance="normal"><primary>checking</primary><secondary>network</secondary><tertiary>configuration</tertiary></indexterm>
<indexterm significance="normal"><primary>checking</primary><secondary>reachabilty</secondary></indexterm>
<indexterm significance="normal"><primary>reaching a host</primary></indexterm>
<indexterm significance="normal"><primary>round-trip time (IP)</primary></indexterm>
<indexterm significance="normal"><primary>ping command</primary></indexterm>
Next, you should check that everything works fine, for example by using
<command moreinfo="none">ping</command>. <command moreinfo="none">ping</command> is the networking equivalent
of a sonar device.<footnote id="x-087-2-fntc05"><para>Anyone remember Pink Floyd's Echoes?</para></footnote> The command is used to verify that a given address is
actually reachable, and to measure the delay that occurs when sending
a datagram to it and back again. The time required for this process is
often referred to as the round-trip time:</para><para><screen format="linespecific"># <userinput moreinfo="none">ping localhost</userinput>
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=0.4 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=255 time=0.4 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=255 time=0.4 ms
^C
--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.4/0.4/0.4 ms
#</screen></para><para>When you invoke <command moreinfo="none">ping</command> as shown here, it will
continue emitting packets forever, unless interrupted by the user. The
<literal moreinfo="none">^C</literal> marks the place where we pressed Ctrl-C.</para><para>The previous example shows that packets for <systemitem moreinfo="none" role="sitename">127.0.0.1</systemitem> are properly delivered and a
reply is returned to <command moreinfo="none">ping</command> almost instantaneously.
This shows that you have successfully set up your first network
interface.</para><para><indexterm significance="normal"><primary>Network Unreachable error message</primary></indexterm>
<indexterm significance="normal"><primary>networks</primary><secondary>unreachable</secondary></indexterm>
If the output you get from <command moreinfo="none">ping</command> does not resemble
that shown in the previous example, you are in trouble. Check any
errors if they indicate that some file hasn't been installed
properly. Check that the <command moreinfo="none">ifconfig</command> and
<command moreinfo="none">route</command> binaries you use are compatible with the
kernel release you run, and above all, that the kernel has been
compiled with networking enabled (you see this from the presence of
the <filename moreinfo="none">/proc/net</filename> directory). If you get an error
message saying Network unreachable, you probably got the
<command moreinfo="none">route</command> command wrong. Make sure you use the same
address you gave to <command moreinfo="none">ifconfig</command>.</para><para><indexterm significance="normal"><primary>networks</primary><secondary>initialization scripts</secondary></indexterm>
The steps previously described are enough to use networking
applications on a standalone host. After adding the lines mentioned
earlier to your network initialization script and making sure it will
be executed at boot time, you may reboot your machine and try out
various applications. For instance, <command moreinfo="none">telnet
localhost</command> should establish a <command moreinfo="none">telnet</command>
connection to your host, giving you a <literal moreinfo="none">login:</literal>
prompt.</para><para>However, the loopback interface is useful not only as an example in
networking books, or as a test bed during development, but is actually
used by some applications during normal operation.<footnote id="x-087-2-fntc06"><para> For example, all applications based on RPC
use the loopback interface to register themselves with the
<command moreinfo="none">portmapper</command> daemon at startup. These applications
include NIS and NFS.</para></footnote>
Therefore, you always have to configure it, regardless of whether your machine
is attached to a network or not.</para></sect2><sect2 id="x-087-2-iface.interface.ethernet"><title>Ethernet Interfaces</title><indexterm significance="normal"><primary>configuring</primary><secondary>Ethernet</secondary></indexterm><indexterm significance="normal"><primary>Ethernet</primary><secondary>configurating interface</secondary></indexterm><indexterm significance="normal"><primary>interfaces</primary><secondary>Ethernet</secondary></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>netmask</secondary></indexterm><indexterm significance="normal"><primary>interfaces</primary><secondary>netmask</secondary></indexterm><indexterm significance="normal"><primary>eth0 (Ethernet interface)</primary></indexterm><indexterm significance="normal"><primary>addresses</primary><secondary>broadcast</secondary></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>broadcast address</secondary></indexterm><para>Configuring an Ethernet interface is pretty much the same as the
loopback interface; it just requires a few more parameters when you are
using subnetting. </para><indexterm significance="normal"><primary>ifconfig command</primary></indexterm><para>At the Virtual Brewery, we have subnetted the IP network, which was
originally a class B network, into class C subnetworks. To make the
interface recognize this, the <command moreinfo="none">ifconfig</command> incantation
would look like this:

<screen format="linespecific"># <userinput moreinfo="none">ifconfig eth0 vstout netmask 255.255.255.0</userinput></screen></para><para>This command assigns the <filename moreinfo="none">eth0</filename> interface the IP
address of <systemitem moreinfo="none" role="sitename">vstout</systemitem>
(<systemitem moreinfo="none" role="sitename">172.16.1.2</systemitem>). If we omitted
the netmask, <command moreinfo="none">ifconfig</command> would deduce the netmask from
the IP network class, which would result in an incorrect netmask of
<systemitem moreinfo="none" role="sitename">255.255.0.0</systemitem>. Now a quick
check shows:

<screen format="linespecific"># <userinput moreinfo="none">ifconfig eth0</userinput>
eth0      Link encap 10Mps Ethernet HWaddr  00:00:C0:90:B3:42
          inet addr 172.16.1.2 Bcast 172.16.1.255 Mask 255.255.255.0
          UP BROADCAST RUNNING  MTU 1500  Metric 1
          RX packets 0 errors 0 dropped 0 overrun 0
          TX packets 0 errors 0 dropped 0 overrun 0</screen></para><para>You can see that <command moreinfo="none">ifconfig</command> automatically sets the broadcast
address (the <systemitem moreinfo="none" role="keyword">Bcast</systemitem> field) to the
usual value, which is the host's network number with all the host bits set.
Also, the maximum transmission unit (the maximum size of IP datagrams the
kernel will generate for this interface) has been set to the maximum size of
Ethernet packets: 1,500 bytes. The defaults are usually what you will use, but
all these values can be overidden if required, with special options that will
be described under <xref linkend="x-087-2-iface.ifconfig"></xref>.</para><para><indexterm significance="normal"><primary>route command</primary></indexterm> 
Just as for the loopback interface, you now have to install a routing
entry that informs the kernel about the network that can be reached
through <filename moreinfo="none">eth0</filename>. For the Virtual Brewery, you might invoke
<command moreinfo="none">route</command> as:

<screen format="linespecific"># <userinput moreinfo="none">route add -net 172.16.1.0</userinput></screen></para><para>At first this looks a little like magic, because it's not really
clear how <command moreinfo="none">route</command> detects which interface to route through.
However, the trick is rather simple: the kernel checks all interfaces
that have been configured so far and compares the destination address
(<systemitem moreinfo="none" role="sitename">172.16.1.0</systemitem> in this case) to the
network part of the interface address (that is, the bitwise AND of the
interface address and the netmask). The only interface that matches is
<filename moreinfo="none">eth0</filename>.</para><para>Now, what's that <option>net</option> option for? This is used
because <command moreinfo="none">route</command> can handle both routes to networks
and routes to single hosts (as you saw before with <systemitem moreinfo="none" role="sitename">localhost</systemitem>). When given an address in
dotted quad notation, <command moreinfo="none">route</command> attempts to guess
whether it is a network or a hostname by looking at the host part
bits. If the address's host part is zero, <command moreinfo="none">route</command>
assumes it denotes a network; otherwise, <command moreinfo="none">route</command>
takes it as a host address. Therefore, <command moreinfo="none">route</command> would
think that <systemitem moreinfo="none" role="sitename">172.16.1.0</systemitem> is a
host address rather than a network number, because it cannot know that
we use subnetting. We have to tell <command moreinfo="none">route</command> explicitly
that it denotes a network, so we give it the
<option>net</option> flag.</para><para>Of course, the <command moreinfo="none">route</command> command is a little tedious to
type, and it's prone to spelling mistakes. A more convenient approach
is to use the network names we defined in
<filename moreinfo="none">/etc/networks</filename>.  This approach makes the command
much more readable; even the <option>net</option> flag can be
omitted because <command moreinfo="none">route</command> knows that <systemitem moreinfo="none" role="sitename">172.16.1.0</systemitem> denotes a network:

<screen format="linespecific"># <userinput moreinfo="none">route add brew-net</userinput></screen></para><para><indexterm significance="normal"><primary>testing</primary><secondary>network configuration</secondary></indexterm>
<indexterm significance="normal"><primary>checking</primary><secondary>network</secondary><tertiary>configuration</tertiary></indexterm>
<indexterm significance="normal"><primary>checking</primary><secondary>reachabilty</secondary></indexterm>
Now that you've finished the basic configuration steps, we want to
make sure that your Ethernet interface is indeed running
happily. Choose a host from your Ethernet, for instance <systemitem moreinfo="none" role="sitename">vlager</systemitem>, and type:

<screen format="linespecific"># <userinput moreinfo="none">ping vlager</userinput>
PING vlager: 64 byte packets
64 bytes from 172.16.1.1: icmp_seq=0. time=11. ms
64 bytes from 172.16.1.1: icmp_seq=1. time=7. ms
64 bytes from 172.16.1.1: icmp_seq=2. time=12. ms
64 bytes from 172.16.1.1: icmp_seq=3. time=3. ms
^C
----vstout.vbrew.com PING Statistics----
4 packets transmitted, 4 packets received, 0
round-trip (ms)  min/avg/max = 3/8/12</screen></para><para><indexterm significance="normal"><primary>netstat command</primary></indexterm>
If you don't see similar output, something is broken. If you encounter
unusual packet loss rates, this hints at a hardware problem, like bad
or missing terminators. If you don't receive any replies at all, you
should check the interface configuration with
<command moreinfo="none">netstat</command> described later in <xref linkend="x-087-2-iface.netstat"></xref>. The packet statistics displayed by
<command moreinfo="none">ifconfig</command> should tell you whether any packets have
been sent out on the interface at all. If you have access to the
remote host too, you should go over to that machine and check the
interface statistics. This way you can determine exactly where the
packets got dropped. In addition, you should display the routing
information with <command moreinfo="none">route</command> to see if both hosts have
the correct routing entry.  <command moreinfo="none">route</command> prints out the
complete kernel routing table when invoked without any arguments
(<option>n</option> just makes it print addresses as dotted
quad instead of using the hostname):

<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>routing</secondary><tertiary>table</tertiary></indexterm>
<indexterm significance="normal"><primary>displaying</primary><secondary>IP routing table</secondary></indexterm>
<indexterm significance="normal"><primary>checking</primary><secondary>IP routing table</secondary></indexterm>
<indexterm significance="normal"><primary>route command</primary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>routing</secondary><tertiary>table</tertiary></indexterm>

<screen format="linespecific"># <userinput moreinfo="none">route -n</userinput>
Kernel routing table
Destination  Gateway  Genmask         Flags Metric Ref Use    Iface
127.0.0.1    *        255.255.255.255 UH    1      0      112 lo
172.16.1.0   *        255.255.255.0   U     1      0       10 eth0</screen></para><para>The detailed meaning of these fields is explained later in <xref linkend="x-087-2-iface.netstat"></xref>." The <systemitem moreinfo="none" role="keyword">Flags</systemitem> column contains a list of flags set
for each interface. <systemitem moreinfo="none" role="keyword">U</systemitem> is
always set for active interfaces, and <systemitem moreinfo="none" role="keyword">H</systemitem> says the destination address denotes a
host. If the <systemitem moreinfo="none" role="keyword">H</systemitem> flag is set for
a route that you meant to be a network route, you have to reissue the
<command moreinfo="none">route</command> command with the <option>net</option>
option. To check whether a route you have entered is used at all,
check to see if the <systemitem moreinfo="none" role="keyword">Use</systemitem> field
in the second to last column increases between two invocations of
<command moreinfo="none">ping</command>.</para></sect2><sect2 id="x-087-2-iface.interface.gateway"><title>Routing Through a Gateway</title><indexterm significance="normal"><primary>routing</primary><secondary>IP</secondary><tertiary>gateways</tertiary></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>routing</secondary></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>gateways</secondary></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>subnets</secondary></indexterm><indexterm significance="normal"><primary>gateways</primary><secondary>routing networks through</secondary></indexterm><para>In the previous section, we covered only the case of setting up a host
on a single Ethernet. Quite frequently, however, one encounters
networks connected to one another by gateways. These gateways may
simply link two or more Ethernets, but may also provide a link to the
outside world, such as the Internet. In order to use a gateway, you
have to provide additional routing information to the networking
layer.</para><para>The Ethernets of the Virtual Brewery and the Virtual Winery are linked
through such a gateway, namely the host <systemitem moreinfo="none" role="sitename">vlager</systemitem>.  Assuming that <systemitem moreinfo="none" role="sitename">vlager</systemitem> has already been configured, we
just have to add another entry to <systemitem moreinfo="none" role="sitename">vstout</systemitem>'s routing table that tells the
kernel it can reach all hosts on the Winery's network through
<systemitem moreinfo="none" role="sitename">vlager</systemitem>. The appropriate
incantation of <command moreinfo="none">route</command> is shown below; the
<systemitem moreinfo="none" role="keyword">gw</systemitem> keyword tells it that the
next argument denotes a gateway:</para><para><screen format="linespecific"># <userinput moreinfo="none">route add wine-net gw vlager</userinput></screen></para><para>Of course, any host on the Winery network you wish to talk to must have
a routing entry for the Brewery's network. Otherwise you would only be able
to send data to the Winery network from the Brewery network, but the hosts on
the Winery would be unable to reply.</para><para>This example describes only a gateway that switches packets between
two isolated Ethernets. Now assume that <systemitem moreinfo="none" role="sitename">vlager</systemitem> also has a connection to the
Internet (say, through an additional SLIP link). Then we would want
datagrams to <emphasis>any</emphasis> destination network other than
the Brewery to be handed to <systemitem moreinfo="none" role="sitename">vlager</systemitem>.  This action can be accomplished
by making it the default gateway for <systemitem moreinfo="none" role="sitename">vstout</systemitem>:

<screen format="linespecific"># <userinput moreinfo="none">route add default gw vlager</userinput></screen></para><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>default route</secondary></indexterm>
<indexterm significance="normal"><primary>route, default</primary></indexterm>
The network name <systemitem moreinfo="none" role="sitename">default</systemitem> is a shorthand
for <systemitem moreinfo="none" role="sitename">0.0.0.0</systemitem>, which denotes the default
route. The default route matches every destination and will be used if there
is no more specific route that matches. You do not have to add this name to
<filename moreinfo="none">/etc/networks</filename> because it is built into
<command moreinfo="none">route</command>.</para><para>If you see high packet loss rates when pinging a host behind one or more
gateways, this may hint at a very congested network. Packet loss is not so
much due to technical deficiencies as to temporary excess loads on
forwarding hosts, which makes them delay or even drop incoming datagrams.</para></sect2><sect2 id="x-087-2-iface.interface.gateway-conf"><title>Configuring a Gateway</title><indexterm significance="normal"><primary>configuring</primary><secondary>IP gateways</secondary></indexterm><indexterm significance="normal"><primary>gateways</primary><secondary>configuring</secondary></indexterm><para>Configuring a machine to switch packets between two Ethernets is
pretty straightforward. Assume we're back at <systemitem moreinfo="none" role="sitename">vlager</systemitem>, which is equipped with two
Ethernet cards, each connected to one of the two networks. All you
have to do is configure both interfaces separately, giving them their
respective IP addresses and matching routes, and that's it.</para><para>It is quite useful to add information on the two interfaces to the
<filename moreinfo="none">hosts</filename> file as shown in the following example, so
we have handy names for them, too:

<screen format="linespecific">172.16.1.1      vlager.vbrew.com    vlager vlager-if1
172.16.2.1      vlager-if2</screen></para><para>The sequence of commands to set up the two interfaces is then:

<screen format="linespecific"># <userinput moreinfo="none">ifconfig eth0 vlager-if1</userinput>
# <userinput moreinfo="none">route add brew-net</userinput>
# <userinput moreinfo="none">ifconfig eth1 vlager-if2</userinput>
# <userinput moreinfo="none">route add wine-net</userinput></screen></para><para>If this sequence doesn't work, make sure your kernel has been compiled
with support for IP forwarding enabled. One good way to do this is to
ensure that the first number on the second line of
<filename moreinfo="none">/proc/net/snmp</filename> is set to <literal moreinfo="none">1</literal>.</para></sect2><sect2 id="x-087-2-iface.interface.plip"><title>The PLIP Interface</title><indexterm significance="normal"><primary>configuring</primary><secondary>PLIP</secondary></indexterm><indexterm significance="normal"><primary>interfaces</primary><secondary>PLIP</secondary></indexterm><indexterm significance="normal"><primary>point-to-point link</primary></indexterm><indexterm significance="normal"><primary>PLIP (Parallel Line IP) protocol</primary><secondary>interface</secondary></indexterm><para>A PLIP link used to connect two machines is a little different from an
Ethernet. PLIP links are an example of what are called
<emphasis>point-to-point</emphasis> links, meaning that there is a single
host at each end of the link. Networks like Ethernet are called
<emphasis>broadcast</emphasis> networks. Configuration of point-to-point links
is different because unlike broadcast networks, point-to-point links don't
support a network of their own.</para><para>PLIP provides very cheap and portable links between computers. As
an example, we'll consider the laptop computer of an employee at the Virtual
Brewery that is connected to <systemitem moreinfo="none" role="sitename">vlager</systemitem>
via PLIP. The laptop itself is called
<systemitem moreinfo="none" role="sitename">vlite</systemitem> and has only one parallel port.
At boot time, this port will be registered as <filename moreinfo="none">plip1</filename>. To
activate the link, you have to configure the <filename moreinfo="none">plip1</filename>
interface using the following commands:<footnote id="x-087-2-fntc07"><para>Note that <userinput moreinfo="none">pointopoint</userinput> is not a typo. It's really spelled like
this.</para></footnote>

<screen format="linespecific"># <userinput moreinfo="none">ifconfig plip1 vlite pointopoint vlager</userinput>
# <userinput moreinfo="none">route add default gw vlager</userinput></screen></para><para>The first command configures the interface, telling the kernel that this
is a point-to-point link, with the remote side having the address of
<systemitem moreinfo="none" role="sitename">vlager</systemitem>. The second installs the default
route, using <systemitem moreinfo="none" role="sitename">vlager</systemitem> as gateway.  On
<systemitem moreinfo="none" role="sitename">vlager</systemitem>, a similar
<command moreinfo="none">ifconfig</command> command is necessary to activate the link
(a <command moreinfo="none">route</command> invocation is not needed):

<screen format="linespecific"># <userinput moreinfo="none">ifconfig plip1 vlager pointopoint vlite</userinput></screen></para><para>Note that the <filename moreinfo="none">plip1</filename> interface on <systemitem moreinfo="none" role="sitename">vlager</systemitem> does not need a separate IP
address, but may also be given the address <systemitem moreinfo="none" role="sitename">172.16.1.1</systemitem>. Point-to-point networks don't
support a network directly, so the interfaces don't require an address
on any supported network. The kernel uses the interface information in
the routing table to avoid any possible confusion.<footnote id="x-087-2-fntc08"><para> As a matter of caution, you should
configure a PLIP or SLIP link only after you have completely set up
the routing table entries for your Ethernets. With some older kernels,
your network route might otherwise end up pointing at the
point-to-point link.</para></footnote></para><para><indexterm significance="normal"><primary>route command</primary></indexterm>
Now we have configured routing from the laptop to the Brewery's
network; what's still missing is a way to route from any of the
Brewery's hosts to <systemitem moreinfo="none" role="sitename">vlite</systemitem>. One
particularly cumbersome way is to add a specific route to every host's routing
table that names <systemitem moreinfo="none" role="sitename">vlager</systemitem> as a gateway
to <systemitem moreinfo="none" role="sitename">vlite</systemitem>:

<screen format="linespecific"># <userinput moreinfo="none">route add vlite gw vlager</userinput></screen></para><para><indexterm significance="normal"><primary>routing</primary><secondary>dynamic</secondary></indexterm>
<indexterm significance="normal"><primary>Routing Information Protocol (RIP)</primary></indexterm>
<indexterm significance="normal"><primary>RIP (Routing Information Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>gated command</primary></indexterm>
<indexterm significance="normal"><primary>ARP (Address Resolution Protocol)</primary><secondary>proxy</secondary></indexterm>
<indexterm significance="normal"><primary>proxy ARP</primary></indexterm>
Dynamic routing offers a much better option for temporary routes. You
could use <command moreinfo="none">gated</command>, a routing daemon, which you would
have to install on each host in the network in order to distribute
routing information dynamically.  The easiest option, however, is to
use <emphasis>proxy ARP</emphasis> (Address Resolution Protocol).
With proxy ARP, <systemitem moreinfo="none" role="sitename">vlager</systemitem> will
respond to any ARP query for <systemitem moreinfo="none" role="sitename">vlite</systemitem> by sending its own Ethernet
address. All packets for <systemitem moreinfo="none" role="sitename">vlite</systemitem> will wind up at <systemitem moreinfo="none" role="sitename">vlager</systemitem>, which then forwards them to the
laptop. We will come back to proxy ARP in the section <xref linkend="x-087-2-iface.verify.arp"></xref>.</para><para><indexterm significance="normal"><primary>plipconfig command</primary></indexterm>
Current <filename moreinfo="none">net-tools</filename> releases contain a tool called
<command moreinfo="none">plipconfig</command>, which allows you to set certain PLIP
timing parameters. The IRQ to be used for the printer port can be set using
the <command moreinfo="none">ifconfig</command> command.</para></sect2><sect2 id="x-087-2-iface.interface.slip"><title>The SLIP and PPP Interfaces</title><indexterm significance="normal"><primary>sl0 (SLIP interface)</primary></indexterm><indexterm significance="normal"><primary>ppp0 (PPP interface)</primary></indexterm><indexterm significance="normal"><primary>point-to-point link</primary></indexterm><indexterm significance="normal"><primary>configuring</primary><secondary>SLIP</secondary></indexterm><indexterm significance="normal"><primary>configuring</primary><secondary>PPP</secondary></indexterm><indexterm significance="normal"><primary>interfaces</primary><secondary>SLIP</secondary></indexterm><indexterm significance="normal"><primary>interfaces</primary><secondary>PPP</secondary></indexterm><indexterm significance="normal"><primary>SLIP (Serial Line IP) protocol</primary><secondary>interface</secondary></indexterm><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary></indexterm><para>Although SLIP and PPP links are only simple point-to-point links like
PLIP connections, there is much more to be said about them.  Usually,
establishing a SLIP connection involves dialing up a remote site
through your modem and setting the serial line to SLIP mode. PPP is
used in a similar fashion. We discuss SLIP and PPP in detail in
<xref linkend="x-087-2-slip"></xref> and <xref linkend="x-087-2-ppp"></xref>.</para></sect2><sect2 id="x-087-2-iface.interface.dummy"><title>The Dummy Interface</title><indexterm significance="normal"><primary>dummy interface configuration</primary></indexterm><indexterm significance="normal"><primary>interfaces</primary><secondary>dummy</secondary></indexterm><indexterm significance="normal"><primary>standalone host</primary></indexterm><indexterm significance="normal"><primary>hosts</primary><secondary>standalone</secondary></indexterm><para>The dummy interface is a little exotic, but rather useful
nevertheless. Its main benefit is with standalone hosts and machines
whose only IP network connection is a dialup link. In fact, the
latter are standalone hosts most of the time, too.</para><para>The dilemma with standalone hosts is that they only have a single
network device active, the loopback device, which is usually assigned
the address <systemitem moreinfo="none" role="sitename">127.0.0.1</systemitem>.  On
some occasions, however, you must send data to the
official IP address of the local host. For instance,
consider the laptop <systemitem moreinfo="none" role="sitename">vlite</systemitem>,
which was disconnected from a network for the duration of this
example. An application on <systemitem moreinfo="none" role="sitename">vlite</systemitem> may now want to send data to
another application on the same host. Looking up <systemitem moreinfo="none" role="sitename">vlite</systemitem> in <filename moreinfo="none">/etc/hosts</filename>
yields an IP address of <systemitem moreinfo="none" role="sitename">172.16.1.65</systemitem>, so the application tries to
send to this address. As the loopback interface is currently the only
active interface on the machine, the kernel has no idea that
<systemitem moreinfo="none" role="sitename">172.16.1.65</systemitem> actually refers
to itself! Consequently, the kernel discards the datagram and returns
an error to the application.</para><para>This is where the dummy device steps in. It solves the dilemma by
simply serving as the alter ego of the loopback interface.  In the
case of <systemitem moreinfo="none" role="sitename">vlite</systemitem>, you simply
give it the address <systemitem moreinfo="none" role="sitename">172.16.1.65</systemitem> and add a host route pointing
to it. Every datagram for <systemitem moreinfo="none" role="sitename">172.16.1.65</systemitem> is then delivered
locally. The proper invocation is:<footnote id="x-087-2-fntc09"><para>The dummy device is called <filename moreinfo="none">dummy0</filename> if you have
loaded it as a module rather than choosing it as an inbuilt kernel
option. This is because you are able to load multiple modules and have
more than one dummy device.</para></footnote>

<screen format="linespecific"># <userinput moreinfo="none">ifconfig dummy vlite</userinput>
# <userinput moreinfo="none">route add vlite</userinput></screen></para></sect2><sect2 id="x-087-2-iface.interface.alias"><title>IP Alias</title><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>alias configuration</secondary></indexterm><indexterm significance="normal"><primary>interfaces</primary><secondary>alias</secondary></indexterm><indexterm significance="normal"><primary>standalone host</primary></indexterm><indexterm significance="normal"><primary>hosts</primary><secondary>standalone</secondary></indexterm><indexterm significance="normal"><primary>hosts</primary><secondary>virtual</secondary></indexterm><para>New kernels support a feature that can completely replace the dummy
interface and serve other useful functions. <emphasis>IP
Alias</emphasis> allows you to configure multiple IP addresses onto a
physical device. In the simplest case, you could replicate the function
of the dummy interface by configuring the host address as an alias
onto the loopback interface and completely avoid using the dummy
interface. In more complex uses, you could configure your host to look
like many different hosts, each with its own IP address. This
configuration is sometimes called Virtual Hosting,
although technically it is also used for a variety of other
techniques.<footnote id="x-087-2-fntc10"><para> More correctly, using
IP aliasing is known as network layer virtual hosting. It is more
common in the WWW and STMP worlds to use application layer virtual
hosting, in which the same IP address is used for each virtual host,
but a different hostname is passed with each application layer
request. Services like FTP are not capable of operating in this way,
and they demand network layer virtual hosting.</para></footnote></para><para>To configure an alias for an interface, you must first ensure that
your kernel has been compiled with support for IP Alias (check that
you have a <filename moreinfo="none">/proc/net/ip_alias</filename> file; if not, you
will have to recompile your kernel). Configuration of an IP alias is
virtually identical to configuring a real network device; you use a
special name to indicate it's an alias that you want. For example:

<screen format="linespecific"># <userinput moreinfo="none">ifconfig lo:0 172.16.1.1</userinput></screen>

This command would produce an alias for the loopback interface with
the address <literal moreinfo="none">172.16.1.1</literal>. IP aliases are referred to
by appending :<replaceable>n</replaceable> to the actual
network device, in which n is an integer. In our example,
the network device we are creating the alias on is
<literal moreinfo="none">lo</literal>, and we are creating an alias numbered zero for
it. This way, a single physical device may support a number of
aliases.</para><para>Each alias may be treated as though it is a separate device, and as
far as the kernel IP software is concerned, it will be; however, it
will be sharing its hardware with another interface.</para></sect2></sect1><sect1 id="x-087-2-iface.ifconfig"><title>All About ifconfig</title><indexterm significance="normal" class="startofrange" id="chtc.ifconfig.cmd"><primary>ifconfig command</primary></indexterm><para>There are many more parameters to <command moreinfo="none">ifconfig</command> than we
have described so far. Its normal invocation is this:

<screen format="linespecific">ifconfig <replaceable>interface</replaceable> [<replaceable>address</replaceable> [<replaceable>parameters</replaceable>]]</screen></para><para><replaceable>interface</replaceable> is the interface name, and
<replaceable>address</replaceable> is the IP address to be assigned to the
interface. This may be either an IP address in dotted quad notation or a
name that <command moreinfo="none">ifconfig</command> will look up in
<filename moreinfo="none">/etc/hosts</filename>.</para><para><indexterm significance="normal"><primary>displaying</primary><secondary>interface</secondary><tertiary>configuration</tertiary></indexterm>
If <command moreinfo="none">ifconfig</command> is invoked with only the interface
name, it displays that interface's configuration. When invoked without
any parameters, it displays all interfaces you have configured so far;
a <option>a</option> option forces it to show the inactive ones
as well. A sample invocation for the Ethernet interface
<filename moreinfo="none">eth0</filename> may look like this:

<screen format="linespecific"># <userinput moreinfo="none">ifconfig eth0</userinput>
eth0      Link encap 10Mbps Ethernet  HWaddr 00:00:C0:90:B3:42
          inet addr 172.16.1.2 Bcast 172.16.1.255 Mask 255.255.255.0
          UP BROADCAST RUNNING  MTU 1500  Metric 0
          RX packets 3136 errors 217 dropped 7 overrun 26
          TX packets 1752 errors 25 dropped 0 overrun 0</screen></para><para><indexterm significance="normal"><primary>Maximum Transmission Unit (MTU)</primary></indexterm>
<indexterm significance="normal"><primary>routing</primary><secondary>metric</secondary></indexterm>
The <literal moreinfo="none">MTU</literal> and <literal moreinfo="none">Metric</literal> fields show the
current MTU and metric value for that interface. The metric value is
traditionally used by some operating systems to compute the cost of a route.
Linux doesn't use this value yet, but defines it for compatibility,
nevertheless.</para><para>The <literal moreinfo="none">RX</literal> and <literal moreinfo="none">TX</literal> lines show how
many packets have been received or transmitted error free, how many
errors occurred, how many packets were dropped (probably because of
low memory), and how many were lost because of an overrun. Receiver
overruns usually occur when packets come in faster than the kernel can
service the last interrupt. The flag values printed by
<command moreinfo="none">ifconfig</command> roughly correspond to the names of its
command-line options; they will be explained later.</para><para>The following is a list of parameters recognized by <command moreinfo="none">ifconfig</command>
with the corresponding flag names. Options that simply turn on a feature also
allow it to be turned off again by preceding the option name by a
dash ().</para><variablelist><varlistentry><term><literal moreinfo="none">up</literal></term><listitem><para>This option makes an interface accessible to the IP layer. This option
is implied when an <replaceable>address</replaceable> is given on the
command line. It may also be used to reenable an interface that has
been taken down temporarily using the <literal moreinfo="none">down</literal> option.</para><para>This option corresponds to the flags <option>UP</option> and
<option>RUNNING</option>.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">down</literal></term><listitem><para>This option marks an interface inaccessible to the IP layer. This
effectively disables any IP traffic through the interface. Note that
this option will also automatically delete all routing entries that
use this interface.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">netmask</literal> <replaceable>mask</replaceable></term><listitem><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>netmask</secondary></indexterm>
<indexterm significance="normal"><primary>interfaces</primary><secondary>netmask</secondary></indexterm>
This option assigns a subnet mask to be used by the interface. It may
be given as either a 32-bit hexadecimal number preceded by 0x, or as a
dotted quad of decimal numbers. While the dotted quad format is more
common, the hexadecimal representation is often easier to work
with. Netmasks are essentially binary, and it is easier to do
binary-to-hexadecimal than binary-to-decimal conversion.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">pointopoint</literal> <replaceable>address</replaceable></term><listitem><para><indexterm significance="normal"><primary>point-to-point link</primary></indexterm> This option is
used for point-to-point IP links that involve only two hosts. This option is
needed to configure SLIP or PLIP interfaces, for example. If a point-to-point address has been set, <command moreinfo="none">ifconfig</command> displays
the <option>POINTOPOINT</option> flag.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">broadcast</literal>
<replaceable>address</replaceable></term><listitem><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>broadcast address</secondary></indexterm>
<indexterm significance="normal"><primary>broadcast address</primary></indexterm>
<indexterm significance="normal"><primary>addresses</primary><secondary>broadcast</secondary></indexterm>
The broadcast address is usually made up from the network number by
setting all bits of the host part. Some IP implementations (systems
derived from BSD 4.2, for instance) use a different scheme in which
all host part bits are cleared instead. The
<option>broadcast</option> option adapts to these strange
environments. If a broadcast address has been set, <command moreinfo="none">ifconfig</command> displays the <option>BROADCAST</option> flag.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">irq</literal></term><listitem><para><indexterm significance="normal"><primary>setting</primary><secondary>IRQ</secondary></indexterm>
<indexterm significance="normal"><primary>IRQ (Interrupt Request)</primary><secondary>setting</secondary></indexterm>
This option allows you to set the IRQ line used by certain devices. This is
especially useful for PLIP, but may also be useful for certain Ethernet cards.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">metric</literal> <replaceable>number</replaceable></term><listitem><para><indexterm significance="normal"><primary>Routing Information Protocol (RIP)</primary></indexterm>
<indexterm significance="normal"><primary>RIP (Routing Information Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>routing</primary><secondary>metric</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>metric</secondary></indexterm>
This option may be used to assign a metric value to the routing table entry
created for the interface. This metric is used by the Routing Information
Protocol (RIP) to build routing tables for the
network.<footnote id="x-087-2-fntc11"><para>RIP chooses the optimal route to a given host based on the length
of the path. It is computed by summing up the individual metric values of each
host-to-host link. By default, a hop has length 1, but this may be any
positive integer less than 16. (A route length of 16 is equal to infinity.
Such routes are considered unusable.) The <option>metric</option> parameter
sets this hop cost, which is then broadcast by the routing daemon.</para></footnote>

The default metric used by <command moreinfo="none">ifconfig</command> is zero. If
you don't run a RIP daemon, you don't need this option at all; if you do, you
will rarely need to change the metric value.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">mtu</literal> <replaceable>bytes</replaceable></term><listitem><para><indexterm significance="normal"><primary>Maximum Transmission Unit (MTU)</primary></indexterm>
This sets the Maximum Transmission Unit, which is the maximum number of octets
the interface is able to handle in one transaction. For Ethernets, the MTU
defaults to 1,500 (the largest allowable size of an Ethernet packet); for SLIP
interfaces, it is 296. (There is no constraint on the MTU of SLIP links; this
value is a good compromise.)</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">arp</literal></term><listitem><para><indexterm significance="normal"><primary>ARP (Address Resolution Protocol)</primary><secondary>enabling/disabling</secondary></indexterm>
This is an option specific to broadcast networks such as Ethernets or packet
radio. It enables the use of the Address Resolution Protocol (ARP) to detect
the physical addresses of hosts attached to the network. For broadcast
networks, it is on by default. If ARP is disabled, <command moreinfo="none">ifconfig</command> displays the <option>NOARP</option> flag.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">arp</literal></term><listitem><para>This option disables the use of ARP on this interface.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">promisc</literal></term><listitem><para><indexterm significance="normal"><primary>Ethernet</primary><secondary>promiscuous mode</secondary></indexterm>
<indexterm significance="normal"><primary>security</primary><secondary>Ethernet</secondary></indexterm>
This option puts the interface in promiscuous mode. On a broadcast
network, this makes the interface receive all packets, regardless of
whether they were destined for this host or not. This allows network
traffic analysis using packet filters and such, also called
<emphasis>Ethernet snooping</emphasis>. Usually, this is a good
technique for hunting down network problems that are otherwise hard to
detect. Tools such as <command moreinfo="none">tcpdump</command> rely on this.</para><para>On the other hand, this option allows attackers to do nasty things,
such as skim the traffic of your network for passwords. You can
protect against this type of attack by prohibiting just anyone from
plugging their computers into your Ethernet. You could also use
secure authentication protocols, such as Kerberos or the secure shell
login suite.<footnote id="x-087-2-fntc12"><para> ssh can be obtained
from <systemitem moreinfo="none" role="sitename">ftp.cs.hut.fi</systemitem> in
<filename moreinfo="none">/pub/ssh</filename>.</para></footnote> This option corresponds to the <option>PROMISC</option> flag.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">promisc</literal></term><listitem><para>This option turns promiscuous mode off.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">allmulti</literal></term><listitem><para><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>multicast addresses</secondary></indexterm>
Multicast addresses are like Ethernet broadcast addresses, except that
instead of automatically including everybody, the only people who
receive packets sent to a multicast address are those programmed to
listen to it. This is useful for applications like Ethernet-based
videoconferencing or network audio, to which only those interested can
listen. Multicast addressing is supported by most, but not all,
Ethernet drivers. When this option is enabled, the interface receives
and passes multicast packets for processing. This option corresponds to the <option>ALLMULTI</option> flag.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">allmulti</literal></term><listitem><para>This option turns multicast addresses off.</para></listitem></varlistentry></variablelist><indexterm significance="normal" class="endofrange" startref="chtc.ifconfig.cmd"></indexterm></sect1><sect1 id="x-087-2-iface.netstat"><title>The netstat Command</title><indexterm significance="normal" class="startofrange" id="idx-commandnetstatcommand-1"><primary>netstat command</primary></indexterm><para><command moreinfo="none">netstat</command> is a useful tool for checking your network
configuration and activity. It is in fact a collection of several
tools lumped together. We discuss each of its functions in the
following sections.</para><sect2 id="x-087-2-iface.netstat.-r"><title>Displaying the Routing Table</title><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>routing</secondary><tertiary>table</tertiary></indexterm><indexterm significance="normal"><primary>checking</primary><secondary>routing table</secondary></indexterm><indexterm significance="normal"><primary>displaying</primary><secondary>IP routing table</secondary></indexterm><indexterm significance="normal"><primary>routing table</primary><secondary>displaying via netstat</secondary></indexterm><para>When you invoke <command moreinfo="none">netstat</command> with the
<option>r</option> flag, it displays the kernel routing table
in the way we've been doing with <command moreinfo="none">route</command>. On
<systemitem moreinfo="none" role="sitename">vstout</systemitem>, it produces:

<screen format="linespecific"># <userinput moreinfo="none">netstat -nr</userinput>
Kernel IP routing table
Destination   Gateway      Genmask         Flags  MSS Window  irtt Iface
127.0.0.1     *            255.255.255.255 UH       0 0          0 lo
172.16.1.0    *            255.255.255.0   U        0 0          0 eth0
172.16.2.0    172.16.1.1   255.255.255.0   UG       0 0          0 eth0</screen></para><para>The <option>n</option> option makes <command moreinfo="none">netstat</command>
print addresses as dotted quad IP numbers rather than the symbolic
host and network names. This option is especially useful when you want
to avoid address lookups over the network (e.g., to a DNS or NIS
server).</para><para>The second column of <command moreinfo="none">netstat</command>'s output shows
the gateway to which the routing entry points. If no gateway is used,
an asterisk is printed instead. The third column shows the
generality of the route, i.e., the network mask for this
route. When given an IP address to find a suitable route for, the
kernel steps through each of the routing table entries, taking the
bitwise AND of the address and the genmask before comparing it to the
target of the route.</para><para>The fourth column displays the following flags that describe the route:

<variablelist><varlistentry><term><literal moreinfo="none">G</literal></term><listitem><para>The route uses a gateway.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">U</literal></term><listitem><para>The interface to be used is up.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">H</literal></term><listitem><para>Only a single host can be reached through the route. For example, this is the
case for the loopback entry <systemitem moreinfo="none" role="sitename">127.0.0.1</systemitem>.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">D</literal></term><listitem><para> This
route is dynamically created. It is set if the table entry has been
generated by a routing daemon like <command moreinfo="none">gated</command> or by an
ICMP redirect message (see the section <xref linkend="x-087-2-issues.icmp"></xref> in Chapter 2).</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">M</literal></term><listitem><para> This
route is set if the table entry was modified by an ICMP redirect
message.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">!</literal></term><listitem><para>The route is a reject route and datagrams will be dropped.</para></listitem></varlistentry></variablelist></para><para><indexterm significance="normal"><primary>irtt parameter</primary></indexterm>
<indexterm significance="normal"><primary>displaying</primary><secondary>irtt</secondary></indexterm>
The next three columns show the MSS, Window and irtt that will be
applied to TCP connections established via this route. The MSS is the
Maximum Segment Size and is the size of the largest datagram the
kernel will construct for transmission via this route. The Window is
the maximum amount of data the system will accept in a single burst
from a remote host. The acronym <literal moreinfo="none">irtt</literal> stands for
initial round trip time. The TCP protocol ensures that
data is reliably delivered between hosts by retransmitting a datagram
if it has been lost.  The TCP protocol keeps a running count of how
long it takes for a datagram to be delivered to the remote end, and an
acknowledgement to be received so that it knows how long to wait
before assuming a datagram needs to retransmitted; this process is
called the round-trip time. The initial round-trip time is the value
that the TCP protocol will use when a connection is first
established. For most network types, the default value is okay, but
for some slow networks, notably certain types of amateur packet radio
networks, the time is too short and causes unnecessary
retransmission. The <literal moreinfo="none">irtt</literal> value can be set using the
<command moreinfo="none">route</command> command. Values of zero in these fields mean
that the default is being used.</para><para>Finally, the last field displays the network interface that this route
will use.</para></sect2><sect2 id="x-087-2-iface.netstat.-i"><title>Displaying Interface Statistics</title><indexterm significance="normal"><primary>displaying</primary><secondary>interface</secondary><tertiary>statistics</tertiary></indexterm><indexterm significance="normal"><primary>interfaces</primary><secondary>statistics, displaying</secondary></indexterm><indexterm significance="normal"><primary>checking</primary><secondary>network</secondary><tertiary>interface</tertiary></indexterm><para>When invoked with the <option>i</option> flag,
<command moreinfo="none">netstat</command> displays statistics for the network
interfaces currently configured. If the <option>a</option>
option is also given, it prints <emphasis>all</emphasis> interfaces
present in the kernel, not only those that have been configured
currently. On <systemitem moreinfo="none" role="sitename">vstout</systemitem>, the
output from <command moreinfo="none">netstat</command> will look like this:

<screen format="linespecific"># <userinput moreinfo="none">netstat -i</userinput>
Kernel Interface table
Iface MTU Met  RX-OK RX-ERR RX-DRP RX-OVR  TX-OK TX-ERR TX-DRP TX-OVR Flags
lo      0   0   3185      0      0      0   3185      0      0      0 BLRU
eth0 1500   0 972633     17     20    120 628711    217      0      0 BRU</screen></para><para>The <literal moreinfo="none">MTU</literal> and <literal moreinfo="none">Met</literal> fields show the
current MTU and metric values for that interface. The
<literal moreinfo="none">RX</literal> and <literal moreinfo="none">TX</literal> columns show how many
packets have been received or transmitted error-free
(<literal moreinfo="none">RX-OK</literal>/<literal moreinfo="none">TX-OK</literal>) or damaged
(<literal moreinfo="none">RX-ERR</literal>/<literal moreinfo="none">TX-ERR</literal>); how many were
dropped (<literal moreinfo="none">RX-DRP</literal>/<literal moreinfo="none">TX-DRP</literal>); and how
many were lost because of an overrun
(<literal moreinfo="none">RX-OVR</literal>/<literal moreinfo="none">TX-OVR</literal>).</para><para>The last column shows the flags that have been set for this interface.
These characters are one-character versions of the long flag names
that are printed when you display the interface configuration with
<command moreinfo="none">ifconfig</command>:

<variablelist><varlistentry><term><literal moreinfo="none">B</literal></term><listitem><para>A broadcast address has been set.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">L</literal></term><listitem><para>This interface is a loopback device.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">M</literal></term><listitem><para>All packets are received (promiscuous mode).</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">O</literal></term><listitem><para>ARP is turned off for this interface.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">P</literal></term><listitem><para>This is a point-to-point connection.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">R</literal></term><listitem><para>Interface is running.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">U</literal></term><listitem><para>Interface is up.</para></listitem></varlistentry></variablelist></para></sect2><sect2 id="x-087-2-iface.netstat.-t-u-x"><title>Displaying Connections</title><indexterm significance="normal"><primary>displaying</primary><secondary>active connections</secondary></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>display connections</secondary></indexterm><indexterm significance="normal"><primary>checking</primary><secondary>network</secondary><tertiary>connections</tertiary></indexterm><indexterm significance="normal"><primary>checking</primary><secondary>TCP server activity</secondary></indexterm><indexterm significance="normal"><primary>netstat command</primary><secondary>displaying connections</secondary></indexterm><para><command moreinfo="none">netstat</command> supports a set of options to display active
or passive sockets. The options <option>t</option>,
<option>u</option>, <option>w</option>, and
<option>x</option> show active TCP, UDP, RAW, or Unix socket
connections. If you provide the <option>a</option> flag in
addition, sockets that are waiting for a connection (i.e., listening)
are displayed as well. This display will give you a list of all
servers that are currently running on your system.</para><para>Invoking <command moreinfo="none">netstat -ta</command> on
<systemitem moreinfo="none" role="sitename">vlager</systemitem> produces this output:

<screen format="linespecific">$ <userinput moreinfo="none">netstat -ta</userinput>
Active Internet Connections
Proto Recv-Q Send-Q Local Address    Foreign Address    (State)
tcp        0      0 *:domain         *:*                LISTEN  
tcp        0      0 *:time           *:*                LISTEN  
tcp        0      0 *:smtp           *:*                LISTEN  
tcp        0      0 vlager:smtp      vstout:1040        ESTABLISHED  
tcp        0      0 *:telnet         *:*                LISTEN  
tcp        0      0 localhost:1046   vbardolino:telnet  ESTABLISHED  
tcp        0      0 *:chargen        *:*                LISTEN  
tcp        0      0 *:daytime        *:*                LISTEN  
tcp        0      0 *:discard        *:*                LISTEN  
tcp        0      0 *:echo           *:*                LISTEN  
tcp        0      0 *:shell          *:*                LISTEN  
tcp        0      0 *:login          *:*                LISTEN  </screen></para><para>This output shows most servers simply waiting for an incoming
connection. However, the fourth line shows an incoming SMTP connection
from <systemitem moreinfo="none" role="sitename">vstout</systemitem>, and the sixth
line tells you there is an outgoing <command moreinfo="none">telnet</command>
connection to <systemitem moreinfo="none" role="sitename">vbardolino</systemitem>.<footnote id="x-087-2-fntc13"><para> You can tell whether a connection is
outgoing from the port numbers. The port number shown for the
<emphasis>calling</emphasis> host will always be a simple integer. On
the host being called, a well-known service port will be in use for
which <command moreinfo="none">netstat</command> uses the symbolic name such as
<literal moreinfo="none">smtp</literal>, found in <filename moreinfo="none">/etc/services</filename>.</para></footnote>
</para><para>Using the <option>a</option> flag by itself will display all
sockets from all families.</para><para><indexterm significance="normal" class="endofrange" startref="idx-commandnetstatcommand-1"></indexterm></para></sect2></sect1><sect1 id="x-087-2-iface.verify.arp"><title>Checking the ARP Tables</title><indexterm significance="normal"><primary>checking</primary><secondary>Ethernet interface</secondary></indexterm><indexterm significance="normal"><primary>checking</primary><secondary>ARP tables</secondary></indexterm><indexterm significance="normal"><primary>ARP (Address Resolution Protocol)</primary><secondary>display table</secondary></indexterm><indexterm significance="normal"><primary>displaying</primary><secondary>ARP table</secondary></indexterm><para>On some occasions, it is useful to view or alter the contents of the
kernel's ARP tables, for example when you suspect a duplicate Internet
address is the cause for some intermittent network problem.  The
<command moreinfo="none">arp</command> tool was made for situations like this.  Its
command-line options are:

<screen format="linespecific">arp [-v] [-t <replaceable>hwtype</replaceable>] -a [<replaceable>hostname</replaceable>]
arp [-v] [-t <replaceable>hwtype</replaceable>] -s <replaceable>hostname</replaceable> <replaceable>hwaddr</replaceable>
arp [-v] -d <replaceable>hostname</replaceable> [<replaceable>hostname</replaceable>]</screen></para><para>All <replaceable>hostname</replaceable> arguments may be either symbolic
hostnames or IP addresses in dotted quad notation.</para><para>The first invocation displays the ARP entry for the IP address or host
specified, or all hosts known if no <replaceable>hostname</replaceable> is
given.  For example, invoking <command moreinfo="none">arp</command> on
<systemitem moreinfo="none" role="sitename">vlager</systemitem> may yield:

<screen format="linespecific"># <userinput moreinfo="none">arp -a</userinput>
IP address      HW type                 HW address
172.16.1.3      10Mbps Ethernet         00:00:C0:5A:42:C1
172.16.1.2      10Mbps Ethernet         00:00:C0:90:B3:42
172.16.2.4      10Mbps Ethernet         00:00:C0:04:69:AA</screen></para><para>which shows the Ethernet addresses of
<systemitem moreinfo="none" role="sitename">vlager</systemitem>,
<systemitem moreinfo="none" role="sitename">vstout</systemitem> and
<systemitem moreinfo="none" role="sitename">vale</systemitem>.</para><para>You can limit the display to the hardware type specified using the
<option>t</option> option.  This may be <systemitem moreinfo="none" role="keyword">ether</systemitem>, <systemitem moreinfo="none" role="keyword">ax25</systemitem>, or <systemitem moreinfo="none" role="keyword">pronet</systemitem>, standing for 10 Mbps Ethernet;
AMPR AX.25, and IEEE 802.5 token ring equipment, respectively.</para><para>The <option>s</option> option is used to permanently add
<replaceable>hostname</replaceable>'s Ethernet address to the ARP
tables. The <replaceable>hwaddr</replaceable> argument specifies the
hardware address, which is by default expected to be an Ethernet
address specified as six hexadecimal bytes separated by colons. You
may also set the hardware address for other types of hardware, using
the <option>t</option> option.</para><para>For some reason, ARP queries for the remote host sometimes fail, for
instance when its ARP driver is buggy or there is another host in the
network that erroneously identifies itself with that host's IP
address; this problem requires you to manually add an IP address to
the ARP table.  Hard-wiring IP addresses in the ARP table is also a
(very drastic) measure to protect yourself from hosts on your Ethernet
that pose as someone else.</para><para>Invoking <command moreinfo="none">arp</command> using the <option>d</option>
switch deletes all ARP entries relating to the given host. This switch
may be used to force the interface to re-attempt obtaining the
Ethernet address for the IP address in question. This is useful when a
misconfigured system has broadcasted wrong ARP information (of course,
you have to reconfigure the broken host first).</para><para><indexterm significance="normal"><primary>point-to-point link</primary></indexterm>
<indexterm significance="normal"><primary>routing</primary><secondary>proxy ARP</secondary></indexterm>
<indexterm significance="normal"><primary>routing</primary><secondary>dynamic</secondary></indexterm>
<indexterm significance="normal"><primary>proxy ARP</primary></indexterm>
<indexterm significance="normal"><primary>ARP (Address Resolution Protocol)</primary><secondary>proxy</secondary></indexterm>
<indexterm significance="normal"><primary>SLIP (Serial Line IP) protocol</primary><secondary>routing</secondary></indexterm>
<indexterm significance="normal"><primary>PLIP (Parallel Line IP) protocol</primary><secondary>routing</secondary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>routing</secondary></indexterm>
The <option>s</option> option may also be used to implement
<emphasis>proxy</emphasis> ARP. This is a special technique through
which a host, say <systemitem moreinfo="none" role="sitename">gate</systemitem>, acts
as a gateway to another host named <systemitem moreinfo="none" role="sitename">fnord</systemitem> by pretending that both addresses
refer to the same host, namely <systemitem moreinfo="none" role="sitename">gate</systemitem>. It does so by publishing an ARP
entry for <systemitem moreinfo="none" role="sitename">fnord</systemitem> that points
to its own Ethernet interface. Now when a host sends out an ARP query
for <systemitem moreinfo="none" role="sitename">fnord</systemitem>, <systemitem moreinfo="none" role="sitename">gate</systemitem> will return a reply containing its
own Ethernet address. The querying host will then send all datagrams
to <systemitem moreinfo="none" role="sitename">gate</systemitem>, which dutifully
forwards them to <systemitem moreinfo="none" role="sitename">fnord</systemitem>.</para><para>These contortions may be necessary when you want to access <systemitem moreinfo="none" role="sitename">fnord</systemitem> from a DOS machine with a broken
TCP implementation that doesn't understand routing too well. When you
use proxy ARP, it will appear to the DOS machine as if <systemitem moreinfo="none" role="sitename">fnord</systemitem> was on the local subnet, so it
doesn't have to know about how to route through a gateway.</para><para>Another useful application of proxy ARP is when one of your hosts acts
as a gateway to some other host only temporarily, for instance,
through a dial-up link. In a previous example, we encountered the
laptop <systemitem moreinfo="none" role="sitename">vlite</systemitem>, which was
connected to <systemitem moreinfo="none" role="sitename">vlager</systemitem> through a
PLIP link from time to time. Of course, this application will work
only if the address of the host you want to provide proxy ARP for is
on the same IP subnet as your gateway. <systemitem moreinfo="none" role="sitename">vstout</systemitem> could proxy ARP for any host on
the Brewery subnet (<systemitem moreinfo="none" role="sitename">172.16.1.0</systemitem>), but never for a host on the
Winery subnet (<systemitem moreinfo="none" role="sitename">172.16.2.0</systemitem>).</para><para>The proper invocation to provide proxy ARP for <systemitem moreinfo="none" role="sitename">fnord</systemitem> is given below; of course, the
given Ethernet address must be that of <systemitem moreinfo="none" role="sitename">gate</systemitem>:</para><para><screen format="linespecific"># arp -s fnord 00:00:c0:a1:42:e0 pub</screen></para><para>The proxy ARP entry may be removed again by invoking:

<screen format="linespecific"># arp -d fnord</screen></para></sect1><indexterm significance="normal" class="endofrange" startref="chtc.tcpip.config.netwks"></indexterm></chapter><chapter id="x-087-2-resolv"><title>Name Service <?lb?>and Resolver <?lb?>Configuration</title><indexterm significance="normal" class="startofrange" id="idx-configuringhostnameres"><primary>configuring</primary><secondary>hostname</secondary><tertiary>resolution</tertiary></indexterm><indexterm significance="normal" class="startofrange" id="chdn.hostname.resolution"><primary>hostname</primary><secondary>resolution</secondary></indexterm><indexterm significance="normal" class="startofrange" id="chdn.sve.config"><primary>name service configuration</primary></indexterm><para>As we discussed in <xref linkend="x-087-2-issues"></xref>, TCP/IP networking
may rely on different schemes to convert names into addresses. The
simplest way is a host table stored in
<filename moreinfo="none">/etc/hosts</filename>. This is useful only for small LANs
that are run by one single administrator and otherwise have no IP
traffic with the outside world. The format of the
<filename moreinfo="none">hosts</filename> file has already been described in <xref linkend="x-087-2-iface"></xref>.</para><para><indexterm significance="normal"><primary>BIND (Berkeley Internet Name
Domain)</primary></indexterm> <indexterm significance="normal"><primary>named
program</primary></indexterm> Alternatively, you can use the
<emphasis>Berkeley Internet Name Domain service</emphasis> (BIND) for
resolving hostnames to IP addresses. Configuring BIND can be a real
chore, but once you've done it, you can easily make changes in the
network topology. On Linux, as on many other Unixish systems, name
service is provided through a program called
<command moreinfo="none">named</command>. At startup, it loads a set of master files
into its internal cache and waits for queries from remote or local
user processes. There are different ways to set up BIND, and not all
require you to run a name server on every host.</para><para><indexterm significance="normal"><primary>newsgroups</primary><secondary>comp.protocols.tcp-ip.domains</secondary></indexterm>
This chapter can do little more than give a rough sketch of how DNS
works and how to operate a name server. It should be sufficient if you
have a small LAN and an Internet uplink. For the most current
information, you may want to check the documentation contained in the
BIND source package, which supplies manual pages, release notes, and
the <emphasis>BIND Operator's Guide</emphasis> (BOG). Don't let this
name scare you off; it's actually a very useful document. For a more
comprehensive coverage of DNS and associated issues, you may find
<emphasis>DNS and BIND</emphasis> by Paul Albitz and Cricket Liu
(O'Reilly) a useful reference. DNS questions may be answered in a
newsgroup called <systemitem moreinfo="none" role="newsgroup">comp.protocols.tcp-ip.domains</systemitem>. For
technical details, the Domain Name System is defined by RFC numbers
1033, 1034, and 1035.</para><sect1 id="x-087-2-resolv.library"><title>The Resolver Library</title><indexterm significance="normal"><primary>resolvers</primary><secondary>library</secondary></indexterm><indexterm significance="normal"><primary>gethostbyname()</primary></indexterm><indexterm significance="normal"><primary>gethostbyaddr()</primary></indexterm><para>The term <emphasis>resolver</emphasis> refers not to a special
application, but to the resolver library. This is a collection of
functions that can be found in the standard C library. The central
routines are <function moreinfo="none">gethostbyname(2)</function> and
<function moreinfo="none">gethostbyaddr(2)</function>, which look up all IP addresses
associated with a host name, and vice versa. They may be configured to
simply look up the information in <filename moreinfo="none">hosts</filename>, to query
a number of DNS name servers, or to use the <emphasis>hosts</emphasis>
database of Network Information Service (NIS).</para><para>The resolver functions read configuration files when they are
invoked. From these configuration files, they determine what databases
to query, in which order, and other details relevant to how you've
configured your environment.  The older Linux standard library, libc,
used <filename moreinfo="none">/etc/host.conf</filename> as its master configuration
file, but Version 2 of the GNU standard library, glibc, uses
<filename moreinfo="none">/etc/nsswitch.conf</filename>. We'll describe each in turn,
since both are commonly used.</para><sect2 id="x-087-2-resolv.host-conf"><title>The host.conf File</title><indexterm significance="normal"><primary>resolvers</primary><secondary>using NIS</secondary></indexterm><indexterm significance="normal"><primary>resolvers</primary><secondary>using a name server</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-resolverconfiguring-1"><primary>resolvers</primary><secondary>configuring</secondary></indexterm><indexterm significance="normal"><primary>host.conf file</primary></indexterm><para>The <filename moreinfo="none">/etc/host.conf</filename> tells the older Linux standard library
resolver functions which services to use, and in what order.</para><para>Options in <filename moreinfo="none">host.conf</filename> must appear on separate lines.
Fields may be separated by white space (spaces or tabs). A hash sign
(<systemitem moreinfo="none" role="keyword">#</systemitem>) introduces a comment that extends
to the next newline. The following options are available:

<variablelist><varlistentry><term><systemitem moreinfo="none" role="keyword">order</systemitem></term><listitem><para><indexterm significance="normal"><primary>NIS (Network Information
System)</primary><secondary>resolver and</secondary></indexterm> This
option determines the order in which the resolving services are
tried. Valid options are <systemitem moreinfo="none" role="keyword">bind</systemitem>
for querying the name server, <filename moreinfo="none">hosts</filename> for lookups
in <filename moreinfo="none">/etc/hosts</filename>, and <systemitem moreinfo="none" role="keyword">nis</systemitem> for NIS lookups. Any or all of them
may be specified. The order in which they appear on the line
determines the order in which the respective services are tried.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">multi</systemitem></term><listitem><para><literal moreinfo="none">multi</literal> takes <systemitem moreinfo="none" role="keyword">on</systemitem> or
<systemitem moreinfo="none" role="keyword">off</systemitem> as options. This determines if a
host in <filename moreinfo="none">/etc/hosts</filename> is allowed to have several IP
addresses, which is usually referred to as being multi-homed.
The default is off. This flag has no effect on DNS or NIS queries.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">nospoof</systemitem></term><listitem><para><indexterm significance="normal"><primary>security</primary><secondary>false hostnames</secondary></indexterm>
<indexterm significance="normal"><primary>security</primary><secondary>spoofing</secondary></indexterm>
<indexterm significance="normal"><primary>spoofing</primary><secondary>preventing</secondary></indexterm>

As we'll explain in the section <xref linkend="x-087-2-resolv.dns.in-addr"></xref>, DNS allows you to find the
hostname belonging to an IP address by using the <systemitem moreinfo="none" role="sitename">in-addr.arpa</systemitem> domain. Attempts by name
servers to supply a false hostname are called
<emphasis>spoofing</emphasis>. To guard against this, the resolver can
be configured to check whether the original IP address is in fact
associated with the obtained hostname. If not, the name is rejected
and an error is returned. This behavior is turned on by setting
<systemitem moreinfo="none" role="keyword">nospoof</systemitem> on.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">alert</systemitem></term><listitem><para>This option takes <systemitem moreinfo="none" role="keyword">on</systemitem> or
<systemitem moreinfo="none" role="keyword">off</systemitem> as arguments. If it is turned on,
any spoof attempts will cause the resolver to log a message to the
<command moreinfo="none">syslog</command> facility.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">trim</systemitem></term><listitem><para>This option takes an argument specifying a domain name that will be
removed from hostnames before lookup. This is useful for
<filename moreinfo="none">hosts</filename> entries, for which you might only want to
specify hostnames without a local domain. If you specify your local
domain name here, it will be removed from a lookup of a host with the
local domain name appended, thus allowing the lookup in
<filename moreinfo="none">/etc/hosts</filename> to succeed. The domain name you add
must end with the (.) character (e.g.,
:<literal moreinfo="none">linux.org.au.</literal>) if <literal moreinfo="none">trim</literal> is to
work correctly.</para><para><systemitem moreinfo="none" role="keyword">trim</systemitem> options accumulate; you
can consider your host as being local to several domains.</para></listitem></varlistentry></variablelist></para><para>A sample file for <systemitem moreinfo="none" role="sitename">vlager</systemitem> is shown in
<xref linkend="x-087-2-dns-host.conf.file"></xref>.</para><example id="x-087-2-dns-host.conf.file"><title>Sample host.conf File</title><screen format="linespecific"># /etc/host.conf
# We have named running, but no NIS (yet)
order   bind,hosts
# Allow multiple addrs
multi   on
# Guard against spoof attempts
nospoof on
# Trim local domain (not really necessary).
trim    vbrew.com.</screen></example><sect3 id="x-087-2-resolv.environ"><title>Resolver environment variables</title><indexterm significance="normal"><primary>resolvers</primary><secondary>environment variables</secondary></indexterm><indexterm significance="normal"><primary>environment variables</primary><secondary>resolver</secondary></indexterm><para>The settings from <filename moreinfo="none">host.conf</filename> may be overridden using a
number of environment variables:

<variablelist><varlistentry><term><systemitem class="environvar" moreinfo="none">RESOLV_HOST_CONF</systemitem></term><listitem><para><indexterm significance="normal"><primary>RESOLV_HOST_CONF environment variable</primary></indexterm>
This variable specifies a file to be read instead of
<filename moreinfo="none">/etc/host.conf</filename>.</para></listitem></varlistentry><varlistentry><term><systemitem class="environvar" moreinfo="none">RESOLV_SERV_ORDER</systemitem></term><listitem><para><indexterm significance="normal"><primary>RESOLV_SERV_ORDER environment variable</primary></indexterm>
This variable overrides the <systemitem moreinfo="none" role="keyword">order</systemitem> option given in
<filename moreinfo="none">host.conf</filename>. Services are given as <systemitem moreinfo="none" role="keyword">hosts</systemitem>, <systemitem moreinfo="none" role="keyword">bind</systemitem>, and <systemitem moreinfo="none" role="keyword">nis</systemitem>, separated by a space, comma, colon,
or semicolon.</para></listitem></varlistentry><varlistentry><term><systemitem class="environvar" moreinfo="none">RESOLV_SPOOF_CHECK</systemitem></term><listitem><para><indexterm significance="normal"><primary>RESOLV_SPOOF_CHECK environment variable</primary></indexterm>
This variable determines the measures taken against spoofing. It is
completely disabled by <systemitem moreinfo="none" role="keyword">off</systemitem>.
The values <systemitem moreinfo="none" role="keyword">warn</systemitem> and
<systemitem moreinfo="none" role="keyword">warn off</systemitem> enable spoof
checking by turning logging on and off, respectively. A value of
<systemitem moreinfo="none" role="keyword">*</systemitem> turns on spoof checks, but
leaves the logging facility as defined in
<filename moreinfo="none">host.conf</filename>.</para></listitem></varlistentry><varlistentry><term><systemitem class="environvar" moreinfo="none">RESOLV_MULTI</systemitem></term><listitem><para><indexterm significance="normal"><primary>RESOLV_MULTI environment variable</primary></indexterm> 
This variable uses a value of <systemitem moreinfo="none" role="keyword">on</systemitem> or <systemitem moreinfo="none" role="keyword">off</systemitem> to override the <systemitem moreinfo="none" role="keyword">multi</systemitem> options from
<filename moreinfo="none">host.conf</filename>.</para></listitem></varlistentry><varlistentry><term><systemitem class="environvar" moreinfo="none">RESOLV_OVERRIDE_TRIM_DOMAINS</systemitem></term><listitem><para><indexterm significance="normal"><primary>RESOLV_OVERRIDE_TRIM_DOMAINS environment variable</primary></indexterm> 
This variable specifies a list of trim domains that override those
given in <filename moreinfo="none">host.conf</filename>.  Trim domains were explained
earlier when we discussed the <systemitem moreinfo="none" role="keyword">trim</systemitem> keyword.</para></listitem></varlistentry><varlistentry><term><systemitem class="environvar" moreinfo="none">RESOLV_ADD_TRIM_DOMAINS</systemitem></term><listitem><para><indexterm significance="normal"><primary>RESOLV_ADD_TRIM_DOMAINS environment variable</primary></indexterm> 
This variable specifies a list of trim domains that are added to those
given in <filename moreinfo="none">host.conf</filename>.</para></listitem></varlistentry></variablelist></para></sect3></sect2><sect2 id="x-087-2-resolv.nsswitch-conf"><title>The nsswitch.conf File</title><indexterm significance="normal"><primary>resolvers</primary><secondary>using NIS</secondary></indexterm><indexterm significance="normal"><primary>resolvers</primary><secondary>using a name server</secondary></indexterm><indexterm significance="normal"><primary>nsswitch.conf file</primary></indexterm><para>Version 2 of the GNU standard library includes a more powerful and
flexible replacement for the older <filename moreinfo="none">host.conf</filename>
mechanism. The concept of the name service has been extended to
include a variety of different types of information. Configuration
options for all of the different functions that query these databases
have been brought back into a single configuration file; the
<filename moreinfo="none">nsswitch.conf</filename> file.</para><para>The <filename moreinfo="none">nsswitch.conf</filename> file allows the system
administrator to configure a wide variety of different
databases. We'll limit our discussion to options that relate to host
and network IP address resolution. You can easily find more
information about the other features by reading the GNU standard
library documentation.</para><para>Options in <filename moreinfo="none">nsswitch.conf</filename> must appear on separate
lines.  Fields may be separated by whitespace (spaces or tabs). A hash
sign (<systemitem moreinfo="none" role="keyword">#</systemitem>) introduces a comment
that extends to the next newline. Each line describes a particular
service; hostname resolution is one of these. The first field in each
line is the name of the database, ending with a colon. The database
name associated with host address resolution is <systemitem moreinfo="none" role="keyword">hosts</systemitem>. A related database is <systemitem moreinfo="none" role="keyword">networks</systemitem>, which is used for resolution of
network names into network addresses. The remainder of each line
stores options that determine the way lookups for that database
are performed.</para><para>The following options are available:

<variablelist><varlistentry><term><systemitem moreinfo="none" role="keyword">dns</systemitem></term><listitem><para><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>resolver and</secondary></indexterm>
Use the Domain Name System (DNS) service to resolve the address. This makes
sense only for host address resolution, not network address
resolution. This mechanism uses the
<filename moreinfo="none">/etc/resolv.conf</filename> file that we'll describe later
in the chapter. </para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">files</systemitem></term><listitem><para>Search a local file for the host or network name and its corresponding address.
This option uses the traditional <filename moreinfo="none">/etc/hosts</filename> and
<filename moreinfo="none">/etc/network</filename> files.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">nis</systemitem> or <systemitem moreinfo="none" role="keyword">nisplus</systemitem></term><listitem><para><indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>resolver and</secondary></indexterm>
Use the Network Information System (NIS) to resolve the host or
network address.  NIS and NIS+ are discussed in detail in <xref linkend="x-087-2-nis"></xref>.</para></listitem></varlistentry></variablelist></para><para>The order in which the services to be queried are listed determines the
order in which they are queried when attempting to resolve a name.
The query-order list is in the service description in the
<filename moreinfo="none">/etc/nsswitch.conf</filename> file. The services are queried
from left to right and by default searching stops when a resolution is
successful.</para><para>A simple example of host and network database specification that would
mimic our configuration using the older libc standard library is shown
in <xref linkend="x-087-2-dns-nsswitch.conf.file"></xref>.</para><example id="x-087-2-dns-nsswitch.conf.file"><title>Sample nsswitch.conf File</title><screen format="linespecific"># /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# Information about this file is available in the `libc6-doc' package.

hosts:          dns files
networks:       files
</screen></example><para>This example causes the system to look up hosts first in the Domain
Name System, and the <filename moreinfo="none">/etc/hosts</filename> file, if that
can't find them. Network name lookups would be attempted using only
the <filename moreinfo="none">/etc/networks</filename> file.</para><para><indexterm significance="normal"><primary>nsswitch.conf file</primary><secondary>action
statements</secondary></indexterm> You are able to control the lookup
behavior more precisely using action items that describe
what action to take given the result of the previous lookup
attempt. Action items appear between service specifications, and are
enclosed within square brackets, <systemitem moreinfo="none" role="keyword">[
]</systemitem>. The general syntax of the action statement is:

<screen format="linespecific">[ [!] <replaceable>status</replaceable> = <replaceable>action</replaceable> ... ]</screen>
</para><para>There are two possible actions:

<variablelist><varlistentry><term><systemitem moreinfo="none" role="keyword">return</systemitem></term><listitem><para>Controls returns to the program that attempted the name resolution. If a lookup attempt was successful, the resolver will return with the details,
otherwise it will return a zero result.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">continue</systemitem></term><listitem><para>The resolver will move on to the next service in the list and attempt
resolution using it.</para></listitem></varlistentry></variablelist>

The optional (!) character specifies that the status value should
be inverted before testing; that is, it means not.</para><para>The available status values on which we can act are:

<variablelist><varlistentry><term><systemitem moreinfo="none" role="keyword">success</systemitem></term><listitem><para>The requested entry was found without error. The default action for
this status is <systemitem moreinfo="none" role="keyword">return</systemitem>.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">notfound</systemitem></term><listitem><para>There was no error in the lookup, but the target host or network could not be
found. The default action for this status is
<systemitem moreinfo="none" role="keyword">continue</systemitem>.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">unavail</systemitem></term><listitem><para>The service queried was unavailable. This could mean that the
<filename moreinfo="none">hosts</filename> or <filename moreinfo="none">networks</filename> file was unreadable
for the <systemitem moreinfo="none" role="keyword">files</systemitem> service or that a
name server or NIS server did not respond for the
<systemitem moreinfo="none" role="keyword">dns</systemitem> or
<systemitem moreinfo="none" role="keyword">nis</systemitem> services.
The default action for this status is
<systemitem moreinfo="none" role="keyword">continue</systemitem>.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">tryagain</systemitem></term><listitem><para>This status means the service is temporarily unavailable. For the
<systemitem moreinfo="none" role="keyword">files</systemitem> files service, this would
usually indicate that the relevant file was locked by some
process. For other services, it may mean the server was temporarily
unable to accept connections. The default action for this status is
<systemitem moreinfo="none" role="keyword">continue</systemitem>.</para></listitem></varlistentry></variablelist></para><para>A simple example of how you might use this mechanism is shown in
<xref linkend="x-087-2-dns-nsswitch.conf.file.extended"></xref>.</para><example id="x-087-2-dns-nsswitch.conf.file.extended"><title>Sample nsswitch.conf File Using an Action Statement</title><screen format="linespecific"># /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# Information about this file is available in the `libc6-doc' package.

hosts:          dns [!UNAVAIL=return] files
networks:       files
</screen></example><para>This example attempts host resolution using the Domain Name Service
system. If the return status is anything other than unavailable, the
resolver returns whatever it has found. If, and only if, the DNS
lookup attempt returns an unavailable status, the resolver attempts to
use the local <filename moreinfo="none">/etc/hosts</filename>. This means that we
should use the <filename moreinfo="none">hosts</filename> file only if our name server
is unavailable for some reason.</para></sect2><sect2 id="x-087-2-resolv.resolv"><title>Configuring Name Server Lookups Using resolv.conf</title><indexterm significance="normal"><primary>configuring</primary><secondary>name server</secondary><tertiary>lookups</tertiary></indexterm><indexterm significance="normal"><primary>resolv.conf file</primary></indexterm><indexterm significance="normal"><primary>name servers</primary><secondary>lookups</secondary></indexterm><para>When configuring the resolver library to use the BIND name service for host
lookups, you also have to tell it which name servers to use. There is a
separate file for this called <filename moreinfo="none">resolv.conf</filename>. If this file
does not exist or is empty, the resolver assumes the name server is on your
local host.</para><para>To run a name server on your local host, you have to set it up separately,
as will be explained in the following section. If you are on a local network
and have the opportunity to use an existing name server, this should always
be preferred. If you use a dialup IP connection to the Internet, you
would normally specify the name server of your service provider in the
<filename moreinfo="none">resolv.conf</filename> file.</para><para>The most important option in <filename moreinfo="none">resolv.conf</filename> is
<systemitem moreinfo="none" role="keyword">name server</systemitem>, which gives the IP address
of a name server to use. If you specify several name servers by giving the
<systemitem moreinfo="none" role="keyword">name server</systemitem> option several times, they
are tried in the order given. You should therefore put the most reliable
server first. The current implementation allows you to have up to three
<systemitem moreinfo="none" role="keyword">name server</systemitem> statements in
<filename moreinfo="none">resolv.conf</filename>. If no
<systemitem moreinfo="none" role="keyword">name server</systemitem> option is given, the resolver
attempts to connect to the name server on the local host.</para><para><?troff .hw mathematics?><indexterm significance="normal"><primary>domains</primary><secondary>names</secondary><tertiary>default</tertiary></indexterm>
<indexterm significance="normal"><primary>configuring</primary><secondary>default domain</secondary></indexterm>
Two other options, <systemitem moreinfo="none" role="keyword">domain</systemitem> and
<systemitem moreinfo="none" role="keyword">search</systemitem>, let you use shortcut names
for hosts in your local domain. Usually, when just telnetting to another
host in your local domain, you don't want to type in the fully qualified
hostname, but use a name like <systemitem moreinfo="none" role="sitename">gauss</systemitem> 
on the command line and have the resolver tack on the
<systemitem moreinfo="none" role="sitename">mathematics.groucho.edu</systemitem> part.</para><para>This is just the <systemitem moreinfo="none" role="keyword">domain</systemitem>
statement's purpose. It lets you specify a default domain name to be
appended when DNS fails to look up a hostname. For instance, when
given the name <systemitem moreinfo="none" role="sitename">gauss</systemitem>, the
resolver fails to find <systemitem moreinfo="none" role="sitename">gauss.</systemitem> in DNS, because there is no such
top-level domain. When given <systemitem moreinfo="none" role="sitename">mathematics.groucho.edu</systemitem> as a default
domain, the resolver repeats the query for <systemitem moreinfo="none" role="sitename">gauss</systemitem> with the default domain appended,
this time succeeding.</para><para>That's just fine, you may think, but as soon you get out of the Math
department's domain, you're back to those fully qualified domain names.
Of course, you would also want to have shorthands like
<systemitem moreinfo="none" role="sitename">quark.physics</systemitem> for hosts in the
Physics department's domain.</para><para>This is when the <emphasis>search list</emphasis> comes in.  A search
list can be specified using the <systemitem moreinfo="none" role="keyword">search</systemitem> option, which is a generalization
of the <systemitem moreinfo="none" role="keyword">domain</systemitem> statement.
Where the latter gives a single default domain, the former specifies a
whole list of them, each to be tried in turn until a lookup
succeeds. This list must be separated by blanks or tabs.</para><para>The <systemitem moreinfo="none" role="keyword">search</systemitem> and
<systemitem moreinfo="none" role="keyword">domain</systemitem> statements are mutually exclusive
and may not appear more than once. If neither option is given, the resolver
will try to guess the default domain from the local hostname using the
<function moreinfo="none">getdomainname(2)</function> system call. If the local hostname
doesn't have a domain part, the default domain will be assumed to be the
root domain.</para><para>If you decide to put a <systemitem moreinfo="none" role="keyword">search</systemitem> statement
into <filename moreinfo="none">resolv.conf</filename>, you should be careful about what
domains you add to this list. Resolver libraries prior to BIND 4.9 used to
construct a default search list from the domain name when no search list was
given. This default list was made up of the default domain itself, plus all
of its parent domains up to the root. This caused some problems because DNS
requests wound up at name servers that were never meant to see them.</para><para>Assume you're at the Virtual Brewery and want to log in to <systemitem moreinfo="none" role="sitename">foot.groucho.edu</systemitem>. By a slip
of your fingers, you mistype <systemitem moreinfo="none" role="sitename">foot</systemitem> as <systemitem moreinfo="none" role="sitename">foo</systemitem>, which doesn't exist. GMU's name
server will therefore tell you that it knows no such host. With the
old-style search list, the resolver would now go on trying the name
with <systemitem moreinfo="none" role="sitename">vbrew.com</systemitem> and
<systemitem moreinfo="none" role="sitename">com</systemitem> appended. The latter is
problematic because <systemitem moreinfo="none" role="sitename">groucho.edu.com</systemitem> might actually be a valid
domain name.  Their name server might then even find <systemitem moreinfo="none" role="sitename">foo</systemitem> in their domain, pointing you to one
of their hostswhich clearly was not intended.</para><para>For some applications, these bogus host lookups can be a security problem.
Therefore, you should usually limit the domains on your search list to your
local organization, or something comparable. At the Mathematics department of
Groucho Marx University, the search list would commonly be set to
<systemitem moreinfo="none" role="sitename">maths.groucho.edu</systemitem> and
<systemitem moreinfo="none" role="sitename">groucho.edu</systemitem>.</para><para>If default domains sound confusing to you, consider this sample
<filename moreinfo="none">resolv.conf</filename> file for the Virtual Brewery:

<screen format="linespecific"># /etc/resolv.conf
# Our domain
domain         vbrew.com
#
# We use vlager as central name server:
name server     172.16.1.1</screen></para><para>When resolving the name <systemitem moreinfo="none" role="sitename">vale</systemitem>, the
resolver looks up <systemitem moreinfo="none" role="sitename">vale</systemitem> and,
failing this, <systemitem moreinfo="none" role="sitename">vale.vbrew.com</systemitem>.</para></sect2><sect2 id="x-087-2-resolv.robustness"><title>Resolver Robustness</title><indexterm significance="normal"><primary>resolvers</primary><secondary>robustness</secondary></indexterm><para>When running a LAN inside a larger network, you definitely should use
central name servers if they are available. The name servers develop
rich caches that speed up repeat queries, since all queries are
forwarded to them. However, this scheme has a drawback: when a fire
destroyed the backbone cable at Olaf's university, no more work was
possible on his department's LAN because the resolver could no longer
reach any of the name servers. This situation caused difficulties with
most network services, such as X terminal logins and printing.</para><para>Although it is not very common for campus backbones to go down in flames,
one might want to take precautions against cases like this.</para><para>One option is to set up a local name server that resolves hostnames from your
local domain and forwards all queries for other hostnames to the main servers.
Of course, this is applicable only if you are running your own domain.</para><para>Alternatively, you can maintain a backup host table for your domain or LAN in
<filename moreinfo="none">/etc/hosts</filename>. This is very simple to do. You simply ensure
that the resolver library queries DNS first, and the hosts file next. In an
<filename moreinfo="none">/etc/host.conf</filename> file you'd use
<systemitem moreinfo="none" role="keyword">order bind,hosts</systemitem>,
and in an <filename moreinfo="none">/etc/nsswitch.conf</filename> file you'd use
<systemitem moreinfo="none" role="keyword">hosts: dns files</systemitem>,
to make the resolver fall back to the hosts file if the central name server is
unreachable.
<indexterm significance="normal" class="endofrange" startref="idx-resolverconfiguring-1"></indexterm>
<indexterm significance="normal"><primary sortas="etc/host.conf file">/etc/host.conf file</primary></indexterm> 
<indexterm significance="normal"><primary sortas="etc/host file">/etc/host file</primary></indexterm> </para></sect2></sect1><sect1 id="x-087-2-resolv.howdnsworks"><title>How DNS Works</title><indexterm significance="normal"><primary>namespace (DNS)</primary></indexterm><indexterm significance="normal"><primary>hostname</primary><secondary>fully qualified</secondary></indexterm><indexterm significance="normal"><primary>hostname</primary><secondary>domain name and</secondary></indexterm><indexterm significance="normal"><primary>domains</primary><secondary>names</secondary></indexterm><indexterm significance="normal"><primary>domains</primary></indexterm><indexterm significance="normal"><primary>subdomains</primary></indexterm><para>DNS organizes hostnames in a domain hierarchy. A
<emphasis>domain</emphasis> is a collection of sites that are related
in some sensebecause they form a proper network (e.g.,
all machines on a campus, or all hosts on BITNET), because they all
belong to a certain organization (e.g., the U.S. government), or
because they're simply geographically close. For instance,
universities are commonly grouped in the <systemitem moreinfo="none" role="sitename">edu</systemitem> domain, with each university or
college using a separate <emphasis>subdomain</emphasis>, below which
their hosts are subsumed. Groucho Marx University have the
<systemitem moreinfo="none" role="sitename">groucho.edu</systemitem> domain, while the
LAN of the Mathematics department is assigned <systemitem moreinfo="none" role="sitename">maths.groucho.edu</systemitem>. Hosts on the
departmental network would have this domain name tacked onto their
hostname, so <systemitem moreinfo="none" role="sitename">erdos</systemitem> would be
known as <systemitem moreinfo="none" role="sitename">erdos.maths.groucho.edu</systemitem>.  This is called
the <emphasis>fully qualified domain name</emphasis> (FQDN), which
uniquely identifies this host worldwide.</para><para><xref linkend="x-087-2-resolv.fig.dns"></xref> shows a section of the namespace.
The entry at the root of this tree, which is denoted by a single dot, is quite
appropriately called the <emphasis>root domain</emphasis> and encompasses all
other domains. To indicate that a hostname is a fully qualified domain name,
rather than a name relative to some (implicit) local domain, it is
sometimes written with a trailing dot. This dot signifies that the name's
last component is the root domain.
<indexterm significance="normal"><primary>root domain</primary></indexterm> </para><figure float="0" id="x-087-2-resolv.fig.dns"><title>A part of the domain namespace</title><graphic fileref="lag2_0601.jpg"></graphic></figure><para><indexterm significance="normal"><primary>domains</primary><secondary>top-level</secondary></indexterm>
Depending on its location in the name hierarchy, a domain may be
called top-level, second-level, or third-level. More levels of
subdivision occur, but they are rare. This list details several
top-level domains you may see frequently:</para><indexterm significance="normal"><primary>edu domain</primary></indexterm><indexterm significance="normal"><primary>com domain</primary></indexterm><indexterm significance="normal"><primary>org domain</primary></indexterm><indexterm significance="normal"><primary>net domain</primary></indexterm><indexterm significance="normal"><primary>mil domain</primary></indexterm><indexterm significance="normal"><primary>gov domain</primary></indexterm><indexterm significance="normal"><primary>uucp domain</primary></indexterm><informaltable><tgroup cols="2"><colspec colwidth="0.5i"></colspec><colspec colwidth="4i"></colspec><thead><row><entry>Domain</entry><entry>Description</entry></row></thead><tbody><row><entry>edu</entry><entry><para>(Mostly U.S.) educational institutions like universities.</para></entry></row><row><entry>com</entry><entry><para>Commercial organizations and companies.</para></entry></row><row><entry>org</entry><entry><para>Non-commercial organizations. Private UUCP networks are often in this domain.</para></entry></row><row><entry>net</entry><entry><para>Gateways and other administrative hosts on a network.</para></entry></row><row><entry>mil</entry><entry><para>U.S. military institutions.</para></entry></row><row><entry>gov</entry><entry><para>U.S. government institutions.</para></entry></row><row><entry>uucp</entry><entry><para>Officially, all site names formerly used as UUCP names without domains have been moved to this domain.</para></entry></row></tbody></tgroup></informaltable><para>Historically, the first four of these were assigned to the U.S., but
recent changes in policy have meant that these domains, named global
Top Level Domains (gTLD), are now considered global in nature.
Negotiations are currently underway to broaden the range of gTLDs,
which may result in increased choice in the future.</para><para>Outside the U.S., each country generally uses a top-level domain of
its own named after the two-letter country code defined in ISO-3166.
Finland, for instance, uses the <systemitem moreinfo="none" role="sitename">fi</systemitem> domain; <systemitem moreinfo="none" role="sitename">fr</systemitem> is used by France, <systemitem moreinfo="none" role="sitename">de</systemitem> by Germany, and <systemitem moreinfo="none" role="sitename">au</systemitem> by Australia. Below this top-level
domain, each country's NIC is free to organize hostnames in whatever
way they want. Australia has second-level domains similar to the
international top-level domains, named <systemitem moreinfo="none" role="sitename">com.au</systemitem> and <systemitem moreinfo="none" role="sitename">edu.au</systemitem>. Other countries, like Germany,
don't use this extra level, but have slightly long names that refer
directly to the organizations running a particular domain. It's not
uncommon to see hostnames like <systemitem moreinfo="none" role="sitename">ftp.informatik.uni-erlangen.de</systemitem>. Chalk
that up to German efficiency.</para><para>Of course, these national domains do not imply that a host below that
domain is actually located in that country; it means only that the
host has been registered with that country's NIC. A Swedish manufacturer
might have a branch in Australia and still have all its hosts
registered with the <systemitem moreinfo="none" role="sitename">se</systemitem> top-level domain.</para><para>Organizing the namespace in a hierarchy of domain names nicely solves
the problem of name uniqueness; with DNS, a hostname has to be unique
only within its domain to give it a name different from all other
hosts worldwide. Furthermore, fully qualified names are easy to
remember.  Taken by themselves, these are already very good reasons to
split up a large domain into several subdomains.</para><para><indexterm significance="normal"><primary>delegating</primary><secondary>DNS
subdomains</secondary></indexterm>
<indexterm significance="normal"><primary>creating</primary><secondary>subdomains</secondary></indexterm>
<indexterm significance="normal"><primary>subdomains</primary><secondary>DNS</secondary></indexterm>
DNS does even more for you than this. It also allows you to delegate
authority over a subdomain to its administrators.  For example, the
maintainers at the Groucho Computing Center might create a subdomain
for each department; we already encountered the <systemitem moreinfo="none" role="sitename">math</systemitem> and <systemitem moreinfo="none" role="sitename">physics</systemitem> subdomains above. When they find
the network at the Physics department too large and chaotic to manage
from outside (after all, physicists are known to be an unruly bunch of
people), they may simply pass control of the <systemitem moreinfo="none" role="sitename">physics.groucho.edu</systemitem> domain to the
administrators of this network. These administrators are free to use
whatever hostnames they like and assign them IP addresses from their
network in whatever fashion they desire, without outside interference.</para><para><indexterm significance="normal" class="startofrange" id="dns.zones"><primary>DNS (Domain Name
System)</primary><secondary>zones</secondary></indexterm> To this end,
the namespace is split up into <emphasis>zones</emphasis>, each rooted
at a domain. Note the subtle difference between a
<emphasis>zone</emphasis> and a <emphasis>domain</emphasis>: the
domain <systemitem moreinfo="none" role="sitename">groucho.edu</systemitem>
encompasses all hosts at Groucho Marx University, while the zone
<systemitem moreinfo="none" role="sitename">groucho.edu</systemitem> includes only the
hosts that are managed by the Computing Center directly; those at the
Mathematics department, for example. The hosts at the Physics
department belong to a different zone, namely <systemitem moreinfo="none" role="sitename">physics.groucho.edu</systemitem>.  In <xref linkend="x-087-2-resolv.fig.dns"></xref>, the start of a zone is marked by a
small circle to the right of the domain name.</para><para><indexterm significance="normal"><primary>domains</primary><secondary>names</secondary></indexterm></para><sect2 id="x-087-2-resolv.dns.lookups"><title>Name Lookups with DNS</title><indexterm significance="normal"><primary>hostname</primary><secondary>lookup</secondary></indexterm><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>lookup</secondary></indexterm><indexterm significance="normal"><primary>name lookups</primary><secondary>via DNS</secondary></indexterm><para>At first glance, all this domain and zone fuss seems to make name
resolution an awfully complicated business. After all, if no central
authority controls what names are assigned to which hosts, how is a
humble application supposed to know?</para><para>Now comes the really ingenious part about DNS. If you want to find the
IP address of <systemitem moreinfo="none" role="sitename">erdos</systemitem>, DNS
says, Go ask the people who manage it, and they will tell
you.</para><para><indexterm significance="normal"><primary>name servers</primary></indexterm> In fact, DNS is
a giant distributed database. It is implemented by so-called name
servers that supply information on a given domain or set of
domains. For each zone there are at least two, or at most a few, name
servers that hold all authoritative information on hosts in that
zone. To obtain the IP address of <systemitem moreinfo="none" role="sitename">erdos</systemitem>, all you have to do is contact the
name server for the <systemitem moreinfo="none" role="sitename">groucho.edu</systemitem> zone, which will then return
the desired data.</para><para><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>query</secondary></indexterm>
Easier said than done, you might think. So how do I know how to reach
the name server at Groucho Marx University? In case your computer isn't
equipped with an address-resolving oracle, DNS provides for this, too.
When your application wants to look up information on
<systemitem moreinfo="none" role="sitename">erdos</systemitem>, it contacts a local name
server, which conducts a so-called iterative query for it. It starts off
by sending a query to a name server for the root domain, asking for the address
of <systemitem moreinfo="none" role="sitename">erdos.maths.groucho.edu</systemitem>. The root
name server recognizes that this name does not belong to its zone of authority,
but rather to one below the <systemitem moreinfo="none" role="sitename">edu</systemitem> domain.
Thus, it tells you to contact an <systemitem moreinfo="none" role="sitename">edu</systemitem>
zone name server for more information and encloses a list of all
<systemitem moreinfo="none" role="sitename">edu</systemitem> name servers along with their
addresses. Your local name server will then go on and query one of those,
for instance, <systemitem moreinfo="none" role="sitename">a.isi.edu</systemitem>. In a manner
similar to the root name server,
<systemitem moreinfo="none" role="sitename">a.isi.edu</systemitem> knows that the
<systemitem moreinfo="none" role="sitename">groucho.edu</systemitem> people run a zone of
their own, and points you to their servers. The local name server will then
present its query for <systemitem moreinfo="none" role="sitename">erdos</systemitem> to one
of these, which will finally recognize the name as belonging to its zone,
and return the corresponding IP address.

<graphic fileref="OREILLY.BIND.DIAGRAM"></graphic></para><para>This looks like a lot of traffic being generated for looking up a
measly IP address, but it's really only miniscule compared to the amount
of data that would have to be transferred if we were still stuck with
<filename moreinfo="none">HOSTS.TXT</filename>. There's still room for improvement with this
scheme, however.</para><para>To improve response time during future queries, the name server stores
the information obtained in its local <emphasis>cache</emphasis>. So
the next time anyone on your local network wants to look up the
address of a host in the <systemitem moreinfo="none" role="sitename">groucho.edu</systemitem> domain, your name server will
go directly to the <systemitem moreinfo="none" role="sitename">groucho.edu</systemitem> name server.<footnote id="x-087-2-fnis06"><para> If information weren't cached, then DNS
would be as inefficient as any other method because each query would
involve the root name servers.</para></footnote></para><para><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>time
to live</secondary></indexterm> Of course, the name server will not
keep this information forever; it will discard it after some time. The
expiration interval is called the <emphasis>time to live</emphasis>,
or TTL. Each datum in the DNS database is assigned such a TTL by
administrators of the responsible zone.</para></sect2><sect2 id="x-087-2-resolv.dns.auth"><title>Types of Name Servers</title><indexterm significance="normal"><primary>domain name servers</primary></indexterm><indexterm significance="normal"><primary>authoritative name server</primary></indexterm><indexterm significance="normal"><primary>name servers</primary><secondary>authoritative</secondary></indexterm><para>Name servers that hold all information on hosts within a zone are
called <emphasis>authoritative</emphasis> for this zone, and sometimes are
referred to as <emphasis>master name servers</emphasis>. Any query for a host
within this zone will end up at one of these master name servers.</para><para><indexterm significance="normal"><primary>synchronizing name servers</primary></indexterm>
<indexterm significance="normal"><primary>name servers</primary><secondary>synchronizing</secondary></indexterm>
<indexterm significance="normal"><primary>name servers</primary><secondary>secondary</secondary></indexterm>
<indexterm significance="normal"><primary>name servers</primary><secondary>primary</secondary></indexterm>
Master servers must be fairly well synchronized. Thus, the zone's
network administrator must make one the <emphasis>primary</emphasis>
server, which loads its zone information from data files, and make
the others <emphasis>secondary</emphasis> servers, which transfer the
zone data from the primary server at regular intervals.</para><para>Having several name servers distributes workload; it also provides
backup. When one name server machine fails in a benign way, like
crashing or losing its network connection, all queries will fall back
to the other servers. Of course, this scheme doesn't protect you from
server malfunctions that produce wrong replies to all DNS requests,
such as from software bugs in the server program itself.</para><para><indexterm significance="normal"><primary>name servers</primary><secondary>caching-only</secondary></indexterm>
You can also run a name server that is not authoritative for any
domain.<footnote id="x-087-2-fnis07"><para>Well, almost. A name server has to provide at least name service for
<systemitem moreinfo="none" role="sitename">localhost</systemitem> and reverse lookups of
<systemitem moreinfo="none" role="sitename">127.0.0.1</systemitem>.</para></footnote> This is useful, as the name server will still be able to
conduct DNS queries for the applications running on the local network
and cache the information. Hence it is called a
<emphasis>caching-only</emphasis> server.</para></sect2><sect2 id="x-087-2-resolv.dns.records"><title>The DNS Database</title><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>databases</secondary></indexterm><para>We have seen that DNS not only deals with IP addresses of hosts, but
also exchanges information on name servers. DNS databases may
have, in fact, many different types of entries.</para><para><indexterm significance="normal"><primary>DNS (Domain Name
System)</primary><secondary>resource record</secondary></indexterm> A
single piece of information from the DNS database is called a
<emphasis>resource record</emphasis> (RR). Each record has a type
associated with it describing the sort of data it represents, and a
class specifying the type of network it applies to. The latter
accommodates the needs of different addressing schemes, like
<indexterm significance="normal"><primary>Hesiod addresses</primary></indexterm>
<indexterm significance="normal"><primary>addresses</primary><secondary>Hesiod</secondary></indexterm>
IP addresses (the IN class), Hesiod addresses (used by MIT's
Kerberos system), and a few more. The prototypical resource record
type is the A record, which associates a fully qualified domain name
with an IP address.</para><para><indexterm significance="normal"><primary>canonical hostname</primary></indexterm>
<indexterm significance="normal"><primary>hostname</primary><secondary>canonical</secondary></indexterm>
<indexterm significance="normal"><primary>aliases</primary><secondary>hostname</secondary></indexterm>
A host may be known by more than one name. For example you might have
a server that provides both FTP and World Wide Web servers, which you
give two names: <systemitem moreinfo="none" role="sitename">ftp.machine.org</systemitem> and <systemitem moreinfo="none" role="sitename">www.machine.org</systemitem>. However, one of these
names must be identified as the official or
<emphasis>canonical</emphasis> hostname, while the others are simply
aliases referring to the official hostname. The difference is that the
canonical hostname is the one with an associated A record, while the
others only have a record of type CNAME that points to the canonical
hostname.</para><para>We will not go through all record types here, but we will give you a brief
example. <xref linkend="x-087-2-resolv.fig.hosts"></xref> shows a part of the
domain database that is loaded into the name servers for the
<systemitem moreinfo="none" role="sitename">physics.groucho.edu</systemitem> zone.</para><example id="x-087-2-resolv.fig.hosts"><title>An Excerpt from the named.hosts File for the Physics Department</title><programlisting format="linespecific">; Authoritative Information on physics.groucho.edu.
@  IN  SOA niels.physics.groucho.edu. janet.niels.physics.groucho.edu. {
                  1999090200       ; serial no
                  360000           ; refresh
                  3600             ; retry
                  3600000          ; expire
                  3600             ; default ttl
                }
;
; Name servers
              IN    NS       niels
              IN    NS       gauss.maths.groucho.edu.
gauss.maths.groucho.edu. IN A 149.76.4.23
;
; Theoretical Physics (subnet 12)
niels         IN    A        149.76.12.1
              IN    A        149.76.1.12
name server    IN    CNAME    niels
otto          IN    A        149.76.12.2
quark         IN    A        149.76.12.4
down          IN    A        149.76.12.5
strange       IN    A        149.76.12.6
...
; Collider Lab. (subnet 14)
boson         IN    A        149.76.14.1
muon          IN    A        149.76.14.7
bogon         IN    A        149.76.14.12
...</programlisting></example><para><indexterm significance="normal"><primary>SOA (DNS record)</primary></indexterm>
<indexterm significance="normal"><primary>authoritative name server</primary></indexterm>
<indexterm significance="normal"><primary>name servers</primary><secondary>authoritative</secondary></indexterm>
<indexterm significance="normal"><primary>Start of Authority</primary></indexterm>
Apart from the A and CNAME records, you can see a special record at the top
of the file, stretching several lines. This is the SOA resource record
signaling the <emphasis>Start of Authority</emphasis>, which holds general
information on the zone the server is authoritative for. The SOA record
comprises, for instance, the default time to live for all records.</para><para>Note that all names in the sample file that do not end with a dot
should be interpreted relative to the <systemitem moreinfo="none" role="sitename">physics.groucho.edu</systemitem> domain. The special
name (<systemitem moreinfo="none" role="sitename">@</systemitem>) used in the
<literal moreinfo="none">SOA</literal> record refers to the domain name by itself.</para><para><indexterm significance="normal"><primary>glue records</primary></indexterm> We have seen
earlier that the name servers for the <systemitem moreinfo="none" role="sitename">groucho.edu</systemitem> domain somehow have to know
about the <systemitem moreinfo="none" role="sitename">physics</systemitem> zone so
that they can point queries to their name servers. This is usually
achieved by a pair of records: the NS record that gives the server's
FQDN, and an A record that associates an address with that name. Since
these records are what holds the namespace together, they are
frequently called <emphasis>glue records</emphasis>. They are the only
instances of records in which a parent zone actually holds information
on hosts in the subordinate zone. The glue records pointing to the
name servers for <systemitem moreinfo="none" role="sitename">physics.groucho.edu</systemitem> are shown in <xref linkend="x-087-2-resolv.fig.nsptr"></xref>.</para><example id="x-087-2-resolv.fig.nsptr"><title>An Excerpt from the named.hosts File for GMU</title><programlisting format="linespecific"> ; Zone data for the groucho.edu zone.
 @  IN  SOA vax12.gcc.groucho.edu. joe.vax12.gcc.groucho.edu. {
                      1999070100       ; serial no
                      360000           ; refresh
                      3600             ; retry
                      3600000          ; expire
                      3600             ; default ttl
               }
 ....
 ;
 ; Glue records for the physics.groucho.edu zone
 physics        IN     NS        niels.physics.groucho.edu.
                IN     NS        gauss.maths.groucho.edu.
 niels.physics  IN     A         149.76.12.1
 gauss.maths    IN     A         149.76.4.23
 ...</programlisting></example></sect2><sect2 id="x-087-2-resolv.dns.in-addr"><title>Reverse Lookups</title><indexterm significance="normal"><primary>reverse mapping</primary></indexterm><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>reverse mapping</secondary></indexterm><indexterm significance="normal"><primary>looking up addresses</primary></indexterm><indexterm significance="normal"><primary>addresses</primary><secondary>mapping to hostnames</secondary></indexterm><indexterm significance="normal"><primary>hostname</primary><secondary>obtaining from address</secondary></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>addresses</secondary><tertiary>hostname and</tertiary></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>networks</secondary></indexterm><indexterm significance="normal"><primary sortas="in addr.arpa domain">in-addr.arpa domain</primary></indexterm><para>Finding the IP address belonging to a host is certainly the most
common use for the Domain Name System, but sometimes you'll want to
find the canonical hostname corresponding to an address. Finding this
hostname is called <emphasis>reverse mapping</emphasis>, and is used
by several network services to verify a client's identity. When using
a single <filename moreinfo="none">hosts</filename> file, reverse lookups simply
involve searching the file for a host that owns the IP address in
question. With DNS, an exhaustive search of the namespace is out of
the question.  Instead, a special domain, <systemitem moreinfo="none" role="sitename">in-addr.arpa</systemitem>, has been created that
contains the IP addresses of all hosts in a reversed dotted quad
notation.  For instance, an IP address of <systemitem moreinfo="none" role="sitename">149.76.12.4</systemitem> corresponds to the name
<systemitem moreinfo="none" role="sitename">4.12.76.149.in-addr.arpa</systemitem>. The
resource-record type linking these names to their canonical hostnames
is PTR.</para><para><indexterm significance="normal"><primary>name servers</primary><secondary>authoritative</secondary></indexterm>
<indexterm significance="normal"><primary>delegating</primary><secondary>DNS subdomains</secondary></indexterm>
<indexterm significance="normal"><primary>creating</primary><secondary>subnets</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>subnets</secondary></indexterm>
<indexterm significance="normal"><primary>subdomains</primary><secondary>DNS</secondary></indexterm>

Creating a zone of authority usually means that its administrators
have full control over how they assign addresses to names.  Since they
usually have one or more IP networks or subnets at their hands,
there's a one-to-many mapping between DNS zones and IP networks. The
Physics department, for instance, comprises the subnets <systemitem moreinfo="none" role="sitename">149.76.8.0</systemitem>, <systemitem moreinfo="none" role="sitename">149.76.12.0</systemitem>, and <systemitem moreinfo="none" role="sitename">149.76.14.0</systemitem>.</para><para>Consequently, new zones in the <systemitem moreinfo="none" role="sitename">in-addr.arpa</systemitem> domain have to be created
along with the <systemitem moreinfo="none" role="sitename">physics</systemitem> zone,
and delegated to the network administrators at the department:
<systemitem moreinfo="none" role="sitename">8.76.149.in-addr.arpa</systemitem>,
<systemitem moreinfo="none" role="sitename">12.76.149.in-addr.arpa</systemitem>, and
<systemitem moreinfo="none" role="sitename">14.76.149.in-addr.arpa</systemitem>.
Otherwise, installing a new host at the Collider Lab would require
them to contact their parent domain to have the new address entered
into their <systemitem moreinfo="none" role="sitename">in-addr.arpa</systemitem> zone
file.</para><para>The zone database for subnet 12 is shown in
<xref linkend="x-087-2-resolv.fig.subnet12"></xref>. The corresponding glue records
in the database of their parent zone are shown in
<xref linkend="x-087-2-resolv.fig.groucho-rev"></xref>.</para><example id="x-087-2-resolv.fig.subnet12"><title>An Excerpt from the named.rev File for Subnet 12</title><programlisting format="linespecific"> ; the 12.76.149.in-addr.arpa domain.
 @  IN  SOA  niels.physics.groucho.edu. janet.niels.physics.groucho.edu. {
                      1999090200 360000 3600 3600000 3600
            }
 2        IN     PTR       otto.physics.groucho.edu.
 4        IN     PTR       quark.physics.groucho.edu.
 5        IN     PTR       down.physics.groucho.edu.
 6        IN     PTR       strange.physics.groucho.edu.</programlisting></example><example id="x-087-2-resolv.fig.groucho-rev"><title>An Excerpt from the named.rev File for Network 149.76</title><programlisting format="linespecific"> ; the 76.149.in-addr.arpa domain.
 @  IN  SOA vax12.gcc.groucho.edu. joe.vax12.gcc.groucho.edu. {
                      1999070100 360000 3600 3600000 3600
                  }
 ...
 ; subnet 4: Mathematics Dept.
 1.4        IN     PTR      sophus.maths.groucho.edu.
 17.4       IN     PTR      erdos.maths.groucho.edu.
 23.4       IN     PTR      gauss.maths.groucho.edu.
 ...
 ; subnet 12: Physics Dept, separate zone
 12         IN     NS       niels.physics.groucho.edu.
            IN     NS       gauss.maths.groucho.edu.
 niels.physics.groucho.edu. IN  A 149.76.12.1
 gauss.maths.groucho.edu. IN  A   149.76.4.23
 ...</programlisting></example><para><indexterm significance="normal"><primary>creating</primary><secondary>DNS zones</secondary></indexterm>
<systemitem moreinfo="none" role="sitename">in-addr.arpa</systemitem> system zones can
only be created as supersets of IP networks. An even more severe
restriction is that these networks' netmasks have to be on byte
boundaries. All subnets at Groucho Marx University have a netmask of
<systemitem moreinfo="none" role="sitename">255.255.255.0</systemitem>, hence an
<systemitem moreinfo="none" role="sitename">in-addr.arpa</systemitem> zone could be
created for each subnet. However, if the netmask were <systemitem moreinfo="none" role="sitename">255.255.255.128</systemitem> instead, creating zones
for the subnet <systemitem moreinfo="none" role="sitename">149.76.12.128</systemitem>
would be impossible, because there's no way to tell DNS that the
<systemitem moreinfo="none" role="sitename">12.76.149.in-addr.arpa</systemitem> domain
has been split into two zones of authority, with hostnames ranging from
<systemitem moreinfo="none" role="sitename">1</systemitem> through
<systemitem moreinfo="none" role="sitename">127</systemitem>, and
<systemitem moreinfo="none" role="sitename">128</systemitem> through
<systemitem moreinfo="none" role="sitename">255</systemitem>, respectively.</para><indexterm significance="normal" class="endofrange" startref="dns.zones"></indexterm></sect2></sect1><sect1 id="x-087-2-resolv.named"><title>Running named</title><indexterm significance="normal" class="startofrange" id="idx-commandnamedcommand-1"><primary>named program</primary></indexterm><indexterm significance="normal" class="startofrange" id="idx-name-serverconfiguring-1"><primary>name servers</primary><secondary>configuring</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-configuringname-server-1"><primary>configuring</primary><secondary>name server</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-dnsconfiguringserver-1"><primary>DNS (Domain Name System)</primary><secondary>configuring server</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-bind-1"><primary>BIND (Berkeley Internet Name Domain)</primary></indexterm><para><command moreinfo="none">named</command> (pronounced <emphasis>name-dee</emphasis>)
provides DNS on most Unix machines.  It is a server program
originally developed for BSD to provide name service to clients, and
possibly to other name servers. BIND Version 4 was around for some
time and appeared in most Linux distributions. The new release,
Version 8, has been introduced in most Linux distributions, and is a
big change from previous versions.<footnote id="x-087-2-fndn01"><para>BIND 4.9 was developed by Paul Vixie,
<systemitem moreinfo="none" role="emailaddr">paul@vix.com</systemitem>,
but BIND is now maintained by the Internet Software Consortium,
<systemitem moreinfo="none" role="emailaddr">bind-bugs@isc.org</systemitem>.</para></footnote>
It has many new features, such as support for DNS dynamic updates, DNS
change notifications, much improved performance, and a new
configuration file syntax. Please check the documentation contained
in the source distribution for details.</para><para>This section requires some understanding of the way DNS works. If the
following discussion is all Greek to you, you may want to reread the
section <xref linkend="x-087-2-resolv.howdnsworks"></xref>."</para><para><indexterm significance="normal"><primary sortas="etc/named.boot file">/etc/named.boot
file</primary></indexterm> <indexterm significance="normal"><primary>zone
files</primary></indexterm> <command moreinfo="none">named</command> is usually
started at system boot time and runs until the machine goes down
again. Implementations of BIND prior to Version 8 take their
information from a configuration file called
<command moreinfo="none">/etc/named.boot</command> and various files that map domain
names to addresses. The latter are called <emphasis>zone
files</emphasis>.  Versions of BIND from Version 8 onwards use
<filename moreinfo="none">/etc/named.conf</filename> in place of
<filename moreinfo="none">/etc/named.boot</filename>.</para><?troff .Nd 10?><para>To run <command moreinfo="none">named</command> at the prompt, enter:

<screen format="linespecific"># <userinput moreinfo="none">/usr/sbin/named</userinput></screen>
</para><para><command moreinfo="none">named</command> will come up and read the <command moreinfo="none">named.boot</command>
file and any zone files specified therein. It writes its process ID to
<filename moreinfo="none">/var/run/named.pid</filename> in ASCII, downloads any zone files
from primary servers, if necessary, and starts listening on port 53 for DNS
queries.</para><sect2><title>The named.boot File</title><para><indexterm significance="normal" class="startofrange" id="idx-namedboot-1"><primary sortas="named boot file">named.boot file</primary></indexterm> The
BIND configuration file prior to Version 8 was very simple in
structure.  BIND Version 8 has a very different configuration file
syntax to deal with many of the new features introduced. The name of
the configuration file changed from
<filename moreinfo="none">/etc/named.boot</filename>, in older versions of BIND, to
<filename moreinfo="none">/etc/named.conf</filename> in BIND Version 8.  We'll focus
on configuring the older version because it is probably what most
distributions are still using, but we'll present an equivalent
<filename moreinfo="none">named.conf</filename> to illustrate the differences, and
we'll talk about how to convert the old format into the new one.</para><para>The <command moreinfo="none">named.boot</command> file is generally small and contains
little but pointers to master files containing zone information and
pointers to other name servers. Comments in the boot file start with the
(#) or (;) characters and extend to the next newline. Before we discuss
the format of <filename moreinfo="none">named.boot</filename> in more detail, we will take a
look at the sample file for <systemitem moreinfo="none" role="sitename">vlager</systemitem>
given in <xref linkend="x-087-2-resolv.fig.named.boot"></xref>.</para><example id="x-087-2-resolv.fig.named.boot"><title>The named.boot File for vlager</title><screen format="linespecific">;
; /etc/named.boot file for vlager.vbrew.com
;
directory     /var/named
;
;             domain                   file
;-----------------
cache         .                        named.ca
primary       vbrew.com                named.hosts
primary       0.0.127.in-addr.arpa     named.local
primary       16.172.in-addr.arpa      named.rev</screen></example><para>Let's look at each statement individually. The
<systemitem moreinfo="none" role="keyword">directory</systemitem> keyword tells
<command moreinfo="none">named</command> that all filenames referred to later in this file,
zone files for example, are located in the <filename moreinfo="none">/var/named</filename>
directory. This saves a little typing.</para><para>The <systemitem moreinfo="none" role="keyword">primary</systemitem> keyword shown in
this example loads information into <command moreinfo="none">named</command>. This
information is taken from the master files specified as the last of
the parameters. These files represent DNS resource records, which we
will look at next.</para><para>In this example, we configured <command moreinfo="none">named</command> as the primary
name server for three domains, as indicated by the three <systemitem moreinfo="none" role="keyword">primary</systemitem> statements.  The first of these
statements instructs <command moreinfo="none">named</command> to act as a primary
server for <systemitem moreinfo="none" role="sitename">vbrew.com</systemitem>, taking
the zone data from the file <filename moreinfo="none">named.hosts</filename>.</para><para>The <systemitem moreinfo="none" role="keyword">cache</systemitem> keyword is very special and
should be present on virtually all machines running a name server. It
instructs <command moreinfo="none">named</command> to enable its cache and to load
the <emphasis>root name server hints</emphasis> from the cache file specified
(<filename moreinfo="none">named.ca</filename> in our example). We will come back to the name
server hints in the following list.</para><para>Here's a list of the most important options you can use in
<filename moreinfo="none">named.boot</filename>:

<variablelist><varlistentry><term><systemitem moreinfo="none" role="keyword">directory</systemitem></term><listitem><para> This
option specifies a directory in which zone files reside. Names of
files in other options may be given relative to this
directory. Several directories may be specified by repeatedly using
<systemitem moreinfo="none" role="keyword">directory</systemitem>. The Linux file
system standard suggests this should be
<filename moreinfo="none">/var/named</filename>.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">primary</systemitem></term><listitem><para><indexterm significance="normal"><primary>primary option (BIND)</primary></indexterm>
<indexterm significance="normal"><primary>name servers</primary><secondary>primary</secondary></indexterm>
This option takes a domain name and filename as an argument, declaring the local
server authoritative for the named domain. As a primary server,
<command moreinfo="none">named</command> loads the zone information from the given master file.</para><para>There will always be at least one <systemitem moreinfo="none" role="keyword">primary</systemitem>
entry in every boot file used for reverse mapping of network
<systemitem moreinfo="none" role="sitename">127.0.0.0</systemitem>, which is the local
loopback network.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">secondary</systemitem></term><listitem><para><indexterm significance="normal"><primary>secondary option (BIND)</primary></indexterm>
<indexterm significance="normal"><primary>name
servers</primary><secondary>secondary</secondary></indexterm> This
statement takes a domain name, an address list, and a filename as an
argument. It declares the local server a secondary master server for
the specified domain.</para><para>A secondary server holds authoritative data on the domain, too, but it
doesn't gather it from files; instead, it tries to download it from
the primary server. The IP address of at least one primary server thus
must be given to <command moreinfo="none">named</command> in the address list. The
local server contacts each of them in turn until it successfully
transfers the zone database, which is then stored in the backup file
given as the third argument. If none of the primary servers responds,
the zone data is retrieved from the backup file instead.</para><para><command moreinfo="none">named</command> then attempts to refresh the zone data at
regular intervals. This process is explained later in connection with
the SOA resource record type.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">cache</systemitem></term><listitem><para><indexterm significance="normal"><primary>cache (BIND option)</primary></indexterm>
<indexterm significance="normal"><primary>name
servers</primary><secondary>cache</secondary></indexterm> This option
takes a domain name and filename as arguments. This file contains
the root server hints, which is a list of records pointing to the root
name servers. Only NS and A records will be recognized. The
<replaceable>domain</replaceable> should be the root domain name, a
simple period (.).</para><para><?troff .hw situation?><?troff .hw follows?>This information is absolutely crucial to <command moreinfo="none">named</command>; if
the <systemitem moreinfo="none" role="keyword">cache</systemitem> statement does not
occur in the boot file, <command moreinfo="none">named</command> will not develop a
local cache at all. This situation/lack of development will severely
degrade performance and increase network load if the next server
queried is not on the local net. Moreover, <command moreinfo="none">named</command>
will not be able to reach any root name servers, and thus won't
resolve any addresses except those it is authoritative for. An
exception from this rule involves forwarding servers (see the
<systemitem moreinfo="none" role="keyword">forwarders</systemitem> option that
follows).</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">forwarders</systemitem></term><listitem><para> This
statement takes a whitespace-separated list of addresses as an
argument.  The IP addresses in this list specify a list of name
servers that <command moreinfo="none">named</command> may query if it fails to resolve
a query from its local cache. They are tried in order until one of
them responds to the query. Typically, you would use the name server of
your network provider or another well-known server as a forwarder.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">slave</systemitem></term><listitem><para><indexterm significance="normal"><primary>name
servers</primary><secondary>slave</secondary></indexterm> This
statement makes the name server a <emphasis>slave</emphasis>
server. It never performs recursive queries itself, but only forwards
them to servers specified in the <systemitem moreinfo="none" role="keyword">forwarders</systemitem> statement.  </para></listitem></varlistentry></variablelist>

There are two options that we will not describe here: <systemitem moreinfo="none" role="keyword">sortlist</systemitem> and <systemitem moreinfo="none" role="keyword">domain</systemitem>. Two other directives may also be
used inside these database files: <systemitem moreinfo="none" role="keyword">INCLUDE</systemitem> and <systemitem moreinfo="none" role="keyword">ORIGIN</systemitem>. Since they are rarely
needed, we will not describe them here, either.</para><indexterm significance="normal" class="endofrange" startref="idx-namedboot-1"></indexterm></sect2><sect2><title>The BIND 8 host.conf File</title><indexterm significance="normal"><primary sortas="named conf file">named.conf file</primary></indexterm><para>BIND Version 8 introduced a range of new features, and with these came
a new configuration file syntax. The <filename moreinfo="none">named.boot</filename>,
with its simple single line statements, was replaced by the
<filename moreinfo="none">named.conf</filename> file, with a syntax like that of
<command moreinfo="none">gated</command> and resembling C source syntax.</para><para>The new syntax is more complex, but fortunately a tool has been
provided that automates conversion from the old syntax to the new
syntax. In the BIND 8 <indexterm significance="normal"><primary>named-bootconf.pl
command</primary></indexterm> source package, a
<command moreinfo="none">perl</command> program called
<command moreinfo="none">named-bootconf.pl</command> is provided that will read your
existing <filename moreinfo="none">named.boot</filename> file from
<literal moreinfo="none">stdin</literal> and convert it into the equivalent
<filename moreinfo="none">named.conf</filename> format on
<literal moreinfo="none">stdout</literal>. To use it, you must have the
<command moreinfo="none">perl</command> interpreter installed.</para><para>You should use the script somewhat like this:

<screen format="linespecific"># <userinput moreinfo="none">cd /etc</userinput>
# <userinput moreinfo="none">named-bootconf.pl named.boot named.conf</userinput></screen>

The script then produces a <filename moreinfo="none">named.conf</filename> that looks
like that shown in <xref linkend="x-087-2-resolv.fig.named.conf"></xref>. We've cleaned out a few of
the helpful comments the script includes to help show the almost
direct relationship between the old and the new syntax.</para><example id="x-087-2-resolv.fig.named.conf"><title>The BIND 8 equivalent named.conf File for vlager</title><screen format="linespecific">// 
// /etc/named.boot file for vlager.vbrew.com                                     
options {
	directory "/var/named";
};

zone "." {
	type hint;
	file "named.ca";
};

zone "vbrew.com" {
	type master;
	file "named.hosts";
};

zone "0.0.127.in-addr.arpa" {
	type master;
	file "named.local";
};

zone "16.172.in-addr.arpa" {
	type master;
	file "named.rev";
};</screen></example><para>If you take a close look, you will see that each of the one-line statements in
<filename moreinfo="none">named.boot</filename> has been converted into a C-like statement
enclosed within {} characters in the
<filename moreinfo="none">named.conf</filename> file.</para><para>The comments, which in the <filename moreinfo="none">named.boot</filename> file were
indicated by a semicolon (;), are now indicated by two
forward slashes (//).</para><para>The <systemitem moreinfo="none" role="keyword">directory</systemitem> statement has been
translated into an <systemitem moreinfo="none" role="keyword">options</systemitem> paragraph
with a <systemitem moreinfo="none" role="keyword">directory</systemitem> clause.</para><para>The <systemitem moreinfo="none" role="keyword">cache</systemitem> and
<systemitem moreinfo="none" role="keyword">primary</systemitem> statements have been converted
into <systemitem moreinfo="none" role="keyword">zone</systemitem> paragraphs with
<systemitem moreinfo="none" role="keyword">type</systemitem> clauses of
<systemitem moreinfo="none" role="keyword">hint</systemitem> and
<systemitem moreinfo="none" role="keyword">master</systemitem>, respectively.</para><para>The zone files do not need to be modified in any way; their syntax remains
unchanged.</para><para>The new configuration syntax allows for many new options that we
haven't covered here. If you'd like information on the new options,
the best source of information is the documentation supplied with the
BIND Version 8 source package.</para></sect2><sect2><title>The DNS Database Files</title><para><indexterm significance="normal"><primary>DNS (Domain Name
System)</primary><secondary>databases</secondary></indexterm> Master
files included with <command moreinfo="none">named</command>, like
<command moreinfo="none">named.hosts</command>, always have a domain associated with
them, which is called the <emphasis>origin</emphasis>. This is the
domain name specified with the <systemitem moreinfo="none" role="keyword">cache</systemitem> and <systemitem moreinfo="none" role="keyword">primary</systemitem> options. Within a master file, you
are allowed to specify domain and host names relative to this
domain. A name given in a configuration file is considered
<emphasis>absolute</emphasis> if it ends in a single dot, otherwise it
is considered relative to the origin. The origin by itself may be
referred to using (<systemitem moreinfo="none" role="keyword">@</systemitem>).</para><para><indexterm significance="normal"><primary>DNS (Domain Name
System)</primary><secondary>resource record</secondary></indexterm>
<indexterm significance="normal"><primary>resource record (RR)</primary></indexterm>
<indexterm significance="normal"><primary>RR (resource record)</primary></indexterm> The
data contained in a master file is split up in <emphasis>resource
records</emphasis>(RRs). RRs are the smallest units of information
available through DNS. Each resource record has a type. A records, for
instance, map a hostname to an IP address, and a CNAME record
associates an alias for a host with its official hostname. To see an
example, look at <xref linkend="x-087-2-resolv.fig.named.hosts"></xref>, which shows the
<command moreinfo="none">named.hosts</command> master file for the Virtual Brewery.</para><para>Resource record representations in master files share a
common format:

<screen format="linespecific">[<replaceable>domain</replaceable>] [<replaceable>ttl</replaceable>] [<replaceable>class</replaceable>] <replaceable>type</replaceable> <replaceable>rdata</replaceable></screen></para><para>Fields are separated by spaces or tabs. An entry may be continued across
several lines if an opening brace occurs before the first newline and the
last field is followed by a closing brace. Anything between a semicolon and
a newline is ignored. A description of the format terms follows:</para><variablelist><varlistentry><term><replaceable>domain</replaceable></term><listitem><para>This term is the domain name to which the entry applies. If no domain name is
given, the RR is assumed to apply to the domain of the previous RR.</para></listitem></varlistentry><varlistentry><term><replaceable>ttl</replaceable></term><listitem><para><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>time to live</secondary></indexterm>
In order to force resolvers to discard information after a certain time, each
RR is associated a time to live (<emphasis>ttl</emphasis>). The
ttl field specifies the time in seconds that the
information is valid after it has been retrieved from the server. It is a
decimal number with at most eight digits.</para><para>If no ttl value is given, the field value defaults to that of the
<replaceable>minimum</replaceable> field of the preceding SOA record.</para></listitem></varlistentry><varlistentry><term><replaceable>class</replaceable></term><listitem><para>This is an address class, like IN for IP addresses or HS for objects in the
Hesiod class. For TCP/IP networking, you have to specify IN.</para><para>If no class field is given, the class of the preceding RR is assumed.</para></listitem></varlistentry><varlistentry><term><replaceable>type</replaceable></term><listitem><para>This describes the type of the RR. The most common types are A, SOA, PTR,
and NS.  The following sections describe the various types of RRs.</para></listitem></varlistentry><varlistentry><term><replaceable>rdata</replaceable></term><listitem><para>This holds the data associated with the RR. The format of this field
depends on the type of RR. In the following discussion, it will be
described for each RR separately.</para></listitem></varlistentry></variablelist><para>The following is partial list of RRs to be used in DNS master files. There
are a couple more of them that we will not explain; they are experimental
and of little use, generally.</para><variablelist><varlistentry><term><emphasis>SOA</emphasis></term><listitem><para><indexterm significance="normal"><primary>authoritative name server</primary></indexterm>
<indexterm significance="normal"><primary>SOA (DNS record)</primary></indexterm>
<indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>zones</secondary></indexterm>
This RR describes a zone of authority (SOA means Start of Authority).
It signals that the records following the SOA RR contain authoritative
information for the domain. Every master file included by a
<systemitem moreinfo="none" role="keyword">primary</systemitem> statement must contain an SOA
record for this zone. The resource data contains the following fields:

<variablelist><varlistentry><term><replaceable>origin</replaceable></term><listitem><para>This field is the canonical hostname of the primary name server for this domain.
It is usually given as an absolute name.</para></listitem></varlistentry><varlistentry><term><replaceable>contact</replaceable></term><listitem><para>This field is the email address of the person responsible for maintaining the
domain, with the "<systemitem moreinfo="none" role="keyword">@</systemitem>" sign replaced
by a dot. For instance, if the responsible person at the Virtual Brewery
were <systemitem moreinfo="none" role="userid">janet</systemitem>, this field would
contain <systemitem moreinfo="none" role="keyword">janet.vbrew.com</systemitem>.</para></listitem></varlistentry><varlistentry><term><replaceable>serial</replaceable></term><listitem><para>This field is the version number of the zone file, expressed as a single decimal
number. Whenever data is changed in the zone file, this number should be
incremented. A common convention is to use a number that reflects the date
of the last update, with a version number appended to it to cover the case
of multiple updates occurring on a single day, e.g., 2000012600 being update 00
that occurred on January 26, 2000.</para><para>The serial number is used by secondary name servers to recognize zone
information changes. To stay up to date, secondary servers request the
primary server's SOA record at certain intervals and compare the
serial number to that of the cached SOA record. If the number has
changed, the secondary servers transfer the whole zone database from
the primary server.</para></listitem></varlistentry><varlistentry><term><replaceable>refresh</replaceable></term><listitem><para>This field specifies the interval in seconds that the secondary servers should wait
between checking the SOA record of the primary server. Again, this is a
decimal number with at most eight digits.</para><para>Generally, the network topology doesn't change too often, so this number
should specify an interval of roughly a day for larger networks, and even
more for smaller ones.</para></listitem></varlistentry><varlistentry><term><replaceable>retry</replaceable></term><listitem><para>This number determines the intervals at which a secondary server should retry
contacting the primary server if a request or a zone refresh fails. It must
not be too low, or a temporary failure of the server or a network problem
could cause the secondary server to waste network resources. One hour, or
perhaps one-half hour, might be a good choice.</para></listitem></varlistentry><varlistentry><term><replaceable>expire</replaceable></term><listitem><para>This field specifies the time in seconds after which a secondary server should
finally discard all zone data if it hasn't been able to contact the primary
server. You should normally set this field to at least a week (604,800 seconds), but
increasing it to a month or more is also reasonable.</para></listitem></varlistentry><varlistentry><term><replaceable>minimum</replaceable></term><listitem><para>This field is the default <emphasis>ttl</emphasis> value for resource records that
do not explicitly contain one. The ttl value specifies
the maximum amount of time other name servers may keep the RR in their cache. This time applies only to normal lookups, and has nothing to do with the time after
which a secondary server should try to update the zone information.</para><para>If the topology of your network does not change frequently, a week or even
more is probably a good choice. If single RRs change more frequently, you could
still assign them smaller ttls individually. If your network changes frequently, you may want to set
<replaceable>minimum</replaceable> to one day (86,400 seconds).</para></listitem></varlistentry></variablelist>
</para></listitem></varlistentry><varlistentry><term>A</term><listitem><para><indexterm significance="normal"><primary>A (DNS record)</primary></indexterm>
<indexterm significance="normal"><primary>addresses</primary><secondary>DNS resource record</secondary></indexterm>
This record associates an IP address with a hostname. The resource data field
contains the address in dotted quad notation.</para><para><indexterm significance="normal"><primary>hostname</primary><secondary>canonical</secondary></indexterm>
<indexterm significance="normal"><primary>canonical hostname</primary></indexterm>
<indexterm significance="normal"><primary>CNAME (DNS record)</primary></indexterm>
<indexterm significance="normal"><primary>hostname</primary><secondary>aliases</secondary></indexterm>
<indexterm significance="normal"><primary>aliases</primary><secondary>hostname</secondary></indexterm>
For each hostname, there must be only one A record. The hostname used in
this A record is considered the official or <emphasis>canonical</emphasis>
hostname. All other hostnames are aliases and must be mapped onto the
canonical hostname using a CNAME record. If the canonical name of
our host were <emphasis role="bold">vlager</emphasis>, we'd have
an A record that associated that hostname with its IP address. Since we may
also want another name associated with that address, say
<systemitem moreinfo="none" role="sitename">news</systemitem>, we'd create a
CNAME record that associates this alternate name with the canonical name.
We'll talk more about CNAME records shortly.</para></listitem></varlistentry><varlistentry><term>NS</term><listitem><para>NS records are used to specify a zone's primary server and all its secondary
servers.  An NS record points to a master name server of the given zone, with
the resource data field containing the hostname of the name server.</para><para>You will meet NS records in two situations: The first situation is when you delegate
authority to a subordinate zone; the second is within the master zone database
of the subordinate zone itself. The sets of servers specified in both the
parent and delegated zones should match.</para><para>The NS record specifies the name of the primary and secondary name
servers for a zone. These names must be resolved to an address so they
can be used. Sometimes the servers belong to the domain they are
serving, which causes a chicken and egg problem; we
can't resolve the address until the name server is reachable, but we
can't reach the name server until we resolve its address. To solve
this dilemma, we can configure special A records directly into the
name server of the parent zone. The A records allow the name servers
of the parent domain to resolve the IP address of the delegated
zone name servers. These records are commonly called <emphasis>glue
records</emphasis> because they provide the glue that
binds a delegated zone to its parent.</para></listitem></varlistentry><varlistentry><term>CNAME</term><listitem><para>This record associates an alias with a host's <emphasis>canonical
hostname</emphasis>. It provides an alternate name by which
users can refer to the host whose canonical name is supplied as a
parameter. The canonical hostname is the one the master file provides
an A record for; aliases are simply linked to that name by a CNAME
record, but don't have any other records of their own.</para></listitem></varlistentry><varlistentry><term>PTR</term><listitem><para><indexterm significance="normal"><primary>PTR (DNS record)</primary></indexterm>
This type of record is used to associate names in the
<systemitem moreinfo="none" role="sitename">in-addr.arpa</systemitem> domain with hostnames.
It is used for reverse mapping of IP addresses to hostnames. The hostname
given must be the canonical hostname.</para></listitem></varlistentry><varlistentry><term>MX</term><listitem><para><indexterm significance="normal"><primary>MX (DNS record)</primary></indexterm>
This RR announces a <emphasis>mail exchanger</emphasis> for a domain.
Mail exchangers are discussed in 
<xref linkend="x-087-2-mail.routing.internet"></xref>. The syntax of an MX record is:

<screen format="linespecific">[<replaceable>domain</replaceable>] [<replaceable>ttl</replaceable>] [<replaceable>class</replaceable>] MX <replaceable>preference</replaceable> <replaceable>host</replaceable></screen></para><para><replaceable>host</replaceable> names the mail exchanger for
<replaceable>domain</replaceable>. Every mail exchanger has an integer
<replaceable>preference</replaceable> associated with it. A mail transport
agent that wants to deliver mail to <replaceable>domain</replaceable>
tries all hosts who have an MX record for this domain until it succeeds.
The one with the lowest preference value is tried first, then the others, in
order of increasing preference value.</para></listitem></varlistentry><varlistentry><term>HINFO</term><listitem><para>This record provides information on the system's hardware and software.
Its syntax is:

<screen format="linespecific">[<replaceable>domain</replaceable>] [<replaceable>ttl</replaceable>] [<replaceable>class</replaceable>] HINFO <replaceable>hardware software</replaceable></screen></para><para>The <replaceable>hardware</replaceable> field identifies the hardware used by
this host. Special conventions are used to specify this. A list of valid
machine names is given in the Assigned Numbers RFC (RFC-1700).
If the field contains any blanks, it must be enclosed in double quotes. The
<replaceable>software</replaceable> field names the operating system software
used by the system. Again, a valid name from the Assigned Numbers RFC should
be chosen.</para><?troff .Nd 10?><para>An <literal moreinfo="none">HINFO</literal> record to describe an Intel-based Linux machine
should look something like:


<screen format="linespecific">tao	 36500  IN  HINFO  IBM-PC  LINUX2.2</screen>

and <literal moreinfo="none">HINFO</literal> records for Linux running on Motorola 68000-based
machines might look like:

<screen format="linespecific">cevad 36500 IN  HINFO  ATARI-104ST LINUX2.0
jedd  36500 IN  HINFO  AMIGA-3000  LINUX2.0</screen>
</para></listitem></varlistentry></variablelist></sect2><sect2 id="x-087-2-resolv.named-cachingonly"><title>Caching-only named Configuration</title><indexterm significance="normal"><primary>configuring</primary><secondary>caching-only name server</secondary></indexterm><indexterm significance="normal"><primary>configuring</primary><secondary>DNS over SLIP/PPP</secondary></indexterm><indexterm significance="normal"><primary>caching-only name server</primary></indexterm><indexterm significance="normal"><primary>name servers</primary><secondary>caching-only</secondary></indexterm><indexterm significance="normal"><primary>resolv.conf file</primary></indexterm><para>There is a special type of <filename moreinfo="none">named</filename> configuration
that we'll talk about before we explain how to build a full name
server configuration.  It is called a
<emphasis>caching-only</emphasis> configuration. It doesn't really
serve a domain, but acts as a relay for all DNS queries produced on
your host.  The advantage of this scheme is that it builds up a cache
so only the first query for a particular host is actually sent to the
name servers on the Internet. Any repeated request will be answered
directly from the cache in your local name server. This may not seem
useful yet, but it will when you are dialing in to the Internet, as
described in <xref linkend="x-087-2-slip"></xref> and <xref linkend="x-087-2-ppp"></xref>.</para><para>A <filename moreinfo="none">named.boot</filename> file for a caching-only server looks like
this:

<screen format="linespecific">; named.boot file for caching-only server
directory                            /var/named
primary       0.0.127.in-addr.arpa   named.local ; localhost network
cache         .                      named.ca    ; root servers</screen></para><para>In addition to this <filename moreinfo="none">named.boot</filename> file, you must set
up the <filename moreinfo="none">named.ca</filename> file with a valid list of root
name servers. You could copy and use <xref linkend="x-087-2-resolv.fig.named.cache"></xref> for this purpose. No other
files are needed for a caching-only server configuration.</para></sect2><sect2><title>Writing the Master Files</title><para><xref linkend="x-087-2-resolv.fig.named.cache"></xref>,
<xref linkend="x-087-2-resolv.fig.named.hosts"></xref>,
<xref linkend="x-087-2-resolv.fig.named.local"></xref>, and
<xref linkend="x-087-2-resolv.fig.named.rev"></xref> give sample files for a name
server at the brewery, located on
<systemitem moreinfo="none" role="sitename">vlager</systemitem>. Due to the nature of the
network discussed (a single LAN), the example is pretty straightforward.</para><para><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>root name servers</secondary></indexterm>
<indexterm significance="normal"><primary>name servers</primary><secondary>root</secondary></indexterm>
The <filename moreinfo="none">named.ca</filename> cache file shown in
<xref linkend="x-087-2-resolv.fig.named.cache"></xref> shows sample hint records for
a root name server. A typical cache file usually describes about a dozen name servers. You can obtain the current list of name servers for the root
domain using the <command moreinfo="none">nslookup</command> tool described in the next
section.<footnote id="x-087-2-fndn03"><para>Note that you can't query your name server for the root servers if you don't
have any root server hints installed. To escape this dilemma, you can either
make <command moreinfo="none">nslookup</command> use a different name server, or use
the sample file in <xref linkend="x-087-2-resolv.fig.named.cache"></xref> as a
starting point, and then obtain the full list of valid servers.</para></footnote>
</para><example id="x-087-2-resolv.fig.named.cache"><title>The named.ca File</title><screen format="linespecific">;
; /var/named/named.ca          Cache file for the brewery.
;                We're not on the Internet, so we don't need
;                any root servers. To activate these
;                records, remove the semicolons.
;
;.                        3600000  IN  NS    A.ROOT-SERVERS.NET.
;A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
;.                        3600000      NS    B.ROOT-SERVERS.NET.
;B.ROOT-SERVERS.NET.      3600000      A     128.9.0.107
;.                        3600000      NS    C.ROOT-SERVERS.NET.
;C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
;.                        3600000      NS    D.ROOT-SERVERS.NET.
;D.ROOT-SERVERS.NET.      3600000      A     128.8.10.90
;.                        3600000      NS    E.ROOT-SERVERS.NET.
;E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
;.                        3600000      NS    F.ROOT-SERVERS.NET.
;F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
;.                        3600000      NS    G.ROOT-SERVERS.NET.
;G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
;.                        3600000      NS    H.ROOT-SERVERS.NET.
;H.ROOT-SERVERS.NET.      3600000      A     128.63.2.53
;.                        3600000      NS    I.ROOT-SERVERS.NET.
;I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
;.                        3600000      NS    J.ROOT-SERVERS.NET.
;J.ROOT-SERVERS.NET.      3600000      A     198.41.0.10
;.                        3600000      NS    K.ROOT-SERVERS.NET.
;K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129 
;.                        3600000      NS    L.ROOT-SERVERS.NET.
;L.ROOT-SERVERS.NET.      3600000      A     198.32.64.12
;.                        3600000      NS    M.ROOT-SERVERS.NET.
;M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
;</screen></example><example id="x-087-2-resolv.fig.named.hosts"><title>The named.hosts File</title><screen format="linespecific">;
; /var/named/named.hosts       Local hosts at the brewery
;                               Origin is vbrew.com
;
@                IN  SOA   vlager.vbrew.com. janet.vbrew.com. (
                           2000012601 ; serial
                           86400      ; refresh: once per day
                           3600       ; retry:   one hour
                           3600000    ; expire:  42 days
                           604800     ; minimum: 1 week
                           )
                 IN  NS    vlager.vbrew.com.
;
; local mail is distributed on vlager
                 IN  MX    10 vlager
;
; loopback address
localhost.       IN  A     127.0.0.1
;
; Virtual Brewery Ethernet
vlager           IN  A     172.16.1.1
vlager-if1       IN  CNAME vlager
; vlager is also news server
news             IN  CNAME vlager
vstout           IN  A     172.16.1.2
vale             IN  A     172.16.1.3
;
; Virtual Winery Ethernet
vlager-if2       IN  A     172.16.2.1
vbardolino       IN  A     172.16.2.2
vchianti         IN  A     172.16.2.3
vbeaujolais      IN  A     172.16.2.4
;
; Virtual Spirits (subsidiary) Ethernet
vbourbon         IN  A     172.16.3.1
vbourbon-if1     IN  CNAME vbourbon</screen></example><example id="x-087-2-resolv.fig.named.local"><title>The named.local File</title><screen format="linespecific">;
; /var/named/named.local       Reverse mapping of 127.0.0
;                              Origin is 0.0.127.in-addr.arpa.
;
@             IN  SOA   vlager.vbrew.com. joe.vbrew.com. (
                        1          ; serial
                        360000     ; refresh: 100 hrs
                        3600       ; retry:   one hour
                        3600000    ; expire:  42 days
                        360000     ; minimum: 100 hrs
                        )
              IN  NS    vlager.vbrew.com.
1             IN  PTR   localhost.</screen></example><example id="x-087-2-resolv.fig.named.rev"><title>The named.rev File</title><screen format="linespecific">;
; /var/named/named.rev         Reverse mapping of our IP addresses
;                               Origin is 16.172.in-addr.arpa.
;
@             IN  SOA   vlager.vbrew.com. joe.vbrew.com. (
                          16         ; serial
                          86400      ; refresh: once per day
                          3600       ; retry:   one hour
                          3600000    ; expire:  42 days
                          604800     ; minimum: 1 week
                          )
              IN  NS    vlager.vbrew.com.
; brewery
1.1           IN  PTR   vlager.vbrew.com.
2.1           IN  PTR   vstout.vbrew.com.
3.1           IN  PTR   vale.vbrew.com.
; winery
1.2           IN  PTR   vlager-if2.vbrew.com.
2.2           IN  PTR   vbardolino.vbrew.com.
3.2           IN  PTR   vchianti.vbrew.com.
4.2           IN  PTR   vbeaujolais.vbrew.com.</screen></example></sect2><sect2 id="x-087-2-resolv.nslookup"><title>Verifying the Name Server Setup</title><indexterm significance="normal"><primary>name servers</primary><secondary>checking</secondary></indexterm><indexterm significance="normal"><primary>checking</primary><secondary>name server</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-commandnslookupcommand-1"><primary>nslookup program</primary></indexterm><indexterm significance="normal"><primary>checking</primary><secondary>hostnames</secondary></indexterm><indexterm significance="normal"><primary>hostname</primary><secondary>lookup</secondary></indexterm><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>checking</secondary></indexterm><para><command moreinfo="none">nslookup</command> is a great tool for checking the operation
of your name server setup. It can be used both interactively with
prompts and as a single command with immediate output. In the latter
case, you simply invoke it as:

<screen format="linespecific">$ <userinput moreinfo="none">nslookup</userinput>
<literal moreinfo="none"><emphasis>hostname</emphasis></literal></screen></para><para><command moreinfo="none">nslookup</command> queries the name server specified in
<filename moreinfo="none">resolv.conf</filename> for <replaceable>hostname</replaceable>.
(If this file names more than one server, <command moreinfo="none">nslookup</command> chooses
one at random.)</para><para>The interactive mode, however, is much more exciting. Besides looking up
individual hosts, you may query for any type of DNS record and transfer
the entire zone information for a domain.</para><para>When invoked without an argument, <command moreinfo="none">nslookup</command> displays the name
server it uses and enters interactive mode. At the <command moreinfo="none"></command> prompt,
you may type any domain name you want to query. By default, it asks
for class A records, those containing the IP address relating to the
domain name.</para><para>You can look for record types by issuing:</para><screen format="linespecific"> <userinput moreinfo="none">set type=</userinput><literal moreinfo="none">type</literal></screen><para>in which <replaceable>type</replaceable> is one of the resource record names described
earlier, or ANY.</para><para>You might have the following <command moreinfo="none">nslookup</command> session:

<screen format="linespecific">$ <userinput moreinfo="none">nslookup</userinput>
Default Server:  tao.linux.org.au
Address:  203.41.101.121

 <userinput moreinfo="none">metalab.unc.edu</userinput>
Server:  tao.linux.org.au
Address:  203.41.101.121

Name:    metalab.unc.edu
Address:  152.2.254.81

</screen></para><para>The output first displays the DNS server being queried, and then the result
of the query.</para><para>If you try to query for a name that has no IP address associated with it,
but other records were found in the DNS database, <command moreinfo="none">nslookup</command>
returns with an error message saying
<literal moreinfo="none">No type A records found</literal>. However, you can
make it query for records other than type A by issuing the
<command moreinfo="none">set type</command> command. To get the SOA record of
<systemitem moreinfo="none" role="sitename">unc.edu</systemitem>, you would issue:

<screen format="linespecific"> <userinput moreinfo="none">unc.edu</userinput>
Server:  tao.linux.org.au
Address:  203.41.101.121

*** No address (A) records available for unc.edu
 <userinput moreinfo="none">set type=SOA</userinput>
 <userinput moreinfo="none">unc.edu</userinput>
Server:  tao.linux.org.au
Address:  203.41.101.121

unc.edu
        origin = ns.unc.edu
        mail addr = host-reg.ns.unc.edu
        serial = 1998111011
        refresh = 14400 (4H)
        retry   = 3600 (1H)
        expire  = 1209600 (2W)
        minimum ttl = 86400 (1D)
unc.edu name server = ns2.unc.edu
unc.edu name server = ncnoc.ncren.net
unc.edu name server = ns.unc.edu
ns2.unc.edu     internet address = 152.2.253.100
ncnoc.ncren.net internet address = 192.101.21.1
ncnoc.ncren.net internet address = 128.109.193.1
ns.unc.edu      internet address = 152.2.21.1</screen></para><para>In a similar fashion, you can query for MX records:

<screen format="linespecific"> <userinput moreinfo="none">set type=MX</userinput>
 <userinput moreinfo="none">unc.edu</userinput>
Server:  tao.linux.org.au
Address:  203.41.101.121

unc.edu preference = 0, mail exchanger = conga.oit.unc.edu
unc.edu preference = 10, mail exchanger = imsety.oit.unc.edu
unc.edu name server = ns.unc.edu
unc.edu name server = ns2.unc.edu
unc.edu name server = ncnoc.ncren.net
conga.oit.unc.edu       internet address = 152.2.22.21
imsety.oit.unc.edu      internet address = 152.2.21.99
ns.unc.edu      internet address = 152.2.21.1
ns2.unc.edu     internet address = 152.2.253.100
ncnoc.ncren.net internet address = 192.101.21.1
ncnoc.ncren.net internet address = 128.109.193.1</screen></para><para>Using a type of ANY returns all resource records associated with a given name.</para><para><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>root name servers</secondary></indexterm>
<indexterm significance="normal"><primary>name servers</primary><secondary>root</secondary></indexterm>
A practical application of <command moreinfo="none">nslookup</command>, besides debugging, is
to obtain the current list of root name servers.  You can obtain this list by querying
for all NS records associated with the root domain:

<screen format="linespecific"> <userinput moreinfo="none">set type=NS</userinput>
 <userinput moreinfo="none">.</userinput>
Server:  tao.linux.org.au
Address:  203.41.101.121

Non-authoritative answer:
(root)  name server = A.ROOT-SERVERS.NET
(root)  name server = H.ROOT-SERVERS.NET
(root)  name server = B.ROOT-SERVERS.NET
(root)  name server = C.ROOT-SERVERS.NET
(root)  name server = D.ROOT-SERVERS.NET
(root)  name server = E.ROOT-SERVERS.NET
(root)  name server = I.ROOT-SERVERS.NET
(root)  name server = F.ROOT-SERVERS.NET
(root)  name server = G.ROOT-SERVERS.NET
(root)  name server = J.ROOT-SERVERS.NET
(root)  name server = K.ROOT-SERVERS.NET
(root)  name server = L.ROOT-SERVERS.NET
(root)  name server = M.ROOT-SERVERS.NET

Authoritative answers can be found from:
A.ROOT-SERVERS.NET      internet address = 198.41.0.4
H.ROOT-SERVERS.NET      internet address = 128.63.2.53
B.ROOT-SERVERS.NET      internet address = 128.9.0.107
C.ROOT-SERVERS.NET      internet address = 192.33.4.12
D.ROOT-SERVERS.NET      internet address = 128.8.10.90
E.ROOT-SERVERS.NET      internet address = 192.203.230.10
I.ROOT-SERVERS.NET      internet address = 192.36.148.17
F.ROOT-SERVERS.NET      internet address = 192.5.5.241
G.ROOT-SERVERS.NET      internet address = 192.112.36.4
J.ROOT-SERVERS.NET      internet address = 198.41.0.10
K.ROOT-SERVERS.NET      internet address = 193.0.14.129
L.ROOT-SERVERS.NET      internet address = 198.32.64.12
M.ROOT-SERVERS.NET      internet address = 202.12.27.33</screen></para><para>To see the complete set of available commands, use the <command moreinfo="none">help</command>
command in <command moreinfo="none">nslookup</command>.</para><para><indexterm significance="normal" class="endofrange" startref="idx-commandnslookupcommand-1"></indexterm></para></sect2><sect2><title>Other Useful Tools</title><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary>tools</secondary></indexterm><para>There are a few tools that can help you with your tasks as a BIND
administrator. We will briefly describe two of them here. Please refer to
the documentation that comes with these tools for more information on how
to use them.</para><para><indexterm significance="normal"><primary>DNS (Domain Name System)</primary><secondary sortas="converting etc/hosts">converting
/etc/hosts</secondary></indexterm> <indexterm significance="normal"><primary>hosts
file</primary><secondary>converting to BIND master
files</secondary></indexterm> <indexterm significance="normal"><primary>hostcvt
program</primary></indexterm> <command moreinfo="none">hostcvt</command> helps you
with your initial BIND configuration by converting your
<filename moreinfo="none">/etc/hosts</filename> file into master files for
<command moreinfo="none">named</command>. It generates both the forward (A) and
reverse mapping (PTR) entries, and takes care of aliases. Of course,
it won't do the whole job for you, as you may still want to tune the
timeout values in the SOA record, for example, or add MX
records. Still, it may help you save a few
aspirins. <command moreinfo="none">hostcvt</command> is part of the BIND source, but
can also be found as a standalone package on a few Linux FTP servers.</para><para><indexterm significance="normal"><primary>DNS (Domain Name
System)</primary><secondary>debugging
databases</secondary></indexterm> <indexterm significance="normal"><primary>dnswalk
program</primary></indexterm> <indexterm significance="normal"><primary>nslint
program</primary></indexterm>
<indexterm significance="normal"><primary>debugging</primary><secondary>DNS
databases</secondary></indexterm> After setting up your name server,
you may want to test your configuration.  Some good tools
that make this job much simpler: the first is called
<command moreinfo="none">dnswalk</command>, which is a Perl-based package.  The second
is called <command moreinfo="none">nslint</command>. They both walk your DNS database
looking for common mistakes and verify that the information they find
is consistent. Two other useful tools are <command moreinfo="none">host</command> and
<command moreinfo="none">dig</command>, which are general purpose DNS database query 
tools. You can use these tools to manually inspect and diagnose DNS 
database entries.</para><para>These tools are likely to be available in prepackaged form.
<command moreinfo="none">dnswalk</command> and <command moreinfo="none">nslint</command> are available
in source from <systemitem moreinfo="none" role="url">http://www.visi.com/~barr/dnswalk/</systemitem> and
<systemitem moreinfo="none" role="url">ftp://ftp.ee.lbl.gov/nslint.tar.Z</systemitem>. The
<command moreinfo="none">host</command> and <command moreinfo="none">dig</command> source codes can be
found at <systemitem moreinfo="none" role="url">ftp://ftp.nikhef.nl/pub/network/</systemitem> and
<systemitem moreinfo="none" role="url">ftp://ftp.is.co.za/networking/ip/dns/dig/</systemitem>.</para><para><indexterm significance="normal" class="endofrange" startref="chdn.hostname.resolution"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-configuringname-server-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-name-serverconfiguring-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-dnsconfiguringserver-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-bind-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-commandnamedcommand-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-configuringhostnameres"></indexterm>
<indexterm significance="normal" class="endofrange" startref="chdn.sve.config"></indexterm>
</para></sect2></sect1></chapter><chapter id="x-087-2-slip"><title>Serial Line IP</title><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>dialup</secondary></indexterm><indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>serial line</secondary></indexterm><indexterm significance="normal"><primary>dialup IP</primary></indexterm><indexterm significance="normal"><primary>telephones</primary><secondary>sending data over</secondary></indexterm><indexterm significance="normal"><primary>Internet</primary><secondary>connecting to</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-configuringslip-1"><primary>configuring</primary><secondary>SLIP</secondary></indexterm><para>Packet protocols like IP or IPX rely upon the receiver host knowing
where the start and end of each packet are in the data stream. The
mechanism used to mark and detect the start and end of packets is
called <emphasis>delimitation</emphasis>. The Ethernet protocol
manages this mechanism in a LAN environment, and the SLIP and PPP protocols
manage it for serial communications lines.</para><para>The comparatively low cost of low-speed dialup modems and telephone circuits
has made the serial line IP protocols immensely popular, especially for
providing connectivity to end users of the Internet. The hardware required
to run SLIP or PPP is simple and readily available. All that is required is
a modem and a serial port equipped with a FIFO buffer.</para><para>The SLIP protocol is very simple to implement and at one time was the more
common of the two. Today almost everyone uses the PPP protocol instead. The
PPP protocol adds a host of sophisticated features that contribute to its
popularity today, and we'll look at the most important of these later.</para><para>Linux supports kernel-based drivers for both SLIP and PPP. The drivers
have both been around for some time and are stable and reliable. In
this chapter and the next, we'll discuss both protocols and how to
configure them.</para><sect1 id="x-087-2-slip.general"><title>General Requirements</title><indexterm significance="normal" class="startofrange" id="idx-slip-1"><primary>SLIP (Serial Line IP) protocol</primary></indexterm><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary></indexterm><para>To use SLIP or PPP, you have to configure some basic networking
features as described in the previous chapters. You must set up the
loopback interface and configure the name resolver. When connecting to
the Internet, you will want to use DNS. Your options here are the same
as for PPP: you can perform your DNS queries across your serial link
by configuring your Internet Service Provider's IP address into your
<filename moreinfo="none">/etc/resolv.conf</filename> file, or configure a
caching-only name server as described under <xref linkend="x-087-2-resolv.named-cachingonly"></xref>, in <xref linkend="x-087-2-resolv"></xref>."</para></sect1><sect1 id="x-087-2-slip.operation"><title>SLIP Operation</title><indexterm significance="normal"><primary>SLIP (Serial Line IP) protocol</primary><secondary>operation</secondary></indexterm><indexterm significance="normal"><primary>protocols</primary><secondary>SLIP</secondary></indexterm><indexterm significance="normal"><primary>SLIPDISC (line discipline)</primary></indexterm><indexterm significance="normal"><primary>ttys</primary><secondary>line discipline</secondary></indexterm><indexterm significance="normal"><primary>line discipline</primary></indexterm><para>Dialup IP servers frequently offer SLIP service through special user
accounts. After logging in to such an account, you are not dropped into
the common shell; instead, a program or shell script is executed that
enables the server's SLIP driver for the serial line and configures the
appropriate network interface. Then you have to do the same at your end
of the link.</para><para>On some operating systems, the SLIP driver is a user-space program;
under Linux, it is part of the kernel, which makes it a lot faster.
This speed requires, however, that the serial line be converted to the
SLIP mode explicitly. This conversion is done by means of a special
tty line discipline, SLIPDISC. While the tty is in normal line
discipline (DISC0), it exchanges data only with user processes, using
the normal <function moreinfo="none">read(2)</function> and
<function moreinfo="none">write(2)</function> calls, and the SLIP driver is unable to
write to or read from the tty. In SLIPDISC, the roles are reversed:
now any user-space processes are blocked from writing to or reading
from the tty, while all data coming in on the serial port is passed
directly to the SLIP driver.</para><para><indexterm significance="normal"><primary>Van Jacobson header
compression</primary></indexterm> <indexterm significance="normal"><primary>TCP/IP
(Transmission Control Protocol/Internet
Protocol)</primary><secondary>compressing
packets</secondary></indexterm> <indexterm significance="normal"><primary>CSLIP (Compressed
Serial Line IP) protocol</primary></indexterm> The SLIP driver itself
understands a number of variations on the SLIP protocol. Apart from
ordinary SLIP, it also understands CSLIP, which performs the so-called
Van Jacobson header compression (described in RFC-1144) on outgoing IP
packets. This compression improves throughput for interactive sessions
noticeably. There are also six-bit versions for each of these
protocols.</para><para><indexterm significance="normal"><primary>slattach program</primary></indexterm>
A simple way to convert a serial line to SLIP mode is by using the
<command moreinfo="none">slattach</command> tool. Assume you have your modem on
<filename moreinfo="none">/dev/ttyS3</filename> and have logged in to the SLIP server
successfully. You will then execute:

<screen format="linespecific"># <userinput moreinfo="none">slattach /dev/ttyS3 </userinput></screen></para><para>This tool switches the line discipline of <filename moreinfo="none">ttyS3</filename> to
<literal moreinfo="none">SLIPDISC</literal> and attaches it to one of the SLIP network
interfaces. If this is your first active SLIP link, the line will be attached
to <filename moreinfo="none">sl0</filename>; the second will be attached to
<filename moreinfo="none">sl1</filename>, and so on. The current kernels support a default
maximum of 256 simultaneous SLIP links.</para><para><indexterm significance="normal"><primary>CSLIP (Compressed Serial Line IP) protocol</primary></indexterm>
The default line discipline chosen by <command moreinfo="none">slattach</command> is CSLIP.
You may choose any other discipline using the <option>p</option> switch.
To use normal SLIP (no compression), you use:

<screen format="linespecific"># <userinput moreinfo="none">slattach -p slip /dev/ttyS3 </userinput></screen></para><para>The disciplines available are listed in <xref linkend="x-087-2-slip.line.disciplines"></xref>. A special pseudo-discipline
is available called <literal moreinfo="none">adaptive</literal>, which causes the
kernel to automatically detect which type of SLIP encapsulation is
being used by the remote end.</para><table id="x-087-2-slip.line.disciplines"><title>Linux Slip-Line Disciplines</title><tgroup cols="2"><colspec colwidth="0.5i"></colspec><colspec colwidth="4i"></colspec><thead><row><entry><para>Disclipline</para></entry><entry>Description</entry></row></thead><tbody><row><entry>slip</entry><entry><para>Traditional SLIP encapsulation.</para></entry></row><row><entry>cslip</entry><entry><para>SLIP encapsulation with Van Jacobsen header compression.</para></entry></row><row><entry>slip6</entry><entry><para>SLIP encapsulation with six-bit encoding. The encoding method is
	similar to that used by the <command moreinfo="none">uuencode</command> command, and causes
	the SLIP datagram to be converted into printable ASCII characters. This conversion is
	useful when you do not have a serial link that is eight bit clean.</para></entry></row><row><entry>cslip6</entry><entry><para>SLIP encapsulation with Van Jacobsen header compression and six-bit
	encoding.</para></entry></row><row><entry>adaptive</entry><entry><para>This is not a real line discipline; instead, it causes the kernel to
	attempt to identify the line discipline being used by the remote machine and
	to match it.</para></entry></row></tbody></tgroup></table><para>Note that you must use the same encapsulation as your peer. For
example, if <systemitem moreinfo="none" role="sitename">cowslip</systemitem> uses
CSLIP, you also have to do so. If your SLIP connection doesn't work,
the first thing you should do is ensure that both ends of the link
agree on whether to use header compression or not. If you are unsure
what the remote end is using, try configuring your host for adaptive
slip. The kernel might figure out the right type for you.</para><para><command moreinfo="none">slattach</command> lets you enable not only SLIP, but other
protocols that use the serial line, like PPP or KISS (another
protocol used by ham radio people). Doing this is not common, though, and there are
better tools available to support these protocols. For details, please refer
to the <filename moreinfo="none">slattach(8)</filename> manual page.</para><para>After turning over the line to the SLIP driver, you must configure the
network interface. Again, you do this using the standard
<command moreinfo="none">ifconfig</command> and <command moreinfo="none">route</command>
commands. Assume that we have dialed up a server named <systemitem moreinfo="none" role="sitename">cowslip</systemitem> from <systemitem moreinfo="none" role="sitename">vlager</systemitem>. On <emphasis role="bold">vlager</emphasis> you would execute:

<indexterm significance="normal"><primary>ifconfig command</primary></indexterm> 
<indexterm significance="normal"><primary>route command</primary></indexterm> 
<screen format="linespecific"># <userinput moreinfo="none">ifconfig sl0 vlager-slip pointopoint cowslip</userinput>
# <userinput moreinfo="none">route add cowslip</userinput>
# <userinput moreinfo="none">route add default gw cowslip</userinput></screen></para><para>The first command configures the interface as a point-to-point link to
<systemitem moreinfo="none" role="sitename">cowslip</systemitem>, while the second and third
add the route to <systemitem moreinfo="none" role="sitename">cowslip</systemitem> and the
default route, using <systemitem moreinfo="none" role="sitename">cowslip</systemitem> as a
gateway.</para><para>Two things are worth noting about the <command moreinfo="none">ifconfig</command>
invocation: The <systemitem moreinfo="none" role="keyword">pointopoint</systemitem>
option that specifies the address of the remote end of a
point-to-point link and our use of <systemitem moreinfo="none" role="sitename">vlager-slip</systemitem> as the address of the local
SLIP interface.</para><para>We have mentioned that you can use the same address you assigned to
<systemitem moreinfo="none" role="sitename">vlager</systemitem>'s Ethernet interface
for your SLIP link, as well. In this case, <systemitem moreinfo="none" role="sitename">vlager-slip</systemitem> might just be another alias
for address <systemitem moreinfo="none" role="sitename">172.16.1.1</systemitem>.
However, it is also possible that you have to use an entirely
different address for your SLIP link. One such case is when your
network uses an unregistered IP network address, as the Brewery
does. We will return to this scenario in greater detail in the next
section.</para><para>For the remainder of this chapter we will always use
<systemitem moreinfo="none" role="sitename">vlager-slip</systemitem> to refer to the address
of the local SLIP interface.</para><para>When taking down the SLIP link, you should first remove all routes
through <systemitem moreinfo="none" role="sitename">cowslip</systemitem> using
<command moreinfo="none">route</command> with the <option>del</option> option, then
take the interface down, and send <command moreinfo="none">slattach</command> the
hangup signal. The you must hang up the modem using your
terminal program again:

<screen format="linespecific"># <userinput moreinfo="none">route del default</userinput>
# <userinput moreinfo="none">route del cowslip</userinput>
# <userinput moreinfo="none">ifconfig sl0 down</userinput>
# <userinput moreinfo="none">kill -HUP <replaceable>516</replaceable></userinput></screen>

Note that the <replaceable>516</replaceable> should be replaced with the
process id (as shown in the output of
<userinput moreinfo="none">ps ax</userinput>) of the <command moreinfo="none">slattach</command>
command controlling the slip device you wish to take down.</para></sect1><sect1><title>Dealing with Private IP Networks</title><indexterm significance="normal"><primary>networks</primary><secondary>private</secondary></indexterm><para>You will remember from <xref linkend="x-087-2-iface"></xref>, that the
Virtual Brewery has an Ethernet-based IP network using unregistered
network numbers that are reserved for internal use only. Packets to or
from one of these networks are not routed on the Internet; if we were
to have <systemitem moreinfo="none" role="sitename">vlager</systemitem> dial into
<systemitem moreinfo="none" role="sitename">cowslip</systemitem> and act as a router
for the Virtual Brewery network, hosts within the Brewery's network
could not talk to real Internet hosts directly because their packets
would be dropped silently by the first major router.</para><para>To work around this dilemma, we will configure <systemitem moreinfo="none" role="sitename">vlager</systemitem> to act as a kind of launch pad for
accessing Internet services. To the outside world, it will present
itself as a normal SLIP-connected Internet host with a registered IP
address (probably assigned by the network provider running <systemitem moreinfo="none" role="sitename">cowslip</systemitem>). Anyone logged in to <systemitem moreinfo="none" role="sitename">vlager</systemitem> can use text-based programs like
<command moreinfo="none">ftp</command>, <command moreinfo="none">telnet</command>, or even
<command moreinfo="none">lynx</command> to make use of the Internet. Anyone on the
Virtual Brewery LAN can therefore telnet and log in to <systemitem moreinfo="none" role="sitename">vlager</systemitem> and use the programs there. For
some applications, there may be solutions that avoid logging in
to <systemitem moreinfo="none" role="sitename">vlager</systemitem>. For WWW users, for
example, we could run a so-called <emphasis>proxy server</emphasis> on
<systemitem moreinfo="none" role="sitename">vlager</systemitem>, which would relay all
requests from your users to their respective servers.</para><para><indexterm significance="normal"><primary>firewalls</primary></indexterm> Having to log in
to <systemitem moreinfo="none" role="sitename">vlager</systemitem> to make use of the
Internet is a little clumsy. But apart from eliminating the paperwork
(and cost) of registering an IP network, it has the added benefit of
going along well with a firewall setup. Firewalls are dedicated
hosts used to provide limited Internet access to users on your local
network without exposing the internal hosts to network attacks from
the outside world. Simple firewall configuration is covered in more
detail in <xref linkend="x-087-2-firewall"></xref>. In <xref linkend="x-087-2-ipmasq"></xref>, we'll discuss a Linux feature called
IP masquerade that provides a powerful alternative to
proxy servers.</para><para>Assume that the Brewery has been assigned the IP address <systemitem moreinfo="none" role="sitename">192.168.5.74</systemitem> for SLIP access. All you
have to do to realize that the setup discussed above is to enter this
address into your <filename moreinfo="none">/etc/hosts</filename> file, naming it
<systemitem moreinfo="none" role="sitename">vlager-slip</systemitem>.  The procedure
for bringing up the SLIP link itself remains unchanged.</para></sect1><sect1 id="x-087-2-slip.dip"><title>Using dip</title><indexterm significance="normal"><primary>configuring</primary><secondary>dip program</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-commanddipcommand-1"><primary>dip program</primary></indexterm><para>Now that was rather simple. Nevertheless, you might want to automate
the steps previously described. It would be much better to have a
simple command that performs all the steps necessary to open the
serial device, cause the modem to dial the provider, log in, enable
the SLIP line discipline, and configure the network interface. This is
what the <command moreinfo="none">dip</command> command is for.</para><para><command moreinfo="none">dip</command> means <emphasis>Dialup IP</emphasis>. It was
written by Fred van Kempen and has been patched very heavily by a
number of people. Today there is one strain that is used by almost
everyone: Version <literal moreinfo="none">dip337p-uri</literal>, which is included
with most modern Linux distributions, or is available from the
<systemitem moreinfo="none" role="sitename">metalab.unc.edu</systemitem> FTP archive.</para><para><command moreinfo="none">dip</command> provides an interpreter for a simple scripting
language that can handle the modem for you, convert the line to SLIP mode, and
configure the interfaces. The script language is powerful enough to suit most configurations.</para><para><indexterm significance="normal"><primary>SLIP (Serial Line IP)
protocol</primary><secondary>let users
initiate</secondary></indexterm>
<indexterm significance="normal"><primary>access</primary><secondary>granting</secondary></indexterm>
<indexterm significance="normal"><primary>security</primary><secondary>SLIP</secondary></indexterm>
To be able to configure the SLIP interface, <command moreinfo="none">dip</command>
requires root privilege. It would now be tempting to make
<command moreinfo="none">dip</command> setuid to <systemitem moreinfo="none" role="userid">root</systemitem> so that all users can dial up some
SLIP server without having to give them root access. This is very
dangerous, though, because setting up bogus interfaces and default
routes with <command moreinfo="none">dip</command> may disrupt routing on your
network. Even worse, this action would give your users power to
connect to <emphasis>any</emphasis> SLIP server and launch dangerous
attacks on your network. If you want to allow your users to fire up a
SLIP connection, write small wrapper programs for each prospective
SLIP server and have these wrappers invoke <command moreinfo="none">dip</command> with
the specific script that establishes the connection. Carefully written
wrapper programs can then safely be made setuid to <systemitem moreinfo="none" role="userid">root</systemitem>.<footnote id="x-087-2-fnsl1"><para><command moreinfo="none">diplogin</command> must be run as
setuid to <systemitem moreinfo="none" role="userid">root</systemitem>, too. See the
section at the end of this chapter.</para></footnote> An alternative,
more flexible approach is to give trusted users root access to
<command moreinfo="none">dip</command> using a program like <command moreinfo="none">sudo</command>.
<indexterm significance="normal"><primary>sudo command</primary></indexterm></para><sect2 id="x-087-2-slip.dip.sample"><title>A Sample Script</title><para>Assume that the host to which we make our SLIP connection is
<systemitem moreinfo="none" role="sitename">cowslip</systemitem>, and that we have
written a script for <command moreinfo="none">dip</command> to run called
<filename moreinfo="none">cowslip.dip</filename> that makes our connection. We invoke
<command moreinfo="none">dip</command> with the script name as argument:

<screen format="linespecific"># <userinput moreinfo="none">dip cowslip.dip</userinput>
DIP: Dialup IP Protocol Driver version 3.3.7 (12/13/93)
Written by Fred N. van Kempen, MicroWalt Corporation.
connected to cowslip.moo.com with addr 192.168.5.74
#</screen></para><para>The script itself is shown in <xref linkend="x-087-2-slip.fig.script"></xref>.</para><example id="x-087-2-slip.fig.script"><title>A Sample dip Script</title><screen format="linespecific"># Sample dip script for dialing up cowslip
# Set local and remote name and address
	get $local vlager-slip
	get $remote cowslip
	port ttyS3                # choose a serial port
	speed 38400              # set speed to max
	modem HAYES              # set modem type
	reset                    # reset modem and tty
	flush                    # flush out modem response
# Prepare for dialing.
	send ATQ0V1E1X1\r
	wait OK 2
	if $errlvl != 0 goto error
	dial 41988
	if $errlvl != 0 goto error
	wait CONNECT 60
	if $errlvl != 0 goto error
# Okay, we're connected now
	sleep 3
	send \r\n\r\n
	wait ogin: 10
	if $errlvl != 0 goto error
	send Svlager\n
	wait ssword: 5
	if $errlvl != 0 goto error
	send knockknock\n
	wait running 30
	if $errlvl != 0 goto error
# We have logged in, and the remote side is firing up SLIP.
	print Connected to $remote with address $rmtip
	default                  # Make this link our default route
	mode SLIP                # We go to SLIP mode, too
# fall through in case of error
error:
	print SLIP to $remote failed.</screen></example><para><indexterm significance="normal"><primary sortas="etc/dip.pid file">/etc/dip.pid file</primary></indexterm>
After connecting to <systemitem moreinfo="none" role="sitename">cowslip</systemitem>
and enabling SLIP, <command moreinfo="none">dip</command> will detach from the
terminal and go to the background. You can then start using the normal
networking services on the SLIP link. To terminate the connection,
simply invoke <command moreinfo="none">dip</command> with the
<option>k</option> option. This sends a hangup signal to
<command moreinfo="none">dip</command>, using the process ID <command moreinfo="none">dip</command>
records in <filename moreinfo="none">/etc/dip.pid</filename>:

<screen format="linespecific"># <userinput moreinfo="none">dip -k</userinput></screen></para><para>In <command moreinfo="none">dip</command>'s scripting language, keywords prefixed with a dollar
symbol denote variable names.  <command moreinfo="none">dip</command> has a predefined set of variables, which will be listed below.
<systemitem moreinfo="none" role="keyword">$remote</systemitem> and
<systemitem moreinfo="none" role="keyword">$local</systemitem>, for instance, contain the
hostnames of the remote and local hosts involved in the SLIP link.</para><para>The first two statements in the sample script are <command moreinfo="none">get</command>
commands, which is <command moreinfo="none">dip</command>'s way to set a variable. Here, the
local and remote hostnames are set to
<systemitem moreinfo="none" role="sitename">vlager</systemitem> and
<systemitem moreinfo="none" role="sitename">cowslip</systemitem>, respectively.</para><para><indexterm significance="normal"><primary>chat program</primary><secondary>SLIP</secondary></indexterm>
The next five statements set up the terminal line and the modem.
<systemitem moreinfo="none" role="keyword">reset</systemitem> sends a reset string to the modem.
The next statement flushes out the modem response so that the login chat in
the next few lines works properly. This chat is pretty straightforward:
it simply dials 41988, the phone number of
<systemitem moreinfo="none" role="sitename">cowslip</systemitem>, and logs in to the account
<systemitem moreinfo="none" role="keyword">Svlager</systemitem> using the password
<systemitem moreinfo="none" role="keyword">knockknock</systemitem>. The
<systemitem moreinfo="none" role="keyword">wait</systemitem> command makes <command moreinfo="none">dip</command>
wait for the string given as its first argument; the number given as its second
argument makes the wait time out after that many seconds if no such string is
received. The <systemitem moreinfo="none" role="keyword">if</systemitem> commands interspersed
in the login procedure check that no error occurred while executing the
command.</para><para>The final commands executed after logging in are
<systemitem moreinfo="none" role="keyword">default</systemitem>, which makes the SLIP link
the default route to all hosts, and <systemitem moreinfo="none" role="keyword">mode</systemitem>,
which enables SLIP mode on the line and configures the interface and routing
table for you.</para></sect2><?troff .wcon_off?><sect2 id="x-087-2-slip.dip.reference"><title>A dip Reference</title><para>In this section, we will give a reference for most of
<command moreinfo="none">dip</command>'s commands. You can get an overview of all the
commands it provides by invoking <command moreinfo="none">dip</command> in test mode
and entering the <systemitem moreinfo="none" role="keyword">help</systemitem>
command. To learn about the syntax of a command, you may enter it<?troff .ne 10?>
without any arguments. Remember that this does not work with commands
that take no arguments. The following example illustrates the
<systemitem moreinfo="none" role="keyword">help</systemitem> command:</para><para><screen format="linespecific"># <userinput moreinfo="none">dip -t</userinput>
DIP: Dialup IP Protocol Driver version 3.3.7p-uri (25 Dec 96)
Written by Fred N. van Kempen, MicroWalt Corporation.
Debian version 3.3.7p-2 (debian).

DIP <userinput moreinfo="none">help</userinput>
DIP knows about the following commands:

	beep         bootp        break        chatkey      config       
	databits     dec          default      dial         echo         
	flush        get          goto         help         if           
	inc          init         mode         modem        netmask      
	onexit       parity       password     proxyarp     print        
	psend        port         quit         reset        securidfixed 
	securid      send         shell        skey         sleep        
	speed        stopbits     term         timeout      wait         

DIP <userinput moreinfo="none">echo</userinput>
Usage: echo on|off
DIP</screen></para><para>Throughout the following section, examples that display the
<command moreinfo="none">DIP</command> prompt show how to enter a command in test mode
and what output it produces. Examples lacking this prompt should be taken
as script excerpts.</para><sect3><title>The modem commands</title><para><indexterm significance="normal"><primary>modems</primary><secondary>links</secondary><tertiary>configuring via dip</tertiary></indexterm> 
<command moreinfo="none">dip</command> provides a number of commands that configure your serial
line and modem. Some of these are obvious, such as
<systemitem moreinfo="none" role="keyword">port</systemitem>, which selects a serial port, and
<systemitem moreinfo="none" role="keyword">speed</systemitem>,
<systemitem moreinfo="none" role="keyword">databits</systemitem>,
<systemitem moreinfo="none" role="keyword">stopbits</systemitem>, and
<systemitem moreinfo="none" role="keyword">parity</systemitem>, which set
the common line parameters.

The <systemitem moreinfo="none" role="keyword">modem</systemitem> command selects a modem type.
Currently, the only type supported is
<systemitem moreinfo="none" role="keyword">HAYES</systemitem> (capitalization required).
You have to provide <command moreinfo="none">dip</command> with a modem type, or else it will
refuse to execute the <systemitem moreinfo="none" role="keyword">dial</systemitem> and
<systemitem moreinfo="none" role="keyword">reset</systemitem> commands. The
<systemitem moreinfo="none" role="keyword">reset</systemitem> command sends a reset string
to the modem; the string used depends on the modem type selected. For
Hayes-compatible modems, this string is
<systemitem moreinfo="none" role="keyword">ATZ</systemitem>.</para><para>The <systemitem moreinfo="none" role="keyword">flush</systemitem> code can be used to flush
out all responses the modem has sent so far. Otherwise, a chat script following
<systemitem moreinfo="none" role="keyword">reset</systemitem> might be confused because it reads
the <systemitem moreinfo="none" role="keyword">OK</systemitem> responses from earlier commands.</para><para>The <systemitem moreinfo="none" role="keyword">init</systemitem> command selects an
initialization string to be passed to the modem before dialing. The
default for Hayes modems is <systemitem moreinfo="none" role="keyword">ATE0 Q0
V1 X1</systemitem>, which turns on echoing of commands and long
result codes, and selects blind dialing (no checking of dial
tone). Modern modems have a good factory default configuration, so
this is a little unnecessary, though it does no harm.</para><?troff .Nd 10?><para>The <systemitem moreinfo="none" role="keyword">dial</systemitem> command sends the
initialization string to the modem and dials up the remote system. The
default dial command for Hayes modems is <systemitem moreinfo="none" role="keyword">ATD</systemitem>.</para></sect3><sect3><title>The echo command</title><para>The <systemitem moreinfo="none" role="keyword">echo</systemitem> command serves as a debugging
aid. Calling <systemitem moreinfo="none" role="keyword">echo on</systemitem> makes
<command moreinfo="none">dip</command> echo to the console everything it sends to
the serial device. This can be turned off again by calling
<systemitem moreinfo="none" role="keyword">echo off</systemitem>.</para><para><command moreinfo="none">dip</command> also allows you to leave script mode
temporarily and enter terminal mode. In this mode, you can use
<command moreinfo="none">dip</command> just like any ordinary terminal program,
writing the characters you type to the serial line, reading data from
the serial line, and displaying the characters. To leave this mode,
enter Ctrl-].</para></sect3><sect3><title>The get command</title><para><indexterm significance="normal"><primary>get command</primary></indexterm> 
The <systemitem moreinfo="none" role="keyword">get</systemitem> command is
<command moreinfo="none">dip</command>'s way of setting a variable. The simplest form is to
set a variable to a constant, as we did in <filename moreinfo="none">cowslip.dip</filename>.
You may, however, also prompt the user for input by specifying the keyword
<systemitem moreinfo="none" role="keyword">ask</systemitem> instead of a value:

<screen format="linespecific">DIP <userinput moreinfo="none">get $local ask</userinput>
Enter the value for $local: _</screen></para><para>A third method is to obtain the value from the remote host.
Bizarre as it seems at first, this is very useful in some cases.
Some SLIP servers will not allow you to use your own IP address on the
SLIP link, but will rather assign you one from a pool of addresses
whenever you dial in, printing some message that informs you about
the address you have been assigned. If the message looks something
like <literal moreinfo="none">Your address: 192.168.5.74</literal>,
the following piece of <command moreinfo="none">dip</command> code would let you
pick up the address:

<screen format="linespecific"># finish login
wait address: 10
get $locip remote</screen></para></sect3><sect3><title>The print command</title><para><indexterm significance="normal"><primary>print command</primary></indexterm> 
This is the command used to echo text to the console from which
<command moreinfo="none">dip</command> was started. Any of <command moreinfo="none">dip</command>'s
variables may be used in print commands. Here's an example:

<screen format="linespecific">DIP <userinput moreinfo="none">print Using port $port at speed $speed</userinput>
Using port ttyS3 at speed 38400</screen></para></sect3><sect3><title>Variable names</title><para><command moreinfo="none">dip</command> understands only a predefined set of variables. A
variable name always begins with a dollar symbol and must be written in
lowercase letters.</para><para>The <systemitem moreinfo="none" role="keyword">$local</systemitem> and <systemitem moreinfo="none" role="keyword">$locip</systemitem> variables contain the local host's
name and IP address. When you store the canonical hostname in
<systemitem moreinfo="none" role="keyword">$local</systemitem>, <command moreinfo="none">dip</command>
will automatically attempt to resolve the hostname to an IP address
and to store it in the <systemitem moreinfo="none" role="keyword">$locip</systemitem>
variable. A similar but backward process occurs when you assign an IP
address to the <systemitem moreinfo="none" role="keyword">$locip</systemitem>
variable; <command moreinfo="none">dip</command> will attempt to perform a reverse
lookup to identify the name of the host and store it in the
<systemitem moreinfo="none" role="keyword">$local</systemitem> variable.</para><para>The <systemitem moreinfo="none" role="keyword">$remote</systemitem> and
<systemitem moreinfo="none" role="keyword">$rmtip</systemitem> variables operate in the same
way for the remote host's name and address.
<systemitem moreinfo="none" role="keyword">$mtu</systemitem> contains the MTU value for
the connection.</para><para>These five variables are the only ones that may be assigned values
directly using the <systemitem moreinfo="none" role="keyword">get</systemitem> command. A
number of other variables are set as a result of the configuration
commands bearing the same name, but may be used in
<systemitem moreinfo="none" role="keyword">print</systemitem> statements;
these variables are <systemitem moreinfo="none" role="keyword">$modem</systemitem>,
<systemitem moreinfo="none" role="keyword">$port</systemitem>, and
<systemitem moreinfo="none" role="keyword">$speed</systemitem>.</para><para><systemitem moreinfo="none" role="keyword">$errlvl</systemitem> is the variable through which
you can access the result of the last command executed. An error level of 0
indicates success, while a nonzero value denotes an error.</para></sect3><sect3><title>The if and goto commands</title><para>The <systemitem moreinfo="none" role="keyword">if</systemitem> command is a conditional
branch, rather than a full-featured programming <emphasis>if</emphasis>
statement. Its syntax is:

<screen format="linespecific">if <replaceable>var</replaceable> <replaceable>op</replaceable> <replaceable>number</replaceable> goto <replaceable>label</replaceable></screen></para><para>The expression must be a simple comparison between one of the variables
<systemitem moreinfo="none" role="keyword">$errlvl</systemitem>,
<systemitem moreinfo="none" role="keyword">$locip</systemitem>, and
<systemitem moreinfo="none" role="keyword">$rmtip</systemitem>.
<replaceable>var</replaceable> must be an integer number; the operator
<replaceable>op</replaceable> may be one of <literal moreinfo="none">==</literal>,
<literal moreinfo="none">!=</literal>, <literal moreinfo="none"></literal>, <literal moreinfo="none"></literal>,
<literal moreinfo="none">=</literal>, and <literal moreinfo="none">=</literal>.</para><para>The <systemitem moreinfo="none" role="keyword">goto</systemitem> command makes the execution
of the script continue at the line following that bearing the
<replaceable>label</replaceable>. A label must be the first word
on the line and must be followed immediately by a colon.</para></sect3><sect3><title>send, wait, and sleep</title><para>These commands help implement simple chat scripts in
<command moreinfo="none">dip</command>. The <systemitem moreinfo="none" role="keyword">send</systemitem> command outputs its arguments to the
serial line. It does not support variables, but understands all
C-style backslash character sequences, such as <systemitem moreinfo="none" role="keyword">\n</systemitem> for newline and <systemitem moreinfo="none" role="keyword">\b</systemitem> for backspace.  The tilde character (~)
can be used as an abbreviation for carriage return/newline.</para><para>The <systemitem moreinfo="none" role="keyword">wait</systemitem> command takes a word
as an argument and will read all input on the serial line until it
detects a sequence of characters that match this word. The word itself
may not contain any blanks.  Optionally, you may give <systemitem moreinfo="none" role="keyword">wait</systemitem> a timeout value as a second argument;
if the expected word is not received within that many seconds, the
command will return with an <systemitem moreinfo="none" role="keyword">$errlvl</systemitem> value of 1. This command is used
to detect login and other prompts.</para><para>The <systemitem moreinfo="none" role="keyword">sleep</systemitem> command may be used to
wait for a certain amount of time; for instance, to patiently wait for any
login sequence to complete. Again, the interval is specified in seconds.</para></sect3><sect3><title>mode and default</title><para>These commands are used to flip the serial line to SLIP mode and
configure the interface. </para><para>The <systemitem moreinfo="none" role="keyword">mode</systemitem> command is the last command
executed by <command moreinfo="none">dip</command> before going into daemon mode. Unless
an error occurs, the command does not return.</para><para><systemitem moreinfo="none" role="keyword">mode</systemitem> takes a protocol name as
argument. <command moreinfo="none">dip</command> currently recognizes
<systemitem moreinfo="none" role="keyword">SLIP</systemitem>,
<systemitem moreinfo="none" role="keyword">CSLIP</systemitem>,
<systemitem moreinfo="none" role="keyword">SLIP6</systemitem>,
<systemitem moreinfo="none" role="keyword">CSLIP6</systemitem>,
<systemitem moreinfo="none" role="keyword">PPP</systemitem>,
and <systemitem moreinfo="none" role="keyword">TERM</systemitem> as valid names. The current
version of <command moreinfo="none">dip</command> does not understand adaptive SLIP, however.</para><para>After enabling SLIP mode on the serial line, <command moreinfo="none">dip</command> executes
<command moreinfo="none">ifconfig</command> to configure the interface as a point-to-point
link, and invokes <command moreinfo="none">route</command> to set the route to the remote host.</para><para>If, in addition, the script executes the <systemitem moreinfo="none" role="keyword">default</systemitem> command before <systemitem moreinfo="none" role="keyword">mode</systemitem>, <command moreinfo="none">dip</command> creates a
default route that points to the SLIP link.</para></sect3></sect2></sect1><sect1 id="x-087-2-slip.server"><title>Running in Server Mode</title><indexterm significance="normal"><primary>diplogin command</primary></indexterm><indexterm significance="normal"><primary>configuring</primary><secondary>SLIP</secondary><tertiary>server</tertiary></indexterm><para>Setting up your SLIP client was the hard part. Configuring your host
to act as a SLIP server is much easier.</para><para><indexterm significance="normal"><primary>Dent, Arthur</primary></indexterm> There are two
ways of configuring a SLIP server. Both ways require that you set up
one login account per SLIP client. Assume you provide SLIP service to
Arthur Dent at <systemitem moreinfo="none" role="sitename">dent.beta.com</systemitem>. You might create an
account named <systemitem moreinfo="none" role="userid">dent</systemitem> by adding
the following line to your <filename moreinfo="none">passwd</filename> file:

<screen format="linespecific">dent:*:501:60:Arthur Dent's SLIP account:/tmp:/usr/sbin/diplogin</screen></para><para>Afterwards, you would set <systemitem moreinfo="none" role="userid">dent</systemitem>'s
password using the <command moreinfo="none">passwd</command> utility.</para><para><indexterm significance="normal"><primary sortas="etc/diphosts file">/etc/diphosts file</primary></indexterm> 
<indexterm significance="normal"><primary>sliplogin program</primary></indexterm> 
The <command moreinfo="none">dip</command> command can be used in server mode by
invoking it as <command moreinfo="none">diplogin</command>. Usually
<command moreinfo="none">diplogin</command> is a link to <command moreinfo="none">dip</command>. Its
main configuration file is <filename moreinfo="none">/etc/diphosts</filename>, which
is where you specify what IP address a SLIP user will be assigned when
he or she dials in.  Alternatively, you can also use the
<command moreinfo="none">sliplogin</command> command, a BSD-derived tool featuring a
more flexible configuration scheme that lets you execute shell scripts
whenever a host connects and disconnects.</para><?troff .wcon_off?><para><indexterm significance="normal"><primary>diphosts file</primary></indexterm> When our SLIP
user <systemitem moreinfo="none" role="userid">dent</systemitem> logs in,
<command moreinfo="none">dip</command> starts up as a server. To find out if he is
indeed permitted to use SLIP, it looks up the username in
<filename moreinfo="none">/etc/diphosts</filename>. This file details the <?troff .ne 10?>
access rights and connection parameter for each SLIP user.
The general format for an <filename moreinfo="none">/etc/diphosts</filename> entry looks like:

<screen format="linespecific"># /etc/diphosts
<replaceable>user</replaceable>:<replaceable>password</replaceable>:<replaceable>rem-addr</replaceable>:<replaceable>loc-addr</replaceable>:<replaceable>netmask</replaceable>:<replaceable>comments</replaceable>:<replaceable>protocol</replaceable>,<replaceable>MTU</replaceable>
#</screen>

Each of the fields is described in
<xref linkend="x-087-2-slip.diphosts.fields"></xref>.</para><table id="x-087-2-slip.diphosts.fields"><title>/etc/diphosts Field Description</title><tgroup cols="2"><colspec colwidth="0.75i"></colspec><colspec colwidth="3.5i"></colspec><thead><row><entry>Field</entry><entry>Description</entry></row></thead><tbody><row><entry><literal moreinfo="none">user</literal></entry><entry><para>The username of the user invoking <command moreinfo="none">dip</command> that this
	entry will apply to.</para></entry></row><row><entry>password</entry><entry><para>Field 2 of the <filename moreinfo="none">/etc/diphosts</filename> file is used to
	add an extra layer of password-based security on the connection. You can place a password in encrypted form here (just as in
	<filename moreinfo="none">/etc/passwd</filename>) and <command moreinfo="none">diplogin</command>
	will prompt for the user to enter the password before allowing SLIP
	access. Note that this password is used in addition to the normal
	<command moreinfo="none">login</command>-based password the user will enter.</para></entry></row><row><entry><literal moreinfo="none">rem-addr</literal></entry><entry><para>    The address that will be assigned to the remote machine. This address may
	be specified either as a hostname that will be resolved or an IP address
	in dotted quad notation.
    </para></entry></row><row><entry><literal moreinfo="none">loc-addr</literal></entry><entry><para>    The IP address that will be used for this end of the SLIP link.
	This may also be specified as a resolvable hostname or in dotted quad
	format.
    </para></entry></row><row><entry><literal moreinfo="none">netmask</literal></entry><entry><para>    The netmask that will be used for routing purposes. Many people
	are confused by this entry. The netmask doesn't apply to the
	SLIP link itself, but is used in combination with the
	<literal moreinfo="none">rem-addr</literal> field to produce a route to the remote site.
	The netmask should be that used by the network supported by that of the
	remote host.
    </para></entry></row><row><entry><literal moreinfo="none">comments</literal></entry><entry><para>    This field is free-form text that you may use to help document
	the <filename moreinfo="none">/etc/diphosts</filename> file. It serves no other purpose.
    </para></entry></row><row><entry><literal moreinfo="none">protocol</literal></entry><entry><para>    This field is where you specify what protocol or line discipline
	you want applied to this connection. Valid entries here are the same as
	those valid for the <option>p</option> argument to the
	<command moreinfo="none">slattach</command> command.
    </para></entry></row><row><entry><literal moreinfo="none">MTU</literal></entry><entry><para>    The maximum transmission unit that this link will carry. This field
	describes the largest datagram that will be transmitted across the link.
	Any datagram routed to the SLIP device that is larger than the MTU will
	be fragmented into datagrams no larger than this value. Usually, the MTU is configured identically at both ends of the link.
    </para></entry></row></tbody></tgroup></table><para>A sample entry for
<systemitem moreinfo="none" role="userid">dent</systemitem> could look like this:

<screen format="linespecific">dent::dent.beta.com:vbrew.com:255.255.255.0:Arthur Dent:CSLIP,296</screen></para><para><indexterm significance="normal"><primary>CSLIP (Compressed Serial Line IP)
protocol</primary></indexterm> Our example gives our user <systemitem moreinfo="none" role="userid">dent</systemitem> access to SLIP with no additional
password required. He will be assigned the IP address associated with
<systemitem moreinfo="none" role="sitename">dent.beta.com</systemitem> with a netmask
of <literal moreinfo="none">255.255.255.0</literal>. His default route should be
directed to the IP address of <systemitem moreinfo="none" role="sitename">vbrew.com</systemitem>, and he will use the CSLIP
protocol with an MTU of 296 bytes.</para><para>When <systemitem moreinfo="none" role="userid">dent</systemitem> logs in,
<command moreinfo="none">diplogin</command> extracts the information on him from the
<filename moreinfo="none">diphosts</filename> file. If the second field contains a
value, <command moreinfo="none">diplogin</command> will prompt for an external
security password. The string entered by the user is encrypted
and compared to the password from <filename moreinfo="none">diphosts</filename>. If
they do not match, the login attempt is rejected. If the password
field contains the string <systemitem moreinfo="none" role="keyword">s/key</systemitem>, and <command moreinfo="none">dip</command>
was compiled with S/Key support, S/Key authentication
will take place. S/Key authentication is described in the
documentation that comes in the <command moreinfo="none">dip</command> source package.</para><para>After a successful login, <command moreinfo="none">diplogin</command> proceeds by
flipping the serial line to CSLIP or SLIP mode, and sets up the
interface and route. This connection remains established until the
user disconnects and the modem drops the
line. <command moreinfo="none">diplogin</command> then returns the line to normal
line discipline and exits.</para><para><indexterm significance="normal"><primary>access</primary><secondary>granting</secondary></indexterm>
<indexterm significance="normal"><primary>security</primary></indexterm>
<command moreinfo="none">diplogin</command> requires superuser privilege. If you don't have
<command moreinfo="none">dip</command> running setuid
<systemitem moreinfo="none" role="userid">root</systemitem>, you should make
<command moreinfo="none">diplogin</command> a separate copy of <command moreinfo="none">dip</command>
instead of a simple link. <command moreinfo="none">diplogin</command> can then safely
be made setuid without affecting the status of
<command moreinfo="none">dip</command> itself.

<indexterm significance="normal" class="endofrange" startref="idx-commanddipcommand-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-configuringslip-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-slip-1"></indexterm></para></sect1></chapter><chapter id="x-087-2-ppp"><title>The Point-to-Point Protocol</title><para><indexterm significance="normal"><primary>Internet</primary><secondary>connecting to</secondary></indexterm>
<indexterm significance="normal"><primary>telephones</primary><secondary>sending data over</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>serial line</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>dialup</secondary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>point-to-point link</primary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-configuringppp-1"><primary>configuring</primary><secondary>PPP</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-ppp-1"><primary>PPP (Point-to-Point Protocol)</primary></indexterm>
Like SLIP, PPP is a protocol used to send datagrams across a
serial connection; however, it addresses a couple of the deficiencies
of SLIP. First, it can carry a large number of protocols and is
thus not limited to the IP protocol. It provides error detection
on the link itself, while SLIP accepts and forwards
corrupted datagrams as long as the corruption does not occur in the
header. Equally important, it lets the communicating sides
negotiate options, such as the IP address and the maximum datagram size
at startup time, and provides client authorization.  This built-in
negotiation allows reliable automation of the connection
establishment, while the authentication removes the need for the
clumsy user login accounts that SLIP requires. For each of these
capabilities, PPP has a separate protocol. In this chapter, we briefly
cover these basic building blocks of PPP. This discussion of PPP is
far from complete; if you want to know more about PPP, we urge you to
read its RFC specification and the dozen or so companion
RFCs.<footnote id="x-087-2-fnpp01"><para> Relevant RFCs are listed
in the Bibiliography at the end of this book.</para></footnote>
There is also a comprehensive O'Reilly book on the topic
of <emphasis>Using  Managing PPP</emphasis>, by Andrew Sun.</para><para><indexterm significance="normal"><primary>HDLC (High-Level Data Link Control) protocol</primary></indexterm>
At the very bottom of PPP is the <emphasis>High-Level Data Link
Control</emphasis> (HDLC) protocol, which defines the
boundaries around the individual PPP frames and provides a 16-bit
checksum.<footnote id="x-087-2-fnpp02"><para> In fact, HDLC is a much
more general protocol devised by the International Standards
Organization (ISO) and is also an essential component of the X.25
specification.</para></footnote> As opposed to the more primitive SLIP
encapsulation, a PPP frame is capable of holding packets from
protocols other than IP, such as Novell's IPX or Appletalk.  PPP
achieves this by adding a protocol field to the basic HDLC frame that
identifies the type of packet carried by the frame.
</para><para><indexterm significance="normal"><primary>LCP (Link Control Protocol)</primary></indexterm>
The <emphasis>Link Control Protocol</emphasis>, (LCP) is used on top of HDLC
to negotiate options pertaining to the data link. For instance, the
<emphasis>Maximum Receive Unit</emphasis> (MRU), states the maximum
datagram size that one side of the link agrees to receive.</para><para><indexterm significance="normal"><primary>authorization</primary><secondary>with PPP</secondary></indexterm>
<indexterm significance="normal"><primary>PAP (Password Authentication Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>CHAP (Challenge Handshake Authentication Protocol)</primary></indexterm>
An important step at the configuration stage of a PPP link is client
authorization. Although it is not mandatory, it is really a must for
dialup lines in order to keep out intruders.  Usually the called host
(the server) asks the client to authorize itself by proving it knows
some secret key.  If the caller fails to produce the correct secret,
the connection is terminated.  With PPP, authorization works both
ways; the caller may also ask the server to authenticate
itself.  These authentication procedures are totally independent of
each other.  There are two protocols for different types of
authorization, which we will discuss further in this chapter: <emphasis>Password Authentication Protocol</emphasis> (PAP)
and <emphasis>Challenge Handshake Authentication Protocol</emphasis>
(CHAP).</para><para><indexterm significance="normal"><primary>NCP (Network Control Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>Network Control Protocol (PPP)</secondary></indexterm>
<indexterm significance="normal"><primary>IPCP (Internet Protocol Control Protocol)</primary></indexterm>
Each network protocol that is routed across the data link (like IP and
AppleTalk) is configured dynamically using a corresponding
<emphasis>Network Control Protocol</emphasis> (NCP).  To
send IP datagrams across the link, both sides running PPP must first
negotiate which IP address each of them uses. The control protocol
used for this negotiation is the <emphasis>Internet Protocol Control
Protocol</emphasis> (IPCP).</para><para><indexterm significance="normal"><primary>Van Jacobson header compression</primary></indexterm>
<indexterm significance="normal"><primary>TCP/IP (Transmission Control Protocol/Internet Protocol)</primary><secondary>compressing packets</secondary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>compressing data</secondary></indexterm>
<indexterm significance="normal"><primary>CSLIP (Compressed Serial Line IP) protocol</primary></indexterm>
Besides sending standard IP datagrams across the link, PPP also supports
Van Jacobson header compression of IP datagrams. This technique
shrinks the headers of TCP packets to as little as three bytes. It is
also used in CSLIP, and is more colloquially referred to as VJ header
compression.  The use of compression may be negotiated at startup time
through IPCP, as well.</para><sect1><title>PPP on Linux</title><indexterm significance="normal"><primary>drivers</primary><secondary>PPP</secondary></indexterm><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>driver</secondary></indexterm><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>daemon</secondary></indexterm><indexterm significance="normal"><primary>pppd (kernel PPP module)</primary></indexterm><indexterm significance="normal"><primary>chat program</primary></indexterm><para>On Linux, PPP functionality is split into two parts: a kernel component that
handles the low-level protocols (HDLC, IPCP, IPXCP, etc.) and the user space
<command moreinfo="none">pppd</command> daemon that handles the various higher-level protocols,
such as PAP and CHAP. The current release of the PPP software for Linux
contains the PPP daemon <command moreinfo="none">pppd</command> and a program named
<command moreinfo="none">chat</command> that automates the dialing of the remote
system.</para><para>The PPP kernel driver was written by Michael Callahan and reworked by
Paul Mackerras. <command moreinfo="none">pppd</command> was derived from a free PPP
implementation<footnote id="x-087-2-fnpp03"><para> If you have any general
questions about PPP, ask the people on the Linux-net mailing
list at <systemitem moreinfo="none" role="sitename">vger.rutgers.edu</systemitem>.</para></footnote> for Sun and 386BSD machines that was written by
Drew Perkins and others, and is maintained by Paul Mackerras. It was
ported to Linux by Al Longyear. <command moreinfo="none">chat</command> was written by
Karl Fox.<footnote id="x-087-2-fnpp04"><para> Karl can be reached at
<systemitem moreinfo="none" role="emailaddr">karl@morningstar.com</systemitem>.</para></footnote></para><para><indexterm significance="normal"><primary>ttys</primary><secondary>line discipline</secondary></indexterm>
<indexterm significance="normal"><primary>line discipline</primary></indexterm>
Like SLIP, PPP is implemented by a special line discipline.
To use a serial line as a PPP link, you first establish the connection
over your modem as usual, and subsequently convert the line to PPP mode.
In this mode, all incoming data is passed to <?troff .Nd 10?><?troff .wcon_off?>the PPP driver, which checks
the incoming HDLC frames for validity (each HDLC frame carries a 16-bit
checksum), and unwraps and dispatches them.  Currently, PPP is able to
transport both the IP protocol, optionally using Van Jacobson header
compression, and the IPX protocol.</para><para><indexterm significance="normal"><primary>PPP-HOWTO</primary></indexterm>
<indexterm significance="normal"><primary>HOWTOs</primary><secondary>PPP</secondary></indexterm>
<command moreinfo="none">pppd</command> aids the kernel driver, performing the
initialization and authentication phase that is necessary before
actual network traffic can be sent across the
link. <command moreinfo="none">pppd</command>'s behavior may be fine-tuned
using a number of options. As PPP is rather complex, it is impossible
to explain all of them in a single chapter. This book therefore cannot
cover all aspects of <command moreinfo="none">pppd</command>, but only gives you an
introduction. For more information, consult <emphasis>Using  Managing
PPP</emphasis> or the <command moreinfo="none">pppd</command> manual pages, and
<filename moreinfo="none">README</filename>s in the <command moreinfo="none">pppd</command>
source distribution, which should help you sort out most questions
this chapter fails to discuss. The PPP-HOWTO might also be of use.</para><para><indexterm significance="normal"><primary>newsgroups</primary><secondary>comp.protocols.ppp</secondary></indexterm>
Probably the greatest help you will find in configuring PPP will come
from other users of the same Linux distribution. PPP configuration
questions are very common, so try your local usergroup mailing list or
the IRC Linux channel. If your problems persist even after reading the
documentation, you could try the <systemitem moreinfo="none" role="newsgroup">comp.protocols.ppp</systemitem> newsgroup. This is
the place where you can find most of the people involved in
<command moreinfo="none">pppd</command> development.</para></sect1><sect1><title>Running pppd</title><para><indexterm significance="normal"><primary>Internet</primary><secondary>connecting to</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-commandpppdcommand-1"><primary>pppd (kernel PPP module)</primary></indexterm>
<indexterm significance="normal"><primary>name servers</primary><secondary>caching-only</secondary></indexterm>
<indexterm significance="normal"><primary>caching-only name server</primary></indexterm>
When you want to connect to the Internet through a PPP link, you have
to set up basic networking capabilities, such as the loopback device
and the resolver. Both have been covered in <xref linkend="x-087-2-iface"></xref>, and <xref linkend="x-087-2-resolv"></xref>. You can
simply configure the name server of your Internet Service Provider in
the <filename moreinfo="none">/etc/resolv.conf</filename> file, but this will mean
that every DNS request is sent across your serial link. This situation is not
optimal; the closer (network-wise) you are to your name server, the
faster the name lookups will be. An alternative solution is to
configure a caching-only name server at a host on your network.  This
means that the first time you make a DNS query for a particular
host, your request will be sent across your serial link, but every
subsequent request will be answered directly by your local name
server, and will be much faster. This configuration is described in Chapter 6, in 
<xref linkend="x-087-2-resolv.named-cachingonly"></xref>.</para><para>As an introductory example of how to establish a PPP connection with
<command moreinfo="none">pppd</command>, assume you are at <systemitem moreinfo="none" role="sitename">vlager</systemitem> again. First, dial in to the PPP
server <systemitem moreinfo="none" role="sitename">c3po</systemitem> and log in to the
<systemitem moreinfo="none" role="userid">ppp</systemitem> account.  <systemitem moreinfo="none" role="sitename">c3po</systemitem> will execute its PPP driver. After
exiting the communications program you used for dialing, execute the
following command, substituting the name of the serial device you used
for the <literal moreinfo="none">ttyS3</literal> shown here:

<screen format="linespecific"># <userinput moreinfo="none">pppd /dev/ttyS3 38400 crtscts defaultroute</userinput></screen></para><para><indexterm significance="normal"><primary>handshake, hardware</primary></indexterm>
<indexterm significance="normal"><primary>hardware</primary><secondary>handshake</secondary></indexterm>
This command flips the serial line <filename moreinfo="none">ttyS3</filename> to the
PPP line discipline and negotiates an IP link with <systemitem moreinfo="none" role="sitename">c3po</systemitem>. The transfer speed used on the
serial port will be 38,400 bps. The <systemitem moreinfo="none" role="keyword">crtscts</systemitem> option turns on hardware handshake
on the port, which is an absolute must at speeds above 9,600 bps.</para><para>The first thing <command moreinfo="none">pppd</command> does after starting up is
negotiate several link characteristics with the remote end using
LCP. Usually, the default set of options <command moreinfo="none">pppd</command> tries
to negotiate will work, so we won't go into this here. Expect to say
that part of this negotiation involves requesting or assigning the IP
addresses at each end of the link.</para><para>For the time being, we also assume that
<systemitem moreinfo="none" role="sitename">c3po</systemitem> doesn't require
any authentication from us, so the configuration phase is completed
successfully.</para><para><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>IP addresses</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>addresses</secondary><tertiary>negotiation in PPP</tertiary></indexterm>
<indexterm significance="normal"><primary>addresses</primary><secondary>negotiation with PPP</secondary></indexterm>
<command moreinfo="none">pppd</command> will then negotiate the IP parameters with its
peer using IPCP, the IP control protocol. Since we didn't specify any
particular IP address to <command moreinfo="none">pppd</command> earlier, it will try to
use the address obtained by having the resolver look up the local hostname.
Both will then announce their addresses to each other.</para><para>Usually, there's nothing wrong with these defaults. Even if your
machine is on an Ethernet, you can use the same IP address for both
the Ethernet and the PPP interface.  Nevertheless,
<command moreinfo="none">pppd</command> allows you to use a different address, or even
to ask your peer to use some specific address.  These options are
discussed later in the <xref linkend="x-087-2-ipconfig.options"></xref>
section.</para><para><indexterm significance="normal"><primary>interfaces</primary><secondary>PPP</secondary></indexterm>
<indexterm significance="normal"><primary>configuring</primary><secondary>PPP</secondary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>default route</secondary></indexterm>
<indexterm significance="normal"><primary>route, default</primary></indexterm>
After going through the IPCP setup phase, <command moreinfo="none">pppd</command> will
prepare your host's networking layer to use the PPP link. It first
configures the PPP network interface as a point-to-point link, using
<filename moreinfo="none">ppp0</filename> for the first PPP link that is active,
<command moreinfo="none">ppp1</command> for the second, and so on. Next, it sets up a
routing table entry that points to the host at the other end of the
link. In the previous example, <command moreinfo="none">pppd</command> made the
default network route point to <systemitem moreinfo="none" role="sitename">c3po</systemitem>, because we gave it the <systemitem moreinfo="none" role="keyword">defaultroute</systemitem> option.<footnote id="x-087-2-fnpp05"><para> The default network route is installed only
if none is already present.</para></footnote> The default route simplifies
your routing by causing any IP datagram destined to a nonlocal host to
be sent to <systemitem moreinfo="none" role="sitename">c3po</systemitem>; this makes
sense since it is the only way they can be reached. There are a number of
different routing schemes <command moreinfo="none">pppd</command> supports, which we will
cover in detail later in this chapter.</para></sect1><sect1 id="x-087-2-ppp.options"><title>Using Options Files</title><para><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>option files</secondary></indexterm>
Before <command moreinfo="none">pppd</command> parses its command-line arguments, it scans
several files for default options.  These files may contain any valid
command-line arguments spread out across an arbitrary number of lines.
Hash signs introduce comments.</para><para><indexterm significance="normal"><primary sortas="etc/ppp/options file">/etc/ppp/options file</primary></indexterm> 
The first options file is <filename moreinfo="none">/etc/ppp/options</filename>, which is
always scanned when <command moreinfo="none">pppd</command> starts up.  Using it to set some
global defaults is a good idea, because it allows you to keep your users from
doing several things that may compromise security.  For instance, to make
<command moreinfo="none">pppd</command> require some kind of authentication (either PAP or
CHAP) from the peer, you add the <option>auth</option> option to this
file. This option cannot be overridden by the user, so it becomes impossible
to establish a PPP connection with any system that is not in your
authentication databases. Note, however, that some options can be overridden;
the <systemitem moreinfo="none" role="keyword">connect</systemitem> string is a good example.</para><para><indexterm significance="normal"><primary sortas="ppprc file">.ppprc file</primary></indexterm>
The other options file, which is read after
<filename moreinfo="none">/etc/ppp/options</filename>, is <filename moreinfo="none">.ppprc</filename> in the
user's home directory. It allows each user to specify her own set of default
options.</para><para>A sample <filename moreinfo="none">/etc/ppp/options</filename> file might look like this:

<screen format="linespecific"># Global options for pppd running on vlager.vbrew.com
lock                 # use UUCP-style device locking
auth                 # require authentication
usehostname          # use local hostname for CHAP
domain vbrew.com     # our domain name</screen></para><para><indexterm significance="normal"><primary>lock files and PPP</primary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>lock files</secondary></indexterm>
The <systemitem moreinfo="none" role="keyword">lock</systemitem> keyword makes
<command moreinfo="none">pppd</command> comply to the standard UUCP method of device locking.
With this convention, each process that accesses a serial device, say
<filename moreinfo="none">/dev/ttyS3</filename>, creates a lock file with a name like
<filename moreinfo="none">LCK..ttyS3</filename> in a special lock-file directory to signal that
the device is in use. This is necessary to prevent signal other programs, such as
<command moreinfo="none">minicom</command> or <command moreinfo="none">uucico</command>, from opening the
serial device while it is used by PPP.</para><para>The next three options relate to authentication and, therefore,
to system security. The authentication options are best placed in the global
configuration file because they are privileged and cannot
be overridden by users' <filename moreinfo="none">~/.ppprc</filename> options files.</para></sect1><sect1><title>Using chat to Automate Dialing</title><para><indexterm significance="normal"><primary>establishing the connection</primary></indexterm>
<indexterm significance="normal"><primary>chat program</primary><secondary>PPP</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-pppchatscript-1"><primary>PPP (Point-to-Point Protocol)</primary><secondary>chat script</secondary></indexterm>
One of the things that may have struck you as inconvenient in the
previous example is that you had to establish the connection manually
before you could fire up <command moreinfo="none">pppd</command>.  Unlike
<command moreinfo="none">dip</command>, <command moreinfo="none">pppd</command> does not have its own
scripting language for dialing the remote system and logging in, but
relies on an external program or shell script to do this. The
command to be executed can be given to <command moreinfo="none">pppd</command> with
the <systemitem moreinfo="none" role="keyword">connect</systemitem> command-line
option. <command moreinfo="none">pppd</command> will redirect the command's standard
input and output to the serial line.</para><para>The <command moreinfo="none">pppd</command> software package is supplied with a very simple
program called <command moreinfo="none">chat</command>, which is capable of being used in
this way to automate simple login sequences. We'll talk about this command in
some detail.</para><para><indexterm significance="normal"><primary>expect program</primary></indexterm>
<indexterm significance="normal"><primary>Libes, Don</primary></indexterm>
If your login sequence is complex, you will need something more
powerful than <command moreinfo="none">chat</command>. One useful alternative you
might consider is <command moreinfo="none">expect</command>, written by Don Libes. It
has a very powerful language based on Tcl, and was designed exactly for
this sort of application. Those of you whose login sequence requires,
for example, challenge/response authentication involving
 calculator-like key generators will find
<command moreinfo="none">expect</command> powerful enough to handle the task. Since
there are so many possible variations on this theme, we won't describe
how to develop an appropriate expect script in this book.  Suffice it
to say, you'd call your expect script by specifying its name using the
<command moreinfo="none">pppd</command> <systemitem moreinfo="none" role="keyword">connect</systemitem> option. It's also important to
note that when the script is running, the standard input and output
will be attached to the modem, not to the terminal that invoked
<command moreinfo="none">pppd</command>. If you require user interaction, you should
manage it by opening a spare virtual terminal, or arrange some other
means.</para><para><indexterm significance="normal" class="startofrange" id="idx-commandchatcommand-1"><primary>chat program</primary></indexterm>
<indexterm significance="normal"><primary>chat script</primary></indexterm>
The <command moreinfo="none">chat</command> command lets you specify a UUCP-style chat script.
Basically, a chat script consists of an alternating sequence of strings that
we expect to receive from the remote system, and the answers we are to send.
We will call them <emphasis>expect</emphasis> and <emphasis>send</emphasis>
strings, respectively.  This is a typical excerpt from a chat script:

<screen format="linespecific">ogin: b1ff ssword: s3|r1t</screen></para><para>This script tells <command moreinfo="none">chat</command> to wait for the remote system to send
the login prompt and return the login name
<systemitem moreinfo="none" role="userid">b1ff</systemitem>. We wait only for
<systemitem moreinfo="none" role="keyword">ogin:</systemitem> so that it doesn't matter if
the login prompt starts with an uppercase or lowercase l, or if it arrives
garbled.  The following string is another expect string that makes
<command moreinfo="none">chat</command> wait for the password prompt and send our
response password.</para><para>This is basically what chat scripts are all about. A complete script to
dial up a PPP server would, of course, also have to include the appropriate
modem commands. Assume that your modem understands the Hayes command set, and
the server's telephone number is 318714. The complete <command moreinfo="none">chat</command>
invocation to establish a connection with
<systemitem moreinfo="none" role="sitename">c3po</systemitem> would then be:

<screen format="linespecific">$ <userinput moreinfo="none">chat -v '' ATZ OK ATDT318714 CONNECT '' ogin: ppp word: GaGariN</userinput></screen></para><para><?troff .hw compatible?>By definition, the first string must be an expect string, but as the
modem won't say anything before we have kicked it, we make
<command moreinfo="none">chat</command> skip the first expect by specifying an empty string.
We then send <systemitem moreinfo="none" role="keyword">ATZ</systemitem>, the reset
command for Hayes-compatible modems, and wait for its response
(<systemitem moreinfo="none" role="keyword">OK</systemitem>). The next string sends the <command moreinfo="none">dial</command>
command along with the phone number to <command moreinfo="none">chat</command>, and expects
the <systemitem moreinfo="none" role="keyword">CONNECT</systemitem> message in response.
This is followed by an empty string again because we don't want to send
anything now, but rather wait for the login prompt. The remainder of the
chat script works exactly as described previously. This description probably looks a bit
confusing, but we'll see in a moment that there is a way to make
chat scripts a lot easier to understand.</para><para>The <option>v</option> option makes <command moreinfo="none">chat</command> log all
activities to the <command moreinfo="none">syslog</command> daemon
<systemitem moreinfo="none" role="keyword">local2</systemitem>
facility.<footnote id="x-087-2-fnpp06"><para>If you edit <filename moreinfo="none">syslog.conf</filename> to redirect these log messages to
a file, make sure this file isn't world readable, as <command moreinfo="none">chat</command>
also logs the entire chat script by defaultincluding passwords.</para></footnote></para><para><indexterm significance="normal"><primary>security</primary><secondary>PPP</secondary></indexterm>
Specifying the chat script on the command line bears a certain risk
because users can view a process's command line with the <command moreinfo="none">ps</command>
command.  You can avoid this risk by putting the chat script in a file like
<filename moreinfo="none">dial-c3po</filename>.  You make <command moreinfo="none">chat</command> read
the script from the file instead of the command line by giving it the
<option>f</option> option, followed by the filename. <?troff .ne 10?><?troff .wcon_off?>This action has the
added benefit of making our chat expect sequences easier to
understand. To convert our example, our <filename moreinfo="none">dial-c3po</filename> file
would look like:

<screen format="linespecific">''      ATZ
OK      ATDT318714
CONNECT ''
ogin:   ppp
word:   GaGariN</screen>

When we use a chat script file in this way, the string we expect to
receive is on the left and the response we will send is on the
right. They are much easier to read and understand when presented this way.</para><para>The complete <command moreinfo="none">pppd</command> incantation would now look like this:

<screen format="linespecific"># <userinput moreinfo="none">pppd connect "chat -f dial-c3po" /dev/ttyS3 38400 -detach \
        crtscts modem defaultroute</userinput></screen></para><para>Besides the <systemitem moreinfo="none" role="keyword">connect</systemitem> option
that specifies the dialup script, we have added two more options to
the command line: <systemitem moreinfo="none" role="keyword">detach</systemitem>, which tells
<command moreinfo="none">pppd</command> not to detach from the console and become a
background process, and the <systemitem moreinfo="none" role="keyword">modem</systemitem>
keyword, which makes it perform
modem-specific actions on the serial device, like disconnecting the
line before and after the call. If you don't use this keyword,
<command moreinfo="none">pppd</command> will not monitor the port's DCD line and will
therefore not detect whether the remote end hangs up unexpectedly.</para><para>The examples we have shown are rather simple; <command moreinfo="none">chat</command>
allows for much more complex scripts. For instance, it can specify
strings on which to abort the chat with an error.  Typical abort
strings are messages like <systemitem moreinfo="none" role="keyword">BUSY</systemitem>
or <systemitem moreinfo="none" role="keyword">NO CARRIER</systemitem> that your modem
usually generates when the called number is busy or doesn't answer. To
make <command moreinfo="none">chat</command> recognize these messages immediately
rather than timing out, you can specify them at the beginning of the
script using the <systemitem moreinfo="none" role="keyword">ABORT</systemitem>
keyword:

<screen format="linespecific">$ <userinput moreinfo="none">chat -v ABORT BUSY ABORT 'NO CARRIER' '' ATZ OK ...</userinput></screen></para><para>Similarly, you can change the timeout value for parts of
the chat scripts by inserting <systemitem moreinfo="none" role="keyword">TIMEOUT</systemitem> 
options.</para><para>Sometimes you also need to have conditional execution
for parts of the chat script: when you don't receive the
remote end's login prompt, you might want to send a BREAK or a carriage
return. You can achieve this by appending a subscript to an expect
string.  The subscript consists of a sequence of send and expect strings, just
like the overall script itself, which are separated by hyphens. The
subscript is executed whenever the expected string it is appended to
is not received in time.  In the example above, we would modify the chat
script as follows:

<screen format="linespecific">ogin:-BREAK-ogin: ppp ssword: GaGariN</screen></para><?troff .Nd 10?><para>When <command moreinfo="none">chat</command> doesn't see the remote system send the login
prompt, the subscript is executed by first sending a BREAK, and then
waiting for the login prompt again. If the prompt now appears, the
script continues as usual; otherwise, it will terminate with an error.

<indexterm significance="normal" class="endofrange" startref="idx-pppchatscript-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-commandchatcommand-1"></indexterm>
</para></sect1><sect1 id="x-087-2-ipconfig.options"><title>IP Configuration Options</title><para><indexterm significance="normal"><primary>IPCP (Internet Protocol Control Protocol)</primary></indexterm>
IPCP is used to negotiate a number of IP parameters at link configuration time.
Usually, each peer sends an IPCP Configuration Request packet, indicating which
values it wants to change from the defaults and the new value. Upon receipt,
the remote end inspects each option in turn and either acknowledges or rejects
it.</para><para><command moreinfo="none">pppd</command> gives you a lot of control over which IPCP options
it will try to negotiate. You can tune it through various command-line
options that we will discuss in this section.</para><sect2><title>Choosing IP Addresses</title><para><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>IP addresses</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>addresses</secondary><tertiary>negotiation in PPP</tertiary></indexterm>
<indexterm significance="normal"><primary>addresses</primary><secondary>negotiation with PPP</secondary></indexterm>
All IP interfaces require IP addresses assigned to them; a PPP device always
has an IP address. The PPP suite of protocols provides a mechanism that allows
the automatic assignment of IP addresses to PPP interfaces. It is possible for
the PPP program at one end of a point-to-point link to assign an IP address for
the remote end to use, or each may use its own.</para><para>Some PPP servers that handle a lot of client sites assign addresses
dynamically; addresses are assigned to systems only when calling in
and are reclaimed after they have logged off again. This allows the
number of IP addresses required to be limited to the number of dialup
lines. While limitation is convenient for managers of the PPP dialup
server, it is often less convenient for users who are dialing
in. We discussed the way that
hostnames are mapped to IP addresses by use of a database in <xref linkend="x-087-2-resolv"></xref>. In order
for people to connect to your host, they must know your IP address or
the hostname associated with it. If you are a user of a PPP service
that assigns you an IP address dynamically, this knowledge is difficult without
providing some means of allowing the DNS database to be updated after
you are assigned an IP address. Such systems do exist, but we won't
cover them in detail here; instead, we will look at the more
preferable approach, which involves you being able to use the same IP
address each time you establish your network connection.<footnote id="x-087-2-fnpp07"><para> More information on two dynamic host
assignment mechanisms can be found at
<systemitem moreinfo="none" role="url">http://www.dynip.com/</systemitem> and
<systemitem moreinfo="none" role="url">http://www.justlinux.com/dynamic_dns.html</systemitem>.</para></footnote></para><para><?troff .hw hostname?>In the previous example, we had <command moreinfo="none">pppd</command> dial up
<systemitem moreinfo="none" role="sitename">c3po</systemitem> and establish an IP
link. No provisions were taken to choose a particular IP address on
either end of the link.  Instead, we let <command moreinfo="none">pppd</command> take
its default action. It attempts to resolve the local hostname,
<systemitem moreinfo="none" role="sitename">vlager</systemitem> in<?troff .ne 10?> our example, to an
IP address, which it uses for the local end, while letting the remote
machine, <systemitem moreinfo="none" role="sitename">c3po</systemitem>, provide its
own. PPP supports several alternatives to this arrangement.</para><para>To ask for particular addresses, you generally provide <command moreinfo="none">pppd</command>
with the following option:

<screen format="linespecific"><replaceable>local_addr</replaceable>:<replaceable>remote_addr</replaceable></screen></para><para><replaceable>local_addr</replaceable> and
<replaceable>remote_addr</replaceable> may be specified either in
dotted quad notation or as hostnames.<footnote id="x-087-2-fnpp08"><para> Using hostnames in this option has
consequences for CHAP authentication. Please refer to the <xref linkend="x-087-2-ppp.authentication"></xref> section later in this
chapter.</para></footnote>
This option makes <command moreinfo="none">pppd</command> attempt to use the first address
supplied as its own IP address, and the second as the peer's. If the peer
rejects either of the addresses during IPCP negotiation, no IP link will be
established.<footnote id="x-087-2-fnpp09"><para>The <option>ipcp-accept-local</option> and <option>ipcp-accept-remote</option>
options instruct your <command moreinfo="none">pppd</command> to accept the local and remote
IP addresses being offered by the remote PPP, even if you've supplied some in
your configuration. If these options are not configured, your
<command moreinfo="none">pppd</command> will reject any attempt to negotiate the IP addresses
used.</para></footnote></para><para><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>dynamic address assignment</secondary></indexterm>
If you are dialing in to a server and expect it to assign you
an IP address, you should ensure that <command moreinfo="none">pppd</command> does not
attempt to negotiate one for itself. To do this, use the
<option>noipdefault</option> option and leave the
<replaceable>local_addr</replaceable> blank. The
<option>noipdefault</option> option will stop <command moreinfo="none">pppd</command>
from trying to use the IP address associated with the hostname as the
local address.</para><para>If you want to set only the local address but accept any address the
peer uses, simply leave out the <replaceable>remote_addr</replaceable>
part. To make <systemitem moreinfo="none" role="sitename">vlager</systemitem> use
the IP address <systemitem moreinfo="none" role="sitename">130.83.4.27</systemitem> instead of
its own, give it <option>130.83.4.27:</option> on the command line.
Similarly, to set the remote address only, leave the
<replaceable>local_addr</replaceable> field blank. By default,
<command moreinfo="none">pppd</command> will then use the address associated with your
hostname.</para></sect2><sect2><title>Routing Through a PPP Link</title><para><indexterm significance="normal"><primary>routing</primary><secondary>over PPP</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-ppprouting-1"><primary>PPP (Point-to-Point Protocol)</primary><secondary>routing</secondary></indexterm>
After setting up the network interface, <command moreinfo="none">pppd</command> will usually
set up a host route to its peer only. If the remote host is on a LAN, you
certainly want to be able to connect to hosts behind your peer as
well; in that case, a network route must be set up.</para><para>We have already seen that <command moreinfo="none">pppd</command> can be
asked to set the default route using the <option>defaultroute</option>
option.  This option is very useful if the PPP server you dialed up acts as your Internet gateway.</para><para><indexterm significance="normal"><primary>ARP (Address Resolution Protocol)</primary><secondary>proxy</secondary></indexterm>
<indexterm significance="normal"><primary>proxy ARP</primary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>proxy ARP</secondary></indexterm><?troff .hw Winery?>
The reverse case, in which your system acts as a gateway for a single
host, is also relatively easy to accomplish. For example, take some
employee at the Virtual Brewery whose home machine is called
<systemitem moreinfo="none" role="sitename">oneshot</systemitem>. Let's also assume
that we've configured <systemitem moreinfo="none" role="sitename">vlager</systemitem>
as a dialin PPP server. If we've configured <systemitem moreinfo="none" role="sitename">vlager</systemitem> to dynamically assign an IP
address that belongs to the Brewery's subnet, then we can use the
<option>proxyarp</option> option with <command moreinfo="none">pppd</command>, which
will install a proxy ARP entry for <systemitem moreinfo="none" role="sitename">oneshot</systemitem>. This automatically makes
<systemitem moreinfo="none" role="sitename">oneshot</systemitem> accessible from all
hosts at the Brewery and the Winery.</para><para><indexterm significance="normal"><primary>Local Area Networks (LANs)</primary><secondary>connecting</secondary></indexterm>
However, things aren't always that simple. Linking two
local area networks usually requires adding a specific network route
because these networks may have their own default routes. Besides,
having both peers use the PPP link as the default route would generate
a loop, through which packets to unknown destinations would ping-pong between
the peers until their time to live expired.</para><para>Suppose the Virtual Brewery opens a branch in another city.
The subsidiary runs an Ethernet of its own using the IP network number
<systemitem moreinfo="none" role="sitename">172.16.3.0</systemitem>, which is subnet 3 of the
Brewery's class B network. The subsidiary wants to connect to the Brewery's
network via PPP to update customer databases. Again,
<systemitem moreinfo="none" role="sitename">vlager</systemitem> acts as the gateway for the
brewery network and will support the PPP link; its peer at the new branch is
called <systemitem moreinfo="none" role="sitename">vbourbon</systemitem> and has an IP address
of <systemitem moreinfo="none" role="sitename">172.16.3.1</systemitem>. This network is
illustrated in <xref linkend="x-087-2-appendix.brewery.subsidiary"></xref> in
<xref linkend="x-087-2-appendix.brewery"></xref>.</para><para>When <systemitem moreinfo="none" role="sitename">vbourbon</systemitem> connects to
<systemitem moreinfo="none" role="sitename">vlager</systemitem>, it makes the default
route point to <systemitem moreinfo="none" role="sitename">vlager</systemitem> as
usual. On <systemitem moreinfo="none" role="sitename">vlager</systemitem>, however, we
will have only the point-to-point route to <systemitem moreinfo="none" role="sitename">vbourbon</systemitem> and will have to specially
configure a network route for subnet 3 that uses <systemitem moreinfo="none" role="sitename">vbourbon</systemitem> as its gateway. We could do this
manually using the <command moreinfo="none">route</command> command by hand after the
PPP link is established, but this is not a very practical
solution. Fortunately, we can configure the route automatically by using a feature
of <command moreinfo="none">pppd</command> that we haven't discussed yetthe
<command moreinfo="none">ip-up</command> command. This command is a shell script or program
located in <filename moreinfo="none">/etc/ppp</filename> that is executed by
<command moreinfo="none">pppd</command> after the PPP interface has been
configured. When present, it is invoked with the following parameters:

<screen format="linespecific">ip-up <replaceable>iface</replaceable> <replaceable>device</replaceable> <replaceable>speed</replaceable> <replaceable>local_addr</replaceable> <replaceable>remote_addr</replaceable></screen></para><para>The following table summarizes the meaning of each of the
arguments (in the first column, we show the number used by the shell
script to refer to each argument):
<informaltable><tgroup cols="3"><colspec colwidth="0.25i"></colspec><colspec colwidth="0.25i"></colspec><colspec colwidth="2.75i"></colspec><thead><row><entry>Argument</entry><entry>Name</entry><entry>Purpose</entry></row></thead><tbody><row><entry>1</entry><entry><replaceable>iface</replaceable></entry><entry><para>	The network interface used, e.g., <literal moreinfo="none">ppp0</literal>	
	</para></entry></row><row><entry>2</entry><entry><replaceable>device</replaceable></entry><entry><para>	The pathname of the serial device file used (<filename moreinfo="none">/dev/tty</filename>,
	if stdin/stdout are used)
	</para></entry></row><row><entry>3</entry><entry><replaceable>speed</replaceable></entry><entry><para>	
	The speed of the serial device in bits per second
	</para></entry></row><row><entry>4</entry><entry><replaceable>local_addr</replaceable></entry><entry><para>	The IP address of the link's remote end in dotted quad notation
	</para></entry></row><row><entry>5</entry><entry><replaceable>remote_addr</replaceable></entry><entry><para>	The IP address of the remote end of the link in dotted quad notation
	</para></entry></row></tbody></tgroup></informaltable></para><para>In our case, the <command moreinfo="none">ip-up</command> script may contain the
following code fragment:<footnote id="x-087-2-fnpp10"><para> If we
wanted to have routes for other sites created when they dial in, we'd
add appropriate case statements to cover those in which the
<literal moreinfo="none">...</literal> appears in the example.</para></footnote>

<screen format="linespecific">#!/bin/sh
case $5 in
172.16.3.1)            # this is vbourbon
        route add -net 172.16.3.0 gw 172.16.3.1;;
...
esac
exit 0</screen></para><para>Similarly, <command moreinfo="none">/etc/ppp/ip-down</command> can be used to undo
any actions of <command moreinfo="none">ip-up</command> after the PPP link has been taken down
again. So in our <command moreinfo="none">/etc/ppp/ip-down</command> script we would have a
<command moreinfo="none">route</command> command that removed the route we created in the
<command moreinfo="none">/etc/ppp/ip-up</command> script.</para><para><indexterm significance="normal"><primary>routing</primary><secondary>dynamic</secondary></indexterm>
<indexterm significance="normal"><primary>gated command</primary></indexterm>
However, the routing scheme is not yet complete. We have set up routing table
entries on both PPP hosts, but so far none of the hosts on either network knows
anything about the PPP link. This is not a big problem if all hosts at the
subsidiary have their default route pointing at
<systemitem moreinfo="none" role="sitename">vbourbon</systemitem>, and all Brewery hosts route
to <systemitem moreinfo="none" role="sitename">vlager</systemitem> by default. If this is not
the case, your only option is usually to use a routing daemon like
<command moreinfo="none">gated</command>. After creating the network route on
<systemitem moreinfo="none" role="sitename">vlager</systemitem>, the routing daemon
broadcasts the new route to all hosts on the attached subnets.
<indexterm significance="normal" class="endofrange" startref="idx-ppprouting-1"></indexterm></para></sect2></sect1><sect1><title>Link Control Options</title><para><indexterm significance="normal" class="startofrange" id="idx-linkcontrolprotocolppp-1"><primary>LCP (Link Control Protocol)</primary><secondary>options</secondary></indexterm>
We already encountered the Link Control Protocol (LCP), which is
used to negotiate link characteristics and test the link.</para><para>The two most important options negotiated by LCP are the
<emphasis>Asynchronous Control Character Map</emphasis> and the
<emphasis>Maximum Receive Unit</emphasis>. There are a number of other
LCP configuration options, but they are far too specialized to discuss
here.</para><para><indexterm significance="normal"><primary>serial line</primary><secondary>protecting characters</secondary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>escaping control characters</secondary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>async map</secondary></indexterm>
<indexterm significance="normal"><primary>Asynchronous Control Character Map</primary></indexterm>
<indexterm significance="normal"><primary>async map</primary></indexterm>
The Asynchronous Control Character Map, colloquially called the
<emphasis>async map</emphasis>, is used on asynchronous links, such as telephone
lines, to identify control characters that must be escaped (replaced by a
specific two-character sequence) to avoid them being interpreted by equipment
used to establish the link. For instance, you may want to avoid the XON and
XOFF characters used for software handshake because a misconfigured modem
might choke upon receipt of an XOFF. Other candidates include Ctrl-l (the
<command moreinfo="none">telnet</command> escape character). PPP allows you to escape any of
the characters with ASCII codes 0 through 31 by specifying them in the async
map.</para><para>The async map is a 32-bit-wide bitmap expressed in hexadecimal. The least
significant bit corresponds to the ASCII NULL character, and the most
significant bit corresponds to ASCII 31 decimal. These 32 ASCII characters are
the control characters. If a bit is set in the bitmap, it signals that the<?troff .ne 10?>
corresponding character must be escaped before it is transmitted across the
link.</para><para>To tell your peer that it doesn't have to escape all control characters,
but only a few of them, you can specify an async map to <command moreinfo="none">pppd</command>
using the <option>asyncmap</option> option. For example, if only
<literal moreinfo="none">^S</literal> and <literal moreinfo="none">^Q</literal> (ASCII 17 and 19, commonly
used for XON and XOFF) must be escaped, use the following option:

<screen format="linespecific">asyncmap 0x000A0000</screen></para><para><?troff .hw characters?>The conversion is simple as long as you can convert binary to hex.
Lay out 32 bits in front of you. The right-most bit corresponds to ASCII 00
(NULL), and the left-most bit corresponds to ASCII 32 decimal. Set the bits
corresponding to the characters you want escaped to one, and all others to zero.
To convert that into the hexadecimal number <command moreinfo="none">pppd</command> expects,
simply take each set of 4 bits and convert them into hex. You should end up
with eight hexadecimal figures. String them all together and preprend
0x to signify it is a hexadecimal number, and you are done.</para><para>Initially, the async map is set to <literal moreinfo="none">0xffffffff</literal>that
is, all control characters will be escaped. This is a safe default,
but is usually much more than you need. Each character that appears in
the async map results in two characters being transmitted across the
link, so escaping comes at the cost of increased link utilization
and a corresponding performance reduction.</para><para>In most circumstances, an async map of <literal moreinfo="none">0x0</literal> works
fine. No escaping is performed.</para><para><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>Maximum Receive Unit</secondary></indexterm>
<indexterm significance="normal"><primary>Maximum Receive Unit (MRU)</primary></indexterm>
<indexterm significance="normal"><primary>MRU (Maximum Receive Unit)</primary></indexterm> 
<indexterm significance="normal"><primary>Maximum Transfer Unit (MTU)</primary></indexterm>
The Maximum Receive Unit (MRU), signals to the peer the maximum size
of HDLC frames we want to receive.  Although this may remind you of the
Maximum Transfer Unit (MTU) value, these two have little in common. The
MTU is a parameter of the kernel networking device and describes the
maximum frame size the interface is able to transmit. The MRU is more of
an advice to the remote end not to generate frames larger than the
MRU; the interface must nevertheless be able to receive frames of up to
1,500 bytes.</para><para><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>compressing data</secondary></indexterm>
Choosing an MRU is therefore not so much a question of what the link
is capable of transferring, but of what gives you the best
throughput. If you intend to run interactive applications over the
link, setting the MRU to values as low as 296 is a good idea, so that
an occasional larger packet (say, from an FTP session) doesn't make
your cursor jump. To tell <command moreinfo="none">pppd</command> to
request an MRU of 296, you give it the option <literal moreinfo="none">mru
296</literal>. Small MRUs, however, make sense only if you have VJ
header compression (it is enabled by default), because otherwise you'd
waste a large amount of your bandwidth just carrying the IP header for
each datagram.</para><para><command moreinfo="none">pppd</command> also understands a couple of LCP options that configure
the overall behavior of the negotiation process, such as the maximum number of
configuration requests that may be exchanged before the link is terminated.
Unless you know exactly what you are doing, you should leave these options alone.</para><para><indexterm significance="normal"><primary>LCP (Link Control Protocol)</primary><secondary>echo messages</secondary></indexterm>
<indexterm significance="normal"><primary>Echo Request/Echo Response messages</primary></indexterm>
Finally, there are two options that apply to LCP echo messages. PPP
defines two messages, <emphasis>Echo Request</emphasis> and
<emphasis>Echo Response</emphasis>. <command moreinfo="none">pppd</command> uses this
feature to check if a link is still operating.  You can enable this by
using the <option>lcp-echo-interval</option> option together with a
time in seconds.  If no frames are received from the remote host
within this interval, <command moreinfo="none">pppd</command> generates an Echo
Request and expects the peer to return an Echo Response.  If the peer
does not produce a response, the link is terminated after a certain
number of requests are sent.  This number can be set using the
<option>lcp-echo-failure</option> option.  By default, this feature is
disabled altogether.

<indexterm significance="normal" class="endofrange" startref="idx-linkcontrolprotocolppp-1"></indexterm></para></sect1><sect1><title>General Security Considerations</title><para><indexterm significance="normal"><primary>access</primary><secondary>PPP</secondary></indexterm>
<indexterm significance="normal"><primary>pppd (kernel PPP module)</primary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>security</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-securityppp-1"><primary>security</primary><secondary>using PPP</secondary></indexterm>
A misconfigured PPP daemon can be a devastating security breach.  It can be as
bad as letting anyone plug their machine into your Ethernet (and that can be
very bad). In this section, we discuss a few measures that should make
your PPP configuration safe.</para><note><para>Root privilege is required to configure the network
device and routing table. You will usually solve this by running
<command moreinfo="none">pppd</command> setuid <systemitem moreinfo="none" role="userid">root</systemitem>.  However, <command moreinfo="none">pppd</command>
allows users to set various security-relevant options. </para></note><para><indexterm significance="normal"><primary sortas="etc/ppp/options file">/etc/ppp/options file</primary></indexterm>
To protect against any attacks a user may launch by manipulating
<command moreinfo="none">pppd</command> options, you should set a couple of
default values in the global <filename moreinfo="none">/etc/ppp/options</filename>
file, like those shown in the sample file in <xref linkend="x-087-2-ppp.options"></xref>, earlier in this chapter. Some of them, such as the
authentication options, cannot be overridden by the user, and thus
provide reasonable protection against manipulations. An important
option to protect is the <systemitem moreinfo="none" role="keyword">connect</systemitem> option. If you intend to allow
non-root users to invoke <command moreinfo="none">pppd</command> to connect to the
Internet, you should always add the <literal moreinfo="none">connect</literal> and
<literal moreinfo="none">noauth</literal> options to the global options file
<filename moreinfo="none">/etc/ppp/options</filename>. <?troff .ne 10?>If you fail to do this, users
will be able to execute arbitrary commands with
<literal moreinfo="none">root</literal> privileges by specifying the command as their
<systemitem moreinfo="none" role="keyword">connect</systemitem> command on the
<command moreinfo="none">pppd</command> line or in their personal options file.</para><para>Another good idea is to restrict which users may execute
<command moreinfo="none">pppd</command> by creating a group in <filename moreinfo="none">/etc/group</filename>
and adding only those users who you wish to have the ability to execute
the PPP daemon. You should then change group ownership of the
<command moreinfo="none">pppd</command> daemon to that group and remove the world execute
privileges. To do this, assuming you've called your group
<systemitem moreinfo="none" role="userid">dialout</systemitem>, you could use something like:

<screen format="linespecific"># <userinput moreinfo="none">chown root /usr/sbin/pppd</userinput>
# <userinput moreinfo="none">chgrp dialout /usr/sbin/pppd</userinput>
# <userinput moreinfo="none">chmod 4750 /usr/sbin/pppd</userinput></screen></para><para>Of course, you have to protect yourself from the systems you speak PPP
with, too.  To fend off hosts posing as someone else, you should
always require some sort of authentication from your peer.  Additionally, you
should not allow foreign hosts to use any IP address they choose, but
restrict them to at most a few.  The following section will deal with
these topics in detail.</para></sect1><sect1 id="x-087-2-ppp.authentication"><title>Authentication with PPP</title><para><indexterm significance="normal" class="startofrange" id="idx-pppauthentication-1"><primary>PPP (Point-to-Point Protocol)</primary><secondary>authentication</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-authenticationwithppp-1"><primary>authentication</primary><secondary>with PPP</secondary></indexterm>
<indexterm significance="normal"><primary>CHAP (Challenge Handshake Authentication Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>PAP (Password Authentication Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>using CHAP</secondary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>using PAP</secondary></indexterm>
With PPP, each system may require its peer to authenticate itself
using one of two authentication protocols: the
<emphasis>Password Authentication Protocol</emphasis> (PAP), and the
<emphasis>Challenge Handshake Authentication Protocol</emphasis>
(CHAP).  When a connection is established, each end can request the
other to authenticate itself, regardless of whether it is the caller
or the callee.  In the description that follows, we will loosely talk
of client and server when we want to
distinguish between the system sending authentication requests and the
system responding to them. A PPP daemon can ask its peer for
authentication by sending yet another LCP configuration request
identifying the desired authentication protocol.</para><sect2><title>PAP Versus CHAP</title><para>PAP, which is offered by many Internet Service Providers, works
basically the same way as the normal login procedure. The client
authenticates itself by sending a username and a (optionally
encrypted) password to the server, which the server compares to its
secrets database.<footnote id="x-087-2-fnpp11"><para>Secret is just the PPP name for passwords. PPP secrets
don't have the same length limitation as Linux login passwords.</para></footnote>
This technique is vulnerable to eavesdroppers, who may try to obtain the
password by listening in on the serial line, and to repeated trial and error
attacks.</para><para>CHAP does not have these deficiencies. With CHAP, the server sends a randomly
generated challenge string to the client, along with its
hostname. The client uses the hostname to look up the appropriate secret,
combines it with the challenge, and encrypts the string using a one-way
hashing function. The result is returned to the server along with the client's
hostname. The server now performs the same computation, and acknowledges the
client if it arrives at the same result.</para><para>CHAP also doesn't require the client to authenticate itself only at
startup time, but sends challenges at regular intervals to make sure
the client hasn't been replaced by an intruder, for instance by
switching phone lines, or because of a modem configuration error that
causes the PPP daemon not to notice that the original phone call has
dropped out and someone else has dialed in.</para><para><indexterm significance="normal"><primary sortas="etc/ppp/chap-secrets file">/etc/ppp/chap-secrets file</primary></indexterm> 
<indexterm significance="normal"><primary sortas="etc/ppp/pap-secrets file">/etc/ppp/pap-secrets file</primary></indexterm> 
<command moreinfo="none">pppd</command> keeps the secret keys for PAP and CHAP in two
separate files called <filename moreinfo="none">/etc/ppp/pap-secrets</filename> and
<filename moreinfo="none">/etc/ppp/chap-secrets</filename>.  By entering
a remote host in one or the other file, you have fine control over
whether PAP or CHAP is used to authenticate yourself with your peer,
and vice versa.</para><para>By default, <command moreinfo="none">pppd</command> doesn't require authentication from the
remote host, but it will agree to authenticate itself when requested by the
remote host. Since CHAP is so much stronger than PAP, <command moreinfo="none">pppd</command>
tries to use the former whenever possible.  If the peer does not support it, or
if <command moreinfo="none">pppd</command> can't find a CHAP secret for the remote system in
its <filename moreinfo="none">chap-secrets</filename> file, it reverts to PAP. If it doesn't
have a PAP secret for its peer either, it refuses to authenticate
altogether. As a consequence, the connection is shut down.</para><para>You can modify this behavior in several ways. When given
the <option>auth</option> keyword, <command moreinfo="none">pppd</command>
requires the peer to authenticate itself. <command moreinfo="none">pppd</command>
agrees to use either CHAP or PAP as long as it has a secret for the
peer in its CHAP or PAP database. There are other options to turn a
particular authentication protocol on or off, but I won't describe
them here.</para><para><indexterm significance="normal"><primary sortas="etc/ppp/options file">/etc/ppp/options file</primary></indexterm> 
If all systems you talk to with PPP agree to authenticate themselves with
you, you should put the <option>auth</option> option in the global
<filename moreinfo="none">/etc/ppp/options</filename> file and define passwords for each
system in the <filename moreinfo="none">chap-secrets</filename> file. If a system doesn't
support CHAP, add an entry for it to the <filename moreinfo="none">pap-secrets</filename>
file. That way, you can make sure no unauthenticated system connects to your
host.</para><para>The next two sections discuss the two PPP secrets files,
<filename moreinfo="none">pap-secrets</filename> and <filename moreinfo="none">chap-secrets</filename>.
They are located in <filename moreinfo="none">/etc/ppp</filename> and contain triplets
of clients, servers, and passwords, optionally followed by a list of IP
addresses.  The interpretation of the client and server fields is
different for CHAP and PAP, and also depends on whether we authenticate
ourselves with the peer, or whether we require the server to authenticate
itself with us.</para></sect2><sect2><title>The CHAP Secrets File</title><para><indexterm significance="normal"><primary>CHAP (Challenge Handshake Authentication Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>using CHAP</secondary></indexterm>
<indexterm significance="normal"><primary sortas="etc/ppp/chap-secrets file">/etc/ppp/chap-secrets file</primary></indexterm> 
<indexterm significance="normal" class="startofrange" id="ppp.secrets.files"><primary>PPP (Point-to-Point Protocol)</primary><secondary>secrets files</secondary></indexterm>
When it has to authenticate itself with a server using CHAP,
<command moreinfo="none">pppd</command> searches the <filename moreinfo="none">chap-secrets</filename>
file for an entry with the client field equal to the local hostname, and
the server field equal to the remote hostname sent in the CHAP challenge.
When requiring the peer to authenticate itself, the roles are simply reversed:
<command moreinfo="none">pppd</command> then looks for an entry with the client field
equal to the remote hostname (sent in the client's CHAP response), and the
server field equal to the local hostname.</para><para>The following is a sample <filename moreinfo="none">chap-secrets</filename> file for
<systemitem moreinfo="none" role="sitename">vlager</systemitem>:<footnote id="x-087-2-fnpp12"><para>The double quotes are not part of the secret; they merely serve to protect the
whitespace within it.</para></footnote>
</para><para><screen format="linespecific"># CHAP secrets for vlager.vbrew.com
#
# client         server           secret                addrs
#---------------------------------------------------------------------
vlager.vbrew.com  c3po.lucas.com   "Use The Source Luke" vlager.vbrew.com
c3po.lucas.com    vlager.vbrew.com "arttoo! arttoo!"     c3po.lucas.com
*                 vlager.vbrew.com "TuXdrinksVicBitter"  pub.vbrew.com</screen></para><para>When <systemitem moreinfo="none" role="sitename">vlager</systemitem> establishes a PPP
connection with <systemitem moreinfo="none" role="sitename">c3po</systemitem>,
<systemitem moreinfo="none" role="sitename">c3po</systemitem> asks
<systemitem moreinfo="none" role="sitename">vlager</systemitem> to authenticate itself by
sending a CHAP challenge. <command moreinfo="none">pppd</command> on
<systemitem moreinfo="none" role="sitename">vlager</systemitem> then scans
<filename moreinfo="none">chap-secrets</filename> for an entry with the client field equal to
<systemitem moreinfo="none" role="sitename">vlager.vbrew.com</systemitem> and the server field
equal to <systemitem moreinfo="none" role="sitename">c3po.lucas.com</systemitem>, and finds
the first line shown in the example.<footnote id="x-087-2-fnpp13"><para>This hostname is taken from the CHAP challenge.</para></footnote>
It then produces the CHAP response from the challenge string and the secret
(<literal moreinfo="none">Use The Source Luke</literal>), and sends it off to
<systemitem moreinfo="none" role="sitename">c3po</systemitem>.</para><para><command moreinfo="none">pppd</command> also composes a CHAP challenge for
<systemitem moreinfo="none" role="sitename">c3po</systemitem> containing a unique challenge
string and its fully qualified hostname,
<systemitem moreinfo="none" role="sitename">vlager.vbrew.com</systemitem>.
<systemitem moreinfo="none" role="sitename">c3po</systemitem> constructs a CHAP response in
the way we discussed, and returns it to
<systemitem moreinfo="none" role="sitename">vlager</systemitem>. <command moreinfo="none">pppd</command> then
extracts the client hostname
(<systemitem moreinfo="none" role="sitename">c3po.vbrew.com</systemitem>) from the response and
searches the <filename moreinfo="none">chap-secrets</filename> file for a line matching
<systemitem moreinfo="none" role="sitename">c3po</systemitem> as a client and
<systemitem moreinfo="none" role="sitename">vlager</systemitem> as the server. The second line
does this, so <command moreinfo="none">pppd</command> combines the CHAP challenge and the
secret <literal moreinfo="none">arttoo! arttoo!</literal>, encrypts them, and compares
the result to <systemitem moreinfo="none" role="sitename">c3po</systemitem>'s CHAP response.</para><para><indexterm significance="normal"><primary>addresses</primary><secondary>negotiation with PPP</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>addresses</secondary><tertiary>negotiation in PPP</tertiary></indexterm>
<indexterm significance="normal"><primary>access</primary><secondary>restricting</secondary></indexterm>
The optional fourth field lists the IP addresses that are acceptable
for the client named in the first field. The addresses can be given
in dotted quad notation or as hostnames that are looked up with the
resolver.  For instance, if <systemitem moreinfo="none" role="sitename">c3po</systemitem>
asks to use an IP address during IPCP negotiation that is not in this
list, the request is rejected, and IPCP is shut down. In the
sample file shown above, <systemitem moreinfo="none" role="sitename">c3po</systemitem>
is therefore limited to using its own IP address. If the address field is
empty, any addresses are allowed; a value of
<literal moreinfo="none">-</literal> prevents the use of IP with that client
altogether.</para><para>The third line of the sample <filename moreinfo="none">chap-secrets</filename> file
allows any host to establish a PPP link with
<systemitem moreinfo="none" role="sitename">vlager</systemitem> because a client or server field
of <literal moreinfo="none">*</literal> is a wildcard matching any hostname. The only
requirements are that the connecting host must know the secret and that it must use
the IP address associated with
<systemitem moreinfo="none" role="sitename">pub.vbrew.com</systemitem>. Entries with wildcard
hostnames may appear anywhere in the secrets file, since
<command moreinfo="none">pppd</command> will always use the best match it can find for
the server/client pair.</para><para><command moreinfo="none">pppd</command> may need some help forming hostnames. As explained
before, the remote hostname is always provided by the peer in the CHAP
challenge or response packet.  The local hostname is obtained by calling
the <function moreinfo="none">gethostname(2)</function> function by default. If you have
set the system name to your unqualified hostname, you also have to provide
<command moreinfo="none">pppd</command> with the domain name using the
<option>domain</option> option:

<screen format="linespecific"># <userinput moreinfo="none">pppd  domain vbrew.com</userinput></screen></para><para>This provision appends the Brewery's domain name to <systemitem moreinfo="none" role="sitename">vlager</systemitem> for all authentication related
activities.  Other options that modify
<command moreinfo="none">pppd</command>'s idea of the local hostname are
<option>usehostname</option> and <option>name</option>.  When you give
the local IP address on the command line using
<command moreinfo="none"><replaceable>local</replaceable>:<replaceable>remote</replaceable></command> and <replaceable>local</replaceable> as a name instead of a dotted
quad, <command moreinfo="none">pppd</command> uses this as the local hostname.</para></sect2><sect2><title>The PAP Secrets File</title><para>
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>using PAP</secondary></indexterm>
<indexterm significance="normal"><primary sortas="etc/ppp/pap-secrets file">/etc/ppp/pap-secrets file</primary></indexterm> 
The PAP secrets file is very similar to CHAP's. The first two
fields always contain a username and a server name; the third holds the
PAP secret.  When the remote host sends its authentication information,
<command moreinfo="none">pppd</command> uses the entry that has a server field equal to the
local hostname, and a user field equal to the username sent in the request.
When it is necessary for us to send our credentials to the peer,
<command moreinfo="none">pppd</command> uses the secret that has a user field equal to the
local username and the server field equal to the remote hostname.</para><para>A sample PAP secrets file might look like this:

<screen format="linespecific"># /etc/ppp/pap-secrets
#
# user          server          secret          addrs
vlager-pap      c3po            cresspahl       vlager.vbrew.com
c3po            vlager          DonaldGNUth     c3po.lucas.com</screen></para><para>The first line is used to authenticate ourselves when talking to
<systemitem moreinfo="none" role="sitename">c3po</systemitem>.  The second line describes
how a user named <systemitem moreinfo="none" role="sitename">c3po</systemitem> has
to authenticate itself with us.</para><para>The name <systemitem moreinfo="none" role="keyword">vlager-pap</systemitem> in the first column
is the username we send to <systemitem moreinfo="none" role="sitename">c3po</systemitem>.
By default, <command moreinfo="none">pppd</command> picks the local hostname as the username,
but you can also specify a different name by giving the <option>user</option>
option followed by that name.</para><para>When picking an entry from the <filename moreinfo="none">pap-secrets</filename> file
to identify us to a remote host, <command moreinfo="none">pppd</command>
must know the remote host's name.  As it has no way of finding that
out, you must specify it on the command line using the
<option>remotename</option> keyword followed by the peer's
hostname. To use the above entry for authentication with
<systemitem moreinfo="none" role="sitename">c3po</systemitem>, for example, we must add the
following option to <command moreinfo="none">pppd</command>'s command line:

<screen format="linespecific"># <userinput moreinfo="none">pppd ... remotename c3po user vlager-pap</userinput></screen></para><?troff .Nd 10?><para>In the fourth field of the PAP secrets file (and all following fields), you can specify what IP addresses are allowed for that
particular host, just as in the CHAP secrets file. The peer will be
allowed to request only addresses from that list. In the sample file,
the entry that <systemitem moreinfo="none" role="sitename">c3po</systemitem> will use
when it dials inthe line where <systemitem moreinfo="none" role="sitename">c3po</systemitem> is the clientallows it to use
its real IP address and no other.</para><?troff .wcon_off?><para>Note that PAP is a rather weak authentication method, you should
use CHAP instead whenever possible. We will therefore not cover PAP in greater
detail here;  if you are interested in using it, you will find more PAP
features in the <filename moreinfo="none">pppd(8)</filename> manual page.

<indexterm significance="normal" class="endofrange" startref="idx-authenticationwithppp-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-pppauthentication-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-securityppp-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="ppp.secrets.files"></indexterm></para></sect2></sect1><sect1><title>Debugging Your PPP Setup</title><para><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>debugging setup of</secondary></indexterm>
<indexterm significance="normal"><primary>debugging</primary><secondary>PPP setup</secondary></indexterm>
<indexterm significance="normal"><primary>syslog</primary></indexterm>
<indexterm significance="normal"><primary>checking</primary><secondary>PPP</secondary></indexterm>
By default, <command moreinfo="none">pppd</command> logs any warnings and error messages
to <command moreinfo="none">syslog</command>'s <systemitem moreinfo="none" role="keyword">daemon</systemitem>
facility. You have to add an entry to <filename moreinfo="none">syslog.conf</filename> that redirects
these messages to a file or even the console; otherwise, <command moreinfo="none">syslog</command> <?troff .ne 3?>
simply discards them. The following entry
sends all messages to <filename moreinfo="none">/var/log/ppp-log</filename>:

<screen format="linespecific">daemon.*                /var/log/ppp-log</screen></para><para>If your PPP setup doesn't work right away, you should look in this log
file. If the log messages don't help, you can also turn on extra
debugging output using the <option>debug</option> option. This output makes
<command moreinfo="none">pppd</command> log the contents of all control packets sent
or received to <command moreinfo="none">syslog</command>.  All messages then go to the
<systemitem moreinfo="none" role="keyword">daemon</systemitem> facility.</para><para><indexterm significance="normal"><primary sortas="proc/kmsg file">/proc/kmsg file</primary></indexterm> 
Finally, the most drastic way to check a problem is to enable kernel-level
debugging by invoking <command moreinfo="none">pppd</command> with the <option>kdebug</option>
option. It is followed by a numeric argument that is the sum of the
following values: 1 for general debug messages, 2 for printing the contents of
all incoming HDLC frames, and 4 to make the driver print all outgoing
HDLC frames. To capture kernel debugging messages, you must either run
a <command moreinfo="none">syslogd</command> daemon that reads the
<filename moreinfo="none">/proc/kmsg</filename> file, or the <command moreinfo="none">klogd</command> daemon.
Either of them directs kernel debugging to the <command moreinfo="none">syslog</command>
<systemitem moreinfo="none" role="keyword">kernel</systemitem> facility.
</para></sect1><sect1><title>More Advanced PPP Configurations</title><para><indexterm significance="normal" class="startofrange" id="ppp.advanced.configs"><primary>PPP (Point-to-Point Protocol)</primary><secondary>advanced configurations</secondary></indexterm>
While configuring PPP to dial in to a network like the Internet is the
most common application, there are those of you who have more
advanced requirements. In this section we'll talk about a few of the more
advanced configurations possible with PPP under Linux.</para><sect2><title>PPP Server</title><para><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>configuring server in</secondary></indexterm>
<indexterm significance="normal"><primary sortas="etc/passwd file">/etc/passwd file</primary></indexterm> 
<indexterm significance="normal"><primary sortas="etc/shadow file">/etc/shadow file</primary></indexterm> 
Running <command moreinfo="none">pppd</command> as a server is just a matter of
configuring a serial tty device to invoke <command moreinfo="none">pppd</command> with
appropriate options when an incoming data call has been received. One
way to do this is to create a special account, say <systemitem moreinfo="none" role="userid">ppp</systemitem>, and give it a script or program as a
login shell that invokes <command moreinfo="none">pppd</command> with these
options. Alternatively, if you intend to support PAP or CHAP
authentication, you can use the <command moreinfo="none">mgetty</command> program to
support your modem and exploit its /AutoPPP/ feature.</para><para>To build a server using the login method, you add a line similar
to the following to your <filename moreinfo="none">/etc/passwd</filename>
file:<footnote id="x-087-2-fnpp14"><para> The
<command moreinfo="none">useradd</command> or <command moreinfo="none">adduser</command> utility, if you have it, will
simplify this task.</para></footnote><?troff .wcon_off?>
<screen format="linespecific">ppp:x:500:200:Public PPP Account:/tmp:/etc/ppp/ppplogin</screen>

If your system supports shadow passwords, you also need to add an entry
to the <filename moreinfo="none">/etc/shadow</filename> file:

<screen format="linespecific">ppp:!:10913:0:99999:7:::</screen></para><?troff .Nd 5?><para>Of course, the UID and GID you use depends on which user you wish to
own the connection, and how you've created it. You also have to set the
password for the mentioned account using the <command moreinfo="none">passwd</command> command.</para><para>The <command moreinfo="none">ppplogin</command> script might look like this:

<screen format="linespecific">#!/bin/sh
# ppplogin - script to fire up pppd on login
mesg n
stty -echo
exec pppd -detach silent modem crtscts</screen></para><para>The <command moreinfo="none">mesg</command> command disables other users from writing
to the tty by using, for instance, the <command moreinfo="none">write</command>
command. The <command moreinfo="none">stty</command> command turns off character
echoing. This command is necessary; otherwise, everything the peer sends would
be echoed back to it. The most important <command moreinfo="none">pppd</command>
option given is <systemitem moreinfo="none" role="keyword">detach</systemitem>
because it prevents <command moreinfo="none">pppd</command> from detaching from the
controlling tty.  If we didn't specify this option, it would go to the
background, making the shell script exit. This in turn would cause the
serial line to hang up and the connection to be dropped.  The
<command moreinfo="none">silent</command> option causes <command moreinfo="none">pppd</command> to
wait until it receives a packet from the calling system before it
starts sending.  This option prevents transmit timeouts from occurring when
the calling system is slow in firing up its PPP client. The
<systemitem moreinfo="none" role="keyword">modem</systemitem> option makes
<command moreinfo="none">pppd</command> drive the modem control lines of the serial
port.  You should always turn this option on when using
<command moreinfo="none">pppd</command> with a modem.  The <option>crtscts</option>
option turns on hardware handshake.</para><para>Besides these options, you might want to force some sort of
authentication, for example, by specifying <option>auth</option> on
<command moreinfo="none">pppd</command>'s command line or in the global
options file.  The manual page also discusses more specific options
for turning individual authentication protocols on and off.</para><para>If you wish to use <command moreinfo="none">mgetty</command>, all you need to do is
configure <command moreinfo="none">mgetty</command> to support the serial device your modem
is connected to (see <xref linkend="x-087-2-serial.getty.mgetty"></xref> for details),
configure <command moreinfo="none">pppd</command> for either PAP or CHAP authentication
with appropriate options in its <filename moreinfo="none">options</filename> file, and finally,
add a section similar to the following to your
<filename moreinfo="none">/etc/mgetty/login.config</filename> file:

<screen format="linespecific"># Configure mgetty to automatically detect incoming PPP calls and invoke
# the pppd daemon to handle the connection.
#
/AutoPPP/ -     ppp   /usr/sbin/pppd auth -chap +pap login</screen></para><para>The first field is a special piece of magic used to detect that
an incoming call is a PPP one. You must not change the case of this string;
it is case sensitive. The third column is the username that appears in
<command moreinfo="none">who</command> listings when someone has logged in. The rest of the
line is the command to invoke. In our example, we've ensured that PAP
authentication is required, disabled CHAP, and specified that the system
<filename moreinfo="none">passwd</filename> file should be used for authenticating users.
This is probably similar to what you'll want. Remember, you can specify
the options in the <filename moreinfo="none">options</filename> file or on the command line
if you prefer.</para><para>Here is a small checklist of tasks to perform and the sequence you should
perform them to get PPP dial in working on your machine. Make sure each
step works before moving on to the next:

<orderedlist inheritnum="ignore" continuation="restarts"><listitem><para>Configure the modem for auto-answer mode. On Hayes-compatible modems,
this is performed using a command like <literal moreinfo="none">ATS0=3</literal>. If you're
going to be using the <command moreinfo="none">mgetty</command> daemon, this isn't necessary.</para></listitem><listitem><para>Configure the serial device with a <command moreinfo="none">getty</command> type of command to
answer incoming calls. A commonly used <command moreinfo="none">getty</command> variant is
<command moreinfo="none">mgetty</command>.</para></listitem><listitem><para>Consider authentication. Will your callers authenticate using PAP,
CHAP, or system login?</para></listitem><listitem><para>Configure <command moreinfo="none">pppd</command> as server as described in this section.</para></listitem><listitem><para>Consider routing. Will you need to provide a network route to callers?
Routing can be performed using the <filename moreinfo="none">ip-up</filename> script.</para></listitem></orderedlist></para></sect2><?troff .wcon_off?><sect2><title>Demand Dialing</title><para><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>configuring demand dialing for</secondary></indexterm>
<indexterm significance="normal"><primary>demand dialing</primary></indexterm>
<indexterm significance="normal"><primary>telephones</primary><secondary>demand dialing</secondary></indexterm>
<indexterm significance="normal"><primary>modems</primary><secondary>demand dialing</secondary></indexterm>
<indexterm significance="normal"><primary>dialing</primary><secondary>demand</secondary></indexterm>
When there is IP
traffic to be carried across the link, <emphasis>demand dialing</emphasis> causes your telephone modem to
dial and to establish a connection to a remote host. Demand dialing is most useful
when you can't leave your telephone line permanently switched to your
Internet provider. For example, you might have to pay timed local calls, so it might be cheaper to have the telephone line
switched on only when you need it and disconnected when you aren't
using the Internet.</para><para>Traditional Linux solutions have used the <command moreinfo="none">diald</command>
command, which worked well but was fairly tricky to
configure. Versions 2.3.0 and later of the PPP daemon have built-in
support for demand dialing and make it very simple to configure. You
must use a modern kernel for this to work, too. Any of the later 2.0
kernels will work just fine.</para><para>To configure <command moreinfo="none">pppd</command> for demand dialing, all you need to do
is add options to your <filename moreinfo="none">options</filename> file or the
<command moreinfo="none">pppd</command> command line. The following table summarizes the
options related to demand dialing:
<?troff .Nd 10?>
<informaltable><tgroup cols="2"><colspec colwidth="0.5i"></colspec><colspec colwidth="2.75i"></colspec><thead><row><entry>Option</entry><entry>Description</entry></row></thead><tbody><row><entry><literal moreinfo="none">demand</literal></entry><entry><para>This option specifies that the PPP link should be placed in demand dial mode. The PPP network device will be created, but the <literal moreinfo="none">connect</literal> command will not be used until a datagram is transmitted by the local host. This option is mandatory for demand dialing to work.</para></entry></row><row><entry><literal moreinfo="none">active-filter</literal> <replaceable>expression</replaceable></entry><entry><para>This option allows you to specify which data packets are to be considered active traffic. Any traffic matching the specified rule will restart the demand dial idle timer, ensuring that <command moreinfo="none">pppd</command> waits again before closing the link. The filter syntax has been borrowed from the <command moreinfo="none">tcpdump</command> command. The default filter matches all datagrams.</para></entry></row><row><entry><literal moreinfo="none">holdoff</literal> <replaceable>n</replaceable></entry><entry><para>This option allows you to specify the minimum amount of time, in seconds, to wait before reconnecting this link if it terminates. If the connection fails while <command moreinfo="none">pppd</command> believes it is in active use, it will be re-established after this timer has expired. This timer does not apply to reconnections after an idle timeout.</para></entry></row><row><entry><literal moreinfo="none">idle</literal> <replaceable>n</replaceable></entry><entry><para>If this option is configured, <command moreinfo="none">pppd</command> will disconnect the link whenever this timer expires. Idle times are specified in seconds. Each new active data packet will reset the timer.</para></entry></row></tbody></tgroup></informaltable>

A simple demand dialing configuration would therefore look something
like this:

<screen format="linespecific">demand
holdoff 60
idle 180</screen>

This configuration would enable demand dialing, wait 60 seconds before
re-establishing a failed connection, and drop the link if 180 seconds pass
without any active data on the link.</para></sect2><sect2><title>Persistent Dialing</title><para><indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>configuring persistent dialing for</secondary></indexterm>
<indexterm significance="normal"><primary>persistent dialing</primary></indexterm>
<indexterm significance="normal"><primary>telephones</primary><secondary>persistent dialing</secondary></indexterm>
<indexterm significance="normal"><primary>modems</primary><secondary>persistent dialing</secondary></indexterm>
<indexterm significance="normal"><primary>dialing</primary><secondary>persistent</secondary></indexterm>
<emphasis>Persistent dialing</emphasis> is what people who have
permanent dialup connections to a network will want to use. There is a
subtle difference between demand dialing and persistent dialing. With
persistent dialing, the connection is automatically established as soon
as the PPP daemon is started, and the persistent aspect comes into play
whenever the telephone call supporting the link fails. Persistent dialing ensures that the link is always
available by automatically rebuilding the connection if it fails.</para><para>You might be fortunate to not have to pay for your telephone calls;
perhaps they are local and free, or perhaps they're paid by your
company. The persistent dialing option is extremely useful in this
situation. If you do have to pay for your telephone calls, then you
have to be a little careful. If you pay for your telephone calls on a
time-charged basis, persistent dialing is almost certainly not what
you want, unless you're very sure you'll be using the connection fairly
steadily twenty-four hours a day. If you do pay for calls, but they
are not time charged, you need to be careful to protect yourself
against situations that might cause the modem to endlessly redial. The
<command moreinfo="none">pppd</command> daemon provides an option that can help reduce
the effects of this problem.</para><para>To enable persistent dialing, you must include the <systemitem moreinfo="none" role="keyword">persist</systemitem> option in one of your
<command moreinfo="none">pppd</command> options files. Including this option alone is
all you need to have <command moreinfo="none">pppd</command> automatically
invoke the command specified by the <systemitem moreinfo="none" role="keyword">connect</systemitem> option to rebuild the connection
when the link fails. If you are concerned about the modem redialing
too rapidly (in the case of modem or server fault at the
other end of the connection), you can use the <systemitem moreinfo="none" role="keyword">holdoff</systemitem> option to set the minimum amount
of time that <command moreinfo="none">pppd</command> will wait before attempting to
reconnect.  This option won't solve the problem of a fault costing you money
in wasted phone calls, but it will at least serve to reduce the impact
of one.</para><para>A typical configuration might have persistent dialing options that
look like this:

<screen format="linespecific">persist
holdoff 600</screen>

The holdoff time is specified in seconds. In our example,
<command moreinfo="none">pppd</command> waits a full five minutes before redialing
after the call drops out.</para><para>It is possible to combine persistent dialing with demand dialing,
using <systemitem moreinfo="none" role="keyword">idle</systemitem> to drop the link if
it has been idle for a specified period of time. We doubt many users
would want to do so, but this scenario is described briefly in the
<command moreinfo="none">pppd</command> manual page, if you'd like to pursue it.</para></sect2></sect1><indexterm significance="normal" class="endofrange" startref="idx-commandpppdcommand-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-ppp-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-configuringppp-1"></indexterm><indexterm significance="normal" class="endofrange" startref="ppp.advanced.configs"></indexterm></chapter><chapter id="x-087-2-firewall"><title>TCP/IP Firewall</title><indexterm significance="normal" class="startofrange" id="chfw.tcp.ip.firewall"><primary>TCP/IP (Transmission Control Protocol/Internet Protocol)</primary><secondary>firewalls</secondary></indexterm><indexterm significance="normal" class="startofrange" id="chfw.firewalls.tcp.ip"><primary>firewalls</primary><secondary>TCP/IP</secondary></indexterm><para><indexterm significance="normal"><primary>firewalls</primary><secondary>security</secondary></indexterm>
<indexterm significance="normal"><primary>security</primary><secondary>network</secondary></indexterm>
<indexterm significance="normal"><primary>security</primary><secondary>firewalls</secondary></indexterm>
Security is increasingly important for companies and individuals alike.
The Internet has provided them with a powerful tool to distribute information
about themselves and obtain information from others, but it has
also exposed them to dangers that they have previously been exempt from. 
Computer crime, information theft, and malicious damage are all potential
dangers.</para><para>An unauthorized and unscrupulous person who gains access to
a computer system may guess system passwords or
exploit the bugs and idiosyncratic behavior of certain programs to obtain
a working account on that machine. Once they are able to log in to the
machine, they may have access to information that may be damaging, such as
commercially sensitive information like marketing plans,
new project details, or customer information databases. Damaging or modifying
this type of data can cause severe setbacks to the company.</para><para>The safest way to avoid such widespread damage is to prevent unauthorized
people from gaining network access to the machine. This is where firewalls
come in.</para><warning><para><indexterm significance="normal"><primary>firewalls</primary><secondary>warning</secondary></indexterm>
Constructing secure firewalls is an art. It involves a good understanding
of technology, but equally important, it requires an understanding
of the philosophy behind firewall designs. We won't cover
everything you need to know in this book; we strongly recommend you
do some additional research before trusting any particular firewall design,
including any we present here.</para></warning><para>There is enough material on firewall configuration and design
to fill a whole book, and indeed there are some good resources that you might
like to read to expand your knowledge on the subject. Two of these are:<?troff .Nd 10?>
<variablelist><varlistentry><term><emphasis>Building Internet Firewalls</emphasis></term><listitem><para>by D. Chapman and E. Zwicky (O'Reilly). A guide
explaining how to design and install firewalls for Unix, Linux, and
Windows NT, and how to configure Internet services to work with the
firewalls.</para></listitem></varlistentry><varlistentry><term><emphasis>Firewalls and Internet Security</emphasis></term><listitem><para>by W. Cheswick and S. Bellovin (Addison Wesley). This book covers the 
philosophy of firewall design and implementation.</para></listitem></varlistentry></variablelist></para><para>We will focus on the Linux-specific technical issues in this chapter. Later
we will present a sample firewall configuration that should serve as a useful
starting point in your own configuration, but as with all security-related
matters, trust no one. Double check the design, make sure you understand it,
and then modify it to suit your requirements. To be safe, be sure.</para><sect1 id="x-082-2-firewall.attacks"><title>Methods of Attack</title><para><indexterm significance="normal"><primary>firewalls</primary><secondary>methods of attack</secondary></indexterm>
<indexterm significance="normal"><primary>security</primary><secondary>methods of attack</secondary></indexterm>
As a network administrator, it is important that you understand the nature of
potential attacks on computer security. We'll briefly
describe the most important types of attacks so that you can better understand
precisely what the Linux IP firewall will protect you against. You should do
some additional reading to ensure that you are able to protect your
network against other types of attacks. Here
are some of the more important methods of attack and ways of protecting
yourself against them:</para><variablelist><varlistentry><term>Unauthorized access</term><listitem><para>This simply means that people who shouldn't use your computer services are
able to connect and
use them. For example, people outside your company might try to
connect to your company accounting machine or to your NFS server.</para><para>There are various ways to avoid this attack by carefully specifying who
can gain access through these services. You can prevent network access
to all except the intended users.</para></listitem></varlistentry><varlistentry><term>Exploitation of known weaknesses in programs</term><listitem><para>Some programs and network services were not originally designed with strong
security in mind and are inherently vulnerable to attack. The BSD remote
services (rlogin, rexec, etc.) are an example.</para><para>The best way to protect yourself against this type of attack is to disable
any vulnerable services or find alternatives. With Open Source, it is
sometimes possible to repair the weaknesses in the software.</para></listitem></varlistentry><varlistentry><term>Denial of service</term><listitem><para><indexterm significance="normal"><primary>denial of service attacks</primary></indexterm>
Denial of service attacks cause the service or program to cease functioning or
prevent others from making use of the service or program. These may be
performed at the network layer by sending carefully crafted and malicious
datagrams that cause network connections to fail. They may also be performed
at the application layer, where carefully crafted application commands are
given to a program that cause it to become extremely busy or stop functioning.</para><para>Preventing suspicious network traffic from reaching your hosts and preventing
suspicious program commands and requests are the best ways of minimizing the
risk of a denial of service attack. It's useful to know the details of the 
attack method, so you should educate yourself about each new attack as it 
gets publicized.</para></listitem></varlistentry><varlistentry><term>Spoofing</term><listitem><para><indexterm significance="normal"><primary>spoofing</primary><secondary>attacks</secondary></indexterm>
This type of attack causes a host or application to mimic the
actions of another. Typically the attacker pretends to be an innocent host
by following IP addresses in network packets. For example, a
well-documented exploit of the BSD rlogin service can use this method to mimic a
TCP connection from another host by guessing TCP sequence numbers.</para><para>To protect against this type of attack, verify the authenticity of datagrams
and commands. Prevent datagram routing with invalid source addresses.
Introduce unpredictablility into connection control mechanisms, such as TCP
sequence numbers and the allocation of dynamic port addresses.</para></listitem></varlistentry><varlistentry><term>Eavesdropping</term><listitem><para><indexterm significance="normal"><primary>eavesdropping programs</primary></indexterm>
This is the simplest type of attack. A host is configured to "listen" to and
capture data not belonging to it. Carefully written eavesdropping programs
can take usernames and passwords from user login network connections.
Broadcast networks like Ethernet are especially vulnerable to this type of
attack.</para><para>To protect against this type of threat, avoid use of broadcast
network technologies and enforce the use of data encryption.</para></listitem></varlistentry></variablelist><para>IP firewalling is very useful in preventing or reducing unauthorized access,
network layer denial of service, and IP spoofing attacks. It not very useful
in avoiding exploitation of weaknesses in network services or programs and
eavesdropping. </para></sect1><sect1 id="x-087-2-firewall.introduction"><title>What Is a Firewall?</title><para><indexterm significance="normal"><primary>firewalls</primary></indexterm>
A firewall is a secure and trusted machine that sits between a private
network and a public network.<footnote id="x-087-2-fw-fn01"><para> The
term <emphasis>firewall</emphasis> comes from a device used to protect
people from fire. The firewall is a shield of material resistant to
fire that is placed between a potential fire and the people it is
protecting.</para></footnote>
The firewall machine is configured with a set of rules that determine
which network traffic will be allowed to pass and which will be blocked
or refused. In some large organizations, you may even find a firewall
located inside their corporate network to segregate sensitive areas
of the organization from other employees. Many cases of computer
crime occur from within an organization, not just from outside.</para><para>Firewalls can be constructed in quite a variety of ways.  The most
sophisticated arrangement involves a number of separate machines and
is known as a <emphasis>perimeter network</emphasis>. Two machines act
as "filters" called chokes to allow only certain types of network
traffic to pass, and between these chokes reside network servers such as a
mail gateway or a World Wide Web proxy server. This configuration can
be very safe and easily allows quite a great range of control over who
can connect both from the inside to the outside, and from the outside
to the inside. This sort of configuration might be used by large
organizations.</para><para>Typically though, firewalls are single machines that serve all of these
functions. These are a little less secure, because if there is some
weakness in the firewall machine itself that allows people to gain access
to it, the whole network security has been breached. Nevertheless,
these types of firewalls are cheaper and easier to manage than the more
sophisticated arrangement just described.
<xref linkend="x-087-2-firewall.design.graphic"></xref> illustrates the two most
common firewall configurations.</para><figure float="1" id="x-087-2-firewall.design.graphic"><title>The two major classes of firewall design</title><graphic fileref="lag2_0901.jpg"></graphic></figure><para>The Linux kernel provides a range of built-in features that allow it
to function quite nicely as an IP firewall. The network implementation
includes code to do IP filtering in a number of different ways, and
provides a mechanism to quite accurately configure what sort of rules
you'd like to put in place. The Linux firewall is flexible enough to
make it very useful in either of the configurations illustrated in
<xref linkend="x-087-2-firewall.design.graphic"></xref>. Linux firewall
software provides two other useful features that we'll discuss in
separate chapters: IP Accounting (<xref linkend="x-087-2-accounting"></xref>) and IP masquerade (<xref linkend="x-087-2-ipmasq"></xref>).</para></sect1><sect1 id="x-087-2-firewall.filtering"><title>What Is IP Filtering?</title><para><indexterm significance="normal"><primary>filtering</primary><secondary>IP</secondary></indexterm>
<indexterm significance="normal"><primary>IP (Internet Protocol)</primary><secondary>filtering</secondary></indexterm>
<indexterm significance="normal"><primary>security</primary><secondary>filtering</secondary></indexterm>
<indexterm significance="normal"><primary>datagrams</primary><secondary>IP filtering</secondary></indexterm>
IP filtering is simply a mechanism that decides which types of IP
datagrams will be processed normally and which will be discarded. By
<emphasis>discarded</emphasis> we mean that the datagram is deleted
and completely ignored, as if it had never been received. You can
apply many different sorts of criteria to determine which datagrams
you wish to filter; some examples of these are:

<itemizedlist><listitem><para>Protocol type: TCP, UDP, ICMP, etc.</para></listitem><listitem><para>Socket number (for TCP/UPD)</para></listitem><listitem><para>Datagram type: SYN/ACK, data, ICMP Echo Request, etc.</para></listitem><listitem><para>Datagram source address: where it came from</para></listitem><listitem><para>Datagram destination address: where it is going to</para></listitem></itemizedlist>
</para><para>It is important to understand at this point that IP filtering is a
network layer facility. This means it doesn't understand anything
about the application using the network connections, only about the
connections themselves. For example, you may deny users access to your
internal network on the default telnet port, but if you rely on IP
filtering alone, you can't stop them from using the telnet program
with a port that you do allow to pass trhough your firewall. You can prevent
this sort of problem by using proxy servers for each service that you
allow across your firewall. The proxy servers understand the
application they were designed to proxy and can therefore prevent
abuses, such as using the telnet program to get past a firewall by
using the World Wide Web port. If your firewall supports a World Wide
Web proxy, their telnet connection will always be answered by the
proxy and will allow only HTTP requests to pass. A large number of
proxy-server programs exist. Some are free software and many others
are commercial products. The Firewall-HOWTO discusses one popular set
of these, but they are beyond the scope of this book.</para><para>The IP filtering ruleset is made up of many combinations of the criteria
listed previously. For example, let's imagine that you wanted to allow World
Wide Web users within the Virtual Brewery network to have no access to the
Internet except to use other sites' web servers. You would configure your
firewall
to allow forwarding of:

<itemizedlist><listitem><para>datagrams with a source address on Virtual Brewery network, a destination
address of anywhere, and with a destination port of 80 (WWW)</para></listitem><listitem><para>datagrams with a destination address of Virtual Brewery network and a
source port of 80 (WWW) from a source address of anywhere</para></listitem></itemizedlist>
</para><para>Note that we've used two rules here. We have to allow our data to go out,
but also the corresponding reply data to come back in. In practice, as we'll
see shortly, Linux simplifies this and allows us to specify this in one
command. </para></sect1><sect1 id="x-087-2-firewall.howto"><title>Setting Up Linux for Firewalling</title><para><indexterm significance="normal" class="startofrange" id="kernel.config.ipfirewall"><primary>kernels</primary><secondary>configured with IP firewall</secondary></indexterm>
<indexterm significance="normal"><primary>configuring</primary><secondary>kernel</secondary><tertiary sortas="IP firewall">with IP firewall</tertiary></indexterm>
To build a Linux IP firewall, it is necessary to have a kernel built
with IP firewall support and the appropriate configuration utility. In
all production kernels prior to the 2.2 series, you would use the
<command moreinfo="none">ipfwadm</command> utility. The 2.2.x kernels marked the
release of the third generation of IP firewall for Linux called
<emphasis>IP Chains</emphasis>.  IP chains use a program similar to
<command moreinfo="none">ipfwadm</command> called <command moreinfo="none">ipchains</command>. Linux
kernels 2.3.15 and later support the fourth generation of Linux IP
firewall called <emphasis>netfilter</emphasis>. The
<emphasis>netfilter</emphasis> code is the result of a large redesign
of the packet handling flow in Linux. The
<emphasis>netfilter</emphasis> is a multifaceted creature, providing
direct backward-compatible support for both <command moreinfo="none">ipfwadm</command>
and <command moreinfo="none">ipchains</command> as well as a new alternative command
called <command moreinfo="none">iptables</command>. We'll talk about the differences
between the three in the next few sections.</para><sect2 id="x-087-2-firewall.howto.kernel"><title>Kernel Configured with IP Firewall</title><para>The Linux kernel must be configured to support IP firewalling. There
isn't much more to it than selecting the appropriate options when
performing a <literal moreinfo="none">make menuconfig</literal> of your
kernel.<footnote id="x-087-2-fw-fn02"><para> Firewall packet logging
is a special feature that writes a line of information about each
datagram that matches a particular firewall rule out to a special
device so you can see them.</para></footnote>
We described how to do this is in
<xref linkend="x-087-2-hardware"></xref>.
In 2.2 kernels you should select the following options:

<screen width="80" format="linespecific">Networking options  ---
	[*] Network firewalls
	[*] TCP/IP networking
	[*] IP: firewalling
	[*] IP: firewall packet logging</screen></para><para>In kernels 2.4.0 and later you should select this option instead:

<screen width="80" format="linespecific">  Networking options  ---
     [*] Network packet filtering (replaces ipchains)
         IP: Netfilter Configuration  ---
              .
             M Userspace queueing via NETLINK (EXPERIMENTAL)
             M IP tables support (required for filtering/masq/NAT)
             M   limit match support
             M   MAC address match support
             M   netfilter MARK match support
             M   Multiple port match support
             M   TOS match support
             M   Connection state match support
             M   Unclean match support (EXPERIMENTAL)
             M   Owner match support (EXPERIMENTAL)
             M   Packet filtering
             M     REJECT target support
             M     MIRROR target support (EXPERIMENTAL)
              .
             M   Packet mangling
             M     TOS target support
             M     MARK target support
             M   LOG target support
             M ipchains (2.2-style) support
             M ipfwadm (2.0-style) support
  </screen>
  </para></sect2><sect2 id="x-087-2-firewall.howto.ipfwadm"><title>The ipfwadm Utility</title><para><indexterm significance="normal"><primary>ipfwadm command</primary></indexterm>
The <command moreinfo="none">ipfwadm</command> (IP Firewall Administration) utility is the
tool used to build the firewall rules for all kernels prior to 2.2.0. Its
command syntax can be very confusing because it can do such a complicated
range of things, but we'll provide some common examples that will illustrate
the most important variations of these.</para><para>The <command moreinfo="none">ipfwadm</command> utility is included in most
modern Linux distributions, but perhaps not by default. There may be a
specific software package for it that you have to install. If your
distribution does not include it, you can obtain the source package from
<systemitem moreinfo="none" role="sitename">ftp.xos.nl</systemitem> in the
<filename moreinfo="none">/pub/linux/ipfwadm/</filename> directory, and compile it yourself.</para></sect2><sect2 id="x-087-2-firewall.howto.ipchains"><title>The ipchains Utility</title><para><indexterm significance="normal"><primary>ipchains command</primary></indexterm>
Just as for the <command moreinfo="none">ipfwadm</command> utility, the
<command moreinfo="none">ipchains</command> utility can be somewhat baffling to use at first.
It provides all of the flexibility of <command moreinfo="none">ipfwadm</command> with a
simplified command syntax, and additionally provides a chaining mechanism that allows you to manage multiple
rulesets and link them together. We'll cover rule chaining in a separate
section near the end of the chapter, because for most situations it is an
advanced concept.</para><para><indexterm significance="normal"><primary>ipfwadm-wrapper command</primary></indexterm>
The <command moreinfo="none">ipchains</command> command appears in most Linux
distributions based on the 2.2 kernels. If you want to compile it
yourself, you can find the source package from its developer's site at
<emphasis>http://www.rustcorp.com/linux/ipchains/</emphasis>.
Included in the source package is a wrapper script called
<command moreinfo="none">ipfwadm-wrapper</command> that mimics the
<command moreinfo="none">ipfwadm</command> command, but actually invokes the
<command moreinfo="none">ipchains</command> command. Migration of an existing firewall
configuration is much more painless with this addition.</para></sect2><sect2 id="x-087-2-firewall.howto.iptables"><title>The iptables Utility</title><para><indexterm significance="normal"><primary>iptables command</primary></indexterm>
The syntax of the <command moreinfo="none">iptables</command> utility is quite similar to that
of the <command moreinfo="none">ipchains</command> syntax. The changes are improvements and a
result of the tool being redesigned to be extensible through shared libraries.
Just as for <command moreinfo="none">ipchains</command>, we'll present
<command moreinfo="none">iptables</command> equivalents of the examples so you can compare
and contrast its syntax with the others.</para><para>The <command moreinfo="none">iptables</command> utility is included in the
<emphasis>netfilter</emphasis> source package available at
<emphasis>http://www.samba.org/netfilter/</emphasis>. It will
also be included in any Linux distribution based on the 2.4 series kernels.</para><para>We'll talk a bit about <emphasis>netfilter</emphasis>'s huge step forward in a section of its own later in this chapter.</para></sect2><indexterm significance="normal" class="endofrange" startref="kernel.config.ipfirewall"></indexterm></sect1><sect1 id="x-087-2-firewall.filteringmethods"><title>Three Ways We Can Do Filtering</title><indexterm significance="normal"><primary>filtering</primary><secondary>stages of</secondary></indexterm><indexterm significance="normal"><primary>datagrams</primary><secondary>stages of processing</secondary></indexterm><para>Consider how a Unix machine, or in fact any machine capable of IP routing,
processes IP datagrams. The basic steps, shown in <xref linkend="x-087-2-firewall.methods.graphic"></xref> are:</para><figure float="1" id="x-087-2-firewall.methods.graphic"><title>The stages of IP datagram processing</title><graphic fileref="lag2_0902.jpg"></graphic></figure><itemizedlist><listitem><para>The IP datagram is received. (1)</para></listitem><listitem><para>The incoming IP datagram is examined to determine if it is destined for a
process on this machine.</para></listitem><listitem><para>If the datagram is for this machine, it is processed locally. (2)</para></listitem><listitem><para>If it is not destined for this machine, a search is made of the routing table
for an appropriate route and the datagram is forwarded to the appropriate
interface or dropped if no route can be found. (3)</para></listitem><listitem><para>Datagrams from local processes are sent to the routing software for forwarding
to the appropriate interface. (4)</para></listitem><listitem><para>The outgoing IP datagram is examined to determine if there is a valid route
for it to take, if not, it is dropped.</para></listitem><listitem><para>The IP datagram is transmitted. (5)</para></listitem></itemizedlist><para>In our diagram, the flow 135 represents our machine
routing data between a host on our Ethernet network to a host
reachable via our PPP link. The flows 12 and 45 represent
the data input and output flows of a network program running on our
local host. The flow 432 would represent data flow via a
loopback connection. Naturally data flows both into and out of network
devices.  The question marks on the diagram represent the points where
the IP layer makes routing decisions.</para><para>The Linux kernel IP firewall is capable of applying filtering at various
stages in this process. That is, you can filter the IP datagrams that come in
to your machine, filter those datagrams being forwarded across your
machine, and filter those datagrams that are ready to be transmitted.</para><para>In <command moreinfo="none">ipfwadm</command> and <command moreinfo="none">ipchains</command>, an
Input rule applies to flow 1 on the diagram, a Forwarding rule to flow
3, and an Output rule to flow 5.  We'll see when we discuss
<emphasis>netfilter</emphasis> later that the points of interception
have changed so that an Input rule is applied at flow 2, and an
Output rule is applied at flow 4. This has important implications for
how you structure your rulesets, but the general principle holds true
for all versions of Linux firewalling.</para><para>This may seem unnecessarily complicated at first, but it provides flexibility
that allows some very sophisticated and powerful configurations to be built.</para></sect1><sect1 id="x-087-2-firewall.original"><title>Original IP Firewall (2.0 Kernels)</title><para><indexterm significance="normal"><primary>Cox, Alan</primary></indexterm>
<indexterm significance="normal"><primary>Vos, Jos</primary></indexterm>
<indexterm significance="normal"><primary>Middelink, Pauline</primary></indexterm>
<indexterm significance="normal" class="startofrange" id="original.firewall"><primary>firewalls</primary><secondary>original IP</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="linux.2.0.kernels"><primary>2.0 kernels</primary><secondary>IP firewalls</secondary></indexterm>
<indexterm significance="normal"><primary>ipfwadm command</primary></indexterm>
The first generation IP firewall support for Linux appeared in the 1.1
series kernel. It was a port of the BSD ipfw firewall support to Linux
by Alan Cox.  The firewall support that appeared in the 2.0 series
kernels and is the second generation was enhanced by Jos Vos, Pauline
Middelink, and others.</para><sect2 id="x-087-2-firewall.usingipfwadm"><title>Using ipfwadm</title><para>The <command moreinfo="none">ipfwadm</command> command was the configuration tool for the
second generation Linux IP firewall. Perhaps the simplest way to describe the
use of the <command moreinfo="none">ipfwadm</command> command is by example. To begin, let's
code the example we presented earlier.</para><sect3 id="x-087-2-firewall.simpleexample"><title>A nave example</title><para>Let's suppose that we have a network in our organization and that we
are using a Linux-based firewall machine to connect our network to
the Internet. Additionally, let's suppose that we wish the users of
that network to be able to access web servers on the Internet, but to
allow no other traffic to be passed.</para><para>We will put in place a forwarding rule to allow datagrams with a source
address on our network and a destination socket of port 80 to be forwarded
out, and for the corresponding reply datagrams to be forwarded back via the
firewall.</para><?troff .sp -1p?><para>Assume our network has a 24-bit network mask (Class C) and an address
of 172.16.1.0. The rules we might use are:
<screen format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -F -f</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -F -p deny</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -F -a accept -P tcp -S 172.16.1.0/24 -D 0/0 80</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -F -a accept -P tcp -S 0/0 80 -D 172.16.1.0/24</userinput></screen></para><para>The <option>-F</option> command-line argument tells
<command moreinfo="none">ipfwadm</command> that this is a forwarding rule.
The first command instructs <command moreinfo="none">ipfwadm</command> to "flush" all
of the forwarding rules. This ensures we are working from a known
state before we begin adding specific rules.</para><para>The second rule sets our default forwarding policy. We
tell the kernel to deny or disallow forwarding of IP datagrams. It
is very important to set the default policy, because this describes what will
happen to any datagrams that are not specifically handled by any other
rule. In most firewall configurations, you will want to set your default
policy to "deny," as shown, to be sure that only the traffic you specifically
allow past your firewall is forwarded.</para><para>The third and fourth rules are the ones that implement our requirement.
The third command allows our datagrams out, and the fourth rule allows
the responses back.</para><para>Let's review each of the arguments:

<variablelist><varlistentry><term>-F</term><listitem><para>This is a Forwarding rule.</para></listitem></varlistentry><varlistentry><term>-a accept</term><listitem><para>Append this rule with the policy set to "accept," meaning we will forward
any datagrams that match this rule.</para></listitem></varlistentry><varlistentry><term>-P tcp</term><listitem><para>This rule applies to tcp datagrams (as opposed to UDP or ICMP).</para></listitem></varlistentry><varlistentry><term>-S 172.16.1.0/24</term><listitem><para>The Source address must have the first 24 bits matching those of the
network address 172.16.1.0.</para></listitem></varlistentry><varlistentry><term>-D 0/0 80</term><listitem><para>The destination address must have zero bits matching the address 0.0.0.0.
This is really a shorthand notation for "anything." The 80 is the
destination port, in this case WWW. You may also use any entry that
appears in the <filename moreinfo="none">/etc/services</filename> file to describe the
port, so <literal moreinfo="none">-D 0/0 www</literal> would have worked just as well.</para></listitem></varlistentry></variablelist></para><para><command moreinfo="none">ipfwadm</command> accepts network masks in a form with which you may
not be familiar. The <literal moreinfo="none">/nn</literal> notation is a means of
describing how many bits of the supplied address are significant, or the
size of the mask. The bits are always counted from left to right;
some common examples are listed in <xref linkend="x-087-2-chfw-netmasks"></xref>.</para><indexterm significance="normal"><primary>firewalls</primary><secondary>netmask specification</secondary></indexterm><table tocentry="1" id="x-087-2-chfw-netmasks"><title>Common Netmask Bit Values</title><tgroup cols="2"><thead><row><entry>Netmask</entry><entry>Bits</entry></row></thead><tbody><row><entry>255.0.0.0</entry><entry>8</entry></row><row><entry>255.255.0.0</entry><entry>16</entry></row><row><entry>255.255.255.0</entry><entry>24</entry></row><row><entry>255.255.255.128</entry><entry>25</entry></row><row><entry>255.255.255.192</entry><entry>26</entry></row><row><entry>255.255.255.224</entry><entry>27</entry></row><row><entry>255.255.255.240</entry><entry>28</entry></row><row><entry>255.255.255.248</entry><entry>29</entry></row><row><entry>255.255.255.252</entry><entry>30</entry></row></tbody></tgroup></table><para>We mentioned earlier that <command moreinfo="none">ipfwadm</command> implements a
small trick that makes adding these sorts of rules easier. This trick
is an option called <emphasis>-b</emphasis>, which makes the command a
bidirectional rule.</para><para>The bidirectional flag allows us to collapse our two
rules into one as follows:

<screen width="80" format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -F -a accept -P tcp -S 172.16.1.0/24 -D 0/0 80 -b</userinput></screen></para></sect3><sect3 id="x-087-2-firewall.simpleexample.refinement"><title>An important refinement</title><para>Take a closer look at our ruleset. Can you see that there is still one method
of attack that someone outside could use to defeat our firewall?</para><para>Our ruleset allows all datagrams from outside our network with a source port
of 80 to pass. This will include those datagrams with the SYN bit set! The SYN
bit is what declares a TCP datagram to be a connection request. If a person
on the outside had privileged access to a host, they could make a connection
through our firewall to any of our hosts, provided they use port 80 at their
end. This is not what we intended.</para><?troff .Nd 10?><para>Fortunately there is a solution to this problem. The
<command moreinfo="none">ipfwadm</command> command provides another flag that allows
us to build rules that will match datagrams with the SYN bit
set. Let's change our example to include such a rule:

<screen width="80" format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -F -a deny -P tcp -S 0/0 80 -D 172.16.10.0/24 -y</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -F -a accept -P tcp -S 172.16.1.0/24 -D 0/0 80 -b</userinput></screen></para><para>The <option>-y</option> flag causes the rule to match only if the
SYN flag is set in the datagram. So our new rule says:
"Deny any TCP datagrams destined for our network from anywhere with a source
port of 80 and the SYN bit set," or "Deny any connection requests from hosts
using port 80."</para><para>Why have we placed this special rule <emphasis>before</emphasis> the
main rule?  IP firewall rules operate so that the first match is the
rule that is used. Both rules would match the datagrams we want to
stop, so we must be sure to put the <literal moreinfo="none">deny</literal> rule
before the <literal moreinfo="none">accept</literal> rule.</para></sect3><sect3 id="x-087-2-firewall.listing"><title>Listing our rules</title><para><?troff .hw command?><indexterm significance="normal"><primary>ipfwadm command</primary><secondary>listing rules with</secondary></indexterm>
After we've entered our rules, we ask <command moreinfo="none">ipfwadm</command> to list
them for us using the command:

<screen width="80" format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -F -l</userinput></screen>

This command will list all of the configured forwarding rules. The output
should look something like this:

<screen width="80" format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -F -l</userinput>
IP firewall forward rules, default policy: accept
type  prot source               destination          ports
deny  tcp  anywhere             172.16.10.0/24       www - any
acc   tcp  172.16.1.0/24        anywhere             any - www</screen>

The <command moreinfo="none">ipfwadm</command> command will attempt to translate the port
number into a service name using the <filename moreinfo="none">/etc/services</filename> if
an entry exists there.</para><para>The default output is lacking in some important detail for us. In the
default listing output, we can't see the effect of the
<literal moreinfo="none">-y</literal> argument.  The <command moreinfo="none">ipfwadm</command> command
is able to produce a more detailed listing output if you specify the
<literal moreinfo="none">-e</literal> (extended output) argument too. We won't show the
whole output here because it is too wide for the page, but it includes
an <literal moreinfo="none">opt</literal> (options) column that shows the <option>-y</option> option
controlling SYN packets:</para><screen width="120" format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -F -l -e</userinput>
P firewall forward rules, default policy: accept
 pkts bytes type  prot opt  tosa tosx ifname  ifaddress   source        ...   
    0     0 deny  tcp  --y- 0xFF 0x00 any     any         anywhere      ...       
    0     0 acc   tcp  b--- 0xFF 0x00 any     any         172.16.1.0/24 ...</screen></sect3></sect2><sect2 id="x-087-2-firewall.complexexample"><title>A More Complex Example</title><para>The previous example was a simple one. Not all network services are as
simple as the WWW service to configure; in practice, a typical firewall
configuration would be much more complex. Let's look at another common
example, this time FTP. We want our internal network users to be able
to log into FTP servers on the Internet to read and write files. But we don't
want people on the Internet to be able to log into our FTP servers.</para><para>We know that FTP uses two TCP ports: port 20 (ftp-data) and port 21 (ftp),
so:

<screen width="80" format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -a deny -P tcp -S 0/0 20 -D 172.16.1.0/24 -y</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -a accept -P tcp -S 172.16.1.0/24 -D 0/0 20 -b</userinput>
#
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -a deny -P tcp -S 0/0 21 -D 172.16.1.0/24 -y</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipfwadm -a accept -P tcp -S 172.16.1.0/24 -D 0/0 21 -b</userinput></screen>

Right? Well, not necessarily. FTP servers
can operate in two different modes: passive mode and active
mode.<footnote id="x-087-2-fw-fn03"><para>FTP active mode is somewhat nonintuitively enabled using the
<command moreinfo="none">PORT</command> command. FTP passive mode is enabled using the
<command moreinfo="none">PASV</command> command.</para></footnote>  In passive mode, the FTP server
listens for a connection from the client. In active mode, the server actually
makes the connection to the client. Active mode is usually the
default. The differences are illustrated in <xref linkend="x-087-2-firewall.ftp.graphic"></xref>.</para><figure float="1" id="x-087-2-firewall.ftp.graphic"><title>FTP server modes</title><graphic fileref="lag2_0903.jpg"></graphic></figure><para>Many FTP servers make their data connection from port 20 when operating in
active mode, which simplifies things for us a little, but unfortunately not
all do.<footnote id="x-087-2-fw-fn04"><para>The ProFTPd daemon is a good example of an FTP server that doesn't, at least
in older versions.</para></footnote></para><para>But how does this affect us? Take a look at our rule for port 20, the
FTP-data port. The rule as we have it now assumes that the connection
will be made by our client to the server. This will work if we
use passive mode. But it is very difficult for us to configure
a satisfactory rule to allow FTP active mode, because we may not know in
advance what ports will be used. If we open up our firewall to allow incoming
connections on any port, we are exposing our network to attack on all
services that accept connections.</para><para>The dilemna is most safely resolved by insisting that our users operate in
passive
mode. Most FTP servers and many FTP clients will operate this way.
The popular <command moreinfo="none">ncftp</command> client also supports passive mode, but
it may require a small configuration change to make it default to passive
mode. Many
World Wide Web browsers such as the Netscape browser also support passive
mode FTP, so it shouldn't be too hard to find appropriate software to use.
Alternatively, you can avoid the issue entirely by using an FTP proxy
server that accepts a connection from the internal network and establishes
connections to the outside network.</para><para>In building your firewall, you will probably find a number of these
sorts of problems. You should always give careful thought to how a service
actually operates to be sure you have put in place an appropriate ruleset for
it. A real firewall configuration can be quite complex.</para></sect2><sect2 id="x-087-2-firewall.ipfwadmargs"><title>Summary of ipfwadm Arguments</title><para><indexterm significance="normal" class="startofrange" id="ipfwadm.firewall.options"><primary>ipfwadm command</primary><secondary>firewall options</secondary></indexterm>
The <command moreinfo="none">ipfwadm</command> has many different arguments that relate to
IP firewall configuration. The general syntax is:

<screen width="45" format="linespecific"><command moreinfo="none">ipfwadm</command> <replaceable>category</replaceable> <replaceable>command</replaceable> <replaceable>parameters</replaceable> <replaceable>[options]</replaceable></screen></para><para>Let's take a look at each of these.</para><sect3 id="x-087-2-firewall.ipfwadm.categories"><title>Categories</title><para>One and only one of the following must be supplied. The category tells the
firewall what sort of firewall rule you are configuring:</para><?troff .Nd 10?><variablelist><varlistentry><term>-I</term><listitem><para>Input rule</para></listitem></varlistentry><varlistentry><term>-O</term><listitem><para>Output rule</para></listitem></varlistentry><varlistentry><term>-F</term><listitem><para>Forwarding rule</para></listitem></varlistentry></variablelist></sect3><sect3 id="x-087-2-firewall.ipfwadm.command"><title>Commands</title><para>At least one of the following must be supplied and applies only to
those rules that relate to the supplied category. The command tells the
firewall what action to take.</para><variablelist><varlistentry><term>-a [policy]</term><listitem><para>Append a new rule</para></listitem></varlistentry><varlistentry><term>-i [policy]</term><listitem><para>Insert a new rule</para></listitem></varlistentry><varlistentry><term>-d [policy]</term><listitem><para>Delete an existing rule</para></listitem></varlistentry><varlistentry><term>-p policy</term><listitem><para>Set the default policy</para></listitem></varlistentry><varlistentry><term>-l</term><listitem><para>List all existing rules</para></listitem></varlistentry><varlistentry><term>-f</term><listitem><para>Flush all existing rules</para></listitem></varlistentry></variablelist><para>The policies relevant to IP firewall and their meanings are:

<variablelist><varlistentry><term>accept</term><listitem><para>Allows matching datagrams to be received, forwarded, or transmitted</para></listitem></varlistentry><varlistentry><term>deny</term><listitem><para>Blocks matching datagrams from being received, forwarded, or transmitted</para></listitem></varlistentry><varlistentry><term>reject</term><listitem><para>Blocks matching datagrams from being received, forwarded, or transmitted, and
sends the host that sent the datagram and ICMP error message</para></listitem></varlistentry></variablelist>
</para></sect3><sect3 id="x-087-2-firewall.ipfwadm.parameters"><title>Parameters</title><para>At least one of the following must be supplied. Use the parameters
to specify to which datagrams this rule applies:</para><variablelist><varlistentry><term>-P protocol</term><listitem><para>Can be TCP, UDP, ICMP, or all. Example:</para><para><literal moreinfo="none">-P tcp</literal></para></listitem></varlistentry><varlistentry><term>-S address[/mask] [port]</term><listitem><para>Source IP address that this rule will match. A netmask of
/32 will be assumed if you don't supply one. You may
optionally specify which ports this rule will apply to. You must also
specify the protocol using the <option>-P</option> argument described
above for this to work. If you don't specify a port or port range,
all ports will be assumed to match. Ports may be
specified by name, using their <filename moreinfo="none">/etc/services</filename> entry
if you wish. In the case of the ICMP protocol, the port field is used
to indicate the ICMP datagram types. Port ranges may be described; use
the general syntax:
<replaceable>lowport</replaceable>:<replaceable>highport</replaceable>. Here is an example:</para><para><literal moreinfo="none">-S 172.29.16.1/24 ftp:ftp-data</literal></para></listitem></varlistentry><varlistentry><term>-D address[/mask] [port]</term><listitem><para>Specify the destination IP address that this rule will match. The destination
address is coded with the same rules as the source address described previously. Here is an example:</para><para><literal moreinfo="none">-D 172.29.16.1/24 smtp</literal></para></listitem></varlistentry><varlistentry><term>-V address</term><listitem><para>Specify the address of the network interface on which the packet is received
(<option>-I</option>) or is being sent (<option>-O</option>). This
allows us to create rules that apply only to certain network interfaces on our
machine. Here is an example:</para><para><literal moreinfo="none">-V 172.29.16.1</literal></para></listitem></varlistentry><varlistentry><term>-W name</term><listitem><para>Specify the name of the network interface. This argument works in the same way
as the <option>-V</option> argument, except you supply the device name
instead of its address. Here is an example:</para><para><literal moreinfo="none">-W ppp0</literal></para></listitem></varlistentry></variablelist></sect3><sect3 id="x-087-2-firewall.ipfwadm.optargs"><title>Optional arguments</title><para>These arguments are sometimes very useful:</para><variablelist><varlistentry><term>-b</term><listitem><para>This is used for bidirectional mode. This flag matches traffic flowing
in either direction between the specified source and
destination. This saves you from having to create two rules: one for
the forward direction of a connection and one for the reverse.</para></listitem></varlistentry><varlistentry><term>-o</term><listitem><para>This enables logging of matching datagrams to the kernel log. Any
datagram that matches this rule will be logged as a kernel
message. This is useful to enable you to detect unauthorized access.</para></listitem></varlistentry><varlistentry><term>-y</term><listitem><para>This is used to match TCP connect datagrams. The option causes the
rule to match only datagrams that attempt to establish TCP
connections. Only datagrams that have their SYN bit set, but their ACK
bit unset, will match. This is useful to filter TCP connection
attempts and is ignored for other protocols.</para></listitem></varlistentry><varlistentry><term>-k</term><listitem><para>This is used to match TCP acknowledgement datagrams. This option
causes the rule to match only datagrams that are acknowledgements to
packets attempting to establish TCP connections.  Only datagrams that
have their ACK bit set will match. This is useful to filter TCP
connection attempts and is ignored for all other protocols.</para></listitem></varlistentry></variablelist></sect3><sect3 id="x-087-2-firewall.ipfwadm.icmp-types"><title>ICMP datagram types</title><para><indexterm significance="normal"><primary>ICMP (Internet Control Message Protocol)</primary><secondary>datagram types</secondary></indexterm>
<indexterm significance="normal"><primary>RFC-1700</primary></indexterm>
<indexterm significance="normal"><primary>datagram types, ICMP protocol</primary></indexterm>
Each of the firewall configuration commands allows you to specify ICMP
datagram types. Unlike TCP and UDP ports, there is no convenient
configuration file that lists the datagram types and their
meanings. The ICMP datagram types are defined in
RFC-1700, the Assigned Numbers RFC. The ICMP datagram types are also
listed in one of the standard C library header files. The
<filename moreinfo="none">/usr/include/netinet/ip_icmp.h</filename> file, which
belongs to the GNU standard library package and is used by C
programmers when writing network software that uses the ICMP protocol,
also defines the ICMP datagram types. For your convenience, we've
listed them in <xref linkend="x-087-2-chfw-icmptypes"></xref>. The
<command moreinfo="none">iptables</command> command interface allows you to specify
ICMP types by name, so we've listed the mnemonics it uses, as well.</para><table tocentry="1" id="x-087-2-chfw-icmptypes"><title>ICMP Datagram Types</title><tgroup cols="3"><thead><row><entry>Type Number</entry><entry>iptables Mnemonic</entry><entry>Type Description</entry></row></thead><tbody><row><entry>0</entry><entry>echo-reply</entry><entry>Echo Reply</entry></row><row><entry>3</entry><entry>destination-unreachable</entry><entry>Destination Unreachable</entry></row><row><entry>4</entry><entry>source-quench</entry><entry>Source Quench</entry></row><row><entry>5</entry><entry>redirect</entry><entry>Redirect</entry></row><row><entry>8</entry><entry>echo-request</entry><entry>Echo Request</entry></row><row><entry>11</entry><entry>time-exceeded</entry><entry>Time Exceeded</entry></row><row><entry>12</entry><entry>parameter-problem</entry><entry>Parameter Problem</entry></row><row><entry>13</entry><entry>timestamp-request</entry><entry>Timestamp Request</entry></row><row><entry>14</entry><entry>timestamp-reply</entry><entry>Timestamp Reply</entry></row><row><entry>15</entry><entry>none</entry><entry>Information Request</entry></row><row><entry>16</entry><entry>none</entry><entry>Information Reply</entry></row><row><entry>17</entry><entry>address-mask-request</entry><entry>Address Mask Request</entry></row><row><entry>18</entry><entry>address-mask-reply</entry><entry>Address Mask Reply</entry></row></tbody></tgroup></table></sect3><indexterm significance="normal" class="endofrange" startref="ipfwadm.firewall.options"></indexterm></sect2><indexterm significance="normal" class="endofrange" startref="original.firewall"></indexterm><indexterm significance="normal" class="endofrange" startref="linux.2.0.kernels"></indexterm></sect1><sect1 id="x-087-2-firewall.fwchains"><title>IP Firewall Chains (2.2 Kernels)</title><indexterm significance="normal" class="startofrange" id="firewall.ip.chains"><primary>firewalls</primary><secondary>IP chains</secondary></indexterm><indexterm significance="normal" class="startofrange" id="ip.firewall.chains"><primary>IP (Internet Protocol)</primary><secondary>Firewall Chains</secondary></indexterm><indexterm significance="normal" class="startofrange" id="chains.ip.firewall"><primary>chains</primary><secondary>IP firewall</secondary></indexterm><indexterm significance="normal" class="startofrange" id="linux.2.2.kernels"><primary>2.2 kernels</primary><secondary>IP firewall chains</secondary></indexterm><para>Most aspects of Linux are evolving to meet the increasing demands of
its users; IP firewall is no exception. The traditional IP firewall
implementation is fine for most applications, but can be clumsy and inefficient
to configure for complex environments. To solve this problem, a new method of
configuring IP firewall and related features was developed. This new method was
called IP Firewall Chains and was first released for general use
in the 2.2.0 Linux kernel.</para><para><indexterm significance="normal"><primary>Russell, Paul</primary></indexterm>
<indexterm significance="normal"><primary>Neuling, Michael</primary></indexterm>
The IP Firewall Chains support was developed by Paul
Russell and Michael Neuling.<footnote id="x-087-2-fn05"><para>Paul can be reached at
<systemitem moreinfo="none" role="emailaddr">Paul.Russell@rustcorp.com.au</systemitem>.</para></footnote>
<indexterm significance="normal"><primary>IPCHAINS-HOWTO</primary></indexterm>
<indexterm significance="normal"><primary>HOWTOs</primary><secondary>IPCHAINS</secondary></indexterm>
Paul has documented the IP Firewall Chains software in the IPCHAINS-HOWTO.</para><para>IP Firewall Chains allows you to
develop classes of firewall rules to which you may then add and remove hosts
or networks. An artifact of firewall rule chaining is that it may
improve firewall performance in configurations in which there are lots of rules.</para><para>IP Firewall Chains are supported by the 2.2 series kernels and are also
available as a patch against the 2.0.* kernels. The HOWTO
describes where to obtain the patch and provides lots of useful hints about
how to effectively use the <command moreinfo="none">ipchains</command> configuration utility.</para><sect2 id="x-087-2-firewall.usingipchains"><title>Using ipchains</title><para><indexterm significance="normal"><primary>ipchains command</primary></indexterm>
<indexterm significance="normal"><primary>ipfwadm-wrapper command</primary></indexterm>
There are two ways you can use the <command moreinfo="none">ipchains</command> utility. The
first way is to make use of the <command moreinfo="none">ipfwadm-wrapper</command> shell
script, which is mostly a drop-in replacement for <command moreinfo="none">ipfwadm</command>
that drives the <command moreinfo="none">ipchains</command> program in the background. If you
want to do this, then read no further. Instead, reread the previous sections
describing <command moreinfo="none">ipfwadm</command>, and substitute
<command moreinfo="none">ipfwadm-wrapper</command> in its place. This will work, but there is
no guarantee that the script will be maintained, and you will not be taking
advantage of any of the advanced features that the IP Firewall Chains have to
offer.</para><para>The second way to use <command moreinfo="none">ipchains</command> is to learn its new syntax
and modify any existing configurations you have to use the new syntax instead
of the old. With some careful consideration, you may find you can optimize your
configuration as you convert. The <command moreinfo="none">ipchains</command> syntax is easier
to learn than the <command moreinfo="none">ipfwadm</command>, so this is a good option.</para><para>The <command moreinfo="none">ipfwadm</command> manipulated three rulesets for the purpose
of configuring firewalling. With IP Firewall Chains you can create arbitrary
numbers of rulesets, each linked to one another, but there are three rulesets
related to firewalling that are always present. The standard rulesets
are direct equivalents of those used with <command moreinfo="none">ipfwadm</command>, except
they have names: <literal moreinfo="none">input</literal>, <literal moreinfo="none">forward</literal> and
<literal moreinfo="none">output</literal>.</para><para>Let's first look at the general syntax of the <command moreinfo="none">ipchains</command>
command, then we'll look at how we'd use <command moreinfo="none">ipchains</command> instead
of <command moreinfo="none">ipfwadm</command> without worrying about any of the advanced
chaining features. We'll do this by revisiting our previous examples.</para></sect2><sect2 id="x-087-2-firewall.ipchains.syntax"><title>ipchains Command Syntax</title><para><indexterm significance="normal" class="startofrange" id="ipchains.firewall.options"><primary>ipchains command</primary><secondary>firewall options</secondary></indexterm>
The <command moreinfo="none">ipchains</command> command syntax is straightforward. We'll now
look at the most important of those. The general syntax of most
<command moreinfo="none">ipchains</command> commands is:

<screen width="80" format="linespecific"><command moreinfo="none">ipchains</command> <replaceable>command</replaceable> <replaceable>rule-specification</replaceable> <replaceable>options</replaceable></screen>
</para><sect3 id="x-087-2-firewall.ipchains.commands"><title>Commands</title><para>There are a number of ways we can manipulate rules and rulesets with the
<command moreinfo="none">ipchains</command> command. Those relevant to IP firewalling are:

<variablelist><varlistentry><term>-A chain</term><listitem><para>Append one or more rules to the end of the nominated chain. If a hostname is
supplied as either source or destination and it resolves to more than one IP
address, a rule will be added for each address.</para></listitem></varlistentry><varlistentry><term>-I chain rulenum</term><listitem><para>Insert one or more rules to the start of the nominated chain. Again, if a
hostname is supplied in the rule specification, a rule will be added for each
of the addresses it resolves to.</para></listitem></varlistentry><varlistentry><term>-D chain</term><listitem><para><?troff .hw specification?>Delete one or more rules from the specified chain that matches the
rule specification.</para></listitem></varlistentry><varlistentry><term>-D chain rulenum</term><listitem><para>Delete the rule residing at position <replaceable>rulenum</replaceable>
in the specified chain. Rule positions start at one for the first rule in the
chain.</para></listitem></varlistentry><varlistentry><term>-R chain rulenum</term><listitem><para>Replace the rule residing at position <replaceable>rulenum</replaceable>
in the specific chain with the supplied rule specification.</para></listitem></varlistentry><varlistentry><term>-C chain</term><listitem><para>Check the datagram described by the rule specification against the specific
chain. This command will return a message describing how the datagram was
processed by the chain. This is very useful for testing your firewall
configuration, and we look at it in detail a little later.</para></listitem></varlistentry><varlistentry><term>-L [chain]</term><listitem><para>List the rules of the specified chain, or for all chains if no chain
is specified.</para></listitem></varlistentry><varlistentry><term>-F [chain]</term><listitem><para>Flush the rules of the specified chain, or for all chains if no chain is
 specified.</para></listitem></varlistentry><varlistentry><term>-Z [chain]</term><listitem><para>Zero the datagram and byte counters for all rules of the specified chain, or
for all chains if no chain is specified.</para></listitem></varlistentry><varlistentry><term>-N chain</term><listitem><para>Create a new chain with the specified name. A chain of the same name must not
 already exist. This is how user-defined chains are created.</para></listitem></varlistentry><varlistentry><term>-X [chain]</term><listitem><para>Delete the specified user-defined chain, or all user-defined chains if
no chain is specified. For this command to be successful, there must
be no references to the specified chain from any other rules chain.</para></listitem></varlistentry><varlistentry><term>-P chain policy</term><listitem><para>Set the default policy of the specified chain to the specified policy.
Valid firewalling policies are <literal moreinfo="none">ACCEPT</literal>,
<literal moreinfo="none">DENY</literal>, <literal moreinfo="none">REJECT</literal>,
<literal moreinfo="none">REDIR</literal>, or
<literal moreinfo="none">RETURN</literal>. <literal moreinfo="none">ACCEPT</literal>,
<literal moreinfo="none">DENY</literal>, and <literal moreinfo="none">REJECT</literal> have the same
meanings as those for the tradition IP firewall
implementation. <literal moreinfo="none">REDIR</literal> specifies that the datagram
should be transparently redirected to a port on the firewall host. The
<literal moreinfo="none">RETURN</literal> target causes the IP firewall code to return
to the Firewall Chain that called the one containing this rule and
continues starting at the rule after the calling rule.</para></listitem></varlistentry></variablelist>
</para></sect3><sect3 id="x-087-2-firewall.ipchains.rulespec"><title>Rule specification parameters</title><para>A number of <command moreinfo="none">ipchains</command> parameters create a rule specification
by determining what types of packets match. If any of these parameters is
omitted from a rule specification, its default is assumed:</para><variablelist><varlistentry><term>-p [!]protocol</term><listitem><para>Specifies the protocol of the datagram that will match this rule. Valid
protocol names are <literal moreinfo="none">tcp</literal>, <literal moreinfo="none">udp</literal>,
<literal moreinfo="none">icmp</literal>, or <literal moreinfo="none">all</literal>. You may also specify a
protocol number here to match other protocols. For example, you might use
<literal moreinfo="none">4</literal> to match the <literal moreinfo="none">ipip</literal> encapsulation
protocol. If the <literal moreinfo="none">!</literal> is supplied, the rule is negated and
the datagram will match any protocol other than the protocol specified. If this
parameter isn't supplied, it will default to <literal moreinfo="none">all</literal>.</para></listitem></varlistentry><varlistentry><term>-s [!]address[/mask] [!] [port]</term><listitem><para>Specifies the source address and port of the datagram that will match
this rule. The address may be supplied as a hostname, a network name,
or an IP address. The optional <literal moreinfo="none">mask</literal> is the netmask
to use and may be supplied either in the traditional form (e.g.,
/255.255.255.0) or the modern form (e.g., /24). The optional
<literal moreinfo="none">port</literal> specifies the TCP or UDP port, or the ICMP
datagram type that will match. You may supply a port specification
only if you've supplied the <option>-p</option> parameter with one of
the <literal moreinfo="none">tcp</literal>, <literal moreinfo="none">udp</literal>, or
<literal moreinfo="none">icmp</literal> protocols. Ports may be specified as a range
by specifying the upper and lower limits of the range with a colon as
a delimiter. For example, <literal moreinfo="none">20:25</literal> described all of
the ports numbered from 20 up to and including 25. Again, the
<literal moreinfo="none">!</literal> character may be used to negate the values.</para></listitem></varlistentry><varlistentry><term>-d [!]address[/mask] [!] [port]</term><listitem><para>Specifies the destination address and port of the datagram that will
match this rule. The coding of this parameter is the same as that of the
<option>-s</option> parameter.</para></listitem></varlistentry><varlistentry><term>-j target</term><listitem><para>Specifies the action to take when this rule matches. You can think of
this parameter as meaning jump to. Valid targets are
<literal moreinfo="none">ACCEPT</literal>, <literal moreinfo="none">DENY</literal>, <literal moreinfo="none">REJECT</literal>,
<literal moreinfo="none">REDIR</literal>, and <literal moreinfo="none">RETURN</literal>. We described the
meanings of each of these targets earlier. However, you may also specify the name of a
user-defined chain where processing will continue. If this parameter is
omitted, no action is taken on matching rule datagrams at all other than to
update the datagram and byte counters.</para></listitem></varlistentry><varlistentry><term>-i [!]interface-name</term><listitem><para>Specifies the interface on which the datagram was received or is to
be transmitted. Again, the <literal moreinfo="none">!</literal> inverts the result of the
match. If the interface name ends with <literal moreinfo="none">+</literal>,
then any interface that begins with the supplied string will match. For
example, <literal moreinfo="none">-i ppp+</literal> would match any PPP network device and
<literal moreinfo="none">-i ! eth+</literal> would match all interfaces except Ethernet
devices.</para></listitem></varlistentry><varlistentry><term>[!] -f</term><listitem><para>Specifies that this rule applies to everything but the first fragment
of a fragmented datagram.</para></listitem></varlistentry></variablelist></sect3><sect3 id="x-087-2-firewall.ipchains.options"><title>Options</title><para>The following <command moreinfo="none">ipchains</command> options are more general in nature.
Some of them control rather esoteric features of the IP chains software:

<variablelist><varlistentry><term>-b</term><listitem><para>Causes the command to generate two rules. One rule matches the
parameters supplied, and the other rule added matches the corresponding
parameters in the reverse direction.</para></listitem></varlistentry><varlistentry><term>-v</term><listitem><para>Causes <command moreinfo="none">ipchains</command> to be verbose in its output. It
will supply more information.</para></listitem></varlistentry><varlistentry><term>-n</term><listitem><para>Causes <command moreinfo="none">ipchains</command> to display IP address and ports as
numbers without attempting to resolve them to their corresponding names.</para></listitem></varlistentry><varlistentry><term>-l</term><listitem><para>Enables kernel logging of matching datagrams. Any datagram that matches
the rule will be logged by the kernel using its <function moreinfo="none">printk()</function>
function, which is usually handled by the <command moreinfo="none">sysklogd</command> program
and written to a log file. This is useful for making unusual datagrams visible.</para></listitem></varlistentry><varlistentry><term>-o[maxsize]</term><listitem><para>Causes the IP chains software to copy any datagrams matching the rule to
the userspace netlink device. The
maxsize argument limits the number of bytes from
each datagram that are passed to the netlink device. This option is of most
use to software developers, but may be exploited by software packages in the
future.</para></listitem></varlistentry><varlistentry><term>-m markvalue</term><listitem><para>Causes matching datagrams to be <emphasis>marked</emphasis> with a value. Mark
values are unsigned 32-bit numbers. In existing implementations this does
nothing, but at some point in the future, it may determine how the datagram is
handled by other software such as the routing code. If a
markvalue begins with a <literal moreinfo="none">+</literal> or
<literal moreinfo="none">-</literal>, the value is added or subtracted from the existing
markvalue.</para></listitem></varlistentry><varlistentry><term>-t andmask xormask</term><listitem><para>Enables you to manipulate the type of service bits in the
IP header of any datagram that matches this rule. The type of service bits are
used by intelligent routers to prioritize datagrams before forwarding them. The
Linux routing software is capable of this sort prioritization. The
<replaceable>andmask</replaceable> and <replaceable>xormask</replaceable>
represent bit masks that will be logically ANDed and ORed with the type of
service bits of the datagram respectively. This is an advanced feature that is
discussed in more detail in the IPCHAINS-HOWTO.</para></listitem></varlistentry><varlistentry><term>-x</term><listitem><para>Causes any numbers in the <command moreinfo="none">ipchains</command> output to be
expanded to their exact values with no rounding.</para></listitem></varlistentry><varlistentry><term>-y</term><listitem><para>Causes the rule to match any TCP datagram with the SYN bit set and the
ACK and FIN bits clear. This is used to filter TCP connection requests.</para></listitem></varlistentry></variablelist>
</para></sect3><indexterm significance="normal" class="endofrange" startref="ipchains.firewall.options"></indexterm></sect2><sect2 id="x-087-2-firewall.simpleexample.again"><title>Our Nave Example Revisited</title><para>Let's again suppose that we have a network in our organization and
that we are using a Linux-based firewall machine to allow our users
access to WWW servers on the Internet, but to allow no other traffic
to be passed.</para><para>If our network has a 24-bit network mask (class C) and has an address of
172.16.1.0, we'd use the following <command moreinfo="none">ipchains</command> rules:

<screen width="80" format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipchains -F forward</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipchains -P forward DENY</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipchains -A forward -s 0/0 80 -d 172.16.1.0/24 -p tcp -y -j DENY</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipchains -A forward -s 172.16.1.0/24 -d 0/0 80 -p tcp -b -j ACCEPT</userinput></screen></para><para>The first of the commands flushes all of the rules from the
<literal moreinfo="none">forward</literal> rulesets and the second set of
commands sets the default policy of the <literal moreinfo="none">forward</literal>
ruleset to <literal moreinfo="none">DENY</literal>. Finally, the third
and fourth commands do the specific filtering we want. The fourth
command allows datagrams to and from web servers on the outside of our
network to pass, and the third prevents incoming TCP connections with
a source port of 80.</para><para>If we now wanted to add rules that allowed passive mode only access to FTP
servers in the outside network, we'd add these rules:

<screen width="80" format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipchains -A forward -s 0/0 20 -d 172.16.1.0/24 -p tcp -y -j DENY</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipchains -A forward -s 172.16.1.0/24 -d 0/0 20 -p tcp -b -j ACCEPT</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipchains -A forward -s 0/0 21 -d 172.16.1.0/24 -p tcp -y -j DENY</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipchains -A forward -s 172.16.1.0/24 -d 0/0 21 -p tcp -b -j ACCEPT</userinput></screen></para></sect2><sect2 id="x-087-2-firewall.listing.again"><title>Listing Our Rules with ipchains</title><para><indexterm significance="normal"><primary>ipchains command</primary><secondary>listing rules with</secondary></indexterm>
To list our rules with <command moreinfo="none">ipchains</command>, we use its
<option>-L</option> argument. Just as with <command moreinfo="none">ipfwadm</command>, there
are arguments that control the amount of detail in the output. In its simplest
form, <command moreinfo="none">ipchains</command> produces output that looks like:

<screen width="80" format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">ipchains -L -n</userinput>
Chain input (policy ACCEPT):
Chain forward (policy DENY):
target     prot opt     source              destination         ports
DENY       tcp  -y----  0.0.0.0/0           172.16.1.0/24       80 -   *
ACCEPT     tcp  ------  172.16.1.0/24       0.0.0.0/0           * -   80
ACCEPT     tcp  ------  0.0.0.0/0           172.16.1.0/24       80 -   *
ACCEPT     tcp  ------  172.16.1.0/24       0.0.0.0/0           * -   20
ACCEPT     tcp  ------  0.0.0.0/0           172.16.1.0/24       20 -   *
ACCEPT     tcp  ------  172.16.1.0/24       0.0.0.0/0           * -   21
ACCEPT     tcp  ------  0.0.0.0/0           172.16.1.0/24       21 -   *

Chain output (policy ACCEPT):</screen></para><para>If you don't supply the name of a chain to list,
<command moreinfo="none">ipchains</command> will list all rules in all chains. The
<literal moreinfo="none">-n</literal> argument in our example tells
<command moreinfo="none">ipchains</command> not to attempt to convert any address or
ports into names. The information presented should be
self-explanatory.</para><para>A verbose form, invoked by the <option>-u</option> option, provides much more
detail. Its output adds fields for the datagram and byte counters,
Type of Service <emphasis>AND</emphasis> and <emphasis>XOR</emphasis> flags, the interface name, the mark, and
the outsize.</para><para>All rules created with <command moreinfo="none">ipchains</command> have datagram and
byte counters associated with them. This is how IP Accounting is
implemented and will be discussed in detail in <xref linkend="x-087-2-accounting"></xref>. By default these counters are presented
in a rounded form using the suffixes <literal moreinfo="none">K</literal> and
<literal moreinfo="none">M</literal> to represent units of one thousand and one
million, respectively. If the <literal moreinfo="none">-x</literal> argument is
supplied, the counters are expanded to their full unrounded form.</para></sect2><sect2 id="x-087-2-firewall.ipchainsyay"><title>Making Good Use of Chains</title><para>You now know that the <command moreinfo="none">ipchains</command> command is a
replacement for the <command moreinfo="none">ipfwadm</command> with a simpler
command-line syntax and some interesting enhancements, but you're no
doubt wanting to know where you'd use the user-defined chains and
why. You'll also probably want to know how to use the support scripts
that accompany the <command moreinfo="none">ipchains</command> command in its software
package. We'll now explore these subjects and address the questions.</para><sect3><title>User-defined chains</title><para><indexterm significance="normal" class="startofrange" id="firewalls.userdef.chains"><primary>firewalls</primary><secondary>user-defined chains</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="chains.userdefined"><primary>chains</primary><secondary>user-defined</secondary></indexterm>
The three rulesets of the traditional IP firewall code provided a
mechanism for building firewall configurations that were fairly simple
to understand and manage for small networks with simple firewalling
requirements. When the configuration requirements are not simple, a
number of problems become apparent.  Firstly, large networks often
require much more than the small number of firewalling rules we've
seen so far; inevitably needs arise that require firewalling rules
added to cover special case scenarios. As the number of rules grows,
the performance of the firewall deterioriates as more and more tests
are conducted on each datagram and managability becomes an
issue. Secondly, it is not possible to enable and disable sets of
rules atomically; instead, you are forced to expose yourself to attack
while you are in the middle of rebuilding your ruleset.</para><para>The design of IP Firewall Chains helps to alleviate these problems by
allowing the network administrator to create arbitrary sets of
firwewall rules that we can link to the three inbuilt rulesets. We can
use the <option>-N</option> option of <command moreinfo="none">ipchains</command> to
create a new chain with any name we please of eight characters or
less. (Restricting the name to lowercase letters only is probably a
good idea.) The <option>-j</option> option configures the action to
take when a datagram matches the rule specification. The <option>-j</option> option
specifies that if a datagram matches a rule, further testing should be
performed against a user-defined chain. We'll illustrate this with a
diagram.</para><para>Consider the following <command moreinfo="none">ipchains</command> commands:

<screen width="80" format="linespecific">ipchains -P input DENY
ipchains -N tcpin
ipchains -A tcpin -s ! 172.16.0.0/16
ipchains -A tcpin -p tcp -d 172.16.0.0/16 ssh -j ACCEPT
ipchains -A tcpin -p tcp -d 172.16.0.0/16 www -j ACCEPT
ipchains -A input -p tcp -j tcpin
ipchains -A input -p all</screen></para><para>We set the default input chain policy to <literal moreinfo="none">deny</literal>. The
second command creates a user-defined chain called
tcpin. The third command adds a rule to the
<literal moreinfo="none">tcpin</literal> chain that matches any datagram that was
sourced from outside our local network; the rule takes no action. This
rule is an accounting rule and will be discussed in more detail in
<xref linkend="x-087-2-accounting"></xref>. The next two rules match any
datagram that is destined for our local network and either of the
<literal moreinfo="none">ssh</literal> or <literal moreinfo="none">www</literal> ports; datagrams
matching these rules are accepted. The next rule is when the real
<emphasis>ipchains</emphasis> magic begins. It causes the firewall
software to check any datagram of protocol TCP against the
tcpin user-defined chain.  Lastly, we add a rule to our
<literal moreinfo="none">input</literal> chain that matches any datagram; this is
another accounting rule. They will produce the following Firewall Chains shown in Figure 9-4.</para><figure float="0" id="x-087-2-firewall.ipchains"><title>A simple IP chain ruleset</title><graphic fileref="lag2_0904.jpg"></graphic></figure><para>Our <literal moreinfo="none">input</literal> and <literal moreinfo="none">tcpin</literal> chains are populated
with our rules. Datagram processing always beings at one of the inbuilt chains.
We'll see how our user-defined chain is called into play by following the
processing path of different types of datagrams.</para><para>First, let's look at what happens when a UDP datagram for one of our hosts
is received. <xref linkend="x-087-2-firewall.ipchains.udp"></xref> illustrates the 
flow through the rules.</para><figure float="0" id="x-087-2-firewall.ipchains.udp"><title>The sequence of rules tested for a received UDP datagram</title><graphic fileref="lag2_0905.jpg"></graphic></figure><para>The datagram is received by the <literal moreinfo="none">input</literal> chain and
falls through the first two rules because they match ICMP and TCP
protocols, respectively. It matches the third rule in the
<literal moreinfo="none">input</literal> chain, but it doesn't specify a target, so
its datagram and byte counters are updated, but no other action takes
place. The datagram reaches the end of the <literal moreinfo="none">input</literal>
chain, meets with the default <literal moreinfo="none">input</literal> chain policy,
and is denied.</para><para>To see our user-defined chain in operation, let's now consider what
happens when we receive a TCP datagram destined for the
<literal moreinfo="none">ssh</literal> port of one of our hosts. The sequence is shown
in <xref linkend="x-087-2-firewall.ipchains.tcp.ssh"></xref>.</para><figure float="0" id="x-087-2-firewall.ipchains.tcp.ssh"><title>The rules flow for a received TCP datagram for ssh</title><graphic fileref="lag2_0906.jpg"></graphic></figure><para>This time the second rule in the <literal moreinfo="none">input</literal> chain does
match and it specifies a target of <literal moreinfo="none">tcpin</literal>, our
user-defined chain.  Specifying a user-defined chain as a target
causes the datagram to be tested against the rules in that chain, so
the next rule tested is the first rule in the <literal moreinfo="none">tcpin</literal>
chain. The first rule matches any datagram that has a source address
outside our local network and specifies no target, so it too is an
accounting rule and testing falls through to the next rule. The second
rule in our <literal moreinfo="none">tcpin</literal> chain does match and specifies a
target of <literal moreinfo="none">ACCEPT</literal>. We have arrived at target, so no
further firewall processing occurs. The datagram is accepted.</para><para>Finally, let's look at what happens when we reach the end of a
user-defined chain. To see this, we'll map the flow for a TCP datagram
destined for a port other than than the two we are handling
specifically, as shown in <xref linkend="x-087-2-firewall.ipchains.tcp.other"></xref>.</para><figure float="0" id="x-087-2-firewall.ipchains.tcp.other"><title>The rules flow for a received TCP datagram for telnet</title><graphic fileref="lag2_0907.jpg"></graphic></figure><para>The user-defined chains do not have default policies. When all rules
in a user-defined chain have been tested, and none have matched, the
firewall code acts as though a <literal moreinfo="none">RETURN</literal> rule were
present, so if this isn't what you want, you should ensure you supply
a rule at the end of the user-defined chain that takes whatever action
you wish. In our example, our testing returns to the rule in the
<literal moreinfo="none">input</literal> ruleset immediately following the one that
moved us to our user-defined chain. Eventually we reach the end of the
<literal moreinfo="none">input</literal> chain, which does have a default policy and
our datagram is denied.</para><para>This example is very simple, but illustrates our point. A more practical use of
IP chains would be much more complex. A slightly more sophisticated example is
provided in the following list of commands:</para><programlisting width="80" format="linespecific" id="x-087-2-firewall.ipchains.example">#
# Set default forwarding policy to REJECT
ipchains -P forward REJECT
#
# create our user-defined chains
ipchains -N sshin
ipchains -N sshout
ipchains -N wwwin
ipchains -N wwwout
#
# Ensure we reject connections coming the wrong way
ipchains -A wwwin -p tcp -s 172.16.0.0/16 -y -j REJECT
ipchains -A wwwout -p tcp -d 172.16.0.0/16 -y -j REJECT
ipchains -A sshin -p tcp -s 172.16.0.0/16 -y -j REJECT
ipchains -A sshout -p tcp -d 172.16.0.0/16 -y -j REJECT
#
# Ensure that anything reaching the end of a user-defined chain is rejected.
ipchains -A sshin -j REJECT
ipchains -A sshout -j REJECT
ipchains -A wwwin -j REJECT
ipchains -A wwwout -j REJECT
#
# divert www and ssh services to the relevant user-defined chain
ipchains -A forward -p tcp -d 172.16.0.0/16 ssh -b -j sshin
ipchains -A forward -p tcp -s 172.16.0.0/16 -d 0/0 ssh -b -j sshout
ipchains -A forward -p tcp -d 172.16.0.0/16 www -b -j wwwin
ipchains -A forward -p tcp -s 172.16.0.0/16 -d 0/0 www -b -j wwwout
#
# Insert our rules to match hosts at position two in our user-defined chains.
ipchains -I wwwin 2 -d 172.16.1.2 -b -j ACCEPT
ipchains -I wwwout 2 -s 172.16.1.0/24 -b -j ACCEPT
ipchains -I sshin 2 -d 172.16.1.4 -b -j ACCEPT <?troff .ne 10?>
ipchains -I sshout 2 -s 172.16.1.4 -b -j ACCEPT
ipchains -I sshout 2 -s 172.16.1.6 -b -j ACCEPT
#</programlisting><para>In this example, we've used a selection of user-defined chains both to
simplify management of our firewall configuration and improve the
efficiency of our firewall as compared to a solution involving only the
built-in chains.</para><para>Our example creates user-defined chains for each of the
<literal moreinfo="none">ssh</literal> and <literal moreinfo="none">www</literal> services in each
connection direction. The chain called <literal moreinfo="none">wwwout</literal> is
where we place rules for hosts that are allowed to make outgoing World
Wide Web connections, and <literal moreinfo="none">sshin</literal> is where we define
rules for hosts to which we want to allow incoming ssh
connections. We've assumed that we have a requirement to allow and
deny individual hosts on our network the ability to make or receive
<literal moreinfo="none">ssh</literal> and <literal moreinfo="none">www</literal> connections. The
simplication occurs because the user-defined chains allow us to neatly
group the rules for the host incoming and outgoing permissions rather
than muddling them all together. The improvement in efficiency occurs
because for any particular datagram, we have reduced the average number
of tests required before a target is found. The efficiency gain
increases as we add more hosts. If we hadn't used user-defined chains,
we'd potentially have to search the whole list of rules to determine
what action to take with each and every datagram received.  Even if we
assume that each of the rules in our list matches an equal proportion
of the total number of datagrams processed, we'd still be searching
half the list on average. User-defined chains allow us to avoid
testing large numbers of rules if the datagram being tested doesn't
match the simple rule in the built-in chain that jumps to them.</para><indexterm significance="normal" class="endofrange" startref="firewalls.userdef.chains"></indexterm><indexterm significance="normal" class="endofrange" startref="chains.userdefined"></indexterm></sect3><sect3><title>The ipchains support scripts</title><para><indexterm significance="normal"><primary>ipchains command</primary><secondary>support scripts</secondary></indexterm>
The <command moreinfo="none">ipchains</command> software package is supplied with
three support scripts. The first of these we've discussed briefly
already, while the remaining two provide an easy and convenient means
of saving and restoring your firewall configuration.</para><para><indexterm significance="normal"><primary>ipfwadm-wrapper command</primary></indexterm>
The <command moreinfo="none">ipfwadm-wrapper</command> script emulates the
command-line syntax of the <command moreinfo="none">ipfwadm</command> command, but
drives the <command moreinfo="none">ipchains</command> command to build the firewall
rules. This is a convenient way to migrate your existing firewall
configuration to the kernel or an alternative to learning the
<command moreinfo="none">ipchains</command> syntax. The
<command moreinfo="none">ipfwadm-wrapper</command> script behaves differently from the
<command moreinfo="none">ipfwadm</command> command in two ways: firstly, because the
<command moreinfo="none">ipchains</command> command doesn't support specification of
an interface by address, the <command moreinfo="none">ipfwadm-wrapper</command> script
accepts an argument of <option>-V</option> but attempts to convert it
into the <command moreinfo="none">ipchains</command> equivalent of a
<option>-W</option> by searching for the interface name configured
with the supplied address. The <command moreinfo="none">ipfwadm-wrapper</command>
script will always provide a warning when you use the
<option>-V</option> option to remind you of this. Secondly, fragment
accounting rules are not translated correctly.</para><para><indexterm significance="normal"><primary>firewalls</primary><secondary>IP chains</secondary><tertiary>restoring/saving</tertiary></indexterm>
<indexterm significance="normal"><primary>ipchains-save command</primary></indexterm>
<indexterm significance="normal"><primary>ipchains-restore command</primary></indexterm>
The <command moreinfo="none">ipchains-save</command> and <command moreinfo="none">ipchains-restore</command>
scripts make building and modifying a firewall configuration much simpler.
The <command moreinfo="none">ipchains-save</command> command reads the current firewall
configuration and writes a simplified form to the standard output. The
<command moreinfo="none">ipchains-restore</command> command reads data in the output format
of the <command moreinfo="none">ipchains-save</command> command and configures the IP firewall
with these rules. The advantage of using these scripts over directly modifying
your firewall configuration script and testing the configuration is the ability
to dynamically build your configuration once and then save it. You can then
restore that configuration, modify it, and resave it as you please.</para><para>To use the scripts, you'd enter something like:

<screen width="80" format="linespecific"><userinput moreinfo="none"><command moreinfo="none">ipchains-save</command> /var/state/ipchains/firewall.state</userinput></screen>

to save your current firewall configuration. You'd restore it, perhaps at
boot time, with:

<screen width="80" format="linespecific"><userinput moreinfo="none"><command moreinfo="none">ipchains-restore</command> /var/state/ipchains/firewall.state</userinput></screen></para><para>The <command moreinfo="none">ipchains-restore</command> script checks if any user-defined
chain listed in its input already exists. If you've supplied the
<literal moreinfo="none">-f</literal> argument, it will automatically flush the rules from
the user-defined chain before configuring those in the input. The default
behavior asks you whether to skip this chain or to flush it.</para></sect3></sect2><indexterm significance="normal" class="endofrange" startref="firewall.ip.chains"></indexterm><indexterm significance="normal" class="endofrange" startref="ip.firewall.chains"></indexterm><indexterm significance="normal" class="endofrange" startref="chains.ip.firewall"></indexterm><indexterm significance="normal" class="endofrange" startref="linux.2.2.kernels"></indexterm></sect1><sect1 id="x-087-2-firewall.future"><title>Netfilter and IP Tables (2.4 Kernels)</title><indexterm significance="normal" class="startofrange" id="firewalls.netfilter"><primary>firewalls</primary><secondary>netfilter</secondary></indexterm><indexterm significance="normal" class="startofrange" id="linux.2.4.kernels"><primary>2.4 kernels</primary><secondary>netfilter and IP tables</secondary></indexterm><indexterm significance="normal" class="startofrange" id="netfilter.ip.tables"><primary>netfilter</primary><secondary>IP tables and</secondary></indexterm><para>While developing IP Firewall Chains, Paul Russell decided that IP firewalling
should be less difficult; he soon set about the task of simplifying aspects of
datagram processing in the kernel firewalling code and produced a filtering
framework that was both much cleaner and much more flexible. He called
this new framework <emphasis>netfilter</emphasis>.</para><note><para>At the time of preparation of this book the
<emphasis>netfilter</emphasis> design had not yet stabilized. We hope
you'll forgive any errors in the description of
<emphasis>netfilter</emphasis> or its associated configuration tools
that result from changes that occurred after preparation of this
material. We considered the <emphasis>netfilter</emphasis> work
important enough to justify the inclusion of this material, despite
parts of it being speculative in nature. If you're in any doubt, the
relevant HOWTO documents will contain the most accurate and up-to-date
information on the detailed issues associated with the
<emphasis>netfilter</emphasis> configuration.</para></note><para>So what was wrong with IP chains? They vastly improved the efficiency
and management of firewall rules. But the way they processed datagrams
was still complex, especially in conjunction with firewall-related
features like IP masquerade (discussed in <xref linkend="x-087-2-ipmasq"></xref>) and other forms of address
translation. Part of this complexity existed because IP masquerade and
Network Address Translation were developed independently of the IP
firewalling code and integrated later, rather than having been
designed as a true part of the firewall code from the start. If a
developer wanted to add yet more features in the datagram processing
sequence, he would have had difficulty finding a place to insert the
code and would have been forced to make changes in the kernel in order
to do so.</para><para>Still, there were other problems. In particular, the
input chain described input to the IP networking layer
as a whole. The input chain affected both datagrams to be
<emphasis>destined for</emphasis> this host and datagrams to be
<emphasis>routed by</emphasis> this host. This was somewhat
counterintuitive because it confused the function of the input chain
with that of the forward chain, which applied only to datagrams to be
forwarded, but which always followed the input chain. If you wanted to
treat datagrams for this host differently from datagrams to be
forwarded, it was necessary to build complex rules that excluded one
or the other. The same problem applied to the output chain.</para><para>Inevitably some of this complexity spilled over into the system
administrator's job because it was reflected in the way that rulesets
had to be designed.  Moreover, any extensions to filtering required
direct modifications to the kernel, because all filtering policies
were implemented there and there was no way of providing a transparent
interface into it. <emphasis>netfilter</emphasis> addresses both the
complexity and the rigidity of older solutions by implementing a
generic framework in the kernel that streamlines the way datagrams are
processed and provides a capability to extend filtering policy without
having to modify the kernel.</para><para><indexterm significance="normal"><primary>datagrams</primary><secondary>IP chains vs. netfilter</secondary></indexterm>
Let's take a look at two of the key changes made.  <xref linkend="x-087-2-firewall.routing.ipchains"></xref> illustrates how datagrams
are processed in the IP chains implementation, while <xref linkend="x-087-2-firewall.routing.netfilter"></xref> illustrates how they are
processed in the <emphasis>netfilter</emphasis> implementation. The
key differences are the removal of the masquerading function from the
core code and a change in the locations of the input and output
chains. To accompany these changes, a new and extensible configuration
tool called <command moreinfo="none">iptables</command> was created.</para><para><?troff .hw irrespective?><?troff .hw config-urations?>In IP chains, the input chain applies to all datagrams received by the
host, irrespective of whether they are destined for the local host or routed to some other host. In <emphasis>netfilter</emphasis>,
the input chain applies <emphasis>only</emphasis> to datagrams
destined for the local host, and the forward chain applies only to
datagrams destined for <emphasis>another</emphasis> host. Similarly,
in IP chains, the output chain applies to all datagrams leaving the
local host, irrespective of whether the datagram is generated on the
local host or routed from some other host. In
<emphasis>netfilter</emphasis>, the output chain applies
<emphasis>only</emphasis> to datagrams generated on this host and does
not apply to datagrams being routed from another host. This change
alone offers a huge simplification of many firewall configurations.</para><figure float="1" id="x-087-2-firewall.routing.ipchains"><title>Datagram processing chain in IP chains</title><graphic fileref="lag2_0908.jpg"></graphic></figure><para>In <xref linkend="x-087-2-firewall.routing.ipchains"></xref>, the components
labeled demasq and masq are separate
kernel components responsible for the incoming and outgoing processing
of masqueraded datagrams.  These have been reimplemented as
<emphasis>netfilter</emphasis> modules.</para><para>Consider the case of a configuration for which the default policy for each
of the input, forward, and output chains is
<literal moreinfo="none">deny</literal>. In IP chains, six rules would
be needed to allow any session through a firewall host: two each in
the input, forward, and output chains (one would cover each forward
path and one would cover each return path). You can imagine how this
could easily become extremely complex and difficult to manage when you
want to mix sessions that could be routed and sessions that could
connect to the local host without being routed. IP chains allow
you to create chains that would simplify this task a little, but the
design isn't obvious and requires a certain level of expertise.</para><para>In the <emphasis>netfilter</emphasis> implementation with
<command moreinfo="none">iptables</command>, this complexity disappears
completely. For a service to be routed across the firewall host, but
not terminate on the local host, only two rules are required: one
each for the forward and the reverse directions in the forward
chain. This is the obvious way to design firewalling rules, and will
serve to simplify the design of firewall configurations immensely.</para><figure float="1" id="x-087-2-firewall.routing.netfilter"><title>Datagram processing chain in netfilter</title><graphic fileref="lag2_0909.jpg"></graphic></figure><para><indexterm significance="normal"><primary>PACKET-FILTERING-HOWTO</primary></indexterm>
<indexterm significance="normal"><primary>HOWTOs</primary><secondary>PACKET-FILTERING</secondary></indexterm>
The PACKET-FILTERING-HOWTO offers a detailed list of the
changes that have been made, so let's focus on the more practical
aspects here.</para><sect2><title>Backward Compatability with ipfwadm<?lb?>and ipchains</title><para>The remarkable flexibility of Linux <emphasis>netfilter</emphasis> is
illustrated by its ability to emulate the <command moreinfo="none">ipfwadm</command> and
<command moreinfo="none">ipchains</command> interfaces. Emulation makes transition to the new
generation of firewall software a little easier.</para><para><indexterm significance="normal"><primary>netfilter</primary><secondary>kernel modules</secondary></indexterm>
The two <emphasis>netfilter</emphasis> kernel modules called
<filename moreinfo="none">ipfwadm.o</filename> and <filename moreinfo="none">ipchains.o</filename>
provide backward compatibility for <command moreinfo="none">ipfwadm</command> and
<command moreinfo="none">ipchains</command>. You may load only one of these modules at
a time, and use one only if the <filename moreinfo="none">ip_tables.o</filename>
module is not loaded.  When the appropriate module is loaded,
<emphasis>netfilter</emphasis> works exactly like the former
firewall implementation.</para><para><emphasis>netfilter</emphasis> mimics the
<command moreinfo="none">ipchains</command> interface with the following commands:

<screen format="linespecific">rmmod ip_tables
modprobe ipchains
ipchains <replaceable>...</replaceable></screen></para></sect2><sect2 id="x-087-2-firewall.usingiptables"><title>Using iptables</title><para><indexterm significance="normal" class="startofrange" id="iptables.firewall.options"><primary>iptables command</primary><secondary>firewall options</secondary></indexterm>
The <command moreinfo="none">iptables</command> utility is used to configure
<emphasis>netfilter</emphasis> filtering rules. Its syntax borrows
heavily from the <command moreinfo="none">ipchains</command> command, but differs in
one very significant respect: it is
<emphasis>extensible</emphasis>. What this means is that its
functionality can be extended without recompiling it. It manages this
trick by using shared libraries. There are standard extensions
and we'll explore some of them in a moment.</para><para>Before you can use the <command moreinfo="none">iptables</command> command, you must
load the <emphasis>netfilter</emphasis> kernel module that provides
support for it. The easiest way to do this is to use the
<command moreinfo="none">modprobe</command> command as follows:

<screen format="linespecific">modprobe ip_tables</screen></para><para>The <command moreinfo="none">iptables</command> command is used to configure both IP
filtering and Network Address Translation. To facilitate this, there are two
tables of rules called <emphasis>filter</emphasis> and
<emphasis>nat</emphasis>. The filter table is assumed if you do not
specify the <option>-t</option> option to override
it. Five built-in chains are also provided. The
<literal moreinfo="none">INPUT</literal> and <literal moreinfo="none">FORWARD</literal> chains are
available for the <literal moreinfo="none">filter</literal> table, the
<literal moreinfo="none">PREROUTING</literal> and <literal moreinfo="none">POSTROUTING</literal>
chains are available for the <literal moreinfo="none">nat</literal> table, and the
<literal moreinfo="none">OUTPUT</literal> chain is available for both tables.  In this
chapter we'll discuss only the <emphasis>filter</emphasis> table. We'll look 
at the <emphasis>nat</emphasis> table in <xref linkend="x-087-2-ipmasq"></xref></para><para>The general syntax of most <command moreinfo="none">iptables</command> commands is:

<screen format="linespecific"><command moreinfo="none">iptables</command> <replaceable>command</replaceable> <replaceable>rule-specification</replaceable> <replaceable>extensions</replaceable></screen>

Now we'll take a look at some options in detail, after which we'll review
some examples.</para><sect3 id="x-087-2-firewall.iptables.commands"><title>Commands</title><para>There are a number of ways we can manipulate rules and rulesets with the
<command moreinfo="none">iptables</command> command. Those relevant to IP firewalling are:

<variablelist><varlistentry><term>-A chain</term><listitem><para>Append one or more rules to the end of the nominated chain. If a hostname is
supplied as either a source or destination and it resolves to more than one IP
address, a rule will be added for each address.</para></listitem></varlistentry><varlistentry><term>-I chain rulenum</term><listitem><para>Insert one or more rules to the start of the nominated chain. Again, if a
hostname is supplied in the rule specification, a rule will be added for each
of the addresses to which it resolves.</para></listitem></varlistentry><varlistentry><term>-D chain</term><listitem><para>Delete one or more rules from the specified chain matching the rule
specification.</para></listitem></varlistentry><varlistentry><term>-D chain rulenum</term><listitem><para>Delete the rule residing at position <replaceable>rulenum</replaceable> in the
specified chain. Rule positions start at 1 for the first rule in the chain.</para></listitem></varlistentry><varlistentry><term>-R chain rulenum</term><listitem><para>Replace the rule residing at position <replaceable>rulenum</replaceable>
in the specific chain with the supplied rule specification.</para></listitem></varlistentry><varlistentry><term>-C chain</term><listitem><para>Check the datagram described by the rule specification against the specific
chain. This command will return a message describing how the chain processed the datagram. This is very useful for testing your firewall
configuration and we will look at it in detail later.</para></listitem></varlistentry><varlistentry><term>-L [chain]</term><listitem><para>List the rules of the specified chain, or for all chains if no chain is
specified.</para></listitem></varlistentry><varlistentry><term>-F [chain]</term><listitem><para>Flush the rules of the specified chain, or for all chains if no chain is
 specified.</para></listitem></varlistentry><varlistentry><term>-Z [chain]</term><listitem><para>Zero the datagram and byte counters for all rules of the specified chain, or
for all chains if no chain is specified.</para></listitem></varlistentry><varlistentry><term>-N chain</term><listitem><para>Create a new chain with the specified name. A chain of the same name must not
 already exist. This is how user-defined chains are created.</para></listitem></varlistentry><varlistentry><term>-X [chain]</term><listitem><para>Delete the specified user-defined chain, or all user-defined chains if no chain
is specified. For this command to be successful, there must be no references
to the specified chain from any other rules chain.</para></listitem></varlistentry><varlistentry><term>-P chain policy</term><listitem><para>Set the default policy of the specified chain to the specified policy. Valid
firewalling policies are <literal moreinfo="none">ACCEPT</literal>, <literal moreinfo="none">DROP</literal>,
<literal moreinfo="none">QUEUE</literal>, and <literal moreinfo="none">RETURN</literal>.
<literal moreinfo="none">ACCEPT</literal> allows the datagram to pass. <literal moreinfo="none">DROP</literal>
causes the datagram to be discarded. <literal moreinfo="none">QUEUE</literal> causes the
datagram to be passed to userspace for further processing. The
<literal moreinfo="none">RETURN</literal> target causes the IP firewall code to return to the
Firewall Chain that called the one containing this rule, and continue starting
at the rule after the calling rule.</para></listitem></varlistentry></variablelist>
</para></sect3><sect3 id="x-087-2-firewall.iptables.rulespec"><title>Rule specification parameters</title><para>There are a number of <command moreinfo="none">iptables</command> parameters that constitute
a rule specification. Wherever a rule specification is required, each of these
parameters must be supplied or their default will be assumed.</para><variablelist><varlistentry><term>-p [!]protocol</term><listitem><para>Specifies the protocol of the datagram that will match this rule. Valid
protocol names are <literal moreinfo="none">tcp</literal>, <literal moreinfo="none">udp</literal>,
<literal moreinfo="none">icmp</literal>, or a number, if you know the IP protocol
number.<footnote id="x-087-2-x-087-2-fw-fn06"><para>Take a look at <filename moreinfo="none">/etc/protocols</filename> for protocol names and numbers.</para></footnote>
For example, you might use <literal moreinfo="none">4</literal> to match the
<literal moreinfo="none">ipip</literal> encapsulation protocol. If the <literal moreinfo="none">!</literal>
character is supplied, the rule is negated and the datagram will match any
protocol other than the specified protocol. If this parameter isn't supplied, it
will default to match all protocols.</para></listitem></varlistentry><varlistentry><term>-s [!]address[/mask]</term><listitem><para>Specifies the source address of the datagram that will match this rule. The
address may be supplied as a hostname, a network name, or an IP address. The
optional <literal moreinfo="none">mask</literal> is the netmask to use and may be supplied
either in the traditional form (e.g., /255.255.255.0) or in the modern form
(e.g., /24).</para></listitem></varlistentry><varlistentry><term>-d [!]address[/mask]</term><listitem><para>Specifies the destination address and port of the datagram that will
match this rule. The coding of this parameter is the same as that of the
<option>-s</option> parameter.</para></listitem></varlistentry><varlistentry><term>-j target</term><listitem><para>Specifies what action to take when this rule matches. You can think of
this parameter as meaning jump to. Valid targets are
<literal moreinfo="none">ACCEPT</literal>, <literal moreinfo="none">DROP</literal>, <literal moreinfo="none">QUEUE</literal>,
and <literal moreinfo="none">RETURN</literal>. We described the meanings of each of these previously in the "Commands" section. You may also specify the name of a user-defined chain where
processing will continue. You may also supply the name of a target supplied
by an extension. We'll talk about extensions shortly. If this parameter is
omitted, no action is taken on matching datagrams at all, other than to
update the datagram and byte counters of this rule.</para></listitem></varlistentry><varlistentry><term>-i [!]interface-name</term><listitem><para><?troff .hw separated?>Specifies the interface on which the datagram was received. Again, the
<literal moreinfo="none">!</literal> inverts the result of the match. If the interface name
ends with <literal moreinfo="none">+</literal> then any interface that begins
with the supplied string will match. For example, <literal moreinfo="none">-i ppp+</literal>
would match any PPP network device and <literal moreinfo="none">-i ! eth+</literal> would
match all interfaces except ethernet devices.</para></listitem></varlistentry><varlistentry><term>-o [!]interface-name</term><listitem><para>Specifies the interface on which the datagram is to be transmitted. This
argument has the same coding as the <option>-i</option> argument.</para></listitem></varlistentry><varlistentry><term>[!] -f</term><listitem><para>Specifies that this rule applies only to the second and later fragments
of a fragmented datagram, not to the first fragment.</para></listitem></varlistentry></variablelist></sect3><sect3 id="x-087-2-firewall.iptables.options"><title>Options</title><para>The following <command moreinfo="none">iptables</command> options are more general in nature.
Some of them control rather esoteric features of the
<emphasis>netfilter</emphasis> software.</para><variablelist><varlistentry><term>-v</term><listitem><para>causes <command moreinfo="none">iptables</command> to be verbose in its output; it
will supply more information.</para></listitem></varlistentry><varlistentry><term>-n</term><listitem><para>causes <command moreinfo="none">iptables</command> to display IP address and ports as
numbers without attempting to resolve them to their corresponding names.</para></listitem></varlistentry><varlistentry><term>-x</term><listitem><para>causes any numbers in the <command moreinfo="none">iptables</command> output to be
expanded to their exact values with no rounding.</para></listitem></varlistentry><varlistentry><term>- -line-numbers</term><listitem><para>causes line numbers to be displayed when listing rulesets. The line number
will correspond to the rule's position within the chain.</para></listitem></varlistentry></variablelist></sect3><sect3 id="x-087-2-firewall.iptables.extensions"><title>Extensions</title><para><indexterm significance="normal"><primary>iptables command</primary><secondary>extensions</secondary></indexterm>
We said earlier that the <command moreinfo="none">iptables</command> utility is
extensible through optional shared library modules. There are some standard
extensions that provide some of the features <command moreinfo="none">ipchains</command>
provided. To make use of an extension, you must specify its name through the
<option>-m</option> <replaceable>name</replaceable> argument to
<command moreinfo="none">iptables</command>. The following list shows the
<option>-m</option> and <option>-p</option> options that set up the extension's
context, and the options provided by
that extension.</para><sect4><title>TCP Extensions: used with -m tcp -p tcp</title><variablelist><varlistentry><term>- -sport [!] [port[:port]]</term><listitem><para>Specifies the port that the datagram source must be using to match this rule.
Ports may be specified as a range by specifying the upper and lower limits of
the range using the colon as a delimiter. For example, <literal moreinfo="none">20:25</literal>
described all of the ports numbered 20 up to and including 25. Again, the
<literal moreinfo="none">!</literal> character may be used to negate the values.</para></listitem></varlistentry><varlistentry><term>- -dport [!] [port[:port]]</term><listitem><para>Specifies the port that the datagram destination must be using to match this
rule. The argument is coded identically to the <option>- -sport</option>
option.</para></listitem></varlistentry><varlistentry><term>- -tcp-flags [!] mask comp</term><listitem><para><indexterm significance="normal"><primary>RFC-793</primary></indexterm>
Specifies that this rule should match when the TCP flags in the
datagram match those specified by <replaceable>mask</replaceable> and
<replaceable>comp</replaceable>. <replaceable>mask</replaceable> is a
comma-separated list of flags that should be examined when making the
test. <replaceable>comp</replaceable> is a comma-separated list of
flags that must be set for the rule to match. Valid flags are:
<emphasis>SYN</emphasis>, <emphasis>ACK</emphasis>,
<emphasis>FIN</emphasis>, <emphasis>RST</emphasis>,
<emphasis>URG</emphasis>, <emphasis>PSH</emphasis>, <emphasis>ALL</emphasis>
or <emphasis>NONE</emphasis>. This is an advanced option: refer to a
good description of the TCP protocol, such as RFC-793, for a
description of the meaning and implication of each of these flags.
The <literal moreinfo="none">!</literal> character negates the rule.</para></listitem></varlistentry><varlistentry><term>[!] - -syn</term><listitem><para>Specifies the rule to match only datagrams with the
<literal moreinfo="none">SYN</literal> bit set and the <literal moreinfo="none">ACK</literal> and
<literal moreinfo="none">FIN</literal> bits cleared. Datagrams with these options are used
to open TCP connections, and this option can therefore be used to manage
connection requests. This option is shorthand for:

<screen format="linespecific"><literal moreinfo="none">- -tcp-flags SYN,RST,ACK SYN</literal></screen>

 When you use the negation
operator, the rule will match all datagrams that do not have both the
<literal moreinfo="none">SYN</literal> and <literal moreinfo="none">ACK</literal> bits set.</para></listitem></varlistentry></variablelist></sect4><sect4><title>UDP Extensions: used with -m udp -p udp</title><variablelist><varlistentry><term>- -sport [!] [port[:port]]</term><listitem><para>Specifies the port that the datagram source must be using to match this rule.
Ports may be specified as a range by specifying the upper and lower limits of
the range using the colon as a delimiter. For example, <literal moreinfo="none">20:25</literal>
describes all of the ports numbered 20 up to and including 25. Again, the
<literal moreinfo="none">!</literal> character may be used to negate the values.</para></listitem></varlistentry><varlistentry><term>- -dport [!] [port[:port]]</term><listitem><para>Specifies the port that the datagram destination must be using to match this
rule. The argument is coded identically to the <option>- -sport</option>
option.</para></listitem></varlistentry></variablelist></sect4><sect4><title>ICMP Extensions: used with <literal moreinfo="none">-m icmp -p icmp</literal></title><variablelist><varlistentry><term>- -icmp-type [!] typename</term><listitem><para><?troff .hw protocol-un-reachable?>Specifies the ICMP message type that this rule will match. The type may be
specified by number or name. Some valid names are:
<literal moreinfo="none">echo-request</literal>, <literal moreinfo="none">echo-reply</literal>,
<literal moreinfo="none">source-quench</literal>, <literal moreinfo="none">time-exceeded</literal>,
<literal moreinfo="none">destination-unreachable</literal>,
<literal moreinfo="none">network-unreachable</literal>, <literal moreinfo="none">host-unreachable</literal>,
<literal moreinfo="none">protocol-unreachable</literal>, and
<literal moreinfo="none">port-unreachable</literal>.</para></listitem></varlistentry></variablelist></sect4><sect4><title>MAC Extensions: used with <literal moreinfo="none">-m mac</literal></title><variablelist><varlistentry><term>- -mac-source [!] address</term><listitem><para>Specifies the host's Ethernet address that transmitted the datagram
that this rule will match. This only makes sense in a rule in the input or
forward chains because we will be transmitting any datagram that passes the
output chain.</para></listitem></varlistentry></variablelist></sect4></sect3><indexterm significance="normal" class="endofrange" startref="iptables.firewall.options"></indexterm></sect2><sect2><title>Our Nave Example Revisited, Yet Again</title><para>To implement our nave example using the <emphasis>netfilter</emphasis>,
you could simply load the <filename moreinfo="none">ipchains.o</filename> module and pretend
it is the <command moreinfo="none">ipchains</command> version. Instead, we'll reimplement
it using <command moreinfo="none">iptables</command> to illustrate how similar it is.</para><para>Yet again, let's suppose that we have a network in our organization
and that we are using a Linux-based firewall machine to allow our
users to be able to access WWW servers on the Internet, but to allow
no other traffic to be passed.</para><para>If our network has a 24-bit network mask (class C) and has an address of
172.16.1.0, then we'd use the following <command moreinfo="none">iptables</command> rules:

<screen width="83" format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">modprobe ip_tables</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">iptables -F FORWARD</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">iptables -P FORWARD DROP</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">iptables -A FORWARD -m tcp -p tcp -s 0/0 --sport 80 -d 172.16.1.0/24 /
    --syn -j DROP</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">iptables -A FORWARD -m tcp -p tcp -s 172.16.1.0/24 --sport /
    80 -d 0/0 -j ACCEPT</userinput>
<prompt moreinfo="none">#</prompt> <userinput moreinfo="none">iptables -A FORWARD -m tcp -p tcp -d 172.16.1.0/24 --dport 80 -s 0/0 -j /
    ACCEPT</userinput></screen></para><?troff .Nd 10?><para>In this example the <command moreinfo="none">iptables</command> commands are interpreted
exactly as the equivalent <command moreinfo="none">ipchains</command> commands. The major
exception that the <filename moreinfo="none">ip_tables.o</filename>
module must load. Note that <command moreinfo="none">iptables</command> doesn't support the
<option>-b</option> option, so we must supply a rule for each
direction.</para></sect2><indexterm significance="normal" class="endofrange" startref="firewalls.netfilter"></indexterm><indexterm significance="normal" class="endofrange" startref="linux.2.4.kernels"></indexterm><indexterm significance="normal" class="endofrange" startref="netfilter.ip.tables"></indexterm></sect1><sect1 id="x-087-2-firewall.tos.manipulation"><title>TOS Bit Manipulation</title><para><indexterm significance="normal" class="startofrange" id="firewalls.tos.bit.manip"><primary>firewalls</primary><secondary>TOS bit manipulation</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="ip.tos.bits"><primary>IP (Internet Protocol)</primary><secondary>TOS (Type Of Service) bits</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="tos.bits.manip"><primary>TOS (Type Of Service) bits, manipulating</primary></indexterm>
The Type Of Service (TOS) bits are a set of four-bit flags in
the IP header. When any one of these bit flags is set, routers may handle the
datagram differently than datagrams with no TOS bits set. Each of the four bits
has a different purpose and only one of the TOS bits may be set at any time, so
combinations are not allowed. The bit flags are called Type of Service bits
because they enable the application transmitting the data to tell the network
the type of network service it requires.</para><para>The classes of network service available are:</para><variablelist><varlistentry><term>Minimum delay</term><listitem><para>Used when the time it takes for a datagram to travel from the source host
to destination host (latency) is most important. A network provider might, for
example, use both optical fiber and satellite network connections. Data carried
across satellite connections has farther to travel and their latency is
generally therefore higher than for terrestrial-based network connections
between the same endpoints. A network provider might choose to ensure that
datagrams with this type of service set are not carried by satellite.</para></listitem></varlistentry><varlistentry><term>Maximum throughput</term><listitem><para>Used when the volume of data transmitted in any period of time is
important. There are many types of network applications for which latency
is not particularly important but the network throughput is; for
example, bulk-file transfers. A network provider might choose to route
datagrams with this type of service set via high-latency,
high-bandwidth routes, such as satellite connections.</para></listitem></varlistentry><varlistentry><term>Maximum reliability</term><listitem><para>Used when it is important that you have some certainty that the data
will arrive at the destination without retransmission being
required. The IP protocol may be carried over any number of underlying
transmission mediums.  While SLIP and PPP are adequate datalink
protocols, they are not as reliable as carrying IP over some other
network, such as an X.25 network. A network provider might make
an alternate network available, offering high reliability, to carry IP
that would be used if this type of service is selected.</para></listitem></varlistentry><varlistentry><term>Minimum cost</term><listitem><para>Used when it is important to minimize the cost of data
transmission. Leasing bandwidth on a satellite for a transpacific
crossing is generally less costly than leasing space on a
fiber-optical cable over the same distance, so network providers may
choose to provide both and charge differently depending on which you
use. In this scenario, your minimum cost type of service
bit may cause your datagrams to be routed via the lower-cost satellite
route.</para></listitem></varlistentry></variablelist><sect2><title>Setting the TOS Bits Using ipfwadm or ipchains</title><para><indexterm significance="normal"><primary>ipfwadm command</primary><secondary>setting the TOS bits</secondary></indexterm>
<indexterm significance="normal"><primary>ipchains command</primary><secondary>setting the TOS bits</secondary></indexterm>
The <command moreinfo="none">ipfwadm</command> and <command moreinfo="none">ipchains</command> commands deal
with the TOS bits in much the same manner. In both cases you specify a rule
that matches the datagrams with particular TOS bits set, and
use the <option>-t</option> argument to specify the change you wish to make.</para><para>The changes are specified using two-bit masks. The first of these bit masks is
logically ANDed with the IP options field of the datagram and the second is
logically eXclusive-ORd with it. If this sounds complicated, we'll give you
the recipes required to enable each of the types of service in a moment.</para><para>The bit masks are specified using eight-bit hexadecimal values. Both
<command moreinfo="none">ipfwadm</command> and <command moreinfo="none">ipchains</command> use the same
argument syntax:

<screen width="80" format="linespecific"><literal moreinfo="none">-t <replaceable>andmask</replaceable> <replaceable>xormask</replaceable></literal></screen>
</para><para>Fortunately the same mask arguments can be used each time you wish to set a
particular type of service, to save you having to work them out. They are
presented with some suggested uses in
<xref linkend="x-087-2-firewall.ipchains.tos.recipes"></xref>.</para><table id="x-087-2-firewall.ipchains.tos.recipes"><title>Suggested Uses for TOS Bitmasks</title><tgroup cols="4"><colspec colnum="1" colwidth="1.50i"></colspec><thead><row><entry>TOS</entry><entry>ANDmask</entry><entry>XORmask</entry><entry>Suggested Use</entry></row></thead><tbody><row><entry>Minimum Delay</entry><entry><literal moreinfo="none">0x01</literal></entry><entry><literal moreinfo="none">0x10</literal></entry><entry>ftp, telnet, ssh</entry></row><row><entry>Maximum Throughput</entry><entry><literal moreinfo="none">0x01</literal></entry><entry><literal moreinfo="none">0x08</literal></entry><entry>ftp-data, www</entry></row><row><entry>Maximum Reliability</entry><entry><literal moreinfo="none">0x01</literal></entry><entry><literal moreinfo="none">0x04</literal></entry><entry>snmp, dns</entry></row><row><entry>Minimum Cost</entry><entry><literal moreinfo="none">0x01</literal></entry><entry><literal moreinfo="none">0x02</literal></entry><entry>nntp, smtp</entry></row></tbody></tgroup></table></sect2><sect2><title>Setting the TOS Bits Using iptables</title><para><indexterm significance="normal"><primary>iptables command</primary><secondary>setting the TOS bits</secondary></indexterm>
The <command moreinfo="none">iptables</command> tool allows you to specify rules that
capture only datagrams with TOS bits matching some predetermined value
using the <option>-m tos</option> option, and for setting the TOS
bits of IP datagrams matching a rule using the <literal moreinfo="none">-j
TOS</literal> target. You may set TOS bits only on the
<literal moreinfo="none">FORWARD</literal> and <literal moreinfo="none">OUTPUT</literal> chains. The
matching and the setting occur quite independently. You can configure
all sort of interesting rules. For example, you can configure a rule
that discads all datagrams with certain TOS bit combinations, or a
rule that sets the TOS bits of datagrams only from certain hosts. Most
often you will use rules that contain both matching and setting to
perform TOS bit translations, just as you could for
<command moreinfo="none">ipfwadm</command> or <command moreinfo="none">ipchains</command>.</para><para>Rather than the complicated two-mask configuration of
<command moreinfo="none">ipfwadm</command> and <command moreinfo="none">ipchains</command>,
<command moreinfo="none">iptables</command> uses the simpler approach of plainly specifying
what the TOS bits should match, or to what the TOS bits should be set.
Additionally, rather than having to remember and use the hexadecimal value,
you may specify the TOS bits using the more friendly mnemonics listed in
the upcoming table.</para><para>The general syntax used to match TOS bits looks like:
 
<screen format="linespecific"><literal moreinfo="none">-m tos --tos <replaceable>mnemonic</replaceable> [<replaceable>other-args</replaceable>] -j <replaceable>target</replaceable></literal></screen></para><para>The general syntax used to set TOS bits looks like:

<screen format="linespecific"><literal moreinfo="none">[<replaceable>other-args</replaceable>] -j TOS --set <replaceable>mnemonic</replaceable></literal></screen></para><para>Remember that these would typically be used together, but they can be
used quite independently if you have a configuration that
requires it.</para><informaltable id="x-087-2-firewall.iptables.tos.recipes"><tgroup cols="2"><thead><row><entry>Mnemonic</entry><entry>Hexadecimal</entry></row></thead><tbody><row><entry>Normal-Service</entry><entry>0x00</entry></row><row><entry>Minimize-Cost</entry><entry>0x02</entry></row><row><entry>Maximize-Reliability</entry><entry>0x04</entry></row><row><entry>Maximize-Throughput</entry><entry>0x08</entry></row><row><entry>Minimize-Delay</entry><entry>0x10</entry></row></tbody></tgroup></informaltable></sect2><indexterm significance="normal" class="endofrange" startref="firewalls.tos.bit.manip"></indexterm><indexterm significance="normal" class="endofrange" startref="ip.tos.bits"></indexterm><indexterm significance="normal" class="endofrange" startref="tos.bits.manip"></indexterm></sect1><sect1 id="x-087-2-firewall.checkingconf"><title>Testing a
Firewall Configuration</title><para><indexterm significance="normal" class="startofrange" id="firewall.test.config"><primary>firewalls</primary><secondary>testing a configuration</secondary></indexterm>
After you've designed an appropriate firewall configuration, it's
important to validate that it does in fact do what you want it to
do. One way to do this is to use a test host outside your network to
attempt to pierce your firewall: this can be quite clumsy and
slow, though, and is limited to testing only those addresses that you can
actually use.</para><para>A faster and easier method is available with the Linux firewall
implementation.  It allows you to manually generate tests and run them 
through the firewall configuration just as if you were testing with
actual datagrams. All varieties of the Linux kernel firewall software,
<command moreinfo="none">ipfwadm</command>, <command moreinfo="none">ipchains</command>, and
<command moreinfo="none">iptables</command>, provide support for this style of
testing. The implementation involves use of the relevant
<emphasis>check</emphasis> command.</para><para>The general test procedure is as follows:</para><orderedlist inheritnum="ignore" continuation="restarts"><listitem><para>Design and configure your firewall using <command moreinfo="none">ipfwadm</command>,
<command moreinfo="none">ipchains</command>, or <command moreinfo="none">iptables</command>.</para></listitem><listitem><para>Design a series of tests that will determine whether your firewall is
actually working as you intend. For these tests you may use any source
or destination address, so choose some address combinations that
should be accepted and some others that should be dropped. If you're
allowing or disallowing only certain ranges of addresses, it is a good
idea to test addresses on either side of the boundary of the
rangeone address just inside the boundary and one address just
outside the boundary. This will help ensure that you have the correct
boundaries configured, because it is sometimes easy to specify
netmasks incorrectly in your configuration.  If you're filtering by
protocol and port number, your tests should also check all important
combinations of these parameters. For example, if you intend to accept
only TCP under certain circumstances, check that UDP datagrams are
dropped.</para></listitem><listitem><para>Develop <command moreinfo="none">ipfwadm</command>, <command moreinfo="none">ipchains</command>, or
<command moreinfo="none">iptables</command> rules to implement each test. It is
probably worthwhile to write all the rules into a script so you can
test and re-test easily as you correct mistakes or change your
design. Tests use almost the same syntax as rule specifications, but
the arguments take on slightly differing meanings. For example, the
source address argument in a rule specification specifies the source
address that datagrams matching this rule should have. The source
address argument in test syntax, in contrast, specifies the source
address of the test datagram that will be generated. For 
<command moreinfo="none">ipfwadm</command>, you must use the <option>c</option>
option to specify that this command is a test, while for
<command moreinfo="none">ipchains</command> and <command moreinfo="none">iptables</command>, you must
use the <option>C</option> option. In all cases you must
<emphasis>always</emphasis> specify the source address, destination
address, protocol, and interface to be used for the test. Other
arguments, such as port numbers or TOS bit settings, are optional.</para></listitem><listitem><para>Execute each test command and note the output. The output of each test
will be a single word indicating the final target of the datagram
after running it through the firewall configurationthat is,
where the processing ended. For <command moreinfo="none">ipchains</command> and
<command moreinfo="none">iptables</command>, user-specified chains will be tested
in addition to the built-in ones.</para></listitem><listitem><para>Compare the output of each test against the desired result. If there
are any discrepancies, you will need to analyse your ruleset to
determine where you've made the error. If you've written your test
commands into a script file, you can easily rerun the test after
correcting any errors in your firewall configuration. It's a good
practice to flush your rulesets completely and rebuild them from
scratch, rather than to make changes dynamically. This helps ensure
that the active configuration you are testing actually reflects the
set of commands in your configuration script.</para></listitem></orderedlist><para>Let's take a quick look at what a manual test transcript would look
like for our nave example with <command moreinfo="none">ipchains</command>. You will remember that our
local network in the example was 172.16.1.0 with a netmask of
255.255.255.0, and we were to allow TCP connections out to web servers
on the net. Nothing else was to pass our forward chain.  Start with a
transmission that we know should work, a connection from a local host
to a web server outside:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -C forward -p tcp -s 172.16.1.0 1025 -d 44.136.8.2 80 -i eth0</userinput>
accepted</screen></para><para>Note the arguments had to be supplied and the way they've been used to
describe a datagram. The output of the command indicates that that the
datagram was accepted for forwarding, which is what we hoped for.</para><para>Now try another test, this time with a source address that doesn't
belong to our network. This one should be denied:
<screen format="linespecific"># <userinput moreinfo="none">ipchains -C forward -p tcp -s 172.16.2.0 1025 -d 44.136.8.2 80 -i eth0</userinput>
denied</screen></para><para>Try some more tests, this time with the same details as the first test,
but with different protocols. These should be denied, too:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -C forward -p udp -s 172.16.1.0 1025 -d 44.136.8.2 80 -i eth0</userinput>
denied
# <userinput moreinfo="none">ipchains -C forward -p icmp -s 172.16.1.0 1025 -d 44.136.8.2 80 -i eth0</userinput>
denied</screen></para><para>Try another destination port, again expecting it to be denied:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -C forward -p tcp -s 172.16.1.0 1025 -d 44.136.8.2 23 -i eth0</userinput>
denied</screen></para><para>You'll go a long way toward achieving peace of mind if you design a series
of exhaustive tests. While this can sometimes be as difficult as designing
the firewall configuration, it's also the best way of knowing
that your design
is providing the security you expect of it.</para><indexterm significance="normal" class="endofrange" startref="firewall.test.config"></indexterm></sect1><sect1 id="x-087-2-firewall.example"><title>A Sample Firewall Configuration</title><para><indexterm significance="normal" class="startofrange" id="firewalls.samp.config"><primary>firewalls</primary><secondary>sample configuration</secondary></indexterm>
We've discussed the fundamentals of firewall configuration. Let's now
look at what a firewall configuration might actually look like.</para><para>The configuration in this example has been designed to be easily
extended and customized. We've provided three versions. The first
version is implemented using the <command moreinfo="none">ipfwadm</command> command
(or the <command moreinfo="none">ipfwadm-wrapper</command> script), the second uses
<command moreinfo="none">ipchains</command>, and the third uses
<command moreinfo="none">iptables</command>. The example doesn't attempt to exploit
user-defined chains, but it will show you the similarities and
differences between the old and new firewall configuration tool
syntaxes:</para><programlisting width="80" format="linespecific">#!/bin/bash
##########################################################################
# IPFWADM VERSION
# This sample configuration is for a single host firewall configuration
# with no services supported by the firewall machine itself.
##########################################################################

# USER CONFIGURABLE SECTION

# The name and location of the ipfwadm utility. Use ipfwadm-wrapper for
# 2.2.* kernels.
IPFWADM=ipfwadm

# The path to the ipfwadm executable.
PATH="/sbin"

# Our internal network address space and its supporting network device.
OURNET="172.29.16.0/24"
OURBCAST="172.29.16.255"
OURDEV="eth0"

# The outside address and the network device that supports it.
ANYADDR="0/0"
ANYDEV="eth1"

# The TCP services we wish to allow to pass - "" empty means all ports
# note: space separated
TCPIN="smtp www"
TCPOUT="smtp www ftp ftp-data irc"

# The UDP services we wish to allow to pass - "" empty means all ports
# note: space separated
UDPIN="domain"
UDPOUT="domain"

# The ICMP services we wish to allow to pass - "" empty means all types
# ref: /usr/include/netinet/ip_icmp.h for type numbers
# note: space separated
ICMPIN="0 3 11"
ICMPOUT="8 3 11"

# Logging; uncomment the following line to enable logging of datagrams
# that are blocked by the firewall.
# LOGGING=1

# END USER CONFIGURABLE SECTION
###########################################################################
# Flush the Incoming table rules
$IPFWADM -I -f

# We want to deny incoming access by default.
$IPFWADM -I -p deny

# SPOOFING
# We should not accept any datagrams with a source address matching ours
# from the outside, so we deny them.
$IPFWADM -I -a deny -S $OURNET -W $ANYDEV

# SMURF
# Disallow ICMP to our broadcast address to prevent "Smurf" style attack.
$IPFWADM -I -a deny -P icmp -W $ANYDEV -D $OURBCAST

# TCP
# We will accept all TCP datagrams belonging to an existing connection
# (i.e. having the ACK bit set) for the TCP ports we're allowing through.
# This should catch more than 95 % of all valid TCP packets.
$IPFWADM -I -a accept -P tcp -D $OURNET $TCPIN -k -b

# TCP - INCOMING CONNECTIONS
# We will accept connection requests from the outside only on the
# allowed TCP ports.
$IPFWADM -I -a accept -P tcp -W $ANYDEV -D $OURNET $TCPIN -y

# TCP - OUTGOING CONNECTIONS
# We accept all outgoing tcp connection requests on allowed TCP ports.
$IPFWADM -I -a accept -P tcp -W $OURDEV -D $ANYADDR $TCPOUT -y

# UDP - INCOMING
# We will allow UDP datagrams in on the allowed ports.
$IPFWADM -I -a accept -P udp -W $ANYDEV -D $OURNET $UDPIN

# UDP - OUTGOING
# We will allow UDP datagrams out on the allowed ports.
$IPFWADM -I -a accept -P udp -W $OURDEV -D $ANYADDR $UDPOUT

# ICMP - INCOMING
# We will allow ICMP datagrams in of the allowed types.
$IPFWADM -I -a accept -P icmp -W $ANYDEV -D $OURNET $UDPIN

# ICMP - OUTGOING
# We will allow ICMP datagrams out of the allowed types.
$IPFWADM -I -a accept -P icmp -W $OURDEV -D $ANYADDR $UDPOUT

# DEFAULT and LOGGING
# All remaining datagrams fall through to the default
# rule and are dropped. They will be logged if you've
# configured the LOGGING variable above.
#
if [ "$LOGGING" ]
then
	# Log barred TCP
	$IPFWADM -I -a reject -P tcp -o

	# Log barred UDP
	$IPFWADM -I -a reject -P udp -o

	# Log barred ICMP
	$IPFWADM -I -a reject -P icmp -o
fi
#
# end.</programlisting><?troff .Nd 10?><para>Now we'll reimplement it using the <command moreinfo="none">ipchains</command> command:</para><programlisting width="80" format="linespecific">#!/bin/bash
##########################################################################
# IPCHAINS VERSION
# This sample configuration is for a single host firewall configuration
# with no services supported by the firewall machine itself.
##########################################################################

# USER CONFIGURABLE SECTION

# The name and location of the ipchains utility.
IPCHAINS=ipchains

# The path to the ipchains executable.
PATH="/sbin"

# Our internal network address space and its supporting network device.
OURNET="172.29.16.0/24"
OURBCAST="172.29.16.255"
OURDEV="eth0"

# The outside address and the network device that supports it.
ANYADDR="0/0"
ANYDEV="eth1"

# The TCP services we wish to allow to pass - "" empty means all ports
# note: space separated
TCPIN="smtp www"
TCPOUT="smtp www ftp ftp-data irc"

# The UDP services we wish to allow to pass - "" empty means all ports
# note: space separated
UDPIN="domain"
UDPOUT="domain"

# The ICMP services we wish to allow to pass - "" empty means all types
# ref: /usr/include/netinet/ip_icmp.h for type numbers
# note: space separated
ICMPIN="0 3 11"
ICMPOUT="8 3 11"

# Logging; uncomment the following line to enable logging of datagrams
# that are blocked by the firewall.
# LOGGING=1

# END USER CONFIGURABLE SECTION
##########################################################################
# Flush the Input table rules
$IPCHAINS -F input

# We want to deny incoming access by default.
$IPCHAINS -P input deny

# SPOOFING
# We should not accept any datagrams with a source address matching ours
# from the outside, so we deny them.
$IPCHAINS -A input -s $OURNET -i $ANYDEV -j deny

# SMURF
# Disallow ICMP to our broadcast address to prevent "Smurf" style attack.
$IPCHAINS -A input -p icmp -w $ANYDEV -d $OURBCAST -j deny

# We should accept fragments, in ipchains we must do this explicitly.
$IPCHAINS -A input -f -j accept

# TCP
# We will accept all TCP datagrams belonging to an existing connection
# (i.e. having the ACK bit set) for the TCP ports we're allowing through.
# This should catch more than 95 % of all valid TCP packets.
$IPCHAINS -A input -p tcp -d $OURNET $TCPIN ! -y -b -j accept

# TCP - INCOMING CONNECTIONS
# We will accept connection requests from the outside only on the
# allowed TCP ports.
$IPCHAINS -A input -p tcp -i $ANYDEV -d $OURNET $TCPIN -y -j accept

# TCP - OUTGOING CONNECTIONS
# We accept all outgoing TCP connection requests on allowed TCP ports.
$IPCHAINS -A input -p tcp -i $OURDEV -d $ANYADDR $TCPOUT -y -j accept

# UDP - INCOMING
# We will allow UDP datagrams in on the allowed ports.
$IPCHAINS -A input -p udp -i $ANYDEV -d $OURNET $UDPIN -j accept

# UDP - OUTGOING
# We will allow UDP datagrams out on the allowed ports.
$IPCHAINS -A input -p udp -i $OURDEV -d $ANYADDR $UDPOUT -j accept

# ICMP - INCOMING
# We will allow ICMP datagrams in of the allowed types.
$IPCHAINS -A input -p icmp -w $ANYDEV -d $OURNET $UDPIN -j accept

# ICMP - OUTGOING
# We will allow ICMP datagrams out of the allowed types.
$IPCHAINS -A input -p icmp -i $OURDEV -d $ANYADDR $UDPOUT -j accept

# DEFAULT and LOGGING
# All remaining datagrams fall through to the default
# rule and are dropped. They will be logged if you've
# configured the LOGGING variable above.
#
if [ "$LOGGING" ]
then
	# Log barred TCP
	$IPCHAINS -A input -p tcp -l -j reject

	# Log barred UDP
	$IPCHAINS -A input -p udp -l -j reject

	# Log barred ICMP
	$IPCHAINS -A input -p icmp -l -j reject
fi
#
# end.</programlisting><para>In our <command moreinfo="none">iptables</command> example, we've switched to using
the <literal moreinfo="none">FORWARD</literal> ruleset because of the difference in
meaning of the <literal moreinfo="none">INPUT</literal> ruleset in the
<emphasis>netfilter</emphasis> implementation. This has implications
for us; it means that none of the rules protect the firewall host
itself. To accurately mimic our <command moreinfo="none">ipchains</command> example,
we would replicate each of our rules in the <literal moreinfo="none">INPUT</literal>
chain. For clarity, we've dropped all incoming datagrams received from
our outside interface instead.</para><programlisting width="103" format="linespecific">#!/bin/bash
##########################################################################
# IPTABLES VERSION
# This sample configuration is for a single host firewall configuration
# with no services supported by the firewall machine itself.
##########################################################################

# USER CONFIGURABLE SECTION

# The name and location of the ipchains utility.
IPTABLES=iptables

# The path to the ipchains executable.
PATH="/sbin"

# Our internal network address space and its supporting network device.
OURNET="172.29.16.0/24"
OURBCAST="172.29.16.255"
OURDEV="eth0"

# The outside address and the network device that supports it.
ANYADDR="0/0"
ANYDEV="eth1"

# The TCP services we wish to allow to pass - "" empty means all ports
# note: comma separated
TCPIN="smtp,www"
TCPOUT="smtp,www,ftp,ftp-data,irc"

# The UDP services we wish to allow to pass - "" empty means all ports
# note: comma separated
UDPIN="domain"
UDPOUT="domain"

# The ICMP services we wish to allow to pass - "" empty means all types
# ref: /usr/include/netinet/ip_icmp.h for type numbers
# note: comma separated
ICMPIN="0,3,11"
ICMPOUT="8,3,11"

# Logging; uncomment the following line to enable logging of datagrams
# that are blocked by the firewall.
# LOGGING=1

# END USER CONFIGURABLE SECTION
###########################################################################
# Flush the Input table rules
$IPTABLES -F FORWARD

# We want to deny incoming access by default.
$IPTABLES -P FORWARD deny

# Drop all datagrams destined for this host received from outside.
$IPTABLES -A INPUT -i $ANYDEV -j DROP

# SPOOFING
# We should not accept any datagrams with a source address matching ours
# from the outside, so we deny them.
$IPTABLES -A FORWARD -s $OURNET -i $ANYDEV -j DROP

# SMURF
# Disallow ICMP to our broadcast address to prevent "Smurf" style attack.
$IPTABLES -A FORWARD -m multiport -p icmp -i $ANYDEV -d $OURNET -j DENY

# We should accept fragments, in iptables we must do this explicitly.
$IPTABLES -A FORWARD -f -j ACCEPT

# TCP
# We will accept all TCP datagrams belonging to an existing connection
# (i.e. having the ACK bit set) for the TCP ports we're allowing through.
# This should catch more than 95 % of all valid TCP packets.
$IPTABLES -A FORWARD -m multiport -p tcp -d $OURNET --dports $TCPIN /
    ! --tcp-flags SYN,ACK ACK -j ACCEPT
$IPTABLES -A FORWARD -m multiport -p tcp -s $OURNET --sports $TCPIN /
    ! --tcp-flags SYN,ACK ACK -j ACCEPT


# TCP - INCOMING CONNECTIONS
# We will accept connection requests from the outside only on the
# allowed TCP ports.
$IPTABLES -A FORWARD -m multiport -p tcp -i $ANYDEV -d $OURNET $TCPIN /
    --syn -j ACCEPT

# TCP - OUTGOING CONNECTIONS
# We will accept all outgoing tcp connection requests on the allowed /
    TCP ports.
$IPTABLES -A FORWARD -m multiport -p tcp -i $OURDEV -d $ANYADDR /
    --dports $TCPOUT --syn -j ACCEPT<?troff .sp -12p?>
# UDP - INCOMING
# We will allow UDP datagrams in on the allowed ports and back.
$IPTABLES -A FORWARD -m multiport -p udp -i $ANYDEV -d $OURNET /
    --dports $UDPIN -j ACCEPT
$IPTABLES -A FORWARD -m multiport -p udp -i $ANYDEV -s $OURNET /
    --sports $UDPIN -j ACCEPT<?troff .sp -12p?>
# UDP - OUTGOING
# We will allow UDP datagrams out to the allowed ports and back.
$IPTABLES -A FORWARD -m multiport -p udp -i $OURDEV -d $ANYADDR /
    --dports $UDPOUT -j ACCEPT
$IPTABLES -A FORWARD -m multiport -p udp -i $OURDEV -s $ANYADDR /
    --sports $UDPOUT -j ACCEPT<?troff .sp -12p?>
# ICMP - INCOMING
# We will allow ICMP datagrams in of the allowed types.
$IPTABLES -A FORWARD -m multiport -p icmp -i $ANYDEV -d $OURNET /
    --dports $ICMPIN -j ACCEPT<?troff .sp -12p?>
# ICMP - OUTGOING
# We will allow ICMP datagrams out of the allowed types.
$IPTABLES -A FORWARD -m multiport -p icmp -i $OURDEV -d $ANYADDR /
    --dports $ICMPOUT -j ACCEPT<?troff .sp -12p?>
# DEFAULT and LOGGING
# All remaining datagrams fall through to the default
# rule and are dropped. They will be logged if you've
# configured the LOGGING variable above.
#
if [ "$LOGGING" ]
then
	# Log barred TCP
	$IPTABLES -A FORWARD -m tcp -p tcp -j LOG<?troff .sp -12p?>
	# Log barred UDP
	$IPTABLES -A FORWARD -m udp -p udp -j LOG<?troff .sp -12p?>
	# Log barred ICMP
	$IPTABLES -A FORWARD -m udp -p icmp -j LOG
fi
#
# end.</programlisting><para>In many simple situations, to use the sample all you have to do is edit
the top section of the file labeled USER
CONFIGURABLE section to specify which protocols and datagrams
type you wish to allow in and out. For more complex configurations,
you will need to edit the section at the bottom, as well. Remember,
this is a simple example, so scrutinize it very carefully to ensure it
does what you want while implementing it.</para><indexterm significance="normal" class="endofrange" startref="firewalls.samp.config"></indexterm></sect1><indexterm significance="normal" class="endofrange" startref="chfw.tcp.ip.firewall"></indexterm><indexterm significance="normal" class="endofrange" startref="chfw.firewalls.tcp.ip"></indexterm></chapter><chapter id="x-087-2-accounting"><title>IP Accounting</title><para><indexterm significance="normal" class="startofrange" id="chac.tcp.ip.accounting"><primary>TCP/IP (Transmission Control Protocol/Internet Protocol)</primary><secondary>accounting</secondary></indexterm>
In todays world of commercial Internet service, it is becoming 
increasingly important to know
how much data you are transmitting and receiving on your network connections.
If you are an Internet Service Provider and you charge your customers by
volume, this will be essential to your business. If you are a customer
of an Internet Service Provider that charges by data volume, you will
find it useful to collect your own data to ensure the accuracy of your
Internet charges.</para><para>There are other uses for network accounting that have nothing to do with
dollars and bills. If you manage a server that offers a number of different
types of network services, it might be useful to you to know exactly
how much data is being generated by each one. This sort of information
could assist you in making decisions, such as what hardware to buy or how
many servers to run.</para><para>The Linux kernel provides a facility that allows you to collect all sorts
of useful information about the network traffic it sees. This facility
is called <emphasis>IP accounting</emphasis>.</para><sect1 id="x-087-2-accounting.kernel.config"><title>Configuring the Kernel <?lb?>for IP Accounting</title><para><indexterm significance="normal"><primary>IP accounting</primary><secondary>kernel configuration</secondary></indexterm>
<indexterm significance="normal"><primary>configuring</primary><secondary>kernel</secondary><tertiary sortas="IP accounting">for IP accounting</tertiary></indexterm>
The Linux IP accounting feature is very closely related to the Linux
firewall software. The places you want to collect
accounting data are the same places that you would be interested in
performing firewall filtering: into and out of a network host, and in the
software that does the routing of datagrams. If you haven't read the section
on firewalls, now is probably a good time to do so, as we will be using some of
the concepts described in <xref linkend="x-087-2-firewall"></xref>.</para><para><indexterm significance="normal"><primary>2.0 kernels</primary><secondary>IP accounting</secondary></indexterm>
<indexterm significance="normal"><primary>2.2 kernels</primary><secondary>IP accounting</secondary></indexterm>
To activate the Linux IP accounting feature, you should first see if your 
Linux kernel is configured for it. Check to see if the <filename moreinfo="none">/proc/net/ip_acct</filename> file exists. If it does, your kernel already supports IP accounting. If it doesn't, you must build a new kernel, ensuring that you answer Y to the options in 2.0 and 2.2 series kernels:

<screen format="linespecific">Networking options  ---
	[*] Network firewalls
	[*] TCP/IP networking
	 ...
	[*] IP: accounting</screen>

<indexterm significance="normal"><primary>2.4 kernels</primary><secondary>IP accounting</secondary></indexterm>
or in 2.4 series kernels:

<screen format="linespecific">Networking options  ---
    [*] Network packet filtering (replaces ipchains)</screen>
</para></sect1><sect1 id="x-087-2-accounting.ipfwadm"><title>Configuring IP Accounting</title><para><indexterm significance="normal" class="startofrange" id="ipaccounting.config"><primary>IP accounting</primary><secondary>configuring</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="config.ipaccounting"><primary>configuring</primary><secondary>IP accounting</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="ipfwadm.config.ipaccount"><primary>ipfwadm command</primary><secondary>configuring IP accounting</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="ipchains.config.ipaccount"><primary>ipchains command</primary><secondary>configuring IP accounting</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="iptables.config.ipaccount"><primary>iptables command</primary><secondary>configuring IP accounting</secondary></indexterm>
Because IP accounting is closely related to IP firewall, the same tool 
was designated to configure it, so <command moreinfo="none">ipfwadm</command>,
<command moreinfo="none">ipchains</command> or <command moreinfo="none">iptables</command> are used to configure IP accounting. The command syntax is very similar to
that of the firewall rules, so we won't focus on it, but we will discuss
what you can discover about the nature of your network traffic using this 
feature.</para><para>The general syntax for IP accounting with <command moreinfo="none">ipfwadm</command> is:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -A [<replaceable>direction</replaceable>] [<replaceable>command</replaceable>] [<replaceable>parameters</replaceable>]</userinput></screen></para><para>The direction argument is new. This is simply coded as
<literal moreinfo="none">in</literal>,
<literal moreinfo="none">out</literal>, or
<literal moreinfo="none">both</literal>.
These directions are from the perspective of the linux machine itself, so
<literal moreinfo="none">in</literal> means data coming into the machine from a network 
connection and <literal moreinfo="none">out</literal> means data that is being transmitted by 
this host on a network connection. The <literal moreinfo="none">both</literal> direction is the 
sum of both the incoming and outgoing directions.</para><para>The general command syntax for <command moreinfo="none">ipchains</command> 
and <command moreinfo="none">iptables</command> is:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -A <replaceable>chain</replaceable> <replaceable>rule-specification</replaceable></userinput>
# <userinput moreinfo="none">iptables -A <replaceable>chain</replaceable> <replaceable>rule-specification</replaceable></userinput></screen></para><para>The <command moreinfo="none">ipchains</command> and <command moreinfo="none">iptables</command>
commands allow you to specify direction in a manner more consistent
with the firewall rules.  IP Firewall Chains doesn't allow you to
configure a rule that aggregates both directions, but it does allow you
to configure rules in the <literal moreinfo="none">forward</literal> chain that the
older implementation did not. We'll see the difference that makes in
some examples a little later.</para><para>The commands are much the same as firewall rules, except that the
policy rules do not apply here. We can add, insert, delete, and list
accounting rules. In the case of <command moreinfo="none">ipchains</command> and
<command moreinfo="none">iptables</command>, all valid rules are accounting rules, and
any command that doesn't specify the <emphasis>-j</emphasis> option
performs accounting only.</para><para>The rule specification parameters for IP accounting are the same as
those used for IP firewall. These are what we use to define precisely
what network traffic we wish to count and total.</para><sect2 id="x-087-2-accounting.by.address"><title>Accounting by Address</title><para><indexterm significance="normal"><primary>IP accounting</primary><secondary sortas="address">by address</secondary></indexterm>
Let's work with an example to illustrate how we'd use IP accounting.</para><para>Imagine we have a Linux-based router that serves two departments
at the Virtual Brewery. The router has two Ethernet devices,
<filename moreinfo="none">eth0</filename> and <filename moreinfo="none">eth1</filename>, each of which
services a department; and a PPP device, <filename moreinfo="none">ppp0</filename>, that
connects us via a high-speed serial link to the main campus of the
Groucho Marx University.</para><para>Let's also imagine that for billing purposes we want to know the total
traffic generated by each of the departments across the serial link, and
for management purposes we want to know the total traffic generated
between the two departments.</para><para>The following table shows the interface addresses we will use in our
example:</para><para><informaltable><tgroup cols="3"><thead><row><entry>iface</entry><entry>address</entry><entry>netmask</entry></row></thead><tbody><row><entry>eth0</entry><entry>172.16.3.0</entry><entry>255.255.255.0</entry></row><row><entry>eth1</entry><entry>172.16.4.0</entry><entry>255.255.255.0</entry></row></tbody></tgroup></informaltable></para><para>To answer the question, How much data does each department
generate on the PPP link?, we could use a rule that looks like
this:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -A both -a -W ppp0 -S 172.16.3.0/24 -b</userinput>
# <userinput moreinfo="none">ipfwadm -A both -a -W ppp0 -S 172.16.4.0/24 -b</userinput></screen>

or:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -A input -i ppp0 -d 172.16.3.0/24</userinput>
# <userinput moreinfo="none">ipchains -A output -i ppp0 -s 172.16.3.0/24</userinput>
# <userinput moreinfo="none">ipchains -A input -i ppp0 -d 172.16.4.0/24</userinput>
# <userinput moreinfo="none">ipchains -A output -i ppp0 -s 172.16.4.0/24</userinput></screen>

and with <command moreinfo="none">iptables</command>:

<screen format="linespecific"># <userinput moreinfo="none">iptables -A FORWARD -i ppp0 -d 172.16.3.0/24</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -o ppp0 -s 172.16.3.0/24</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -i ppp0 -d 172.16.4.0/24</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -o ppp0 -s 172.16.4.0/24</userinput></screen>
</para><para>The first half of each of these set of rules say, Count all data
traveling in either direction across the interface named ppp0 with a source
or destination (remember the function of the <emphasis>-b</emphasis> flag in
<command moreinfo="none">ipfwadm</command> and <command moreinfo="none">iptables</command>) address of
<literal moreinfo="none">172.16.3.0/24.</literal> The second half of each ruleset is
the same, but for the second Ethernet network at our site.</para><para>To answer the second question, How much data travels between the
two departments?, we need a rule that looks like this:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -A both -a -S 172.16.3.0/24 -D 172.16.4.0/24 -b</userinput></screen>

or:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -A forward -s 172.16.3.0/24 -d 172.16.4.0/24 -b</userinput></screen>

or:

<screen format="linespecific"># <userinput moreinfo="none">iptables -A FORWARD -s 172.16.3.0/24 -d 172.16.4.0/24</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -s 172.16.4.0/24 -d 172.16.3.0/24</userinput></screen>

These rules will count all datagrams with a source address belonging
to one of the department networks and a destination address belonging
to the other.</para></sect2><sect2 id="x-087-2-accounting.by.service"><title>Accounting by Service Port</title><para><indexterm significance="normal" class="startofrange" id="ipaccounting.service.port"><primary>IP accounting</primary><secondary sortas="service port">by service port</secondary></indexterm>
Okay, let's suppose we also want a better idea of exactly what sort of traffic
is being carried across our PPP link. We might, for example, want to know
how much of the link the FTP, smtp, and World Wide Web services are consuming.</para><para>A script of rules to enable us to collect this information might look like:

<screen format="linespecific">#!/bin/sh
# Collect FTP, smtp and www volume statistics for data carried on our
# PPP link using ipfwadm
#
ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 ftp ftp-data
ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 smtp
ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 www</screen>

or:

<screen format="linespecific">#!/bin/sh
# Collect ftp, smtp and www volume statistics for data carried on our
# PPP link using ipchains
#
ipchains -A input -i ppp0 -p tcp -s 0/0 ftp-data:ftp
ipchains -A output -i ppp0 -p tcp -d 0/0 ftp-data:ftp
ipchains -A input -i ppp0 -p tcp -s 0/0 smtp
ipchains -A output -i ppp0 -p tcp -d 0/0 smtp
ipchains -A input -i ppp0 -p tcp -s 0/0 www
ipchains -A output -i ppp0 -p tcp -d 0/0 www</screen>

or:

<screen format="linespecific">#!/bin/sh
# Collect ftp, smtp and www volume statistics for data carried on our
# PPP link using iptables.
#
iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport ftp-data:ftp
iptables -A FORWARD -o ppp0 -m tcp -p tcp --dport ftp-data:ftp
iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport smtp
iptables -A FORWARD -o ppp0 -m tcp -p tcp --dport smtp
iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport www
iptables -A FORWARD -o ppp0 -m tcp -p tcp --dport www</screen></para><para>There are a couple of interesting features to this
configuration. Firstly, we've specified the protocol. When we specify
ports in our rules, we must also specify a protocol because TCP and UDP
provide separate sets of ports. Since all of these services are
TCB-based, we've specified it as the protocol.  Secondly, we've
specified the two services <literal moreinfo="none">ftp</literal> and
<literal moreinfo="none">ftp-data</literal> in one command. <command moreinfo="none">ipfwadm</command>
allows you to specify single ports, ranges of ports, or arbitrary lists
of ports. The <command moreinfo="none">ipchains</command> command allows either single
ports or ranges of ports, which is what we've used here. The syntax
"<literal moreinfo="none">ftp-data:ftp</literal>" means "ports ftp-data (20) through
ftp (21)," and is how we encode ranges of ports in both
<command moreinfo="none">ipchains</command> and <command moreinfo="none">iptables</command>. When you
have a list of ports in an accounting rule, it means that any data
received for any of the ports in the list will cause the data to be
added to that entry's totals. Remembering that the FTP service uses
two ports, the command port and the data transfer port, we've added
them together to total the FTP traffic. Lastly, we've specified the
source address as <literal moreinfo="none">0/0,</literal> which is
special notation that matches all addresses and is required by both
the <command moreinfo="none">ipfwadm</command> and <command moreinfo="none">ipchains</command>
commands in order to specify ports.</para><para>We can expand on the second point a little to give us a different view
of the data on our link. Let's now imagine that we class FTP, SMTP,
and World Wide Web traffic as essential traffic, and all other traffic
as nonessential. If we were interested in seeing the ratio of
essential traffic to nonessential traffic, we could do something like:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 ftp ftp-data smtp www</userinput>
# <userinput moreinfo="none">ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 1:19 22:24 26:79 81:32767</userinput></screen></para><para>If you have already examined your <filename moreinfo="none">/etc/services</filename> file, you
will see that the second rule covers all ports except (<literal moreinfo="none">ftp</literal>, <literal moreinfo="none">ftp-data</literal>, <literal moreinfo="none">smtp</literal>,
and <literal moreinfo="none">www</literal>).</para><para>How do we do this with the <command moreinfo="none">ipchains</command> or
<command moreinfo="none">iptables</command> commands, since they allow only one argument in
their port specification? We can exploit user-defined chains in accounting
just as easily as in firewall rules. Consider the following approach:</para><para><screen format="linespecific"># <userinput moreinfo="none">ipchains -N a-essent</userinput>
# <userinput moreinfo="none">ipchains -N a-noness</userinput>
# <userinput moreinfo="none">ipchains -A a-essent -j ACCEPT</userinput>
# <userinput moreinfo="none">ipchains -A a-noness -j ACCEPT</userinput>
# <userinput moreinfo="none">ipchains -A forward -i ppp0 -p tcp -s 0/0 ftp-data:ftp -j a-essent</userinput>
# <userinput moreinfo="none">ipchains -A forward -i ppp0 -p tcp -s 0/0 smtp -j a-essent</userinput>
# <userinput moreinfo="none">ipchains -A forward -i ppp0 -p tcp -s 0/0 www -j a-essent</userinput>
# <userinput moreinfo="none">ipchains -A forward -j a-noness</userinput></screen>

Here we create two user-defined chains, one called 
<literal moreinfo="none">a-essent</literal>, where we capture accounting data for 
essential services and another called <literal moreinfo="none">a-noness</literal>, where we 
capture accounting data for nonessential services. We then add rules to 
our forward chain that match our essential services and jump to the 
<literal moreinfo="none">a-essent</literal> chain, where we have just one rule that accepts 
all datagrams and counts them. The last rule in our forward chain is a rule 
that jumps to our <literal moreinfo="none">a-noness</literal> chain, where again we have just 
one rule that accepts all datagrams and counts them. The rule that jumps to the
<literal moreinfo="none">a-noness</literal> chain will not be reached by any of our essential 
services, as they will have been accepted in their own chain. Our tallies for 
essential and nonessential services will therefore be available in the 
rules within those chains. This is just one approach you could take; there 
are others. Our <command moreinfo="none">iptables</command> implementation of the same 
approach would look like:

<screen format="linespecific"># <userinput moreinfo="none">iptables -N a-essent</userinput>
# <userinput moreinfo="none">iptables -N a-noness</userinput>
# <userinput moreinfo="none">iptables -A a-essent -j ACCEPT</userinput>
# <userinput moreinfo="none">iptables -A a-noness -j ACCEPT</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport ftp-data:ftp -j a-essent</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport smtp -j a-essent</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport www -j a-essent</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -j a-noness</userinput></screen></para><para><indexterm significance="normal"><primary>datagrams</primary><secondary>fragmentation of</secondary></indexterm>
<indexterm significance="normal"><primary>fragmentation, datagram</primary></indexterm>
This looks simple enough. Unfortunately, there is a small but unavoidable
problem when trying to do accounting by service type. You will remember that
we discussed the role the MTU plays in TCP/IP networking in an earlier
chapter. The MTU defines the largest datagram that will be transmitted on
a network device. When a datagram is received by a router that is larger than
the MTU of the interface that needs to retransmit it, the router performs a
trick called <emphasis>fragmentation</emphasis>. The router breaks the large 
datagram into small pieces no longer than the MTU of the interface and then 
transmits these pieces. The router builds new headers to put in front of each 
of these pieces, and these are what the remote machine uses to reconstruct the
original data. Unfortunately, during the fragmentation process the port
is lost for all but the first fragment. This means that the IP accounting
can't properly count fragmented datagrams. It can reliably count only
the first fragment, or unfragmented datagrams. There is a small trick permitted
by <command moreinfo="none">ipfwadm</command> that ensures that while we won't be able to know
exactly what port the second and later fragments were from, we can still
count them.  An early version of Linux accounting software assigned
the fragments a fake port number, 0xFFFF, that we could count. To ensure that
we capture the second and later fragments, we could use a rule like:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 0xFFFF</userinput></screen></para><para>The IP chains implementation has a slightly more sophisticated solution, but
the result is much the same. If using the <command moreinfo="none">ipchains</command> command
we'd instead use:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -A forward -i ppp0 -p tcp -f</userinput></screen>

and with <command moreinfo="none">iptables</command> we'd use:

<screen format="linespecific"># <userinput moreinfo="none">iptables -A FORWARD -i ppp0 -m tcp -p tcp -f</userinput></screen></para><para>These won't tell us what the original port for this data was, but at least we are able to see how much of our data is fragments, and be able to account
for the volume of traffic they consume.</para><para>In 2.2 kernels you can select a kernel compile-time option that
negates this whole issue if your Linux machine is acting as the single
access point for a network. If you enable the <option>IP:
always defragment</option> option when you compile your
kernel, all received datagrams will be reassembled by the Linux router
before routing and retransmission. This operation is performed before
the firewall and accounting software sees the datagram, and thus you
will have no fragments to deal with. In 2.4 kernels you compile and
load the <emphasis>netfilter</emphasis>
<filename moreinfo="none">forward-fragment</filename> module.</para><indexterm significance="normal" class="endofrange" startref="ipaccounting.service.port"></indexterm></sect2><sect2 id="x-087-2-accounting.of.icmp"><title>Accounting of ICMP Datagrams</title><para><indexterm significance="normal"><primary>IP accounting</primary><secondary sortas="ICMP datagrams">of ICMP datagrams</secondary></indexterm>
<indexterm significance="normal"><primary>ICMP (Internet Control Message Protocol)</primary><secondary>datagram accounting</secondary></indexterm>
<indexterm significance="normal"><primary>ping flooding</primary></indexterm>
The ICMP protocol does not use service port numbers and is therefore a little
bit more difficult to collect details on. ICMP uses a number of different
types of datagrams. Many of these are harmless and normal, while others
should only be seen under special circumstances. Sometimes people with too
much time on their hands attempt to maliciously disrupt the network
access of a user by generating large numbers of ICMP messages. This is
commonly called <emphasis>ping flooding</emphasis>. While IP accounting 
cannot do anything to prevent this problem (IP firewalling can help, though!) 
we can at least put accounting rules in place that will show us if anybody 
has been trying.</para><para>ICMP doesn't use ports as TCP and UDP do. Instead ICMP has ICMP message
types. We can build rules to account for each ICMP message type. To do this,
we place the ICMP message and type number in place of the port field in the
<command moreinfo="none">ipfwadm</command> accounting commands. We listed the ICMP message
types in <xref linkend="x-087-2-firewall.ipfwadm.icmp-types"></xref>, so refer to it
if you need to remember what they are.</para><para>An IP accounting rule to collect information about the volume of ping data
that is being sent to you or that you are generating might look like:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -A both -a -P icmp -S 0/0 8</userinput>
# <userinput moreinfo="none">ipfwadm -A both -a -P icmp -S 0/0 0</userinput>
# <userinput moreinfo="none">ipfwadm -A both -a -P icmp -S 0/0 0xff</userinput></screen>

or, with <command moreinfo="none">ipchains</command>:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -A forward -p icmp -s 0/0 8</userinput>
# <userinput moreinfo="none">ipchains -A forward -p icmp -s 0/0 0</userinput>
# <userinput moreinfo="none">ipchains -A forward -p icmp -s 0/0 -f</userinput></screen>

or, with <command moreinfo="none">iptables</command>:

<screen format="linespecific"># <userinput moreinfo="none">iptables -A FORWARD -m icmp -p icmp --sports echo-request</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -m icmp -p icmp --sports echo-reply</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -m icmp -p icmp -f</userinput></screen>

The first rule collects information about the
ICMP Echo Request datagrams (ping requests), and the
second rule collects information about the ICMP Echo Reply
datagrams (ping replies). The third rule collects information about ICMP
datagram fragments. This is a trick similar to that described for fragmented
TCP and UDP datagrams.</para><para>If you specify source and/or destination addresses in your rules, you can
keep track of where the pings are coming from, such as whether they originate
inside or outside your network. Once you've determined where the rogue
datagrams are coming from, you can decide whether you want to put firewall
rules in place to prevent them or take some other action, such as
contacting the owner of the offending network to advise them of the problem,
or perhaps even legal action if the problem is a malicious act.</para></sect2><sect2 id="x-087-2-accounting.by.protocol"><title>Accounting by Protocol</title><para><indexterm significance="normal"><primary>IP accounting</primary><secondary sortas="protocol">by protocol</secondary></indexterm>
Let's now imagine that we are interested in knowing how much of the
traffic on our link is TCP, UDP, and ICMP. We would use rules like
the following:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -A both -a -W ppp0 -P tcp -D 0/0</userinput>
# <userinput moreinfo="none">ipfwadm -A both -a -W ppp0 -P udp -D 0/0</userinput>
# <userinput moreinfo="none">ipfwadm -A both -a -W ppp0 -P icmp -D 0/0</userinput></screen>

or:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -A forward -i ppp0 -p tcp -d 0/0</userinput>
# <userinput moreinfo="none">ipchains -A forward -i ppp0 -p udp -d 0/0</userinput>
# <userinput moreinfo="none">ipchains -A forward -i ppp0 -p icmp -d 0/0</userinput></screen>

or:

<screen format="linespecific"># <userinput moreinfo="none">iptables -A FORWARD -i ppp0 -m tcp -p tcp</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -o ppp0 -m tcp -p tcp</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -i ppp0 -m udp -p udp</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -o ppp0 -m udp -p udp</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -i ppp0 -m icmp -p icmp</userinput>
# <userinput moreinfo="none">iptables -A FORWARD -o ppp0 -m icmp -p icmp</userinput></screen>

With these rules in place, all of the traffic flowing across the
<literal moreinfo="none">ppp0</literal> interface will be analyzed to determine
whether it is TCP, UDP, or IMCP traffic, and the appropriate counters will
be updated for each. The <command moreinfo="none">iptables</command> example splits incoming
flow from outgoing flow as its syntax demands it.</para></sect2><indexterm significance="normal" class="endofrange" startref="ipaccounting.config"></indexterm><indexterm significance="normal" class="endofrange" startref="config.ipaccounting"></indexterm></sect1><sect1 id="x-087-2-accounting.viewing.results"><title>Using IP Accounting Results</title><para><indexterm significance="normal" class="startofrange" id="ipaccounting.results"><primary>IP accounting</primary><secondary>using results of</secondary></indexterm>
It is all very well to be collecting this information, but how do we
actually get to see it? To view the collected accounting data and the
configured accounting rules, we use our firewall configuration
commands, asking them to list our rules. The packet and byte counters
for each of our rules are listed in the output.</para><para>The <command moreinfo="none">ipfwadm</command>, <command moreinfo="none">ipchains</command>, and
<command moreinfo="none">iptables</command> commands differ in how accounting data is handled,
so we will treat them independently.</para><sect2><title>Listing Accounting Data with ipfwadm</title><para><indexterm significance="normal"><primary>ipfwadm command</primary><secondary>listing accounting data with</secondary></indexterm>
The most basic means of listing our accounting data with the
<command moreinfo="none">ipfwadm</command> command is to use it like this:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -A -l</userinput>
IP accounting rules
 pkts bytes dir prot source               destination          ports
 9833 2345K i/o all  172.16.3.0/24      anywhere             n/a
56527   33M i/o all  172.16.4.0/24      anywhere             n/a</screen></para><para>This will tell us the number of packets sent in each direction. If we use 
the extended output format with the <option>-e</option> option (not shown here because the 
output is too wide for the page), we are also supplied the options and
applicable interface names. Most of the fields in the output will be 
self-explanatory, but the following may not:</para><variablelist><varlistentry><term>dir</term><listitem><para>The direction in which the rule applies. Expected values here are
<literal moreinfo="none">in</literal>, <literal moreinfo="none">out</literal>,
or <literal moreinfo="none">i/o</literal>, meaning both ways.</para></listitem></varlistentry><varlistentry><term>prot</term><listitem><para>The protocols to which the rule applies.</para></listitem></varlistentry><varlistentry><term>opt</term><listitem><para>A coded form of the options we use when invoking
<command moreinfo="none">ipfwadm</command>. </para></listitem></varlistentry><varlistentry><term>ifname</term><listitem><para>The name of the interface to which the rule applies.</para></listitem></varlistentry><varlistentry><term>ifaddress</term><listitem><para>The address of the interface to which the rule applies.</para></listitem></varlistentry></variablelist><para>By default, <command moreinfo="none">ipfwadm</command> displays the packet and byte
counts in a shortened form, rounded to the nearest thousand (K) or million
(M). We can ask it to display the collected data in exact units by using the
expanded option as follows:

<screen width="105" format="linespecific"># <userinput moreinfo="none">ipfwadm -A -l -e -x</userinput></screen></para></sect2><sect2><title>Listing Accounting Data with ipchains</title><para><indexterm significance="normal"><primary>ipchains command</primary><secondary>listing accounting data with</secondary></indexterm>
The <command moreinfo="none">ipchains</command> command will not display our accounting data
(packet and byte counters) unless we supply it the <literal moreinfo="none">-v</literal>
argument. The simplest means of listing our accounting data with the
<command moreinfo="none">ipchains</command> is to use it like this:

<screen width="130" format="linespecific"># <userinput moreinfo="none">ipchains -L -v</userinput></screen></para><para>Again, just as with <command moreinfo="none">ipfwadm</command>, we can display the packet and
byte counters in units by using the expanded output mode. The
<command moreinfo="none">ipchains</command> uses the <literal moreinfo="none">-x</literal> argument for this:

<screen width="134" format="linespecific"># <userinput moreinfo="none">ipchains -L -v -x</userinput></screen></para></sect2><sect2><title>Listing Accounting Data with iptables</title><para><indexterm significance="normal"><primary>iptables command</primary><secondary>listing accounting data with</secondary></indexterm>
The <command moreinfo="none">iptables</command> command behaves very similarly to the
<command moreinfo="none">ipchains</command> command. Again, we must use the <literal moreinfo="none">-v</literal>
when listing tour rules to see the accounting counters. To list our accounting
data, we would use:</para><screen width="88" format="linespecific"># <userinput moreinfo="none">iptables -L -v</userinput></screen><para>Just as for the <command moreinfo="none">ipchains</command> command, you can use the 
<literal moreinfo="none">-x</literal> argument to show the output in expanded
format with unit figures.</para></sect2><indexterm significance="normal" class="endofrange" startref="ipaccounting.results"></indexterm></sect1><sect1 id="x-087-2-accounting.zeroing.counter"><title>Resetting the Counters</title><para><indexterm significance="normal"><primary>IP accounting</primary><secondary>resetting the counters</secondary></indexterm>
The IP accounting counters will overflow if you leave them long enough.
If they overflow, you will have difficulty determining the
value they actually represent. To avoid this problem, you should read
the accounting data periodically, record it, and then reset the counters
back to zero to begin collecting accounting information for the next
accounting interval.</para><para>The <command moreinfo="none">ipfwadm</command> and <command moreinfo="none">ipchains</command> commands provide
you with a means of doing this quite simply:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -A -z</userinput></screen>

or:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -Z</userinput></screen>

or:

<screen format="linespecific"># <userinput moreinfo="none">iptables -Z</userinput></screen>

You can even combine the list and zeroing actions together to ensure that
no accounting data is lost in between:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -A -l -z</userinput></screen>

or:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -L -Z</userinput></screen>

or:

<screen format="linespecific"># <userinput moreinfo="none">iptables -L -Z -v</userinput></screen>

These commands will first list the accounting data and then immediately
zero the counters and begin counting again. If you are interested in
collecting and using this information regularly, you would probably want to
put this command into a script that recorded the output and stored it
somewhere, and execute the script periodically using the
<command moreinfo="none">cron</command> command.</para></sect1><sect1 id="x-087-2-accounting.flushing.rules"><title>Flushing the Ruleset</title><para><indexterm significance="normal"><primary>IP accounting</primary><secondary>flushing the rules</secondary></indexterm>
One last command that might be useful allows you to flush all the IP
accounting rules you have configured. This is most useful when you want to
radically alter your ruleset without rebooting the machine.</para><para>The <literal moreinfo="none">-f</literal> argument in combination with the
<command moreinfo="none">ipfwadm</command> command will flush all of the rules of the type
you specify. <command moreinfo="none">ipchains</command> supports the <literal moreinfo="none">-F</literal>
argument, which does the same:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -A -f</userinput></screen>

or:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -F</userinput></screen>

or:

<screen format="linespecific"># <userinput moreinfo="none">iptables -F</userinput></screen>

This flushes all of your configured IP accounting rules, removing them all
and saving you having to remove each of them individually. Note that flushing
the rules with <command moreinfo="none">ipchains</command> does not cause any user-defined
chains to be removed, only the rules within them.</para><indexterm significance="normal" class="endofrange" startref="ipfwadm.config.ipaccount"></indexterm><indexterm significance="normal" class="endofrange" startref="ipchains.config.ipaccount"></indexterm><indexterm significance="normal" class="endofrange" startref="iptables.config.ipaccount"></indexterm></sect1><sect1 id="x-087-2-accounting.passive.collection"><title>Passive Collection of Accounting Data</title><para><indexterm significance="normal"><primary>IP accounting</primary><secondary>passive collection</secondary></indexterm>
One last trick you might like to consider: if your Linux machine is
connected to an Ethernet, you can apply accounting rules to all of the data
from the segment, not only that which it is transmitted by or destined for it.
Your machine will passively listen to all of the data on the segment and
count it.</para><para>You should first turn IP forwarding off on your Linux machine so
that it doesn't try to route the datagrams it
receives.<footnote id="x-087-2-fnac01"><para>This isn't a good thing to do if your Linux machine serves as a router. If
you disable IP forwarding, it will cease to route! Do this only on a
machine with a single physical network interface.</para></footnote>
In the 2.0.36 and 2.2 kernels, this is a matter of:

<screen format="linespecific"># <userinput moreinfo="none">echo 0 /proc/sys/net/ipv4/ip_forward</userinput></screen></para><para><indexterm significance="normal"><primary>ifconfig command</primary></indexterm>
You should then enable promiscuous mode on your Ethernet interface using the
<command moreinfo="none">ifconfig</command> command. Now you can establish accounting
rules that allow you to collect information about the datagrams flowing
across your Ethernet without involving your Linux in the route at all.</para></sect1><indexterm significance="normal" class="endofrange" startref="chac.tcp.ip.accounting"></indexterm></chapter><chapter id="x-087-2-ipmasq"><title>IP Masquerade and <?lb?>Network Address <?lb?>Translation</title><indexterm significance="normal" class="startofrange" id="chmq.ip.masq"><primary>IP (Internet Protocol)</primary><secondary>masquerade</secondary></indexterm><para>You don't have to have a good memory to remember a time when only large
organizations could afford to have a number of computers networked together
by a LAN. Today network technology has dropped so much in
price that two things have happened. First, LANs are now
commonplace, even in many household environments. Certainly many Linux
users will have two or more computers connected by some Ethernet. 
Second, network resources, particularly IP addresses, are now
a scarce resource and while they used to be free, they are now being bought 
and sold.</para><para>Most people with a LAN will probably also want an Internet
connection that every computer on the LAN can use. The IP routing rules
are quite strict in how they deal with this situation. Traditional solutions
to this problem would have involved requesting an IP network address, perhaps
a class C address for small sites, assigning each host on the LAN an
address from this network and using a router to connect the LAN to the
Internet.</para><para>In a commercialized Internet environment, this is quite an
expensive proposition. First, you'd be required to pay for the network
address that is assigned to you. Second, you'd probably have to pay your
Internet Service Provider for the privilege of having a suitable route
to your network put in place so that the rest of the Internet knows how to
reach you. This might still be practical for companies, but domestic
installations don't usually justify the cost.</para><para><indexterm significance="normal"><primary>NAT (Network Address Translation)</primary></indexterm>
Fortunately, Linux provides an answer to this dilemma.
This answer involves a component of a group of advanced networking features
called <emphasis>Network Address Translation</emphasis> (NAT).
NAT describes the process of modifying the network 
addresses contained with datagram headers while they are in transit. This 
might sound odd at first, but we'll show that it is ideal for solving 
the problem we've just described and many have encountered. IP masquerade 
is the name given to one type of network address translation
that allows all of the hosts on a private network to use the Internet at the
price of a single IP address.</para><para><indexterm significance="normal"><primary>masquerade</primary><secondary>how it works</secondary></indexterm>
<indexterm significance="normal"><primary>datagrams</primary><secondary>masquerading</secondary></indexterm>
IP masquerading allows you to use a private (reserved) IP network
address on your LAN and have your Linux-based router perform some
clever, real-time translation of IP addresses and ports. When it
receives a datagram from a computer on the LAN, it takes note of the
type of datagram it is, TCP, UDP,
ICMP, etc., and modifies the datagram so that it looks
like it was generated by the router machine itself (and remembers that
it has done so). It then transmits the datagram onto the Internet with
its single connected IP address. When the destination host receives
this datagram, it believes the datagram has come from the routing
host and sends any reply datagrams back to that address.  When the
Linux masquerade router receives a datagram from its Internet
connection, it looks in its table of established masqueraded
connections to see if this datagram actually belongs to a computer on
the LAN, and if it does, it reverses the modification it did on the
forward path and transmits the datagram to the LAN computer.</para><para>A simple example is illustrated in <xref linkend="x-087-2-masquerade.net"></xref>.</para><figure float="0" id="x-087-2-masquerade.net"><title>A typical IP masquerade configuration</title><graphic fileref="lag2_1101.jpg"></graphic></figure><para>We have a small Ethernet network using one of the reserved network addresses.
The network has a Linux-based masquerade router providing access to the
Internet. One of the workstations on the network (192.168.1.3) wishes to
establish a connection to the remote host 209.1.106.178 on port 8888. The
workstation routes its datagram to the masquerade router, which identifies
this connection request as requiring masquerade services. It accepts the
datagram and allocates a port number to use (1035), substitutes its own
IP address and port number for those of the originating host, and transmits
the datagram to the destination host. The destination host believes it has
received a connection request from the Linux masquerade host and generates
a reply datagram. The masquerade host, upon receiving this datagram,
finds the association in its masquerade table and reverses the substution
it performed on the outgoing datagram. It then transmits the reply datagram
to the originating host.</para><para>The local host believes it is speaking directly to the remote host. The
remote host knows nothing about the local host at all and believes it has
received a connection from the Linux masquerade host. The Linux masquerade
host knows these two hosts are speaking to each other, and on what ports,
and performs the address and port translations necessary to allow
communication.</para><para>This might all seem a little confusing, and it can be, but it works and
is really quite simple to configure. So don't worry if you don't understand 
all the details yet.</para><sect1 id="x-087-2-masq.side.effects"><title>Side Effects and Fringe Benefits</title><para><indexterm significance="normal"><primary>masquerade</primary><secondary>side effects of</secondary></indexterm>
The IP masquerade facility comes with its own set of side effects, some of
which are useful and some of which might become bothersome.</para><para><?troff .hw specially?>None of the hosts on the supported network behind the masquerade router
are ever directly seen; consequently, you need only one valid and
routable IP address to allow all hosts to make network connections out
onto the Internet. This has a downside; none of those hosts are
visible from the Internet and you can't directly connect to them from
the Internet; the only host visible on a masqueraded network is the
masquerade machine itself. This is important when you consider
services such as mail or FTP. It helps determine what services should
be provided by the masquerade host and what services it should proxy
or otherwise treat specially.</para><para>Second, because none of the masqueraded hosts are visible, they are relatively
protected from attacks from outside; this could simplify or even remove
the need for firewall configuration on the masquerade host. You shouldn't rely
too heavily on this, though. Your whole network will be only as safe as
your masquerade host, so you should use firewall to protect it if security is 
a concern.</para><para>Third, IP masquerade will have some impact on the performance of your
networking. In typical configurations this will probably be barely measurable.
If you have large numbers of active masquerade sessions, though, you may find
that the processing required at the masquerade machine begins to impact 
your network throughput. IP masquerade must do a good deal of work for 
each datagram compared to the process of conventional routing. That
386SX16 machine you have been planning on using as a masquerade machine
supporting a dial-up link to the Internet might be fine, but don't expect
too much if you decide you want to use it as a router in your corporate
network at Ethernet speeds.</para><para>Last, some network services just won't work through masquerade, or at least
not without a lot of help. Typically, these are services that rely on incoming
sessions to work, such as some types of Direct Communications Channels (DCC), 
features in IRC, or certain types of video and audio multicasting services. 
Some of these services have specially developed kernel modules to provide 
solutions for these, and we'll talk about those in a moment. For others, it 
is possible that you will find no support, so be aware,it won't be suitable 
in all situations.</para></sect1><sect1 id="x-087-2-masq.kernel.config"><title>Configuring the Kernel <?lb?>for IP Masquerade</title><para><indexterm significance="normal"><primary>configuring</primary><secondary>kernel</secondary><tertiary sortas="IP masquerade">for IP masquerade</tertiary></indexterm>
<indexterm significance="normal"><primary>masquerade</primary><secondary>kernel configuration</secondary></indexterm>
<indexterm significance="normal"><primary>kernels</primary><secondary>configuring for masquerade</secondary></indexterm>
<?troff .hw kernel?>
<indexterm significance="normal"><primary>2.2 kernels</primary><secondary>IP masquerade</secondary></indexterm>
To use the IP masquerade facility, your kernel must be compiled with masquerade
support. You must select the following options when configuring a 2.2 series
kernel:

<screen format="linespecific">Networking options  ---
	[*] Network firewalls
	[*] TCP/IP networking
	[*] IP: firewalling
	[*] IP: masquerading
	--- Protocol-specific masquerading support will be built as modules.
	[*] IP: ipautofw masq support
	[*] IP: ICMP masquerading</screen>

Note that some of the masquerade support is available only as a kernel module.
This means that you must ensure that you
<literal moreinfo="none">make modules</literal> in addition to the usual
<literal moreinfo="none">make zImage</literal> when building
your kernel.</para><para><indexterm significance="normal"><primary>2.4 kernels</primary><secondary>IP masquerade</secondary></indexterm>
The 2.4 series kernels no longer offer IP masquerade support as a kernel
compile time option. Instead, you should select the network packet
filtering option:

<screen width="80" format="linespecific">Networking options  ---
    [M] Network packet filtering (replaces ipchains)</screen></para><para>In the 2.2 series kernels, a number of protocol-specific helper
modules are created during kernel compilation. Some protocols begin with
an outgoing request on one port, and then expect an incoming connection on
another. Normally these cannot be masqueraded, as there is no way of associating
the second connection with the first without peering inside the protocols
themselves. The helper modules do just that; they actually look inside the
datagrams and allow masquerading to work for supported protocols that
otherwise would be impossible to masquerade. The supported protocols are:

<informaltable><tgroup cols="2"><thead><row><entry>Module</entry><entry>Protocol</entry></row></thead><tbody><row><entry>ip_masq_ftp</entry><entry>FTP</entry></row><row><entry>ip_masq_irc</entry><entry>IRC</entry></row><row><entry>ip_masq_raudio</entry><entry>RealAudio</entry></row><row><entry>ip_masq_cuseeme</entry><entry>CU-See-Me</entry></row><row><entry>ip_masq_vdolive</entry><entry>For VDO Live</entry></row><row><entry>ip_masq_quake</entry><entry>IdSoftware's Quake</entry></row></tbody></tgroup></informaltable>

You must load these modules manually using the <command moreinfo="none">insmod</command> 
command to implement them. Note that these modules cannot be loaded using
the <command moreinfo="none">kerneld</command> daemon. Each of the modules takes an argument
specifying what ports it will listen on. For the
RealAudio module you might use:<footnote id="x-087-2-mq01"><para>RealAudio is a trademark of the Progressive Networks Corporation.</para></footnote>
<screen format="linespecific"># <userinput moreinfo="none">insmod ip_masq_raudio.o ports=7070,7071,7072</userinput>           </screen>

The ports you need to specify depend on the protocol. An IP masquerade
mini-HOWTO written by Ambrose Au explains more about the IP masquerade modules
and how to configure them.<footnote id="x-087-2-fnmq02"><para>You can contact Ambrose at
<systemitem moreinfo="none" role="email">ambrose@writeme.com</systemitem>.</para></footnote></para><para>The <emphasis>netfilter</emphasis> package includes modules that perform
similar functions. For example, to provide connection tracking of FTP
sessions, you'd load and use the <filename moreinfo="none">ip_conntrack_ftp</filename> and
<filename moreinfo="none">ip_nat_ftp.o</filename> modules.</para></sect1><sect1 id="x-087-2-masq.configuration"><title>Configuring IP Masquerade</title><para><indexterm significance="normal"><primary>masquerade</primary><secondary>configuration</secondary></indexterm>
<indexterm significance="normal"><primary>configuring</primary><secondary>IP masquerade</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="ipfwadm.config.masq"><primary>ipfwadm command</primary><secondary>configuring IP masquerade</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="ipchains.config.masq"><primary>ipchains command</primary><secondary>configuring IP masquerade</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="iptables.config.masq"><primary>iptables command</primary><secondary>configuring IP masquerade</secondary></indexterm>
If you've already read the firewall and accounting chapters, it
probably comes as no surprise that the <command moreinfo="none">ipfwadm</command>,
<command moreinfo="none">ipchains</command>, and <command moreinfo="none">iptables</command> commands
are used to configure the IP masquerade rules as well.</para><para>Masquerade rules are a special class of filtering rule. You can
masquerade only datagrams that are received on one interface that will
be routed to another interface. To configure a masquerade rule you
construct a rule very similar to a firewall forwarding rule, but with
special options that tell the kernel to masquerade the datagram. The
<command moreinfo="none">ipfwadm</command> command uses the <emphasis>-m</emphasis>
option, <command moreinfo="none">ipchains</command> uses <literal moreinfo="none">-j MASQ</literal>, and <command moreinfo="none">iptables</command> uses
<literal moreinfo="none">-j MASQUERADE</literal> to
indicate that datagrams matching the rule specification should be
masqueraded.</para><?troff .wcon_off?><para>Let's look at an example.
A computing science student at Groucho Marx University has a number of
computers at home internetworked onto a small Ethernet-based local area
network. She has chosen to use one of the reserved private Internet network
addresses for her network. She shares her accomodation with other students,
all of whom have an interest in using the Internet. Because student living 
conditions are very frugal, they cannot afford to use a permanent Internet 
connection, so instead they use a simple dial-up PPP Internet connection. 
They would all like to be able<?troff .ne 10?>
to share the connection to chat on IRC, surf 
the Web, and retrieve files by FTP directly to each of their computersIP 
masquerade is the answer.</para><para>The student first configures a Linux machine to support the dial-up link and to
act as a router for the LAN. The IP address she is assigned when she dials up
isn't important. She configures the Linux router with IP masquerade and uses 
one of the private network addresses for her LAN: 
<literal moreinfo="none">192.168.1.0</literal>. She ensures that each of the hosts on the 
LAN has a default route pointing at the Linux router.</para><para>The following <command moreinfo="none">ipfwadm</command> commands are all that are required to
make masquerading work in her configuration:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -F -p deny</userinput>
# <userinput moreinfo="none">ipfwadm -F -a accept -m -S 192.168.1.0/24 -D 0/0</userinput></screen>

or with <command moreinfo="none">ipchains</command>:

<screen format="linespecific"># <userinput moreinfo="none">ipchains -P forward -j deny</userinput>
# <userinput moreinfo="none">ipchains -A forward -s 192.168.1.0/24 -d 0/0 -j MASQ</userinput></screen>

or with <command moreinfo="none">iptables</command>:

<screen format="linespecific"># <userinput moreinfo="none">iptables -t nat -P POSTROUTING DROP</userinput>
# <userinput moreinfo="none">iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE</userinput> </screen>

Now whenever any of the LAN hosts try to connect to a service on a
remote host, their datagrams will be automatically masqueraded by the
Linux masquerade router. The first rule in each example prevents the
Linux machine from routing any other datagrams and also adds some
security.</para><para><indexterm significance="normal"><primary>masquerade</primary><secondary>listing rules</secondary></indexterm>
To list the masquerade rules you have created, use the <literal moreinfo="none">-l</literal> 
argument to the <command moreinfo="none">ipfwadm</command>
command, as we described in earlier while discussing firewalls.</para><para>To list the rule we created earlier we use:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -F -l -e</userinput></screen>

which should display something like:

<screen format="linespecific"># <userinput moreinfo="none">ipfwadm -F -l -e</userinput>
IP firewall forward rules, default policy: accept
 pkts bytes type  prot opt  tosa tosx ifname  ifaddress  
    0     0 acc/m all  ---- 0xFF 0x00 any     any        </screen>

The <literal moreinfo="none">/m</literal> in the output indicates this is a
masquerade rule.</para><para>To list the masquerade rules with the <command moreinfo="none">ipchains</command> command, 
use the <command moreinfo="none">-L</command> argument. If we list the rule
we created earlier with <command moreinfo="none">ipchains</command>, the output will look like:

<screen format="linespecific"><userinput moreinfo="none"># ipchains -L</userinput>
Chain input (policy ACCEPT):
Chain forward (policy ACCEPT):
target     prot opt     source                destination           ports
MASQ       all  ------  192.168.1.0/24        anywhere              n/a

Chain output (policy ACCEPT):</screen></para><para>Any rules with a target of <literal moreinfo="none">MASQ</literal> are masquerade rules.</para><para>Finally, to list the rules using <command moreinfo="none">iptables</command> you need to use:

<screen width="98" format="linespecific"># <userinput moreinfo="none">iptables -t nat -L</userinput>
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy DROP)
target     prot opt source               destination         
MASQUERADE  all  --  anywhere             anywhere           MASQUERADE 

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         </screen>

Again, masquerade rules appear with a target of <literal moreinfo="none">MASQUERADE</literal>.</para><sect2 id="x-087-2-masq.setting.timing"><title>Setting Timing Parameters for IP Masquerade</title><para><indexterm significance="normal"><primary>masquerade</primary><secondary>setting timing parameters for</secondary></indexterm>
When each new connection is established, the IP masquerade software
creates an association in memory between each of the hosts involved in
the connection.  You can view these associations at any time by
looking at the <filename moreinfo="none">/proc/net/ip_masquerade</filename> file.
These associations will timeout after a period of inactivity, though.</para><para><indexterm significance="normal" class="endofrange" startref="ipfwadm.config.masq"></indexterm>
You can set the timeout values using the <command moreinfo="none">ipfwadm</command> command.
The general syntax for this is:

<screen format="linespecific">ipfwadm -M -s <replaceable>tcp</replaceable> <replaceable>tcpfin</replaceable> <replaceable>udp</replaceable></screen></para><para><indexterm significance="normal" class="endofrange" startref="ipchains.config.masq"></indexterm>
and for the <command moreinfo="none">ipchains</command> command it is:

<screen format="linespecific">ipchains -M -S <replaceable>tcp</replaceable> <replaceable>tcpfin</replaceable> <replaceable>udp</replaceable></screen></para><para>The <emphasis>iptables</emphasis> implementation uses much longer default
timers and does not allow you to set them.</para><para><?troff .hw meanings?>Each of these values represents a timer used by the IP masquerade software and
are in units of seconds. The following table summarizes the timers and their
meanings:</para><informaltable><tgroup cols="2"><colspec colnum="2" colwidth="3.57i"></colspec><thead><row><entry>Name</entry><entry>Description</entry></row></thead><tbody><row><entry>tcp</entry><entry><para>	TCP session timeout. How long a TCP connection may remain idle before the
	association for it is removed.
	</para></entry></row><row><entry>tcpfin</entry><entry><para>        <?troff .hw disconnected?>
	TCP timeout after FIN. How long an association will remain
	after a TCP connection has been disconnected.
	</para></entry></row><row><entry>udp</entry><entry><para>	UDP session timeout. How long a UDP connection may remain idle before the
	association for it is removed.
	</para></entry></row></tbody></tgroup></informaltable></sect2></sect1><sect1 id="x-087-2-masq.namelookups"><title>Handling Name Server Lookups</title><para><indexterm significance="normal"><primary>masquerade</primary><secondary>name server lookups</secondary></indexterm>
<indexterm significance="normal"><primary>name servers</primary><secondary>for IP masquerade</secondary></indexterm>
Handling domain name server lookups from the hosts on the LAN with IP
masquerading has always presented a problem. There are two ways of
accomodating DNS in a masquerade environment. You can tell each of the
hosts that they use the same DNS that the Linux router machine does,
and let IP masquerade do its magic on their DNS
requests. Alternatively, you can run a caching name server on the
Linux machine and have each of the hosts on the LAN use the Linux
machine as their DNS. Although a more aggressive action, this is
probably the better option because it reduces the volume of DNS
traffic travelling on the Internet link and will be marginally faster
for most requests, since they'll be served from the cache. The downside
to this configuration is that it is more complex. <xref linkend="x-087-2-resolv.named-cachingonly"></xref>, in Chapter 6, describes how to configure
a caching name server.</para></sect1><sect1><title>More About Network Address Translation</title><para><indexterm significance="normal"><primary>NAT (Network Address Translation)</primary></indexterm>
The <emphasis>netfilter</emphasis> software is capable of many different types
of Network Address Translation. IP Masquerade is one simple application of it.</para><para>It is possible, for example, to build NAT rules that translate only certain
addresses or ranges of addresses and leave all others untouched, or to
translate addresses into pools of addresses rather than just a single address,
as masquerade does. You can in fact use the <command moreinfo="none">iptables</command> command
to generate NAT rules that map just about anything, with
combinations of matches using any of the standard attributes, such as source
address, destination address, protocol type, port number, etc.</para><para><indexterm significance="normal" class="endofrange" startref="iptables.config.masq"></indexterm>
Translating the Source Address of a datagram is referred to as Source
NAT, or <literal moreinfo="none">SNAT</literal>, in the <emphasis>netfilter</emphasis>
documentation. Translating the Destination Address of a datagram is known as
Destination NAT, or <literal moreinfo="none">DNAT</literal>. Translating the TCP
or UDP port is known by the term <literal moreinfo="none">REDIRECT</literal>. 
<literal moreinfo="none">SNAT</literal>, <literal moreinfo="none">DNAT</literal>, and
<literal moreinfo="none">REDIRECT</literal> are targets that you may use with the
<command moreinfo="none">iptables</command> command to build more complex and sophisticated
rules.</para><para><indexterm significance="normal"><primary>IPTABLES-HOWTO</primary></indexterm>
<indexterm significance="normal"><primary>HOWTOs</primary><secondary>IPTABLES</secondary></indexterm>
The topic of Network Address Translation and its uses warrants at least a
whole chapter of its own.<footnote><para>... and perhaps even a whole book!</para></footnote> Unfortunately we don't have the space in this book to cover it in
any greater depth. You should read the IPTABLES-HOWTO for more information, if
you're interested in discovering more about how you might use Network Address 
Translation.</para></sect1><indexterm significance="normal" class="endofrange" startref="chmq.ip.masq"></indexterm></chapter><chapter id="x-087-2-appl"><title>Important<?lb?>Network Features</title><para>After successfully setting up IP and the resolver, you then must look at
the services you want to provide over the network. This chapter covers the
configuration of a few simple network applications, including the
<command moreinfo="none">inetd</command> server and the programs from the
<command moreinfo="none">rlogin</command> family. We'll also deal briefly with the Remote
Procedure Call interface, upon which services like the Network File System (NFS)
and the Network Information System (NIS) are based. The configuration of
NFS and NIS, however, is more complex and are described in separate
chapters, as are electronic mail and network news.</para><para>Of course, we can't cover all network applications in this book. If you
want to install one that's not discussed here, like <command moreinfo="none">talk</command>,
<command moreinfo="none">gopher</command>, or <command moreinfo="none">http</command>, please refer to
the manual pages of the server for details.</para><sect1 id="x-087-2-appl.inetd"><title>The inetd Super Server</title><indexterm significance="normal" class="startofrange" id="chfe.inetd.svr"><primary>inetd super server</primary></indexterm><indexterm significance="normal"><primary>services</primary><secondary>setting up</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-servercommandinetd"><primary>servers</primary><secondary>inetd</secondary></indexterm><indexterm significance="normal"><primary>configuring</primary><secondary>networks</secondary><tertiary>services</tertiary></indexterm><indexterm significance="normal"><primary>daemons</primary></indexterm><indexterm significance="normal"><primary>Internet</primary><secondary>daemon</secondary></indexterm><para>Programs that provide application services via the network are called
network <emphasis>daemons</emphasis>. A daemon is a program that opens a
port, most commonly a well-known service port, and waits for incoming
connections on it. If one occurs, the daemon creates a child process that 
accepts the connection, while the parent continues to listen for further
requests. This mechanism works well, but has a few disadvantages; at
least one instance of every possible service you wish to provide must be
active in memory at all times. In addition, the software routines that 
do the listening and port handling must be replicated in every network daemon.</para><para>To overcome these inefficiencies, most Unix installations run a special
network daemon, what you might consider a super server. This
daemon creates sockets on behalf of a number of services and listens on
all of them simultaneously. When an incoming connection is received on
any of these sockets, the super server accepts the connection and spawns
the server specified for this port, passing the socket across to the child
to manage. The server then returns to listening.</para><para><indexterm significance="normal" class="startofrange" id="idx-filenameinetdconf"><primary>inetd.conf file</primary></indexterm>
<indexterm significance="normal"><primary>chargen (internal service)</primary></indexterm>
<indexterm significance="normal"><primary>daytime (internal service)</primary></indexterm>
The most common super server is called <command moreinfo="none">inetd</command>,
the Internet Daemon. It is started at system boot time and takes the list
of services it is to manage from a startup file named
<filename moreinfo="none">/etc/inetd.conf</filename>. In addition to those servers,
there are a number of trivial services performed by <command moreinfo="none">inetd</command>
itself called <emphasis>internal services</emphasis>. They include
<command moreinfo="none">chargen</command>, which simply generates a string of characters,
and <command moreinfo="none">daytime</command>, which returns the system's idea of the time
of day.</para><para>An entry in this file consists of a single line made up of the
following fields:

<screen format="linespecific"><replaceable>service</replaceable> <replaceable>type</replaceable> <replaceable>protocol</replaceable> <replaceable>wait</replaceable> <replaceable>user</replaceable> <replaceable>server</replaceable> <replaceable>cmdline</replaceable></screen></para><para>Each of the fields is described in the following list:</para><variablelist><varlistentry><term><replaceable>service</replaceable></term><listitem><para>Gives the service name. The service name has to be translated to a port
number by looking it up in the <filename moreinfo="none">/etc/services</filename> file. This
file will be described later in this chapter in the section <xref linkend="x-087-2-appl.services"></xref>.</para></listitem></varlistentry><varlistentry><term><replaceable>type</replaceable></term><listitem><para>Specifies a socket type, either <systemitem moreinfo="none" role="keyword">stream</systemitem>
(for connection-oriented protocols) or
<systemitem moreinfo="none" role="keyword">dgram</systemitem> (for datagram protocols).
TCP-based services should therefore always use
<systemitem moreinfo="none" role="keyword">stream</systemitem>, while UDP-based services
should always use <systemitem moreinfo="none" role="keyword">dgram</systemitem>.</para></listitem></varlistentry><varlistentry><term><replaceable>protocol</replaceable></term><listitem><para>Names the transport protocol used by the service. This must be a valid
protocol name found in the <filename moreinfo="none">protocols</filename> file, explained
later.</para></listitem></varlistentry><varlistentry><term><replaceable>wait</replaceable></term><listitem><para>This option applies only to <systemitem moreinfo="none" role="keyword">dgram</systemitem>
sockets. It can be either <systemitem moreinfo="none" role="keyword">wait</systemitem> or
<systemitem moreinfo="none" role="keyword">nowait</systemitem>. If
<systemitem moreinfo="none" role="keyword">wait</systemitem> is specified,
<command moreinfo="none">inetd</command> executes only one server for the specified
port at any time. Otherwise, it immediately continues to listen on
the port after executing the server.</para><para>This is useful for single-threaded servers that read all
incoming datagrams until no more arrive, and then exit. Most RPC servers
are of this type and should therefore specify
<systemitem moreinfo="none" role="keyword">wait</systemitem>. The opposite type,
multi-threaded servers, allow an unlimited number of
instances to run concurrently. These servers should specify
<systemitem moreinfo="none" role="keyword">nowait</systemitem>.</para><para><systemitem moreinfo="none" role="keyword">stream</systemitem> sockets should always use
<systemitem moreinfo="none" role="keyword">nowait</systemitem>.</para></listitem></varlistentry><varlistentry><term><replaceable>user</replaceable></term><listitem><para>This is the login ID of the user who will own the process when it is
executing. This will frequently be the <systemitem moreinfo="none" role="userid">root</systemitem>
user, but some services may use different accounts. It is a very good idea to
apply the principle of least privilege here, which states that you shouldn't
run a command under a privileged account if the program doesn't require this for
proper functioning. For example, the NNTP news server runs as
<systemitem moreinfo="none" role="userid">news</systemitem>, while services that may pose
a security risk (such as <command moreinfo="none">tftp</command> or <command moreinfo="none">finger</command>)
are often run as <systemitem moreinfo="none" role="userid">nobody</systemitem>.</para></listitem></varlistentry><varlistentry><term><replaceable>server</replaceable></term><listitem><para>Gives the full pathname of the server program to be executed. Internal
services are marked by the keyword
<systemitem moreinfo="none" role="keyword">internal</systemitem>.</para></listitem></varlistentry><varlistentry><term><replaceable>cmdline</replaceable></term><listitem><para>This is the command line to be passed to the server. It starts with the
name of the server to be executed and can include any arguments that need
to be passed to it. If you are using the TCP wrapper, you specify
the full pathname to the server here. If not, then you just specify the
server name as you'd like it to appear in a process list. We'll talk about
the TCP wrapper shortly.</para><para>This field is empty for internal services.</para></listitem></varlistentry></variablelist><para><indexterm significance="normal"><primary>security</primary><secondary>TCP servers</secondary></indexterm>
<indexterm significance="normal"><primary>finger daemon</primary></indexterm>
A sample <filename moreinfo="none">inetd.conf</filename> file is shown in
<xref linkend="x-087-2-appl.fig.inetd.conf"></xref>. The <command moreinfo="none">finger</command>
service is commented out so that it is not available. This is often done
for security reasons, because it can be used by attackers to obtain names
and other details of users on your system.</para><example id="x-087-2-appl.fig.inetd.conf"><title>A Sample /etc/inetd.conf File</title><screen format="linespecific"># 
# inetd services
ftp      stream tcp nowait root  /usr/sbin/ftpd    in.ftpd -l
telnet   stream tcp nowait root  /usr/sbin/telnetd in.telnetd -b/etc/issue
#finger  stream tcp nowait bin   /usr/sbin/fingerd in.fingerd
#tftp    dgram  udp wait  nobody /usr/sbin/tftpd   in.tftpd
#tftp    dgram  udp wait  nobody /usr/sbin/tftpd   in.tftpd /boot/diskless
#login   stream tcp nowait root  /usr/sbin/rlogind in.rlogind
#shell   stream tcp nowait root  /usr/sbin/rshd    in.rshd
#exec    stream tcp nowait root  /usr/sbin/rexecd  in.rexecd
#
#       inetd internal services
#
daytime  stream tcp nowait root internal
daytime  dgram  udp nowait root internal
time     stream tcp nowait root internal
time     dgram  udp nowait root internal
echo     stream tcp nowait root internal
echo     dgram  udp nowait root internal
discard  stream tcp nowait root internal
discard  dgram  udp nowait root internal
chargen  stream tcp nowait root internal
chargen  dgram  udp nowait root internal</screen></example><para><indexterm significance="normal"><primary>TFTP (Trivial File Transfer Protocol)</primary></indexterm>
<indexterm significance="normal"><primary sortas="etc/passwd file">/etc/passwd file</primary></indexterm> 
The <command moreinfo="none">tftp</command> daemon is shown commented out as well.
<command moreinfo="none">tftp</command> implements the <emphasis>Trivial File Transfer
Protocol</emphasis> (TFTP), which allows someone to transfer any
world-readable files from your system without password checking.
This is especially harmful with the <filename moreinfo="none">/etc/passwd</filename> file, and even more so when you don't use shadow passwords.</para><para>TFTP is commonly used by diskless clients and Xterminals to download their
code from a boot server. If you need to run <command moreinfo="none">tftpd</command> for this
reason, make sure to limit its scope to those directories from which clients 
will retrieve files; you will need to add those directory names to
<command moreinfo="none">tftpd</command>'s command line. This is shown in the second
<command moreinfo="none">tftp</command> line in the example.
<indexterm significance="normal" class="endofrange" startref="idx-servercommandinetd"></indexterm>
<indexterm significance="normal" class="endofrange" startref="chfe.inetd.svr"></indexterm> 
<indexterm significance="normal" class="endofrange" startref="idx-filenameinetdconf"></indexterm></para></sect1><sect1 id="x-087-2-appl.tcpd"><title>The tcpd Access Control Facility</title><indexterm significance="normal"><primary>security</primary><secondary>TCP servers</secondary></indexterm><indexterm significance="normal"><primary>services</primary><secondary>restricting access to</secondary></indexterm><indexterm significance="normal"><primary>access</primary><secondary>restricting</secondary></indexterm><indexterm significance="normal"><primary>restricting access to services</primary></indexterm><indexterm significance="normal"><primary>wrapper, TCP</primary></indexterm><indexterm significance="normal"><primary>TCP (Transmission Control Protocol)</primary><secondary>wrapper program</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-commandtcpdcommand-1"><primary>tcpd daemon wrapper</primary></indexterm><indexterm significance="normal" class="startofrange" id="idx-servercommandtcpdcommand-1"><primary>servers</primary><secondary>tcpd daemon wrapper</secondary></indexterm><indexterm significance="normal"><primary>daemons</primary><secondary>wrapping via tcpd</secondary></indexterm><para>Since opening a computer to network access involves many security risks,
applications are designed to guard against several types of attacks. Some
security features, however, may be flawed (most drastically demonstrated by the
RTM Internet worm, which exploited a hole in a number of programs, including old
versions of the sendmail mail daemon), or do not distinguish between secure
hosts from which requests for a particular service will be accepted and
insecure hosts whose requests should be rejected. We've already briefly
discussed the <command moreinfo="none">finger</command> and <command moreinfo="none">tftp</command> services.
Network Administrator would want to limit access to these services to 
trusted hosts only, which is impossible with the usual setup, 
for which <command moreinfo="none">inetd</command> provides this service either to all clients 
or not at all.</para><para>A useful tool for managing host-specific access is <command moreinfo="none">tcpd</command>,
often called the daemon
wrapper.<footnote id="x-087-2-fnfe01"><para>Written by Wietse Venema,
<systemitem moreinfo="none" role="emailaddr">wietse@wzv.win.tue.nl</systemitem>.</para></footnote>
For TCP services you want to monitor or protect, it is invoked instead of the
server program. <command moreinfo="none">tcpd</command> checks if the remote host is allowed 
to use that service, and only if this succeeds will it execute the real server
program. <command moreinfo="none">tcpd</command> also logs the request to the 
<command moreinfo="none">syslog</command> daemon. Note that this does not work with 
UDP-based services.</para><para><indexterm significance="normal"><primary>finger daemon</primary><secondary>wrapping via tcpd</secondary></indexterm> 
For example, to wrap the <command moreinfo="none">finger</command> daemon, you have to change
the corresponding line in <filename moreinfo="none">inetd.conf</filename> from this:

<screen format="linespecific"># unwrapped finger daemon
finger    stream tcp nowait bin    /usr/sbin/fingerd in.fingerd</screen>

to this:

<screen format="linespecific"># wrap finger daemon
finger  stream  tcp     nowait  root    /usr/sbin/tcpd   in.fingerd</screen></para><para><indexterm significance="normal"><primary>syslog</primary></indexterm>
Without adding any access control, this will appear to the client as
the usual <command moreinfo="none">finger</command> setup, except that any requests are logged
to <command moreinfo="none">syslog</command>'s <emphasis>auth</emphasis>
facility.</para><para><indexterm significance="normal"><primary sortas="etc/hosts.allow file">/etc/hosts.allow file</primary></indexterm> 
<indexterm significance="normal"><primary sortas="etc/hosts.deny file">/etc/hosts.deny file</primary></indexterm> 
Two files called <filename moreinfo="none">/etc/hosts.allow</filename> and 
<filename moreinfo="none">/etc/hosts.deny</filename> implement access control.
They contain entries that allow and deny access to certain services and hosts.
When <command moreinfo="none">tcpd</command> handles a request for a service such as
<command moreinfo="none">finger</command> from a client host named
<systemitem moreinfo="none" role="sitename">biff.foobar.com</systemitem>, it scans
<filename moreinfo="none">hosts.allow</filename> and <filename moreinfo="none">hosts.deny</filename>
(in this order) for an entry matching both the service and client host.
If a matching entry is found in <filename moreinfo="none">hosts.allow</filename>, access
is granted and <command moreinfo="none">tcpd</command> doesn't consult the
<filename moreinfo="none">hosts.deny</filename> file. If no match is found in the
<filename moreinfo="none">hosts.allow</filename> file, but a match is found in
<filename moreinfo="none">hosts.deny</filename>, the request is rejected by closing down the
connection. The request is accepted if no match is found at all.</para><para>Entries in the access files look like this:

<screen format="linespecific"><replaceable>servicelist</replaceable>: <replaceable>hostlist</replaceable> [:<replaceable>shellcmd</replaceable>]</screen></para><para><replaceable>servicelist</replaceable> is a list of service names from
<filename moreinfo="none">/etc/services</filename>, or the keyword
<systemitem moreinfo="none" role="keyword">ALL</systemitem>. To match all services except
<command moreinfo="none">finger</command> and <command moreinfo="none">tftp</command>, use
<systemitem moreinfo="none" role="keyword">ALL</systemitem>
<systemitem moreinfo="none" role="keyword">EXCEPT</systemitem>
<literal moreinfo="none">finger, tftp</literal>.</para><para><replaceable>hostlist</replaceable> is a list of hostnames, IP addresses,
or the keywords <systemitem moreinfo="none" role="keyword">ALL</systemitem>,
<systemitem moreinfo="none" role="keyword">LOCAL</systemitem>,
<systemitem moreinfo="none" role="keyword">UNKNOWN</systemitem> or
<systemitem moreinfo="none" role="keyword">PARANOID</systemitem>.
<systemitem moreinfo="none" role="keyword">ALL</systemitem> matches any host, while
<systemitem moreinfo="none" role="keyword">LOCAL</systemitem> matches hostnames that don't 
contain a dot.<footnote id="x-087-2-fnfe02"><para>Usually only local hostnames obtained from lookups in
<filename moreinfo="none">/etc/hosts</filename> contain no dots.</para></footnote>

<systemitem moreinfo="none" role="keyword">UNKNOWN</systemitem> matches any hosts whose name
or address lookup failed. <systemitem moreinfo="none" role="keyword">PARANOID</systemitem>
matches any host whose hostname does not resolve back to its IP
address.<footnote id="x-087-2-fnfe03"><para>While its name suggests it is an extreme measure, the <systemitem moreinfo="none" role="keyword">PARANOID</systemitem> keyword is
a good default, as it protects you against mailicious hosts pretending to
be someone they are not. Not all <command moreinfo="none">tcpd</command> are supplied with
<systemitem moreinfo="none" role="keyword">PARANOID</systemitem> compiled in; if yours is not, you need to recompile
<command moreinfo="none">tcpd</command> to use it.</para></footnote>

A name starting with a dot matches all hosts whose domain is equal to this
name. For example, <systemitem moreinfo="none" role="sitename">.foobar.com</systemitem> matches
<systemitem moreinfo="none" role="sitename">biff.foobar.com</systemitem>, but not
<systemitem moreinfo="none" role="sitename">nurks.fredsville.com</systemitem>. A pattern that
ends with a dot matches any host whose IP address begins with the supplied
pattern, so <systemitem moreinfo="none" role="sitename">172.16.</systemitem> matches
<systemitem moreinfo="none" role="sitename">172.16.32.0</systemitem>, but not
<systemitem moreinfo="none" role="sitename">172.15.9.1</systemitem>. A pattern of the form
<literal moreinfo="none"><replaceable>n.n.n.n</replaceable>/<replaceable>m.m.m.m</replaceable></literal><emphasis></emphasis> is treated as an IP address and network mask, so we could specify
our previous example as
<systemitem moreinfo="none" role="sitename">172.16.0.0/255.255.0.0</systemitem> instead.
Lastly, any pattern beginning with a / character allows you to
specify a file that is presumed to contain a list of hostname or IP address
patterns, any of which are allowed to match. So a pattern that looked like
<emphasis>/var/access/trustedhosts</emphasis> would cause
the <command moreinfo="none">tcpd</command> daemon to read that file, testing if any of the
lines in it matched the connecting host.</para><para>To deny access to the <command moreinfo="none">finger</command> and <command moreinfo="none">tftp</command>
services to all but the local hosts, put the following in
<filename moreinfo="none">/etc/hosts.deny</filename> and leave
<filename moreinfo="none">/etc/hosts.allow</filename> empty:

<screen format="linespecific">in.tftpd, in.fingerd: ALL EXCEPT LOCAL, <replaceable>.your.domain</replaceable></screen></para><para>The optional <replaceable>shellcmd</replaceable> field may contain a shell
command to be invoked when the entry is matched. This is useful to set up
traps that may expose potential attackers. The following example creates
a log file listing the user and host connecting, and if the host is not
<emphasis role="bold">vlager.vbrew.com</emphasis> it will append the
output of a <command moreinfo="none">finger</command> to that host:

<screen format="linespecific">in.ftpd: ALL EXCEPT LOCAL, .vbrew.com : \
      echo "request from %d@%h:  /var/log/finger.log; \
      if [ %h != "vlager.vbrew.com:" ]; then \ 
          finger -l @%h  /var/log/finger.log \
      fi</screen></para><para>The <systemitem moreinfo="none" role="keyword">%h</systemitem> and
<systemitem moreinfo="none" role="keyword">%d</systemitem> arguments are expanded by
<command moreinfo="none">tcpd</command> to the client hostname and service name,
respectively. Please refer to the <filename moreinfo="none">hosts_access(5)</filename>
manual page for details.

<indexterm significance="normal" class="endofrange" startref="idx-commandtcpdcommand-1"></indexterm>
<indexterm significance="normal" class="endofrange" startref="idx-servercommandtcpdcommand-1"></indexterm></para></sect1><sect1 id="x-087-2-appl.services"><title>The Services and Protocols Files</title><indexterm significance="normal" class="startofrange" id="idx-filenameservicesfilename-1"><primary>services file</primary></indexterm><indexterm significance="normal" class="startofrange" id="idx-filenameprotocolsfilename-1"><primary>protocols file</primary></indexterm><indexterm significance="normal"><primary>services</primary><secondary>well-known</secondary></indexterm><indexterm significance="normal"><primary sortas="etc/services file">/etc/services file</primary></indexterm><para>The port numbers on which certain standard services are
offered are defined in the Assigned Numbers RFC. To enable server and client
programs to convert service names to these numbers, at least part of
the list is kept on each host; it is stored in a file called
<filename moreinfo="none">/etc/services</filename>.  An entry is made up like this:

<screen format="linespecific"><replaceable>service</replaceable> <replaceable>port</replaceable>/<replaceable>protocol</replaceable>   [<replaceable>aliases</replaceable>]</screen></para><para>Here, <replaceable>service</replaceable> specifies the service name,
<replaceable>port</replaceable> defines the port the service is offered on,
and <replaceable>protocol</replaceable> defines which transport protocol
is used. Commonly, the latter field is either
<replaceable>udp</replaceable> or
<replaceable>tcp</replaceable>. It is possible for a service to be
offered for more than one protocol, as well as offering different services on
the same port as long as the protocols are different. The
<replaceable>aliases</replaceable> field allows you to specify alternative
names for the same service.</para><para>Usually, you don't have to change the services file that comes along
with the network software on your Linux system. Nevertheless, we give a
small excerpt from that file in <xref linkend="x-087-2-etc.services"></xref>.</para><example id="x-087-2-etc.services"><title>A Sample /etc/services File</title><screen format="linespecific"># The services file:
#
# well-known services
echo           7/tcp                 # Echo
echo           7/udp                 #
discard        9/tcp  sink null      # Discard
discard        9/udp  sink null      #
daytime       13/tcp                 # Daytime
daytime       13/udp                 #
chargen       19/tcp  ttytst source  # Character Generator
chargen       19/udp  ttytst source  #
ftp-data      20/tcp                 # File Transfer Protocol (Data)
ftp           21/tcp                 # File Transfer Protocol (Control)
telnet        23/tcp                 # Virtual Terminal Protocol
smtp          25/tcp                 # Simple Mail Transfer Protocol
nntp         119/tcp  readnews       # Network News Transfer Protocol
#
# UNIX services
exec         512/tcp                 # BSD rexecd
biff         512/udp  comsat         # mail notification
login        513/tcp                 # remote login
who          513/udp  whod           # remote who and uptime
shell        514/tcp  cmd            # remote command, no passwd used
syslog       514/udp                 # remote system logging
printer      515/tcp  spooler        # remote print spooling
route        520/udp  router routed  # routing information protocol</screen></example><para><indexterm significance="normal"><primary>echo service</primary></indexterm> 
Note that the <command moreinfo="none">echo</command> service is offered on port 7 for both 
TCP and UDP, and that port 512 is used for two
different services: remote execution (<command moreinfo="none">rexec</command>) using TCP,
and the <command moreinfo="none">COMSAT</command> daemon, which notifies users of new mail, over UDP
(see <command moreinfo="none">xbiff(1x)</command>).</para><para><indexterm significance="normal"><primary sortas="etc/protocols file">/etc/protocols file</primary></indexterm> 
<indexterm significance="normal"><primary>protocol numbers</primary></indexterm>
Like the services file, the networking library needs a way to translate
protocol namesfor example, those used in the services fileto
protocol numbers understood by the IP layer on other hosts. This is done by
looking up the name in the <filename moreinfo="none">/etc/protocols</filename> file. It
contains one entry per line, each containing a protocol name, and the
associated number. Having to touch this file is even more unlikely than
having to meddle with <filename moreinfo="none">/etc/services</filename>. A sample file
is given in <xref linkend="x-087-2-etc.protocols"></xref>.</para><example id="x-087-2-etc.protocols"><title>A Sample /etc/protocols File</title><screen format="linespecific">#
# Internet (IP) protocols
#
ip      0       IP              # internet protocol, pseudo protocol number
icmp    1       ICMP            # internet control message protocol
igmp    2       IGMP            # internet group multicast protocol
tcp     6       TCP             # transmission control protocol
udp     17      UDP             # user datagram protocol
raw     255     RAW             # RAW IP interface</screen></example><indexterm significance="normal" class="endofrange" startref="idx-filenameservicesfilename-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-filenameprotocolsfilename-1"></indexterm></sect1><sect1 id="x-087-2-appl.rpc"><title>Remote Procedure Call</title><indexterm significance="normal"><primary>RPC (Remote Procedure Call)</primary></indexterm><para>The general mechanism for client-server applications is provided by the
<emphasis>Remote Procedure Call</emphasis> (RPC) package. RPC was developed by Sun
Microsystems and is a collection of tools and library functions. Important
applications built on top of RPC are NIS, the Network Information System 
(described in <xref linkend="x-087-2-nis"></xref>), and NFS, the Network File System 
(described in <xref linkend="x-087-2-nfs"></xref>), which are both described in 
this book.</para><para><indexterm significance="normal"><primary>XDR (External Data Representation)</primary></indexterm>
<indexterm significance="normal"><primary>External Data Representation (XDR)</primary></indexterm>
An RPC server consists of a collection of procedures that a client can call
by sending an RPC request to the server along with the procedure parameters.
The server will invoke the indicated procedure on behalf of the client,
handing back the return value, if there is any. In order to be
machine-independent, all data exchanged between client and server is
converted to the <emphasis>External Data Representation</emphasis> format
(XDR) by the sender, and converted back to the machine-local representation
by the receiver. RPC relies on standard UDP and TCP sockets to transport the
XDR formatted data to the remote host. Sun has graciously placed RPC in the
public domain; it is described in a series of RFCs.</para><para>Sometimes improvements to an RPC application introduce incompatible changes
in the procedure call interface. Of course, simply changing the server would
crash all applications that still expect the original behavior. Therefore,
RPC programs have version numbers assigned to them, usually starting with 1,
and with each new version of the RPC interface, this counter will be bumped up.
Often, a server may offer several versions simultaneously; clients then
indicate by the version number in their requests which implementation of
the service they want to use.</para><para><indexterm significance="normal"><primary>rpc file</primary></indexterm>
<indexterm significance="normal"><primary>RPC (Remote Procedure Call)</primary><secondary>program numbers</secondary></indexterm>
The communication between RPC servers and clients is somewhat peculiar. An
RPC server offers one or more collections of procedures; each set is called
a <emphasis>program</emphasis> and is uniquely identified by a
<emphasis>program number</emphasis>. A list that maps service names to program
numbers is usually kept in <filename moreinfo="none">/etc/rpc</filename>, an excerpt of which
is shown in <xref linkend="x-087-2-rpc.fig"></xref>.</para><example id="x-087-2-rpc.fig"><title>A Sample /etc/rpc File</title><screen format="linespecific">#
# /etc/rpc - miscellaneous RPC-based services
#
portmapper      100000  portmap sunrpc
rstatd          100001  rstat rstat_svc rup perfmeter
rusersd         100002  rusers
nfs             100003  nfsprog
ypserv          100004  ypprog
mountd          100005  mount showmount
ypbind          100007
walld           100008  rwall shutdown
yppasswdd       100009  yppasswd
bootparam       100026
ypupdated       100028  ypupdate</screen></example><para>In TCP/IP networks, the authors of RPC faced the problem of mapping
program numbers to generic network services. They designed each server to
provide both a TCP and a UDP port for each program and each version. Generally,
RPC applications use UDP when sending data, and fall back to TCP only
when the data to be transferred doesn't fit into a single UDP datagram.</para><para><indexterm significance="normal"><primary>portmapper daemon</primary></indexterm>
<indexterm significance="normal"><primary>RPC (Remote Procedure Call)</primary><secondary>mapping ports to programs</secondary></indexterm>
Of course, client programs need to find out to which port
a program number maps. Using a configuration file for this would be
too unflexible; since RPC applications don't use reserved ports, there's
no guarantee that a port originally meant to be used by our database
application hasn't been taken by some other process. Therefore, RPC
applications pick any port they can get and register it with a special program
called the <emphasis>portmapper daemon</emphasis>. The portmapper acts as a
service broker for all RPC servers running on its machine. A client that
wishes to contact a service with a given program number first queries
the portmapper on the server's host, which returns the TCP and UDP port
numbers the service can be reached at.</para><para><indexterm significance="normal"><primary>inetd super server</primary></indexterm>
This method introduces a single point of failure, much like the 
<command moreinfo="none">inetd</command> daemon does for the standard
Berkeley services. However, this case is even a little worse because
when the portmapper dies, all RPC port information is lost; this
usually means you have to restart all RPC servers manually or reboot
the entire machine.</para><para><indexterm significance="normal"><primary>rpc.portmap daemon</primary></indexterm> 
<indexterm significance="normal"><primary>portmap daemon</primary></indexterm> 
On Linux, the portmapper is called <filename moreinfo="none">/sbin/portmap</filename>, or
sometimes <filename moreinfo="none">/usr/sbin/rpc.portmap</filename>. Other than making sure
it is started from your network boot scripts, the portmapper doesn't require
any configuration.</para></sect1><sect1 id="x-087-2-appl.remote"><title>Configuring Remote Login<?lb?>and Execution</title><indexterm significance="normal" class="startofrange" id="idx-configuringrcommands"><primary>configuring</primary><secondary>remote login and execution</secondary></indexterm><indexterm significance="normal"><primary>authentication</primary><secondary>on remote hosts</secondary></indexterm><indexterm significance="normal"><primary>remote</primary><secondary>command execution</secondary></indexterm><indexterm significance="normal"><primary>security</primary><secondary>remote login</secondary></indexterm><indexterm significance="normal"><primary>remote</primary><secondary>login</secondary></indexterm><indexterm significance="normal"><primary>remote</primary><secondary>file access</secondary></indexterm><para>It's often very useful to execute a command on a remote host and
have input or output from that command be read from, or written to, a network
connection.</para><para><indexterm significance="normal"><primary>rlogin command</primary></indexterm>
<indexterm significance="normal"><primary>rcp command</primary></indexterm>
<indexterm significance="normal"><primary>rsh command</primary></indexterm>
<indexterm significance="normal"><primary>slogin command</primary></indexterm>
<indexterm significance="normal"><primary>scp command</primary></indexterm>
<indexterm significance="normal"><primary>ssh command</primary></indexterm>
The traditional commands used for executing commands on remote hosts are
<command moreinfo="none">rlogin</command>, <command moreinfo="none">rsh</command> and <command moreinfo="none">rcp</command>.
We saw an example of the <command moreinfo="none">rlogin</command> command in <xref linkend="x-087-2-intro"></xref> in the section <xref linkend="x-087-2-intro.tcpip.intro"></xref>. We briefly discussed the security
issues associated with it in <xref linkend="x-087-2-intro.security"></xref> and
suggested <command moreinfo="none">ssh</command> as a replacement.
The <command moreinfo="none">ssh</command> package provides replacements called
<command moreinfo="none">slogin</command>, <command moreinfo="none">ssh</command>, and <command moreinfo="none">scp</command>.</para><para><indexterm significance="normal"><primary>passwords</primary><secondary>remote login and</secondary></indexterm>
Each of these commands spawns a shell on the remote host and allows the user
to execute commands. Of course, the client needs to have an account on the
remote host where the command is to be executed. Thus, all these commands
use an authentication process. The <emphasis>r</emphasis> commands use a simple
username and password exchange between the hosts with no encryption, so anyone
listening could easily intercept the passwords. The <command moreinfo="none">ssh</command>
command suite provides a higher level of security: it uses a technique 
called <command moreinfo="none">Public Key Cryptography</command>, which provides 
authentication and encryption between the hosts to ensure that
neither passwords nor session data are easily intercepted by other hosts.</para><para><indexterm significance="normal"><primary>Local Area Networks (LANs)</primary><secondary>remote login</secondary></indexterm>
It is possible to relax authentication checks for certain users even further. For
instance, if you frequently have to log into other machines on your LAN,
you might want to be admitted without having to type your password every
time. This was always possible with the <emphasis>r</emphasis> commands, but the
<command moreinfo="none">ssh</command> suite allows you to do this a little more easily. It's
still not a great idea because it means that if an account on one machine
is breached, access can be gained to all other accounts that user has
configured for password-less login, but it is very convenient and people will
use it.</para><para>Let's talk about removing the <emphasis>r</emphasis> commands and getting
<command moreinfo="none">ssh</command> to work instead.</para><sect2><title>Disabling the r; Commands</title><para>Start by removing the <command moreinfo="none">r</command> commands if they're
installed.  The easiest way to disable the old <command moreinfo="none">r</command>
commands is to comment out (or remove) their entries in the
<filename moreinfo="none">/etc/inetd.conf</filename> file. The relevant entries will
look something like this:

<screen format="linespecific"># Shell, login, exec and talk are BSD protocols.
shell    stream  tcp     nowait  root  /usr/sbin/tcpd /usr/sbin/in.rshd
login    stream  tcp     nowait  root  /usr/sbin/tcpd /usr/sbin/in.rlogind
exec     stream  tcp     nowait  root  /usr/sbin/tcpd /usr/sbin/in.rexecd</screen>

You can comment them by placing a <literal moreinfo="none">#</literal> character at the start
of each line, or delete the lines completely. Remember, you need to restart the
<command moreinfo="none">inetd</command> daemon for this change to take effect. Ideally, you 
should remove the daemon programs themselves, too.</para></sect2><sect2><title>Installing and Configuring ssh</title><para><indexterm significance="normal" class="startofrange" id="ssh.command.config"><primary>ssh command</primary><secondary>configuring</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="config.ssh.command"><primary>configuring</primary><secondary>ssh command</secondary></indexterm>
OpenSSH is a free version of the ssh suite of programs; the Linux port can
be found at
<systemitem moreinfo="none" role="url">http://violet.ibs.com.au/openssh/</systemitem> and in
most modern Linux distributions.<footnote id="x-087-2-fnfe04"><para>OpenSSH was developed by the OpenBSD project and is a fine example of the
benefit of free software.</para></footnote>
We won't describe compilation here; good instructions are included in the
source. If you can install it from a precompiled package, then it's probably
wise to do so.</para><para>There are two parts to an <command moreinfo="none">ssh</command> session. There is an
<command moreinfo="none">ssh</command> client that you need to configure and run on the local
host and an <command moreinfo="none">ssh</command> daemon that must be running on the remote
host.</para><sect3><title>The ssh daemon</title><para><indexterm significance="normal" class="startofrange" id="ssh.sshd.daemon"><primary>ssh command</primary><secondary>sshd daemon</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="sshd.daemon"><primary>sshd daemon</primary></indexterm>
The <command moreinfo="none">sshd</command> daemon is the program that listens for network
connections from <command moreinfo="none">ssh</command> clients, manages authentication, and
executes the requested command. It has one main configuration file called
<filename moreinfo="none">/etc/ssh/sshd_config</filename> and a special file containing a
key used by the authentication and encryption processes to represent the host
end. Each host and each client has its own key.</para><para><indexterm significance="normal"><primary>ssh-keygen utility</primary></indexterm>
<indexterm significance="normal"><primary sortas="etc/ssh/ssh_host_key file">/etc/ssh/ssh_host_key file</primary></indexterm>
<indexterm significance="normal"><primary>host keys</primary></indexterm>
<indexterm significance="normal"><primary>keys</primary><secondary>host</secondary></indexterm>
A utility called <command moreinfo="none">ssh-keygen</command> is supplied to generate
a random key. This is usually used once at installation time to
generate the host key, which the system administrator usually stores
in a file called <filename moreinfo="none">/etc/ssh/ssh_host_key</filename>.  Keys can
be of any length of 512 bits or greater. By default,
<command moreinfo="none">ssh-keygen</command> generates keys of 1024 bits in length,
and most people use the default. To generate a random key, you would
invoke the <command moreinfo="none">ssh-keygen</command> command like this:

<screen format="linespecific"># <userinput moreinfo="none">ssh-keygen -f /etc/ssh/ssh_host_key</userinput></screen>
</para><para>You will be prompted to enter a passphrase. However, host keys must not use 
a passphrase, so just press the return key to leave it blank. The program 
output will look something like:

<screen format="linespecific">Generating RSA keys:  ......oooooO...............................oooooO
Key generation complete.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /etc/ssh/ssh_host_key
Your public key has been saved in /etc/ssh/ssh_host_key.pub
The key fingerprint is:
1024 3a:14:78:8e:5a:a3:6b:bc:b0:69:10:23:b7:d8:56:82 root@moria</screen></para><para><indexterm significance="normal"><primary>private keys</primary></indexterm>
<indexterm significance="normal"><primary>public keys</primary></indexterm>
<indexterm significance="normal"><primary>keys</primary><secondary>private</secondary></indexterm>
<indexterm significance="normal"><primary>keys</primary><secondary>public</secondary></indexterm>
<indexterm significance="normal"><primary sortas="etc/ssh/ssh_host_key.pub file">/etc/ssh/ssh_host_key.pub file</primary></indexterm>
You will find at the end that two files have been created. The first is 
called the private key, which must be kept secret and will be in
<filename moreinfo="none">/etc/ssh/ssh_host_key</filename>. The second is called the public
key and is one that you can share; it will be in
<filename moreinfo="none">/etc/ssh/ssh_host_key.pub</filename>.</para><para>Armed with the keys for <command moreinfo="none">ssh</command> communication, you need to 
create a configuration file. The <command moreinfo="none">ssh</command> suite is very 
powerful and the configuration file
may contain many options. We'll present a simple example to get you started;
you should refer to the <command moreinfo="none">ssh</command> documentation to enable other
features. The following code shows a safe and minimal
<command moreinfo="none">sshd</command> configuration file. The rest of the configuration
options are detailed in the <command moreinfo="none">sshd</command>(8) manpage:</para><screen format="linespecific"># /etc/ssh/sshd_config
#

# The IP adddresses to listen for connections on. 0.0.0.0 means all
# local addresses.
ListenAddress 0.0.0.0

# The TCP port to listen for connections on. The default is 22.
Port 22

# The name of the host key file.
HostKey /etc/ssh/ssh_host_key

# The length of the key in bits.
ServerKeyBits 1024

# Should we allow root logins via ssh?
PermitRootLogin no

# Should the ssh daemon check users' home directory and files permissions?
# are safe before allowing login?
StrictModes yes

# Should we allow old ~/.rhosts and /etc/hosts.equiv authentication method?
RhostsAuthentication no
# Should we allow pure RSA authentication?
RSAAuthentication yes
# Should we allow password authentication?
PasswordAuthentication yes

# Should we allow /etc/hosts.equiv combined with RSA host authentication?
RhostsRSAAuthentication no
# Should we ignore ~/.rhosts files?
IgnoreRhosts yes<?troff .ne 7?>
# Should we allow logins to accounts with empty passwords?
PermitEmptyPasswords no</screen><para>It's important to make sure the permissions of the configuration files are 
correct to ensure that system security is maintained. Use the following
commands:

<screen format="linespecific"># <userinput moreinfo="none">chown -R root:root /etc/ssh</userinput>
# <userinput moreinfo="none">chmod 755 /etc/ssh</userinput>
# <userinput moreinfo="none">chmod 600 /etc/ssh/ssh_host_key</userinput>
# <userinput moreinfo="none">chmod 644 /etc/ssh/ssh_host_key.pub</userinput>
# <userinput moreinfo="none">chmod 644 /etc/ssh/sshd_config</userinput></screen></para><para><?troff .hw simple?>The final stage of <command moreinfo="none">sshd</command> administration daemon is
to run it. Normally you'd create an <filename moreinfo="none">rc</filename> file
for it or add it to an existing one, so that it is automatically executed
at boot time. The daemon runs standalone and doesn't require any entry in
the <filename moreinfo="none">/etc/inetd.conf</filename> file. The daemon must be run as the
<literal moreinfo="none">root</literal> user. The syntax is very simple:

<screen format="linespecific">/usr/sbin/sshd</screen>

The <command moreinfo="none">sshd</command> daemon will automatically place itself into the
background when being run. You are now ready to accept <emphasis>ssh</emphasis>
connections.</para><indexterm significance="normal" class="endofrange" startref="ssh.sshd.daemon"></indexterm><indexterm significance="normal" class="endofrange" startref="sshd.daemon"></indexterm></sect3><sect3><title>The ssh client</title><para><indexterm significance="normal" class="startofrange" id="ssh.ssh.clients"><primary>ssh command</primary><secondary>clients</secondary></indexterm>
<indexterm significance="normal"><primary>slogin command</primary></indexterm>
<indexterm significance="normal"><primary>scp command</primary></indexterm>
<indexterm significance="normal"><primary sortas="etc/ssh/ssh_config file">/etc/ssh/ssh_config file</primary></indexterm>
There are a number of <command moreinfo="none">ssh</command> client programs:
<command moreinfo="none">slogin</command>, <command moreinfo="none">scp</command> and <command moreinfo="none">ssh</command>.
They each read the same configuration file, usually called
<filename moreinfo="none">/etc/ssh/ssh_config</filename>. They each also read configuration
files from the <filename moreinfo="none">.ssh</filename> directory in the home directory
of the user executing them. The most important of these files is the
<filename moreinfo="none">.ssh/config</filename> file, which may contain options that override
those specified in the <filename moreinfo="none">/etc/ssh/ssh_config</filename> file, the
<filename moreinfo="none">.ssh/identity</filename> file, which contains the user's own
private key, and the corresponding <filename moreinfo="none">.ssh/identity.pub</filename>
file, containing the user's public key. Other important files are <filename moreinfo="none">.ssh/known_hosts</filename> and 
<filename moreinfo="none">.ssh/authorized_keys</filename>; we'll talk about those later in <xref linkend="x-087-2-features.ssh.using"></xref>. First, let's create the global
configuration file and the user key file.</para><para><filename moreinfo="none">/etc/ssh/ssh_config</filename> is very similar to the server
configuration file. Again, there are lots of features you can configure, but
a minimal configuration looks like that presented in
<xref linkend="x-087-2-features.ssh.conf"></xref>. The rest of the configuration
options are detailed in the <command moreinfo="none">sshd(8)</command> manpage. You can add sections that match
specific hosts or groups of hosts. The parameter to the
<literal moreinfo="none">Host</literal> statement may be either the full name of
a host or a wildcard specification, as we've used in our example, to match all
hosts. We could create an entry that used, for example,
<literal moreinfo="none">Host *.vbrew.com</literal> to match any host in the
<literal moreinfo="none">vbrew.com</literal> domain.</para><example id="x-087-2-features.ssh.conf"><title>Example ssh Client Configuration File</title><screen format="linespecific"># /etc/ssh/ssh_config

# Default options to use when connecting to a remote host
Host *
  # Compress the session data?
  Compression yes
  # .. using which compression level? (1 - fast/poor, 9 - slow/good)
  CompressionLevel 6

  # Fall back to rsh if the secure connection fails?
  FallBackToRsh no

  # Should we send keep-alive messages? Useful if you use IP masquerade
  KeepAlive yes

  # Try RSA authentication?
  RSAAuthentication yes
  # Try RSA authentication in combination with .rhosts authentication?
  RhostsRSAAuthentication yes</screen></example><para><indexterm significance="normal"><primary>ssh-keygen utility</primary></indexterm>
We mentioned in the server configuration section that every host and user has a key. The user's key is stored in his or her
<filename moreinfo="none">~/.ssh/indentity</filename> file. To generate the key, use the
same <command moreinfo="none">ssh-keygen</command> command as we used to generate the
host key, except this time you do not need to specify the name of the file
in which you save the key. The <command moreinfo="none">ssh-keygen</command> defaults to
the correct location, but it prompts you to enter a filename in case you'd like
to save it elsewhere. It is sometimes useful to have multiple identity files,
so <command moreinfo="none">ssh</command> allows this.
Just as before, <command moreinfo="none">ssh-keygen</command> will prompt you to entry a
passphrase. Passphrases add yet another level of security and are a good idea.
Your passphrase won't be echoed on the screen when you type it.
<warning><para>There is no way to recover a passphrase if you forget it. Make sure it is
something you will remember, but as with all passwords, make it something
that isn't obvious, like a proper noun or your name. For a passphrase to 
be truly effective, it should be between 10 and 30 characters
long and not be plain English prose. Try to throw in some unusual
characters. If you forget your passphrase, you will be forced to generate a
new key.</para></warning>
<indexterm significance="normal"><primary>private keys</primary></indexterm>
<indexterm significance="normal"><primary>public keys</primary></indexterm>
<indexterm significance="normal"><primary>keys</primary><secondary>private</secondary></indexterm>
<indexterm significance="normal"><primary>keys</primary><secondary>public</secondary></indexterm>
You should ask each of your users to run the <command moreinfo="none">ssh-keygen</command>
command just once to ensure their key file is created correctly. The
<command moreinfo="none">ssh-keygen</command> will create their <filename moreinfo="none">~/.ssh/</filename>
directories for them with appropriate permissions and create their private and
public keys in <filename moreinfo="none">.ssh/identity</filename> and
<filename moreinfo="none">.ssh/identity.pub</filename>, respectively. A sample session
should look like:

<screen format="linespecific">$ <userinput moreinfo="none">ssh-keygen</userinput>
Generating RSA keys:  .......oooooO..............................
Key generation complete.
Enter file in which to save the key (/home/maggie/.ssh/identity): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/maggie/.ssh/identity.
Your public key has been saved in /home/maggie/.ssh/identity.pub.
The key fingerprint is:
1024 85:49:53:f4:8a:d6:d9:05:d0:1f:23:c4:d7:2a:11:67 maggie@moria
$</screen></para><para>Now <command moreinfo="none">ssh</command> is ready to run.</para><indexterm significance="normal" class="endofrange" startref="ssh.ssh.clients"></indexterm></sect3><sect3 id="x-087-2-features.ssh.using"><title>Using ssh</title><para><indexterm significance="normal" class="startofrange" id="ssh.command.running"><primary>ssh command</primary><secondary>running clients</secondary></indexterm>
We should now have the <command moreinfo="none">ssh</command> command and it's associated
programs installed and ready to run. Let's now take a quick look at how to
run them.</para><para><indexterm significance="normal"><primary>slogin command</primary></indexterm>
<indexterm significance="normal"><primary>fingerprints</primary></indexterm>
<indexterm significance="normal"><primary>key fingerprints</primary></indexterm>
First, we'll try a remote login to a host. We can use the <command moreinfo="none">slogin</command> program in much the same way as we used the <command moreinfo="none">rlogin</command> 
program in our example earlier in the book. The first time you attempt a 
connection to a host, the <command moreinfo="none">ssh</command> client will retrieve the 
public key of the host and ask you to confirm its identity by prompting you 
with a shortened version of the public key called a 
<command moreinfo="none">fingerprint</command>. </para><para>The administrator at the remote host should have supplied you in
advance with its public key fingerprint, which you should add to your 
<filename moreinfo="none">.ssh/known_hosts</filename> file. If the remote
administrator has not supplied you the appropriate key, you can
connect to the remote host, but <command moreinfo="none">ssh</command> will warn you
that it does have a key and prompt you whether you wish to accept the
one offered by the remote host.  Assuming that you're sure no one is
engaging in DNS spoofing and you are in fact talking to the correct
host, answer yes to the prompt.  The relevant key is then stored
automatically in your <filename moreinfo="none">.ssh/known_hosts</filename> and you
will not be prompted for it again. If, on a future connection attempt, 
the public key retrieved from that host does not match the one that is 
stored, you will be warned, because this represents a potential security 
breach.</para><para>A first-time login to a remote host will look something like:

<screen format="linespecific">$ <userinput moreinfo="none">slogin vchianti.vbrew.com</userinput>
The authenticity of host 'vchianti.vbrew.com' can't be established.
Key fingerprint is 1024 7b:d4:a8:28:c5:19:52:53:3a:fe:8d:95:dd:14:93:f5.
Are you sure you want to continue connecting (yes/no)? <userinput moreinfo="none">yes</userinput>
Warning: Permanently added 'vchianti.vbrew.com,172.16.2.3' to the list of/
    known hosts.
maggie@vchianti.vbrew.com's password: 
Last login: Tue Feb  1 23:28:58 2000 from vstout.vbrew.com
$</screen></para><?troff .Nd 10?><para>You will be prompted for a password, which you should answer with the 
password belonging to the remote account, not the local one. This password 
is not echoed when you type it.</para><para>Without any special arguments, <command moreinfo="none">slogin</command> will attempt to log in
with the same userid used on the local machine. You can override this
using the <literal moreinfo="none">-l</literal> argument, supplying an alternate login name
on the remote host. This is what we did in our example earlier in the book.</para><para><indexterm significance="normal"><primary>scp command</primary></indexterm>
We can copy files to and from the remote host using the <command moreinfo="none">scp</command>
program. Its syntax is similar to the conventional <command moreinfo="none">cp</command>
with the exception that you may specify a hostname before a filename, meaning 
that the file path is on the specified host. The following example illustrates
<command moreinfo="none">scp</command> syntax by copying a local file called 
<filename moreinfo="none">/tmp/fred</filename> to the <filename moreinfo="none">/home/maggie/</filename> of 
the remote host <emphasis role="bold">chianti.vbrew.com</emphasis>:

<screen format="linespecific">$ <userinput moreinfo="none">scp /tmp/fred vchianti.vbrew.com:/home/maggie/</userinput>
maggie@vchianti.vbrew.com's password:
fred                 100% |*****************************| 50165   00:01 ETA</screen></para><para>Again, you'll be prompted for a password. The <command moreinfo="none">scp</command> command 
displays useful progress messages by default. You can copy a file from a 
remote host with the same ease; simply specify its hostname and filepath as 
the source and the local path as the destination. It's even possible to copy 
a file from a remote host to some other remote host, but it is something you 
wouldn't normally want to do, because all of the data travels via your host.</para><para>You can execute commands on remote hosts using the
<command moreinfo="none">ssh</command> command. Again, its syntax is very simple. Let's
have our user <userinput moreinfo="none">maggie</userinput> retrieve the root directory of
the remote host <emphasis role="bold">vchianti.vbrew.com</emphasis>.
She'd do this with:

<screen format="linespecific">$ <userinput moreinfo="none">ssh vchianti.vbrew.com ls -CF /</userinput>
maggie@vchianti.vbrew.com's password:
bin/    console@  dos/     home/    lost+found/  pub@   tmp/  vmlinuz@
boot/   dev/      etc/     initrd/  mnt/         root/  usr/  vmlinuz.old@
cdrom/  disk/     floppy/  lib/     proc/        sbin/  var/</screen></para><para>You can place <command moreinfo="none">ssh</command> in a command pipeline
and pipe program input/output to or from it just like any other command,
except that the input or output is directed to or from the remote host
via the <command moreinfo="none">ssh</command> connection. Here is an example of how you might
use this capability in combination with the <command moreinfo="none">tar</command> command
to copy a whole directory with subdirectories and files from a remote host
to the local host:

<screen format="linespecific">$ <userinput moreinfo="none">ssh vchianti.vbrew.com "tar cf - /etc/" | tar xvf -</userinput>
maggie@vchianti.vbrew.com's password:
etc/GNUstep
etc/Muttrc
etc/Net
etc/X11
etc/adduser.conf
..
..</screen></para><?troff .Nd 7?><para>Here we surrounded the command we will execute with quotation marks to make it
clear what is passed as an argument to <command moreinfo="none">ssh</command> and what is used
by the local shell. This command executes the <command moreinfo="none">tar</command>
command on the remote host to archive the <filename moreinfo="none">/etc/</filename> directory
and write the output to standard output. We've piped to an instance of the
<command moreinfo="none">tar</command> command running on our local host in extract mode
reading from standard input.</para><para><indexterm significance="normal"><primary sortas="ssh/authorized_keys file">.ssh/authorized_keys file</primary></indexterm>
Again, we were prompted for the password. Now you can see why we encouraged 
you to configure <command moreinfo="none">ssh</command> so
that it doesn't prompt you for passwords all the time! Let's now configure
our local <command moreinfo="none">ssh</command> client so that it won't prompt for a password
when connecting to the
<systemitem moreinfo="none" role="hostname">vchianti.vbrew.com</systemitem> host. We mentioned
the <filename moreinfo="none">.ssh/authorized_keys</filename> file earlier; this is where
it is used. The <filename moreinfo="none">.ssh/authorized_keys</filename> file contains the
<emphasis>public</emphasis> keys on any remote user accounts that we wish to
automatically log in to. You can set up automatic logins by copying the 
contents of the
<filename moreinfo="none">.ssh/identity.pub</filename> from the <emphasis>remote</emphasis>
account into our local <filename moreinfo="none">.ssh/authorized_keys</filename> file. It is
vital that the file permissions of <filename moreinfo="none">.ssh/authorized_keys</filename> 
allow only that you read and write it; anyone may steal and use the
keys to log in to that remote account. To ensure the permissions are correct,
change <filename moreinfo="none">.ssh/authorized_keys</filename>, as shown:

<screen format="linespecific">$ <userinput moreinfo="none">chmod 600 ~/.ssh/authorized_keys</userinput></screen></para><para>The public keys are a long <emphasis>single</emphasis> line of plain
text. If you use copy and paste to duplicate the key into your local file, 
be sure to remove any end of line characters that might have been introduced 
along the way. The <filename moreinfo="none">.ssh/authorized_keys</filename> file may contain 
many such keys, each on a line of its own.</para><para><?troff .hw information?>The <command moreinfo="none">ssh</command> suite of tools is very powerful and there are many
other useful features and options that you will be interested in exploring.
Please refer to the manual pages and other documentation that is supplied
with the package for more information.</para></sect3><indexterm significance="normal" class="endofrange" startref="ssh.command.config"></indexterm><indexterm significance="normal" class="endofrange" startref="config.ssh.command"></indexterm><indexterm significance="normal" class="endofrange" startref="ssh.command.running"></indexterm></sect2><indexterm significance="normal" class="endofrange" startref="idx-configuringrcommands"></indexterm></sect1></chapter><chapter id="x-087-2-nis"><title>The Network <?lb?>Information System</title><indexterm significance="normal" class="startofrange" id="idx-configuringnis-1"><primary>configuring</primary><secondary>NIS</secondary></indexterm><indexterm significance="normal"><primary>NIS (Network Information System)</primary></indexterm><indexterm significance="normal" class="startofrange" id="idx-nis-1"><primary>NIS (Network Information System)</primary></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>synchronizing passwords</secondary></indexterm><indexterm significance="normal"><primary>hostname</primary><secondary>resolution</secondary></indexterm><para>When you're running a local area network, your overall goal is usually to
provide an environment for your users that makes the network transparent. An
important stepping stone is keeping vital data such as user account
information synchronized among all hosts. This provides users with the freedom
to move from machine to machine without the inconvenience of having to remember
different passwords and copy data from one machine to another. Data that is
centrally stored doesn't need to be replicated, so long as there is some
convenient means of accessing it from a network-connected host. By storing
important administrative information centrally, you can make ensure 
consistency of that data, increase flexibility for the users by
allowing them to move from host to host in a transparent way, and make the
system administrator's life much easier by maintaining a single copy of
information to maintain when required.</para><para>We previously discussed an important example of this concept that is used on 
the Internetthe Domain Name System (DNS). DNS serves a limited range of
information, the most important being the mapping between hostname and
IP address. For other types of information, there is no such specialized
service. Moreover, if you manage only a small LAN with no Internet
connectivity, setting up DNS may not seem to be worth the trouble.</para><para><indexterm significance="normal"><primary sortas="etc/hosts file">/etc/hosts file</primary></indexterm> 
This is why Sun developed the <emphasis>Network Information
System</emphasis> (NIS). NIS provides generic database access facilities that
can be used to distribute, for example,  information contained in the
<filename moreinfo="none">passwd</filename> and <filename moreinfo="none">groups</filename> files to all
hosts on your network. This makes the network appear as a single system,
with the same accounts on all hosts. Similarly, you can use NIS
to distribute the hostname information from <filename moreinfo="none">/etc/hosts</filename>
to all machines on the network.</para><para>NIS is based on RPC, and comprises a server, a client-side library, and
several administrative tools.  Originally, NIS was called <emphasis>Yellow
Pages</emphasis>, or YP, which is still used to refer to it.
Unfortunately, the name is a trademark of British Telecom, which required
Sun to drop that name. As things go, some names stick with people, and so
YP lives on as a prefix to the names of most NIS-related commands such as
<command moreinfo="none">ypserv</command> and <command moreinfo="none">ypbind</command>.</para><para><indexterm significance="normal"><primary>Thmmler, Swen</primary></indexterm>
<indexterm significance="normal"><primary>yp-linux command</primary></indexterm>
Today, NIS is available for virtually all Unixes, and there are even
free implementations. BSD Net-2 released one that has
been derived from a public domain reference implementation donated by
Sun. The library client code from this release had been in the Linux
<filename moreinfo="none">libc</filename> for a long time, and the administrative programs
were ported to Linux by
Swen Thmmler.<footnote id="x-087-2-fnni01"><para>Swen can be reached at
<systemitem moreinfo="none" role="emailaddr">swen@uni-paderborn.de</systemitem>. The NIS clients
are available as <filename moreinfo="none">yp-linux.tar.gz</filename> from
<systemitem moreinfo="none" role="sitename">metalab.unc.edu</systemitem> in
<filename moreinfo="none">system/Network</filename>.</para></footnote>
An NIS server is missing from the reference implementation, though.
</para><para><indexterm significance="normal"><primary>Eriksson, Peter</primary></indexterm>
<indexterm significance="normal"><primary>NYS</primary></indexterm>
<indexterm significance="normal"><primary>host.conf file</primary></indexterm>
Peter Eriksson developed a new
implementation called NYS.<footnote id="x-087-2-fnni02"><para>Peter may be reached at
<systemitem moreinfo="none" role="emailaddr">pen@lysator.liu.se</systemitem>.
The current version of NYS is 1.2.8.</para></footnote>
It supports both plain NIS and Sun's much enhanced NIS+. NYS not only
provides a set of NIS tools and a server, but also adds a whole new
set of library functions that need to be compiled into your
<filename moreinfo="none">libc</filename> if you wish to use it.  This includes a new
configuration scheme for hostname resolution that replaces the current
scheme using <filename moreinfo="none">host.conf</filename>.</para><para><indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>GNU libc</secondary></indexterm>
<indexterm significance="normal"><primary>Kukuk, Thorsten</primary></indexterm>
<indexterm significance="normal"><primary>GNU libc (NIS support)</primary></indexterm>
<indexterm significance="normal"><primary>libc6 (NIS support)</primary></indexterm>
The GNU libc, known as <filename moreinfo="none">libc6</filename> in the Linux community,
includes an updated version of the traditional NIS support developed by
Thorsten Kukuk.<footnote id="x-087-2-fnni04"><para>Thorsten may be reached at
<systemitem moreinfo="none" role="emailaddr">kukuk@uni-paderborn.de</systemitem>.</para></footnote> It supports all of the
library functions that NYS provided and also uses the enhanced configuration
scheme of NYS. You still need the tools and server, but using GNU <filename moreinfo="none">libc</filename> saves
you the trouble of having to meddle with patching and recompiling the library.</para><para>This chapter focuses on the NIS support included in the GNU <filename moreinfo="none">libc</filename> rather than
the other two packages. If you do want to run any of these packages, the
instructions in this chapter may or may not be enough. For additional
information, refer to the NIS-HOWTO or a book such as <emphasis>Managing 
NFS and NIS</emphasis> by Hal Stern (O'Reilly).</para><sect1><title>Getting Acquainted with NIS</title><para><indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>databases</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-nismap-1"><primary>NIS (Network Information System)</primary><secondary>maps</secondary></indexterm>
NIS keeps database information in files called <emphasis>maps</emphasis>, 
which contain key-value pairs. An example of a key-value pair is a user's login
name and the encrypted form of their login password. Maps are stored on a
central host running the NIS server, from which clients may retrieve the
information through various RPC calls. Quite frequently, maps are stored in DBM
files.<footnote id="x-087-2-fnni05"><para>DBM is a simple database management library that uses hashing techniques
to speed up search operations. There's a free DBM implementation from the
GNU project called <filename moreinfo="none">gdbm</filename>, which is part of most Linux
distributions.</para></footnote>
</para><para><indexterm significance="normal"><primary sortas="etc/hosts file">/etc/hosts file</primary></indexterm>
<indexterm significance="normal"><primary sortas="etc/passwd file">/etc/passwd file</primary></indexterm>
<indexterm significance="normal"><primary>hosts.byname file</primary></indexterm>
<indexterm significance="normal"><primary>hosts.byaddr file</primary></indexterm>
<indexterm significance="normal"><primary sortas="etc/networks file">/etc/networks file</primary></indexterm> 
<indexterm significance="normal"><primary sortas="etc/group file">/etc/group file</primary></indexterm> 
<indexterm significance="normal"><primary sortas="etc/services file">/etc/services file</primary></indexterm> 
<indexterm significance="normal"><primary sortas="etc/rpc file">/etc/rpc file</primary></indexterm> 
<indexterm significance="normal"><primary sortas="etc/protocols file">/etc/protocols file</primary></indexterm> 
<indexterm significance="normal"><primary sortas="etc/aliases file">/etc/aliases file</primary></indexterm> 
The maps themselves are usually generated from master text files such as
<filename moreinfo="none">/etc/hosts</filename> or <filename moreinfo="none">/etc/passwd</filename>. For
some files, several maps are created, one for each search key type. For
instance, you may search the <filename moreinfo="none">hosts</filename> file for a hostname
as well as for an IP address. Accordingly, two NIS maps are derived from it,
called <filename moreinfo="none">hosts.byname</filename> and <filename moreinfo="none">hosts.byaddr</filename>.
<xref linkend="x-087-2-nis.table.maps"></xref> lists common maps and the files from
which they are generated.</para><table id="x-087-2-nis.table.maps"><title>Some Standard NIS Maps and Corresponding Files</title><tgroup cols="3"><thead><row><entry>Master File</entry><entry>Map(s)</entry><entry>Description</entry></row></thead><tbody><row><entry><filename moreinfo="none">/etc/hosts</filename></entry><entry><para><filename moreinfo="none">hosts.byname</filename>, <filename moreinfo="none">hosts.byaddr</filename></para></entry><entry><para>Maps IP addresses to host names</para></entry></row><row><entry><filename moreinfo="none">/etc/networks</filename></entry><entry><para><filename moreinfo="none">networks.byname</filename>, <filename moreinfo="none">networks.byaddr</filename></para></entry><entry><para>Maps IP network addresses to network names</para></entry></row><row><entry><para><filename moreinfo="none">/etc/passwd</filename></para></entry><entry><para><filename moreinfo="none">passwd.byname</filename>, <filename moreinfo="none">passwd.byuid</filename></para></entry><entry><para>Maps encrypted passwords to user login names</para></entry></row><row><entry><para><filename moreinfo="none">/etc/group</filename></para></entry><entry><para><filename moreinfo="none">group.byname</filename>, <filename moreinfo="none">group.bygid</filename></para></entry><entry><para>Maps Group IDs to group names</para></entry></row><row><entry><para><filename moreinfo="none">/etc/services</filename></para></entry><entry><para><filename moreinfo="none">services.byname</filename>, <filename moreinfo="none">services.bynumber</filename></para></entry><entry>Maps service descriptions to service names</entry></row><row><entry><filename moreinfo="none">/etc/rpc</filename></entry><entry><para><filename moreinfo="none">rpc.byname</filename>, <filename moreinfo="none">rpc.bynumber</filename></para></entry><entry><para>Maps Sun RPC service numbers to RPC service names</para></entry></row><row><entry><filename moreinfo="none">/etc/protocols</filename></entry><entry><para><filename moreinfo="none">protocols.byname</filename>, <filename moreinfo="none">protocols.bynumber</filename></para></entry><entry><para>Maps protocol numbers to protocol names</para></entry></row><row><entry><filename moreinfo="none">/usr/lib/aliases</filename></entry><entry><filename moreinfo="none">mail.aliases</filename></entry><entry><para>Maps mail aliases to mail alias names</para></entry></row></tbody></tgroup></table><para>You may find support for other files and maps in other NIS packages.
These usually contain information for applications not discussed in this book,
such as the <filename moreinfo="none">bootparams</filename> map that is used by Sun's
<command moreinfo="none">bootparamd</command> server.</para><para><indexterm significance="normal"><primary>displaying</primary><secondary>NIS map nicknames</secondary></indexterm>
<indexterm significance="normal"><primary>ypcat</primary><secondary>command</secondary></indexterm>
<indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>nicknames</secondary></indexterm>
<indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>maps</secondary></indexterm>
For some maps, people commonly use <emphasis>nicknames</emphasis>, which are
shorter and therefore easier to type. Note that these nicknames are understood
only by <command moreinfo="none">ypcat</command> and <command moreinfo="none">ypmatch</command>, two tools for
checking your NIS configuration. To obtain a full list of nicknames understood
by these tools, run the following command:

<screen format="linespecific">$ <userinput moreinfo="none">ypcat -x</userinput>
Use "passwd" for "passwd.byname"
Use "group" for "group.byname"
Use "networks" for "networks.byaddr"
Use "hosts" for "hosts.byaddr"
Use "protocols" for "protocols.bynumber"
Use "services" for "services.byname"
Use "aliases" for "mail.aliases"
Use "ethers" for "ethers.byname"</screen></para><para><indexterm significance="normal" class="startofrange" id="idx-nisserver-1"><primary>NIS (Network Information System)</primary><secondary>servers</secondary></indexterm>
<indexterm significance="normal"><primary>ypserv command</primary></indexterm>
<indexterm significance="normal"><primary>servers</primary><secondary>ypserv command</secondary></indexterm>
<indexterm significance="normal"><primary>servers</primary><secondary>NIS</secondary></indexterm>
<indexterm significance="normal"><primary>servers</primary><secondary>master</secondary></indexterm>
<indexterm significance="normal"><primary>servers</primary><secondary>slave</secondary></indexterm>
<indexterm significance="normal"><primary>master servers</primary></indexterm>
<indexterm significance="normal"><primary>slave servers</primary></indexterm>
The NIS server program is traditionally called <command moreinfo="none">ypserv</command>. For
an average network, a single server usually suffices; large networks may
choose to run several of these on different machines and different segments
of the network to relieve the load on the server machines and routers.
These servers are synchronized by making one of them the <emphasis>master
server</emphasis>, and the others <emphasis>slave servers</emphasis>. Maps are
created only on the master server's host. From there, they are distributed to
all slaves.</para><para><indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>domains</secondary></indexterm>
<indexterm significance="normal"><primary>choosing</primary><secondary>NIS domain</secondary></indexterm>
<indexterm significance="normal"><primary>domains</primary><secondary>NIS</secondary></indexterm>
We have been talking very vaguely about networks. There's a 
distinctive term in NIS that refers to a collection of all hosts that share 
part of their system configuration data through NIS: the 
<emphasis>NIS domain</emphasis>. Unfortunately, NIS domains
have absolutely nothing in common with the domains we encountered in DNS. To
avoid any ambiguity throughout this chapter, we will therefore always specify
which type of domain we mean.</para><para><indexterm significance="normal"><primary>setting</primary><secondary>NIS domain</secondary></indexterm>
<indexterm significance="normal"><primary>domains</primary><secondary>NIS</secondary></indexterm>
<indexterm significance="normal"><primary>domainname command</primary></indexterm>
NIS domains have a purely administrative function. They are mostly
invisible to users, except for the sharing of passwords between all
machines in the domain. Therefore, the name given to an NIS domain is
relevant only to the administrators. Usually, any name will do, as long
as it is different from any other NIS domain name on your local network.
For instance, the administrator at the Virtual Brewery may choose to
create two NIS domains, one for the Brewery itself, and one for the
Winery, which she names <systemitem moreinfo="none" role="sitename">brewery</systemitem> and
<systemitem moreinfo="none" role="sitename">winery</systemitem> respectively. Another quite
common scheme is to simply use the DNS domain name for NIS as well.</para><para>To set and display the NIS domain name of your host, you can use the
<command moreinfo="none">domainname</command> command. When invoked without any argument, it
prints the current NIS domain name; to set the domain name, you must
become the superuser:

<screen format="linespecific"># <userinput moreinfo="none">domainname brewery</userinput></screen></para><para>NIS domains determine which NIS server an application will query. For
instance, the <command moreinfo="none">login</command> program on a host at the Winery should,
of course, query only the Winery's NIS server (or one of them, if there
are several) for a user's password information, while an application on
a Brewery host should stick with the Brewery's server.</para><para><indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>locating servers</secondary></indexterm>
<indexterm significance="normal"><primary>ypbind command</primary></indexterm>
<indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>security</secondary></indexterm>
One mystery now remains to be solved: how does a client find out which
server to connect to? The simplest approach would use a configuration
file that names the host on which to find the server. However, this approach
is rather inflexible because it doesn't allow clients to use different servers
(from the same domain, of course) depending on their availability. Therefore,
NIS implementations rely on a special daemon called <command moreinfo="none">ypbind</command>
to detect a suitable NIS server in their NIS domain. Before performing any 
NIS queries, an application first finds out from
<command moreinfo="none">ypbind</command> which server to use.</para><para><command moreinfo="none">ypbind</command> probes for servers by broadcasting to the local IP
network; the first to respond is assumed to be the fastest one and
is used in all subsequent NIS queries. After a certain interval has
elapsed, or if the server becomes unavailable, <command moreinfo="none">ypbind</command>
probes for active servers again.</para><para>Dynamic binding is useful only when your network provides more than one
NIS server. Dynamic binding also introduces a security problem.
<command moreinfo="none">ypbind</command> blindly believes whoever answers, whether it be a
humble NIS server or a malicious intruder. Needless to say, this
becomes especially troublesome if you manage your password databases over NIS.
To guard against this, the Linux <command moreinfo="none">ypbind</command> program provides
you with the option of probing the local network to find the local NIS server,
or configuring the NIS server hostname in a configuration file.</para></sect1><sect1 id="x-087-2-nis.nisplus"><title>NIS Versus NIS+</title><indexterm significance="normal"><primary>NIS+</primary></indexterm><para>NIS and NIS+ share little more than their name and a common goal. NIS+ is
structured entirely differently from NIS. Instead of a flat namespace with
disjoint NIS domains, NIS+ uses a hierarchical namespace similar to that of
DNS. Instead of maps, so-called <emphasis>tables</emphasis> are used that
are made up of rows and columns, in which each row represents an object in the
NIS+ database and the columns cover properties of the objects that NIS+
knows and cares about. Each table for a given NIS+ domain comprises those of
its parent domains. In addition, an entry in a table may contain a link to
another table. These features make it possible to structure information in
many ways.</para><para>NIS+ additionally supports secure and encrypted RPC, which helps greatly to
solve the security problems of NIS.</para><para>Traditional NIS has an RPC Version number of 2, while NIS+ is Version 3.
At the time we're writing, there isn't yet a good working implementation 
of NIS+ for Linux, so it isn't covered here.</para></sect1><sect1 id="x-087-2-nis.clients"><title>The Client Side of NIS</title><indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>clients</secondary></indexterm><indexterm significance="normal"><primary>getpwnam()</primary></indexterm><indexterm significance="normal"><primary>getpwuid()</primary></indexterm><para><?troff .hw get-pwnam?>If you are familiar with writing or porting network applications, you
may notice that most of the NIS maps listed previously correspond to library
functions in the C library. For instance, to obtain <filename moreinfo="none">passwd</filename>
information, you generally use the <function moreinfo="none">getpwnam</function> and
<function moreinfo="none">getpwuid</function> functions, which return the account information
associated with the given username or numerical user ID, respectively.
Under normal circumstances, these functions perform the requested
lookup on the standard file, such as <filename moreinfo="none">/etc/passwd</filename>.</para><para>An NIS-aware implementation of these functions, however, modifies this
behavior and places an RPC call to the NIS server, which looks up the username 
or user ID. This happens transparently to the application. The function may
treat the NIS data as though it has been appended to the original
<filename moreinfo="none">passwd</filename> file so both sets of information are available
to the application and used, or as though it has completely replaced it so 
that the information in the local <filename moreinfo="none">passwd</filename> is ignored 
and only the NIS data is used.</para><para>For traditional NIS implementations, there were certain conventions for
which maps were replaced and which were appended to the original information.
Some, like the <filename moreinfo="none">passwd</filename> maps, required kludgy modifications
of the <filename moreinfo="none">passwd</filename> file which, when done incorrectly, would
open up security holes. To avoid these pitfalls, NYS and the GNU <filename moreinfo="none">libc</filename> use a
general configuration scheme that determines whether a particular set of
client functions uses the original files, NIS, or NIS+, and in which order.
This scheme will be described later in this chapter.</para></sect1><sect1 id="x-087-2-nis.server"><title>Running an NIS Server</title><para><indexterm significance="normal"><primary>configuring</primary><secondary>NIS</secondary></indexterm>
After so much theoretical techno-babble, it's time to get our hands
dirty with actual configuration work. In this section, we will cover the
configuration of an NIS server. If an NIS server is running on your network,
you won't have to set up your own; in this case, you may safely skip this
section.</para><para>Note that if you are just going to experiment with the server, make
sure you don't set it up for an NIS domain name that is already in use
on your network. This may disrupt the entire network service and make a
lot of people very unhappy and very angry.</para><para><indexterm significance="normal"><primary>servers</primary><secondary>master</secondary></indexterm>
<indexterm significance="normal"><primary>servers</primary><secondary>slave</secondary></indexterm>
<indexterm significance="normal"><primary>master servers</primary></indexterm>
<indexterm significance="normal"><primary>slave servers</primary></indexterm>
There are two possible NIS server configurations: master and slave. The slave
configuration provides a live backup machine, should your master server 
fail. We will cover the configuration only for a master server here. 
The server documentation will explain the differences, should you wish 
to configure a slave server.</para><para>There are currently two NIS servers freely available for Linux: one contained
in Tobias Reber's <filename moreinfo="none">yps</filename> package, and the other in Peter
Eriksson's <filename moreinfo="none">ypserv</filename> package. It doesn't matter which one
you run.</para><para>After installing the server program (<command moreinfo="none">ypserv</command>) in
<filename moreinfo="none">/usr/sbin</filename>, you should create the directory that
is going to hold the map files your server is to distribute. When
setting up an NIS domain for the <systemitem moreinfo="none" role="sitename">brewery</systemitem> domain, the maps would go to
<filename moreinfo="none">/var/yp/brewery</filename>.  The server determines whether it is
serving a particular NIS domain by checking if the map directory
is present. If you are disabling service for some NIS domain, make
sure to remove the directory as well.
<indexterm significance="normal" class="endofrange" startref="idx-nismap-1"></indexterm></para><para><indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>creating maps</secondary></indexterm>
<indexterm significance="normal"><primary>creating</primary><secondary>NIS maps</secondary></indexterm>
<indexterm significance="normal"><primary>dbmload program</primary></indexterm> 
<indexterm significance="normal"><primary>makedbm program</primary></indexterm> 
Maps are usually stored in DBM files to speed up lookups. They are created
from the master files using a program called <command moreinfo="none">makedbm</command> (for
Tobias's server) or <command moreinfo="none">dbmload</command> (for Peter's server).</para><?troff .wcon_off?><para>Transforming a master file into a form that <command moreinfo="none">dbmload</command> can 
parse usually requires some <command moreinfo="none">awk</command> or <command moreinfo="none">sed</command> 
magic, which tends to be a little tedious to type and hard to remember. 
Therefore, Peter Eriksson's <filename moreinfo="none">ypserv</filename> package contains a 
Makefile (called <filename moreinfo="none">ypMakefile</filename>) that manages the conversion 
of the most common master files for you. You should install it as
<filename moreinfo="none">Makefile</filename> in your map directory and edit it to reflect
the maps you want the NIS server to share. Towards the top of the file, you'll
find <?troff .ne 10?>
the <systemitem moreinfo="none" role="keyword">all</systemitem>
target that lists the services <command moreinfo="none">ypserv</command> offers. By default, the line looks
something like this:

<screen format="linespecific">all: ethers hosts networks protocols rpc services passwd group netid</screen></para><para><indexterm significance="normal"><primary>checking</primary><secondary>NIS</secondary></indexterm>
If you don't want to produce, for example, the 
<filename moreinfo="none">ethers.byname</filename> and <filename moreinfo="none">ethers.byaddr</filename> 
maps, simply remove the <systemitem moreinfo="none" role="keyword">ethers</systemitem> 
prerequisite from this rule. To test your setup, you can start with just 
one or two maps, like the <filename moreinfo="none">services.</filename>* maps.</para><para>After editing the <filename moreinfo="none">Makefile</filename>, while in the map directory,
type <userinput moreinfo="none">make</userinput>. This will automatically generate and install the
maps. You have to make sure to update the maps whenever you change the master
files, otherwise the changes will remain invisible to the network.</para><para><indexterm significance="normal"><primary>checking</primary><secondary>NIS</secondary></indexterm>
The section Setting Up an NIS Client with GNU libc 
will explain how to configure the NIS client code. If your setup doesn't
work, you should try to find out whether requests are arriving at your
server. If you specify the <option>debug</option>
command-line flag to <command moreinfo="none">ypserv</command>, it prints debugging
messages to the console about all incoming NIS queries and the results
returned. These should give you a hint as to where the problem
lies. Tobias's server doesn't have this option.</para></sect1><sect1 id="x-087-2-nis.securenets"><title>NIS Server Security</title><para><indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>security</secondary></indexterm>
<indexterm significance="normal"><primary>security</primary><secondary>using NIS</secondary></indexterm>
NIS used to have a major security flaw: it left your password file
readable by virtually anyone in the entire Internet, which made for
quite a number of possible intruders. As long as an intruder knew your
NIS domain name and the address of your server, he could simply send
it a request for the <filename moreinfo="none">passwd.byname</filename> map and
instantly receive all your system's encrypted passwords. With a fast
password-cracking program like <command moreinfo="none">crack</command> and a good
dictionary, guessing at least a few of your users' passwords is rarely
a problem.</para><para><indexterm significance="normal"><primary>securenets option</primary></indexterm>
<indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>securenets option</secondary></indexterm>
<indexterm significance="normal"><primary sortas="etc/ypserv.securenets file">/etc/ypserv.securenets file</primary></indexterm>
This is what the <emphasis>securenets</emphasis> option is all
about. It simply restricts access to your NIS server to certain hosts,
based on their IP addresses or network numbers. The latest version of
<command moreinfo="none">ypserv</command> implements this feature in two ways. The
first relies on a special configuration file called
<filename moreinfo="none">/etc/ypserv.securenets</filename> and the second
conveniently uses the <filename moreinfo="none">/etc/hosts.allow</filename> and
<filename moreinfo="none">/etc/hosts.deny</filename> files we already encountered in
<xref linkend="x-087-2-appl"></xref>.<footnote id="x-087-2-fnni06"><para> To
enable use of the <filename moreinfo="none">/etc/hosts.allow</filename> method, you may
have to recompile the server. Please read the instructions in the
<filename moreinfo="none">README</filename> included in the distribution.</para></footnote>
Thus, to restrict access to hosts from within the Brewery, their
network manager would add the following line to
<filename moreinfo="none">hosts.allow</filename>:
<screen format="linespecific">ypserv: 172.16.2.</screen></para><?troff .Nd 10?><para>This would let all hosts from IP network <systemitem moreinfo="none" role="sitename">172.16.2.0</systemitem> access the NIS server.  To
shut out all other hosts, a corresponding entry in
<filename moreinfo="none">hosts.deny</filename> would have to read:

<screen format="linespecific">ypserv: ALL</screen></para><para>IP numbers are not the only way you can specify hosts or networks in
<filename moreinfo="none">hosts.allow</filename> and <filename moreinfo="none">hosts.deny</filename>. Please
refer to the <filename moreinfo="none">hosts_access(5)</filename> manual page on your system
for details.  However, be warned that you <emphasis>cannot</emphasis> use host
or domain names for the <systemitem moreinfo="none" role="keyword">ypserv</systemitem> entry.
If you specify a hostname, the server tries to resolve this hostnamebut
the resolver in turn calls <command moreinfo="none">ypserv</command>, and you fall into an
endless loop.</para><para><indexterm significance="normal"><primary sortas="etc/ypserv.securenets file">/etc/ypserv.securenets file</primary></indexterm> 
To configure <systemitem moreinfo="none" role="keyword">securenets</systemitem> security
using the <filename moreinfo="none">/etc/ypserv.securenets</filename> method, you need
to create its configuration file, <filename moreinfo="none">/etc/ypserv.securenets</filename>.
This configuration file is simple
in structure. Each line describes a host or network of hosts that will be
allowed access to the server. Any address not described by an entry in this
file will be refused access. A line beginning with a # will be
treated as a comment. Example 13-1 shows what a simple <filename moreinfo="none">/etc/ypserv.securenets</filename>
would look like:</para><example id="x-087-2-nis.securenets.file"><title>Sample ypserv.securenets File</title><screen format="linespecific"># allow connections from local host -- necessary
host 127.0.0.1
# same as 255.255.255.255 127.0.0.1
#
# allow connections from any host on the Virtual Brewery network
255.255.255.0   172.16.1.0
#</screen></example><para>The first entry on each line is the netmask to use for the entry, with
<systemitem moreinfo="none" role="keyword">host</systemitem> being treated as a special
keyword meaning netmask 255.255.255.255. The second entry
on each line is the IP address to which to apply the netmask.</para><para>A third option is to use the secure portmapper instead of the
<option>securenets</option> option in
<command moreinfo="none">ypserv</command>. The secure portmapper
(<filename moreinfo="none">portmap-5.0</filename>) uses the <filename moreinfo="none">hosts.allow</filename> scheme as well, but
offers this for all RPC servers, not just <command moreinfo="none">ypserv</command>.<footnote id="x-087-2-fnni07"><para>The secure portmapper is available via anonymous FTP from
<systemitem moreinfo="none" role="sitename">ftp.win.tue.nl</systemitem> below the
<filename moreinfo="none">/pub/security/</filename> directory.</para></footnote>
However, you should not use both the <option>securenets</option> option and the secure
portmapper at the same time, because of the overhead this
authorization incurs.</para><indexterm significance="normal" class="endofrange" startref="idx-nisserver-1"></indexterm></sect1><sect1 id="x-087-2-nis.yp"><title>Setting Up an NIS Client with GNU libc</title><para><indexterm significance="normal"><primary>configuring</primary><secondary>NIS</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-nisclient-2"><primary>NIS (Network Information System)</primary><secondary>clients</secondary></indexterm>
<indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>GNU libc</secondary></indexterm> 
We will now describe and discuss the configuration of an NIS client using 
the GNU libc library support.</para><?troff .Nd 10?><para><indexterm significance="normal" class="startofrange" id="idx-filenameypconffilename-1"><primary sortas="etc/yp.conf file">/etc/yp.conf file</primary></indexterm>
<indexterm significance="normal"><primary>setting</primary><secondary>NIS domain</secondary></indexterm>
<indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>domains</secondary></indexterm>
<indexterm significance="normal"><primary>domains</primary><secondary>NIS</secondary></indexterm>
Your first step should be to tell the GNU libc NIS client which server to use
for NIS service. We mentioned earlier that the Linux <command moreinfo="none">ypbind</command>
allows you to configure the NIS server to use. The default behavior is to
query the server on the local network. If the host you are configuring is
likely to move from one domain to another, such as a laptop, you 
would leave the <filename moreinfo="none">/etc/yp.conf</filename> file empty and it would
query on the local network for the local NIS server wherever it happens to be.</para><para>A more secure configuration for most hosts is to set the server name in the
<filename moreinfo="none">/etc/yp.conf</filename> configuration file. A very simple file for a
host on the Winery's network may look like this:

<screen format="linespecific"># yp.conf - YP configuration for GNU libc library.
#
ypserver vbardolino</screen></para><para><?troff .hw argument?>The <systemitem moreinfo="none" role="keyword">ypserver</systemitem> statement tells your host
to use the host supplied as the NIS server for the local domain. In this
example we've specified the NIS server as <systemitem moreinfo="none" role="sitename">vbardolino</systemitem>. Of course, the IP address corresponding to
<systemitem moreinfo="none" role="sitename">vbardolino</systemitem> must be set
in the <filename moreinfo="none">hosts</filename> file; alternatively, you may use the
IP address itself with the <systemitem moreinfo="none" role="keyword">server</systemitem>
argument.</para><para>In the form shown in the example, the 
<command moreinfo="none">ypserver</command> command tells 
<command moreinfo="none">ypbind</command> to use the named server regardless of what the
current NIS domain may be. If, however, you are moving your machine between
different NIS domains frequently, you may want to keep information for several
domains in the <filename moreinfo="none">yp.conf</filename> file. You can have information on
the servers for various NIS domains in <filename moreinfo="none">yp.conf</filename> by
specifying the information using the
<systemitem moreinfo="none" role="keyword">domain</systemitem> statement. For instance, you
might change the previous sample file to look like this for a laptop:

<screen format="linespecific"># yp.conf - YP configuration for GNU libc library.
# 
domain winery server vbardolino 
domain brewery server vstout </screen></para><para>This lets you bring up the laptop in either of the two domains by simply
setting the desired NIS domain at boot time using the
<command moreinfo="none">domainname</command> command. The NIS client then uses whichever
server is relevant for the current domain.</para><para>There is a third option you may want to use. It covers the case when you
don't know the name or IP address of the server to use in a particular domain,
but still want the ability use a fixed server on certain domains. Imagine
we want to insist on using a specified server while operating within the 
Winery domain, but want to probe for the server to use while
in the Brewery domain. We would modify our <filename moreinfo="none">yp.conf</filename> 
file again to look like this instead:

<screen format="linespecific"># yp.conf - YP configuration for GNU libc library.
# 
domain winery server vbardolino 
domain brewery broadcast</screen></para><para>The <systemitem moreinfo="none" role="keyword">broadcast</systemitem> keyword tells
<command moreinfo="none">ypbind</command> to use whichever NIS server it finds for the domain.
<indexterm significance="normal" class="endofrange" startref="idx-filenameypconffilename-1"></indexterm></para><para><indexterm significance="normal"><primary>ypcat</primary><secondary>utility</secondary></indexterm>
<indexterm significance="normal"><primary>checking</primary><secondary>NIS</secondary></indexterm>
After creating this basic configuration file and making sure it is
world-readable, you should run your first test to connect
to your server. Make sure to choose a map your server distributes, like
<filename moreinfo="none">hosts.byname</filename>, and try to retrieve it by using the
<command moreinfo="none">ypcat</command> utility:</para><para><screen format="linespecific"># <userinput moreinfo="none">ypcat hosts.byname</userinput>
172.16.2.2      vbeaujolais.vbrew.com    vbeaujolais
172.16.2.3      vbardolino.vbrew.com     vbardolino
172.16.1.1      vlager.vbrew.com         vlager
172.16.2.1      vlager.vbrew.com         vlager
172.16.1.2      vstout.vbrew.com         vstout
172.16.1.3      vale.vbrew.com           vale
172.16.2.4      vchianti.vbrew.com       vchianti</screen></para><para><indexterm significance="normal"><primary>rpcinfo command</primary></indexterm>
The output you get should resemble that just shown. If you get an error
message instead that says: <literal moreinfo="none">Can't bind to server which serves
domain</literal>, then either the NIS domain name you've set doesn't
have a matching server defined in <filename moreinfo="none">yp.conf</filename>, or the server
is unreachable for some reason. In the latter case, make sure that a
<command moreinfo="none">ping</command> to the host yields a positive result, and that it is
indeed running an NIS server. You can verify the latter by using
<command moreinfo="none">rpcinfo</command>, which should produce the following output:

<screen format="linespecific"># <userinput moreinfo="none">rpcinfo -u</userinput> <replaceable>serverhost</replaceable> <userinput moreinfo="none">ypserv</userinput>
program 100004 version 1 ready and waiting
program 100004 version 2 ready and waiting</screen></para><indexterm significance="normal" class="endofrange" startref="idx-nisclient-2"></indexterm></sect1><sect1 id="x-087-2-nis.nsswitch"><title>Choosing the Right Maps</title><para><indexterm significance="normal" class="startofrange" id="idx-filenamensswitchconffilename-1"><primary sortas="etc/nsswitch.conf file">/etc/nsswitch.conf file</primary></indexterm>
<indexterm significance="normal"><primary>choosing</primary><secondary>NIS maps</secondary></indexterm>
Having made sure you can reach the NIS server, you have to decide which
configuration files to replace or augment with NIS maps. Commonly, you
will want to use NIS maps for the host and password lookup functions. The
former is especially useful if you do not have the BIND name service. The
password lookup lets all users log into their accounts from any system in the
NIS domain; this usually goes along with sharing a central
<filename moreinfo="none">/home</filename> directory among all hosts via NFS. The password
map is explained detail in the next section. </para><para>Other maps, like <filename moreinfo="none">services.byname</filename>, don't provide such
dramatic gains, but do save you some editing work. The
<filename moreinfo="none">services.byname</filename> map is valuable if you install
any network applications that use a service name not in the standard
<filename moreinfo="none">services</filename> file.</para><para>Generally, you want to have some choice of when a lookup function uses the
local files, when it queries the NIS server, and when it uses other servers 
such as DNS. GNU libc allows you to configure the order in which a function
accesses these services. This is controlled through the
<filename moreinfo="none">/etc/nsswitch.conf</filename> file, which stands for
<emphasis>Name Service Switch</emphasis>, but of course isn't limited to
the name service. For any of the data lookup functions supported by GNU libc,
the file contains a line naming the services to use.</para><para><indexterm significance="normal"><primary>services.byname map</primary></indexterm>
The right order of services depends on the type of data each service is 
offering. It is unlikely that the <filename moreinfo="none">services.byname</filename> map 
will contain entries differing from those in the local 
<filename moreinfo="none">services</filename> file; it will only contain additional entries. 
So it appears reasonable to query the local files first and check NIS only 
if the service name isn't found. Hostname information, on the other hand, 
may change very frequently, so DNS or the NIS server should always have the 
most accurate account, while the local <filename moreinfo="none">hosts</filename> file is 
only kept as a backup if DNS and NIS should fail. For hostnames, therefore, 
you normally want to check the local file last.</para><para><indexterm significance="normal"><primary>gethostbyname()</primary></indexterm> 
<indexterm significance="normal"><primary>gethostbyaddr()</primary></indexterm> 
<indexterm significance="normal"><primary>getservbyname()</primary></indexterm> 
The following example shows how to force <function moreinfo="none">gethostbyname</function>
and <function moreinfo="none">gethostbyaddr</function> to look in NIS and DNS before the
<filename moreinfo="none">hosts</filename> file and how to have the
<function moreinfo="none">getservbyname</function> function look in the local files before
querying NIS. These resolver functions will try each of the listed services 
in turn; if a lookup succeeds, the result is returned; otherwise, they will 
try the next service in the list. The file setting for these priorities is:</para><screen format="linespecific"># small sample /etc/nsswitch.conf
#
hosts:     nis dns files 
services:  files nis</screen><para>The following is a complete list of services and locations that may be used 
with an entry in the <filename moreinfo="none">nsswitch.conf</filename> file. The actual maps,
files, servers, and objects queried depend on the entry name. The 
following can appear to the right of a colon: </para><variablelist><varlistentry><term><systemitem moreinfo="none" role="keyword">nis</systemitem></term><listitem><para>Use the current domain NIS server. The location of the server queried
is configured in the <filename moreinfo="none">yp.conf</filename> file, as shown in the
previous section.  For the <systemitem moreinfo="none" role="keyword">hosts</systemitem> entry,
the <filename moreinfo="none">hosts.byname</filename> and <filename moreinfo="none">hosts.byaddr</filename> 
maps are queried.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">nisplus</systemitem> or
<systemitem moreinfo="none" role="keyword">nis+</systemitem></term><listitem><para>Use the NIS+ server for this domain. The location of the server is obtained
from the <filename moreinfo="none">/etc/nis.conf</filename> file.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">dns</systemitem></term><listitem><para>Use the DNS name server. This service type is useful only with the
<systemitem moreinfo="none" role="keyword">hosts</systemitem> entry. The name servers queried
are still determined by the standard <filename moreinfo="none">resolv.conf</filename> file.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">files</systemitem></term><listitem><para>Use the local file, such as the <filename moreinfo="none">/etc/hosts</filename> file for the
<systemitem moreinfo="none" role="keyword">hosts</systemitem> entry.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">compat</systemitem></term><listitem><para>Be compatible with older file formats. This option can be used when either 
NYS or glibc 2.x is used for NIS or NIS+ lookups. While these versions 
normally can't interpret older NIS entries in <filename moreinfo="none">passwd</filename> 
and <filename moreinfo="none">group</filename> files, 
<systemitem moreinfo="none" role="keyword">compat</systemitem> option allows them to work with 
those formats.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">db</systemitem></term><listitem><para>Look up the information from DBM files located in the
<filename moreinfo="none">/var/db</filename> directory. The corresponding NIS map name is used for that file.</para></listitem></varlistentry></variablelist><para>Currently, the NIS support in GNU libc caters to the following
<filename moreinfo="none">nsswitch.conf</filename> databases:
<systemitem moreinfo="none" role="keyword">aliases</systemitem>,
<systemitem moreinfo="none" role="keyword">ethers.group</systemitem>,
<systemitem moreinfo="none" role="keyword">hosts</systemitem>,
<systemitem moreinfo="none" role="keyword">netgroup</systemitem>,
<systemitem moreinfo="none" role="keyword">network</systemitem>,
<systemitem moreinfo="none" role="keyword">passwd</systemitem>,
<systemitem moreinfo="none" role="keyword">protocols</systemitem>,
<systemitem moreinfo="none" role="keyword">publickey</systemitem>,
<systemitem moreinfo="none" role="keyword">rpc</systemitem>,
<systemitem moreinfo="none" role="keyword">services</systemitem>, and
<systemitem moreinfo="none" role="keyword">shadow</systemitem>.
More entries are likely to be added.</para><para><xref linkend="x-087-2-nis.fig.switch"></xref> shows a more complete example that
introduces another feature of <filename moreinfo="none">nsswitch.conf</filename>. The
<systemitem moreinfo="none" role="keyword">[NOTFOUND=return]</systemitem> keyword in the
<systemitem moreinfo="none" role="keyword">hosts</systemitem> entry tells the NIS client to
return if the desired item couldn't be found in the NIS or DNS database. That
is, the NIS client will continue searching the local files
<emphasis>only</emphasis> if calls to the NIS and DNS servers fail for some
other reason. The local files will then be used only at boot time and as a
backup when the NIS server is down.</para><example id="x-087-2-nis.fig.switch"><title>Sample nsswitch.conf File</title><screen format="linespecific"># /etc/nsswitch.conf
#
hosts:      nis dns [NOTFOUND=return] files
networks:   nis [NOTFOUND=return] files
services:   files nis
protocols:  files nis
rpc:        files nis</screen></example><para>GNU libc provides some other actions that are described in the
<filename moreinfo="none">nsswitch</filename> manpage.</para><indexterm significance="normal" class="endofrange" startref="idx-filenamensswitchconffilename-1"></indexterm></sect1><sect1 id="x-087-2-nis.passwd"><title>Using the passwd and group Maps</title><para><indexterm significance="normal" class="startofrange" id="idx-nisfilenamepasswdfilenamemaps-1"><primary>NIS (Network Information System)</primary><secondary>passwd maps</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-passwordsnetwork-wide-1"><primary>passwords</primary><secondary>network-wide</secondary></indexterm>
<indexterm significance="normal"><primary>networks</primary><secondary>passwords</secondary></indexterm>
<indexterm significance="normal"><primary>Local Area Networks (LANs)</primary><secondary>passwords</secondary></indexterm>
One of the major applications of NIS is synchronizing user and account
information on all hosts in an NIS domain. Consequently, you usually keep
only a small local <filename moreinfo="none">/etc/passwd</filename> file, to which
site-wide information from the NIS maps is appended. However, simply
enabling NIS lookups for this service in <filename moreinfo="none">nsswitch.conf</filename>
is not nearly enough.</para><para>When relying on the password information distributed by NIS, you first
have to make sure that the numeric user IDs of any users you have in
your local <filename moreinfo="none">passwd</filename> file match the NIS server's idea of
user IDs. Consistency in user IDs is important for other purposes as
well, like mounting NFS volumes from other hosts in your network.</para><?troff .wcon_off?><para><indexterm significance="normal"><primary sortas="etc/passwd file">/etc/passwd file</primary></indexterm> 
<indexterm significance="normal"><primary sortas="etc/group file">/etc/group file</primary></indexterm> 
If any of the numeric IDs in <filename moreinfo="none">/etc/passwd</filename> or
<filename moreinfo="none">/etc/group</filename> differ from those in the maps, you have to
adjust file ownerships for all files that belong to that user. First, you
should change all uids and gids in <filename moreinfo="none">passwd</filename> and
<filename moreinfo="none">group</filename> to the new values, then find that all files
that belong to the users just changed and change their
ownership.  Assume <systemitem moreinfo="none" role="userid">news</systemitem>
used to have a user ID of 9 and <systemitem moreinfo="none" role="userid">okir</systemitem>
had a user ID of 103, which were changed to some other value; you could
then<?troff .ne 10?>
issue the following commands as root:

<screen format="linespecific"># <userinput moreinfo="none">find / -uid   9 -print /tmp/uid.9</userinput>
# <userinput moreinfo="none">find / -uid 103 -print /tmp/uid.103</userinput>
# <userinput moreinfo="none">cat /tmp/uid.9   | xargs chown news</userinput>
# <userinput moreinfo="none">cat /tmp/uid.103 | xargs chown okir</userinput></screen></para><para>It is important that you execute these commands with the new
<filename moreinfo="none">passwd</filename> file installed, and that you collect all
filenames before you change the ownership of any of them. To update the
group ownerships of files, use a similar method with the gid instead of the 
uid, and chgrp instead of chown.</para><para><?troff .hw information?>Once you do this, the numerical uids and gids on your system will
agree with those on all other hosts in your NIS domain.  The next step
is to add configuration lines to <filename moreinfo="none">nsswitch.conf</filename>
that enable NIS lookups for user and group information:

<screen format="linespecific"># /etc/nsswitch.conf - passwd and group treatment
passwd: nis files
group:  nis files</screen></para><para><indexterm significance="normal"><primary>login command and NIS maps</primary></indexterm> 
This affects where the <command moreinfo="none">login</command> command and all its
friends look for user information. When a user tries to log in,
<command moreinfo="none">login</command> queries the NIS maps first, and if this
lookup fails, falls back to the local files. Usually, you will remove
almost all users from your local files, and only leave entries for
<systemitem moreinfo="none" role="userid">root</systemitem> and generic accounts like
<systemitem moreinfo="none" role="userid">mail</systemitem> in it.  This is because
some vital system tasks may have to map uids to usernames or vice
versa.  For example, administrative <command moreinfo="none">cron</command> jobs may
execute the <filename moreinfo="none">su</filename> command to temporarily become
<systemitem moreinfo="none" role="userid">news</systemitem>, or the UUCP subsystem may
mail a status report.  If <systemitem moreinfo="none" role="userid">news</systemitem>
and <systemitem moreinfo="none" role="userid">uucp</systemitem> don't have entries in
the local <filename moreinfo="none">passwd</filename> file, these jobs will fail
miserably during an NIS brownout.</para><para>Lastly, if you are using either the old NIS implementation (supported by the
<systemitem moreinfo="none" role="keyword">compat</systemitem> mode for the
<filename moreinfo="none">passwd</filename> and <filename moreinfo="none">group</filename> files in the
NYS or glibc implementations), you must insert the unwieldy special entries
into them. These entries represent where the NIS derived records will
be inserted into the database of information. The entries can be added
anywhere, but are usually just added to the end. The entries to add for the 
<filename moreinfo="none">/etc/passwd</filename> file are:

<screen format="linespecific"><userinput moreinfo="none">+::::::</userinput></screen>

and for the <filename moreinfo="none">/etc/groups</filename> file:

<screen format="linespecific"><userinput moreinfo="none">+:::</userinput></screen></para><para>With both glibc 2.x and NYS you can override parameters in a users 
record received from the NIS server by creating entries with a +
prepended to the login name, and exclude specified users by creating
entries with a - prepended to the login name.
For example the entries:

<screen format="linespecific"><userinput moreinfo="none">+stuart::::::/bin/jacl</userinput>
<userinput moreinfo="none">-jedd::::::</userinput></screen>

would override the shell specified for the user
<systemitem moreinfo="none" role="userid">stuart</systemitem> supplied by the NIS server,
and would disallow the user <systemitem moreinfo="none" role="userid">jedd</systemitem> from
logging in on this machine. Any fields left blank use the information
supplied by the NIS server.</para><para>There are two big caveats in order here. First, the setup as described up to
here works only for login suites that don't use shadow passwords. The
intricacies of using shadow passwords with NIS will be discussed in the next 
section.
Second, the login commands are not the only ones that access the
<filename moreinfo="none">passwd</filename> filelook at the <command moreinfo="none">ls</command>
command, which most people use almost constantly. Whenever compiling a long
listing, <command moreinfo="none">ls</command> displays the symbolic names for user
and group owners of a file; that is, for each uid and gid it encounters,
it has to query the NIS server. An NIS query takes slightly longer to
perform than the equivalent lookup in a local file. You may find that sharing
your <filename moreinfo="none">passwd</filename> and <filename moreinfo="none">group</filename> information
using NIS causes a noticable reduction in the performance of some programs that
use this information frequently.</para><para>Still, this is not the whole story. Imagine what happens if a user wants to
change her password. Usually, she will invoke <command moreinfo="none">passwd</command>, which
reads the new password and updates the local <filename moreinfo="none">passwd</filename> file.
This is impossible with NIS, since that file isn't available locally anymore,
but having users log into the NIS server whenever they want to change their
passwords is not an option, either. Therefore, NIS provides a drop-in
replacement for <command moreinfo="none">passwd</command> called <command moreinfo="none">yppasswd</command>,
which handles password changes under NIS. To change the password
on the server host, it contacts the <command moreinfo="none">yppasswdd</command> daemon on
that host via RPC, and provides it with the updated password information.
Usually you install <command moreinfo="none">yppasswd</command> over the normal program by
doing something like this:

<indexterm significance="normal"><primary>yppasswd</primary></indexterm> 
<screen format="linespecific"># <userinput moreinfo="none">cd /bin</userinput>
# <userinput moreinfo="none">mv passwd passwd.old</userinput>
# <userinput moreinfo="none">ln yppasswd passwd</userinput></screen></para><para>At the same time, you have to install <command moreinfo="none">rpc.yppasswdd</command> on the
server and start it from a network script. This will effectively hide any of
the contortions of NIS from your users.</para><indexterm significance="normal" class="endofrange" startref="idx-passwordsnetwork-wide-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-nisfilenamepasswdfilenamemaps-1"></indexterm></sect1><sect1 id="x-087-2-nis.shadow"><title>Using NIS with Shadow Support</title><para><indexterm significance="normal"><primary>NIS (Network Information System)</primary><secondary>shadow passwords and</secondary></indexterm>
<indexterm significance="normal"><primary>shadow passwords and NIS</primary></indexterm> 
Using NIS in conjunction with shadow password files is somewhat problematic.
First we have some bad news: using NIS defeats the goals of shadow passwords. 
The <filename moreinfo="none">shadow</filename> password scheme was designed to prevent 
nonroot users from having access to the encrypted form of the login 
passwords. Using NIS to share <filename moreinfo="none">shadow</filename> data by necessity 
makes the encrypted passwords available to any user who can listen to the NIS 
server replies on the network. A policy to enforce users to choose 
good passwords is arguably better than trying to shadow 
passwords in an NIS environment. Let's take a quick look at how you do it, 
should you decide to forge on ahead.</para><para>In libc5 there is no real solution to sharing <filename moreinfo="none">shadow</filename> data
using NIS. The only way to distribute password and user information by NIS is
through the standard <filename moreinfo="none">passwd.*</filename> maps. If you do have
shadow passwords installed, the easiest way to share them is to generate a
proper <filename moreinfo="none">passwd</filename> file from <filename moreinfo="none">/etc/shadow</filename>
using tools like <command moreinfo="none">pwuncov</command>, and create the NIS maps from
that file.</para><indexterm significance="normal"><primary sortas="etc/shadow file">/etc/shadow file</primary></indexterm><para>Of course, there are some hacks necessary to use NIS and shadow passwords at
the same time, for instance, by installing an <filename moreinfo="none">/etc/shadow</filename>
file on each host in the network, while distributing user information, through
NIS. However, this hack is really crude and defies the goal of NIS,
which is to ease system administration.</para><para><indexterm significance="normal"><primary>GNU libc (NIS support)</primary></indexterm>
<indexterm significance="normal"><primary>libc6 (NIS support)</primary></indexterm>
The NIS support in the GNU libc library (libc6) provides support for shadow
password databases. It does not provide any real solution to making your 
passwords accessible, but it does simplify password management in 
environments in which you do want to use NIS with shadow passwords.
To use it, you must create a <filename moreinfo="none">shadow.byname</filename> database
and add the following line to your <filename moreinfo="none">/etc/nsswitch.conf</filename>:

<screen format="linespecific"><userinput moreinfo="none"># Shadow password support</userinput>
<userinput moreinfo="none">shadow:         compat</userinput></screen></para><para><?troff .hw chapter?>If you use shadow passwords along with NIS, you must try to maintain some 
security by restricting access to your NIS database.  See <xref linkend="x-087-2-nis.securenets"></xref> earlier in this chapter.</para></sect1><indexterm significance="normal" class="endofrange" startref="idx-configuringnis-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-nis-1"></indexterm></chapter><chapter id="x-087-2-nfs"><title>The Network<?lb?>File System</title><indexterm significance="normal"><primary>file sharing</primary></indexterm><indexterm significance="normal"><primary>remote</primary><secondary>file access</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-nfs-1"><primary>NFS (Network File System)</primary></indexterm><para>The Network File System (NFS) is probably the most prominent network
service using RPC. It allows you to access files on remote hosts in
exactly the same way you would access local files. A mixture of kernel
support and user-space daemons on the client side, along with an NFS
server on the server side, makes this possible. This file access is
completely transparent to the client and works across a variety of
server and host architectures.</para><para>NFS offers a number of useful features:

<itemizedlist><listitem><para>Data accessed by all users can be kept on a central host, with clients
mounting this directory at boot time. For example, you can keep all user
accounts on one host and have all hosts on your network mount
<filename moreinfo="none">/home</filename> from that host. If NFS is installed beside
NIS, users can log into any system and still work on one set of files.</para></listitem><listitem><para>Data consuming large amounts of disk space can be kept on a single host. For
example, all files and programs relating to LaTeX and METAFONT can be kept
and maintained in one place.</para></listitem><listitem><para>Administrative data can be kept on a single host. There is no need to use
<command moreinfo="none">rcp</command> to install the same stupid file on 20 different
machines.</para></listitem></itemizedlist></para><para>It's not too hard to set up basic NFS operation on both the client and
server; this chapter tells you how.</para><para>Linux NFS is largely the work of
Rick Sladkey, who wrote the NFS kernel code and large parts of the NFS server.<footnote id="x-087-2-fnnf01"><para>Rick can be reached at
<systemitem moreinfo="none" role="emailaddr">jrs@world.std.com</systemitem>.</para></footnote> The latter is derived from the <emphasis role="bold">unfsd</emphasis> user space NFS server, originally written by Mark Shand, and the <emphasis role="bold">hnfs</emphasis> Harris NFS server, written by Donald Becker.

</para><para><indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>mounting volume on</secondary></indexterm>
Let's have a look at how NFS works. First, a client tries to mount a
directory from a remote host on a local directory just the same way it
does a physical device.  However, the syntax used to specify the
remote directory is different. For example, to mount
<filename moreinfo="none">/home</filename> from host <systemitem moreinfo="none" role="sitename">vlager</systemitem> to <filename moreinfo="none">/users</filename> on
<systemitem moreinfo="none" role="sitename">vale</systemitem>, the administrator
issues the following command on <systemitem moreinfo="none" role="sitename">vale</systemitem>:<footnote id="x-087-2-fnnf02"><para>Actually, you can omit the <literal moreinfo="none">t nfs</literal> argument
because <command moreinfo="none">mount</command> sees from the colon that this
specifies an NFS volume.</para></footnote>

<screen format="linespecific"># <userinput moreinfo="none">mount -t nfs vlager:/home /users</userinput></screen></para><para><indexterm significance="normal"><primary>mount command</primary></indexterm> 
<command moreinfo="none">mount</command> will try to connect to the
<command moreinfo="none">rpc.mountd</command> mount daemon on
<systemitem moreinfo="none" role="sitename">vlager</systemitem> via RPC. The
server will check if <systemitem moreinfo="none" role="sitename">vale</systemitem> is
permitted to mount the directory in question, and if so, return it a
file handle. This file handle will be used in all subsequent requests to
files below <filename moreinfo="none">/users</filename>.</para><para><indexterm significance="normal"><primary>servers</primary><secondary>rpc.nfsd daemon</secondary></indexterm>
<indexterm significance="normal"><primary>servers</primary><secondary>nfsd daemon</secondary></indexterm>
<indexterm significance="normal"><primary>rpc.nfsd daemon</primary></indexterm>
<indexterm significance="normal"><primary>nfsd daemon</primary></indexterm>
When someone accesses a file over NFS, the kernel places an RPC call
to <command moreinfo="none">rpc.nfsd</command> (the NFS daemon) on the server
machine. This call takes the file handle, the name of the file to be
accessed, and the user and group IDs of the user as parameters. These
are used in determining access rights to the specified file. In order
to prevent unauthorized users from reading or modifying files, user
and group IDs must be the same on both hosts.</para><para>On most Unix implementations, the NFS functionality of both client and
server is implemented as kernel-level daemons that are started from
user space at system boot. These are the <emphasis>NFS Daemon</emphasis> 
(<command moreinfo="none">rpc.nfsd</command>) on the server host, and the
<emphasis>Block I/O Daemon</emphasis>
(<command moreinfo="none">biod</command>) on the client host. To improve
throughput, <command moreinfo="none">biod</command> performs asynchronous I/O using
read-ahead and write-behind; also, several <command moreinfo="none">rpc.nfsd</command>
daemons are usually run concurrently.</para><para><indexterm significance="normal"><primary>Kirch, Olaf</primary></indexterm>
<indexterm significance="normal"><primary>2.2 kernels</primary><secondary>NFS server support</secondary></indexterm>
The current NFS implementation of Linux is a little different from the
classic NFS in that the server code runs entirely in user space, so
running multiple copies simultaneously is more complicated. The
current <command moreinfo="none">rpc.nfsd</command> implementation offers an
experimental feature that allows limited support for multiple
servers. Olaf Kirch developed kernel-based NFS server support 
featured in 2.2 Version Linux kernels. Its performance is
significantly better than the existing userspace implementation. We'll
describe it later in this chapter.</para><sect1 id="x-087-2-nfs.nfsd"><title>Preparing NFS</title><para><indexterm significance="normal"><primary sortas="proc/filesystems file">/proc/filesystems file</primary></indexterm>
Before you can use NFS, be it as server or client, you must make sure your
kernel has NFS support compiled in. Newer kernels have a simple interface
on the <filename moreinfo="none">proc</filename> filesystem for this, the
<filename moreinfo="none">/proc/filesystems</filename> file, which you can display
using <command moreinfo="none">cat</command>:

<screen format="linespecific">$ <userinput moreinfo="none">cat /proc/filesystems</userinput>
	minix
	ext2
	msdos
nodev	proc
nodev	nfs</screen></para><para>If <systemitem moreinfo="none" role="keyword">nfs</systemitem> is missing from this
list, you have to compile your own kernel with NFS enabled, or perhaps
you will need to load the kernel module if your NFS support was
compiled as a module.  Configuring the kernel network options is
explained in the Kernel Configuration section of <xref linkend="x-087-2-hardware"></xref>.</para></sect1><sect1 id="x-087-2-nfs.mountd"><title>Mounting an NFS Volume</title><para><indexterm significance="normal"><primary>remote</primary><secondary>filesystem</secondary></indexterm>
<indexterm significance="normal"><primary>mounting</primary><secondary>an NFS volume</secondary></indexterm>
<indexterm significance="normal"><primary>access</primary><secondary>to remote files</secondary></indexterm>
<indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>mounting volume on</secondary></indexterm>
The mounting of NFS volumes closely resembles regular file
systems. Invoke <command moreinfo="none">mount</command> using the following syntax:<footnote id="x-087-2-fnnf05"><para> One doesn't say filesystem
because these are not proper filesystems.</para></footnote>

<screen format="linespecific"># <userinput moreinfo="none">mount -t nfs</userinput> <replaceable>nfs_volume local_dir options</replaceable> </screen></para><para><replaceable>nfs_volume</replaceable> is given as
<replaceable>remote_host</replaceable>:<replaceable>remote_dir</replaceable>.
Since this notation is unique to NFS filesystems, you can leave out
the <option>t nfs</option> option.</para><para><indexterm significance="normal"><primary sortas="etc/fstab file">/etc/fstab file</primary></indexterm>
There are a number of additional options that you can specify to
<command moreinfo="none">mount</command> upon mounting an NFS volume. These may be
given either following the <option>o</option> switch on the
command line or in the options field of the
<filename moreinfo="none">/etc/fstab</filename> entry for the volume.  In both cases,
multiple options are separated by commas and must not
contain any whitespace characters. Options specified on the command
line always override those given in the <filename moreinfo="none">fstab</filename>
file.</para><para>Here is a sample entry from <filename moreinfo="none">/etc/fstab</filename>:

<screen format="linespecific"># volume              mount point       type  options
news:/var/spool/news  /var/spool/news   nfs   timeo=14,intr</screen></para><para>This volume can then be mounted using this command:

<screen format="linespecific"># <userinput moreinfo="none">mount news:/var/spool/news</userinput></screen></para><para>In the absence of an <filename moreinfo="none">fstab</filename> entry, NFS
<command moreinfo="none">mount</command> invocations look a lot uglier. For instance,
suppose you mount your users' home directories from a machine named
<systemitem moreinfo="none" role="sitename">moonshot</systemitem>, which uses a default
block size of 4 K for read/write operations. You might increase the
block size to 8 K to obtain better performance by issuing the command:

<screen format="linespecific"># <userinput moreinfo="none">mount moonshot:/home /home -o rsize=8192,wsize=8192</userinput></screen></para><para><indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>restricting block size</secondary></indexterm>
The list of all valid options is described in its entirety in the
<filename moreinfo="none">nfs(5)</filename> manual page. The following is a partial list
of options you would probably want to use:

<variablelist><varlistentry><term><emphasis>rsize=n</emphasis> and <emphasis>wsize=n</emphasis></term><listitem><para>These specify the datagram size used by the NFS clients on read and write
requests, respectively. The default depends on the version of kernel, but
is normally 1,024 bytes.</para></listitem></varlistentry><varlistentry><term><emphasis>timeo=n</emphasis></term><listitem><para>This sets the time (in tenths of a second) the NFS client will wait for a
request to complete. The default value is 7 (0.7 seconds). What happens after
a timeout depends on whether you use the <emphasis>hard</emphasis> or 
<emphasis>soft</emphasis> option.</para></listitem></varlistentry><varlistentry><term><emphasis>hard</emphasis></term><listitem><para>Explicitly mark this volume as hard-mounted. This is on by default.
This option causes the server to report a message to the console when a
major timeout occurs and continues trying indefinitely.</para></listitem></varlistentry><varlistentry><term><emphasis>soft</emphasis></term><listitem><para>Soft-mount (as opposed to hard-mount) the driver. This option causes
an I/O error to be reported to the process attempting a file operation when
a major timeout occurs.</para></listitem></varlistentry><varlistentry><term><emphasis>intr</emphasis></term><listitem><para>Allow signals to interrupt an NFS call. Useful for aborting when the
server doesn't respond.</para></listitem></varlistentry></variablelist></para><para>Except for <emphasis>rsize</emphasis> and <emphasis>wsize</emphasis>, all of these options
apply to the client's behavior if the server should become temporarily
inaccessible. They work together in the following way: Whenever the
client sends a request to the NFS server, it expects the operation to
have finished after a given interval (specified in the
<emphasis>timeout</emphasis> option). If no confirmation
is received within this time, a so-called <emphasis>minor timeout</emphasis>
occurs, and the operation is retried with the timeout interval doubled. After
reaching a maximum timeout of 60 seconds, a <emphasis>major timeout</emphasis>
occurs.</para><para><indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>hard-mounting versus soft-mounting</secondary></indexterm>
<indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>timeout</secondary></indexterm>
By default, a major timeout causes the client to print a message
to the console and start all over again, this time with an initial
timeout interval twice that of the previous cascade. Potentially, this
may go on forever. Volumes that stubbornly retry an operation until
the server becomes available again are called
<emphasis>hard-mounted</emphasis>. The opposite variety, called
<emphasis>soft-mounted</emphasis>, generate an I/O error for the
calling process whenever a major timeout occurs. Because of the
write-behind introduced by the buffer cache, this error condition is
not propagated to the process itself before it calls the
<function moreinfo="none">write</function> function the next time, so a program can
never be sure that a write operation to a soft-mounted volume has
succeeded at all.</para><para>Whether you hard- or soft-mount a volume depends partly on taste but
also on the type of information you want to access from a volume. For
example, if you mount your X programs by NFS, you certainly would not
want your X session to go berserk just because someone brought the
network to a grinding halt by firing up seven copies of Doom at the
same time or by pulling the Ethernet plug for a moment. By
hard-mounting the directory containing these programs, you make sure
that your computer waits until it is able to re-establish contact
with your NFS server. On the other hand, non-critical data such as
NFS-mounted news partitions or FTP archives may also be
soft-mounted, so if the remote machine is temporarily unreachable or
down, it doesn't hang your session. If your network connection to the
server is flaky or goes through a loaded router, you may either
increase the initial timeout using the <emphasis>timeo</emphasis> option or hard-mount the
volumes. NFS volumes are hard-mounted by default.</para><para>Hard mounts present a problem because, by default, the file operations
are not interruptible. Thus, if a process attempts, for example, a
write to a remote server and that server is unreachable, the user's
application hangs and the user can't do anything to abort the
operation. If you use the <emphasis>intr</emphasis>
option in conjuction with a hard mount, any signals received by the
process interrupt the NFS call so that users can still abort
hanging file accesses and resume work (although without saving the
file).</para><para>Usually, the <command moreinfo="none">rpc.mountd</command> daemon in some way or other
keeps track of which directories have been mounted by what hosts. This
information can be displayed using the <command moreinfo="none">showmount</command>
program, which is also included in the NFS server package:

<screen format="linespecific"># <userinput moreinfo="none">showmount -e moonshot</userinput>
Export list for localhost:
/home anon clnt

# <userinput moreinfo="none">showmount -d moonshot</userinput>
Directories on localhost:
/home

# <userinput moreinfo="none">showmount -a moonshot</userinput>
All mount points on localhost:
localhost:/home</screen></para></sect1><sect1 id="x-087-2-nfs.daemons"><title>The NFS Daemons</title><para><indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>daemons</secondary></indexterm>
<indexterm significance="normal"><primary>rpc.mountd daemon</primary></indexterm>
<indexterm significance="normal"><primary>rpc.nfsd daemon</primary></indexterm>
If you want to provide NFS service to other hosts, you have to run the
<command moreinfo="none">rpc.nfsd</command> and <command moreinfo="none">rpc.mountd</command> daemons on your
machine. As RPC-based programs, they are not managed by
<command moreinfo="none">inetd</command>, but are started up at boot time and register
themselves with the portmapper; therefore, you have to make sure to start them
only after <command moreinfo="none">rpc.portmap</command> is running. Usually, you'd use
something like the following example in one of your network boot scripts:

<screen format="linespecific">if [ -x /usr/sbin/rpc.mountd ]; then
        /usr/sbin/rpc.mountd; echo -n " mountd"
fi
if [ -x /usr/sbin/rpc.nfsd ]; then
        /usr/sbin/rpc.nfsd; echo -n " nfsd"
fi</screen></para><para><indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>matching uids and gids</secondary></indexterm>
The ownership information of the files an NFS daemon provides to its clients
usually contains only numerical user and group IDs.  If both client and server
associate the same user and group names with these numerical IDs, they are
said to their share uid/gid space. For example, this is the case when you
use NIS to distribute the <filename moreinfo="none">passwd</filename> information to all
hosts on your LAN.</para><para>On some occasions, however, the IDs on different hosts do not
match. Rather than updating the uids and gids of the client to match
those of the server, you can use the <command moreinfo="none">rpc.ugidd</command>
mapping daemon to work around the disparity.  Using the <emphasis>map_daemon</emphasis> option explained a little later, you can
tell <command moreinfo="none">rpc.nfsd</command> to map the server's uid/gid space to
the client's uid/gid space with the aid of the
<command moreinfo="none">rpc.ugidd</command> on the client. Unfortunately, the
<command moreinfo="none">rpc.ugidd</command> daemon isn't supplied on all modern Linux
distributions, so if you need it and yours doesn't have it, you will need to
compile it from source.</para><para><command moreinfo="none">rpc.ugidd</command> is an RPC-based server that is started from your
network boot scripts, just like <command moreinfo="none">rpc.nfsd</command> and
<command moreinfo="none">rpc.mountd</command>:</para><screen format="linespecific">if [ -x /usr/sbin/rpc.ugidd ]; then
        /usr/sbin/rpc.ugidd; echo -n " ugidd"
fi</screen></sect1><sect1 id="x-087-2-nfs.exports"><title>The exports File</title><para><indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>exporting a volume</secondary></indexterm>
<indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>exports file</secondary></indexterm>
<indexterm significance="normal"><primary>access</primary><secondary>granting</secondary></indexterm>
<indexterm significance="normal"><primary>mountd daemon</primary></indexterm>
<indexterm significance="normal"><primary>exports file</primary></indexterm>
<indexterm significance="normal"><primary sortas="etc/exports file">/etc/exports file</primary></indexterm> 
Now we'll look at how we configure the NFS server. Specifically, we'll
look at how we tell the NFS server what filesystems it should make
available for mounting, and the various parameters that control the
access clients will have to the filesystem. The server determines the
type of access that is allowed to the server's files. The
<filename moreinfo="none">/etc/exports</filename> file lists the filesystems that the
server will make available for clients to mount and use.</para><para>By default, <command moreinfo="none">rpc.mountd</command> disallows all directory mounts,
which is a rather sensible attitude. If you wish to permit one or more hosts
to NFS-mount a directory, you must <emphasis>export</emphasis> it, that is,
specify it in the <filename moreinfo="none">exports</filename> file. A sample file may look
like this:

<screen format="linespecific"># exports file for vlager
/home             vale(rw) vstout(rw) vlight(rw)
/usr/X11R6        vale(ro) vstout(ro) vlight(ro)
/usr/TeX          vale(ro) vstout(ro) vlight(ro)
/                 vale(rw,no_root_squash)
/home/ftp         (ro)</screen></para><para>Each line defines a directory and the hosts that are allowed to mount it.  A
hostname is usually a fully qualified domain name but may additionally
contain the <systemitem moreinfo="none" role="keyword">*</systemitem> and
<systemitem moreinfo="none" role="keyword">?</systemitem> wildcards, which act the way they
do with the Bourne shell. For instance, <literal moreinfo="none">lab*.foo.com</literal>
matches <systemitem moreinfo="none" role="sitename">lab01.foo.com</systemitem> as well as
<systemitem moreinfo="none" role="sitename">laboratory.foo.com</systemitem>. The host may also
be specified using an IP address range in the form
<replaceable>address</replaceable>/<replaceable>netmask</replaceable>. If
no hostname is given, as with the <filename moreinfo="none">/home/ftp</filename> directory
in the previous example, any host matches and is allowed to mount the
directory.</para><para>When checking a client host against the <filename moreinfo="none">exports</filename> file,
<command moreinfo="none">rpx.mountd</command> looks up the client's hostname using the
<function moreinfo="none">gethostbyaddr</function> call. With DNS, this call returns the
client's canonical hostname, so you must make sure not to use aliases in
<filename moreinfo="none">exports</filename>. In an NIS environment the returned name is
the first match from the hosts database, and with neither DNS or NIS, the
returned name is the first hostname found in the <filename moreinfo="none">hosts</filename>
file that matches the client's address.</para><para>The hostname is followed by an optional comma-separated list of flags,
enclosed in parentheses. Some of the values these flags may take are:

<variablelist><varlistentry><term><emphasis>secure</emphasis></term><listitem><para>This flag insists that requests be made from a reserved source port,
i.e., one that is less than 1,024. This flag is set by default.</para></listitem></varlistentry><varlistentry><term><emphasis>insecure</emphasis></term><listitem><para>This flag reverses the effect of the
<emphasis>secure</emphasis> flag.</para></listitem></varlistentry><varlistentry><term><emphasis>ro</emphasis></term><listitem><para>This flag causes the NFS mount to be read-only. This flag is enabled
by default.</para></listitem></varlistentry><varlistentry><term><emphasis>rw</emphasis></term><listitem><para>This option mounts file hierarchy read-write.</para></listitem></varlistentry><varlistentry><term><emphasis>root_squash</emphasis></term><listitem><para><indexterm significance="normal"><primary>access</primary><secondary>restricting</secondary></indexterm>
This security feature denies the superusers on the specified hosts any
special access rights by mapping requests from uid 0 on the client to
the uid 65534 (that is, -2) on the server. This uid should be
associated with the user <systemitem moreinfo="none" role="userid">nobody</systemitem>.</para></listitem></varlistentry><varlistentry><term><emphasis>no_root_squash</emphasis></term><listitem><para>Don't map requests from uid 0.  This option is on by default, so
superusers have superuser access to your system's exported
directories.</para></listitem></varlistentry><varlistentry><term><emphasis>link_relative</emphasis></term><listitem><para>This option converts absolute symbolic links (where the link contents
start with a slash) into relative links. This option makes sense only
when a host's entire filesystem is mounted; otherwise, some of the
links might point to nowhere, or even worse, to files they were never
meant to point to. This option is on by default.</para></listitem></varlistentry><varlistentry><term><emphasis>link_absolute</emphasis></term><listitem><para>This option leaves all symbolic links as they are (the normal behavior
for Sun-supplied NFS servers).</para></listitem></varlistentry><varlistentry><term><emphasis>map_identity</emphasis></term><listitem><para><indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>matching uids and gids</secondary></indexterm>
This option tells the server to assume that the client uses the same
uids and gids as the server. This option is on by default.</para></listitem></varlistentry><varlistentry><term><emphasis>map_daemon</emphasis></term><listitem><para>This option tells the NFS server to assume that client and server do not
share the same uid/gid space.  <command moreinfo="none">rpc.nfsd</command> then builds a
list that maps IDs between client and server by querying the client's
<command moreinfo="none">rpc.ugidd</command> daemon.</para></listitem></varlistentry><varlistentry><term><emphasis>map_static</emphasis></term><listitem><para>This option allows you to specify the name of a file that contains a
static map of uids and gids. For example,
<literal moreinfo="none">map_static=/etc/nfs/vlight.map</literal> would specify the
<filename moreinfo="none">/etc/nfs/vlight.map</filename> file as a uid/gid map. The
syntax of the map file is described in the
<filename moreinfo="none">exports(5)</filename> manual page.</para></listitem></varlistentry><varlistentry><term><emphasis>map_nis</emphasis></term><listitem><para>This option causes the NIS server to do the uid and gid mapping.</para></listitem></varlistentry><varlistentry><term><emphasis>anonuid</emphasis> and <emphasis>anongid</emphasis></term><listitem><para>These options allow you to specify the uid and gid of the anonymous account.
This is useful if you have a volume exported for public mounts.</para></listitem></varlistentry></variablelist></para><para><indexterm significance="normal"><primary>syslog</primary></indexterm>
Any error in parsing the <filename moreinfo="none">exports</filename> file is reported
to <command moreinfo="none">syslogd</command>'s <systemitem moreinfo="none" role="keyword">daemon</systemitem> facility at level <systemitem moreinfo="none" role="keyword">notice</systemitem> whenever
<command moreinfo="none">rpc.nfsd</command> or <command moreinfo="none">rpc.mountd</command> is
started up.</para><para><?troff .hw security?>Note that hostnames are obtained from the client's IP address by
reverse mapping, so the resolver must be configured properly.
If you use BIND and are very security conscious, you should enable spoof
checking in your <filename moreinfo="none">host.conf</filename> file. We discuss these
topics in <xref linkend="x-087-2-resolv"></xref>.</para></sect1><sect1 id="x-087-2-nfs.kernelv2"><title>Kernel-Based NFSv2 Server Support</title><para><indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>kernel-based server support</secondary></indexterm>
<indexterm significance="normal"><primary>NFSv2/NFSv3 server support</primary></indexterm>
<indexterm significance="normal"><primary>servers</primary><secondary>kernel-based support</secondary></indexterm>
<indexterm significance="normal"><primary>kernels</primary><secondary>NFSv2/NFSv3 server support</secondary></indexterm>
The user-space NFS server traditionally used in Linux works reliably but
suffers performance problems when overworked. This is primarily because
of the overhead the system call interface adds to its operation, and because
it must compete for time with other, potentially less important, user-space
processes.</para><para><?troff .hw performance?><indexterm significance="normal"><primary>Kirch, Olaf</primary></indexterm>
<indexterm significance="normal"><primary>Lu, H.J.</primary></indexterm>
<indexterm significance="normal"><primary>Morris, G. Allan</primary></indexterm>
<indexterm significance="normal"><primary>Myklebust, Trond</primary></indexterm>
<indexterm significance="normal"><primary>2.2 kernels</primary><secondary>NFS server support</secondary></indexterm>
The 2.2.0 kernel supports an experimental kernel-based NFS server developed
by Olaf Kirch and further developed by H.J. Lu, G. Allan Morris, and Trond
Myklebust. The kernel-based NFS support provides a significant boost in server
performance.</para><para>In current release distributions, you may find the server tools
available in prepackaged form. If not, you can locate them at
<systemitem moreinfo="none" role="url">http://csua.berkeley.edu/~gam3/knfsd/</systemitem>.  You need to 
build a 2.2.0 kernel with the kernel-based NFS daemon
included in order to make use of the tools. You can check if your
kernel has the NFS daemon included by looking to see if the
<filename moreinfo="none">/proc/sys/sunrpc/nfsd_debug</filename> file exists. If it's
not there, you may have to load the <command moreinfo="none">rpc.nfsd</command> module
using the <command moreinfo="none">modprobe</command> utility.</para><para>The kernel-based NFS daemon uses a standard
<filename moreinfo="none">/etc/exports</filename> configuration file. The package
supplies replacement versions of the <command moreinfo="none">rpc.mountd</command> and
<command moreinfo="none">rpc.nfsd</command> daemons that you start much the same way
as their userspace daemon counterparts.</para></sect1><sect1 id="x-087-2-nfs.kernelv3"><title>Kernel-Based NFSv3 Server Support</title><para>The version of NFS that has been most commonly used is NFS Version 2.
Technology has rolled on ahead and it has begun to show weaknesses that only a
revision of the protocol could overcome. Version 3 of the Network File System
supports larger files and filesystems, adds significantly enhanced security,
and offers a number of performance improvements that most users will find
useful.</para><para>Olaf Kirch and Trond Myklebust are developing an experimental NFSv3 server. It is featured in the developer Version 2.3 kernels and a patch is
available against the 2.2 kernel source. It builds on the Version 2
kernel-based NFS daemon.</para><para>The patches are available from the Linux Kernel based NFS server home page at
<systemitem moreinfo="none" role="url">http://csua.berkeley.edu/~gam3/knfsd/</systemitem>.</para></sect1><indexterm significance="normal" class="endofrange" startref="idx-nfs-1"></indexterm></chapter><chapter id="x-087-2-ipx"><title>IPX and the <?lb?>NCP Filesystem</title><indexterm significance="normal"><primary>IPX (Internet Packet eXchange)</primary></indexterm><indexterm significance="normal"><primary>protocols</primary><secondary>Internet Packet eXchange (IPX)</secondary></indexterm><indexterm significance="normal"><primary>file sharing</primary></indexterm><indexterm significance="normal"><primary>remote</primary><secondary>file access</secondary></indexterm><indexterm significance="normal"><primary>NCPFS (NetWare Core Protocol Filesystem)</primary></indexterm><para><indexterm significance="normal"><primary>Novell Corporation</primary></indexterm>
<indexterm significance="normal"><primary>NetWare</primary></indexterm>
Long before Microsoft learned about networking, and even before the
Internet was known outside academic circles, corporate environments
shared files and printers using file and print servers based on the
Novell NetWare operating system and associated protocols.<footnote id="x-087-2-fnix01"><para> Novell and NetWare are trademarks of the
Novell Corporation.  </para></footnote> Many of these corporate users
still have legacy networks using these protocols and want to integrate
this support with their new TCP/IP support.</para><para>Linux supports not only the TCP/IP protocols, but also the suite of
protocols used by the Novell Corporation's NetWare operating
system. These protocols are distant cousins of TCP/IP, and while they
perform similar sorts of functions, they differ in a number of ways
and are unfortunately incompatible.</para><para>Linux has both free and commercial software offerings to provide support 
for integration with the Novell products.
</para><para>We'll provide a brief description of the protocols themselves in this
chapter, but we focus on how to configure and use free software to
allow Linux to interoperate with Novell products.</para><sect1><title>Xerox, Novell, and History</title><para><indexterm significance="normal"><primary>Xerox Corporation</primary></indexterm>
<indexterm significance="normal"><primary>Xerox Network Specification (XNS)</primary></indexterm>
<indexterm significance="normal"><primary>Internet Datagram Protocol (IDP)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>Internet Datagram Protocol (IDP)</secondary></indexterm>
<indexterm significance="normal"><primary>Sequenced Packet Protocol (SPP)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>Sequenced Packet Protocol (SPP)</secondary></indexterm> 
First, let's look at where the protocols came from and what they look
like.  In the late 1970s, the Xerox Corporation developed and
published an open standard called the Xerox Network Specification
(XNS). The Xerox Network Specification described a series of protocols
designed for general purpose internetworking, with a strong emphasis
on the use of local area networks. There were two primary networking
protocols involved: the Internet Datagram Protocol (IDP), which
provided a connectionless and unreliable transport of datagrams from
one host to another, and the Sequenced Packet Protocol (SPP), which
was a modified form of IDP that was connection-based and reliable. The
datagrams of an XNS network were individually addressed. The
addressing scheme used a combination of a 4-byte IDP network
address (which was uniquely assigned to each Ethernet LAN segment),
and the 6-byte node address (the address of the NIC card).  Routers
were devices that switched datagrams between two or more separate IDP
networks. IDP has no notion of subnetworks; any new collection of
hosts requires another network address to be assigned. Network
addresses are chosen such that they are unique on the internetwork in
question. Sometimes administrators develop conventions by having each
byte encode some other information, such as geographic location, so that
network addresses are allocated in a systemic way; it isn't a
protocol requirement, however.</para><para><indexterm significance="normal"><primary>Sequenced Packet eXchange (SPX)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>Sequenced Packet eXchange (SPX)</secondary></indexterm>
<indexterm significance="normal"><primary>NetWare Core Protocol (NCP)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>NetWare Core Protocol (NCP)</secondary></indexterm>
<indexterm significance="normal"><primary>Service Advertisement Protocol (SAP)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>Service Advertisement Protocol (SAP)</secondary></indexterm>
The Novell Corporation chose to base their own networking suite on the
XNS suite. Novell made small enhancements to IDP and SPP and renamed
them IPX (Internet Packet eXchange) and SPX (Sequenced Packet
eXchange).  Novell added new protocols, such as the NetWare Core
Protocol (NCP), which provided file and printer sharing features that
ran over IPX, and the Service Advertisement Protocol (SAP), which
enabled hosts on a Novell network to know which hosts provided which
services.</para><para><indexterm significance="normal"><primary>protocols</primary><secondary>mapping XNS, Novell, and TCP/IP</secondary></indexterm>
<xref linkend="x-087-2-ix.protocol.family"></xref> maps the relationship between
the XNS, Novell, and TCP/IP suites in terms of function. The relationships
are an approximation only, but should help you understand what is
happening when we refer to these protocols later on.</para><table id="x-087-2-ix.protocol.family"><title>XNS, Novell, and TCP/IP Protocol Relationships</title><tgroup cols="4"><thead><row><entry>XNS</entry><entry>Novell</entry><entry>TCP/IP</entry><entry>Features</entry></row></thead><tbody><row><entry>IDP</entry><entry>IPX</entry><entry>UDP/IP</entry><entry>Connectionless, unreliable transport</entry></row><row><entry>SPP</entry><entry>SPX</entry><entry>TCP</entry><entry>Connection-based, reliable transport</entry></row><row><entry></entry><entry>NCP</entry><entry>NFS</entry><entry>File services</entry></row><row><entry></entry><entry>RIP</entry><entry>RIP</entry><entry>Routing information exchange</entry></row><row><entry></entry><entry>SAP</entry><entry></entry><entry>Service availability information exchange</entry></row></tbody></tgroup></table></sect1><sect1><title>IPX and Linux</title><para><indexterm significance="normal"><primary>Cox, Alan</primary></indexterm>
<indexterm significance="normal"><primary>Page, Greg</primary></indexterm>
<indexterm significance="normal"><primary>Lendecke, Volker</primary></indexterm>
<indexterm significance="normal"><primary>Dryak, Ales</primary></indexterm>
<indexterm significance="normal"><primary>Stover, Martin</primary></indexterm><?troff .hw volumes?>
Alan Cox first developed IPX support for the Linux kernel in
1985.<footnote id="x-087-2-fnix02"><para> Alan can be reached at
<systemitem moreinfo="none" role="emailaddr">alan@lxorguk.ukuu.org.uk</systemitem>.</para></footnote> Initially it was useful for little more than
routing IPX datagrams. Since then, other people, notably Greg Page,
have provided additional support.<footnote id="x-087-2-fnix03"><para>Greg can be reached at <systemitem moreinfo="none" role="emailaddr">gpage@sovereign.org</systemitem>.</para></footnote><?troff .ffn -2?>
Greg developed the IPX configuration utilities that we'll use in this chapter
to configure our interfaces. Volker Lendecke developed support for the NCP
filesystem to allow Linux to mount volumes on network-connected NetWare
fileservers.<footnote id="x-087-2-fnix04"><para>Volker can be reached at
<systemitem moreinfo="none" role="emailaddr">lendecke@namu01.gwdg.de</systemitem>.</para></footnote>
He also created tools that allow printing to and from Linux. Ales<?troff .ffn?>
Dryak and Martin Stover each independently developed NCP fileserver
daemons for Linux that allow network-connected NetWare clients to
mount Linux directories exported as NCP volumes, just as the NFS
daemon allows Linux to serve filesystems to clients using the NFS
protocol.<footnote id="x-087-2-fnix05"><para>Ales can be reached at <systemitem moreinfo="none" role="emailaddr">A.Dryak@sh.cvut.cz</systemitem>. Martin can be reached at <systemitem moreinfo="none" role="emailaddr">mstover@freeway.de</systemitem>.</para></footnote> Caldera Systems, Inc. offers a commercial and fully
licensed NetWare client and server that supports the latest Novell
standards, including support for the NetWare Directory Service
(NDS).<footnote id="x-087-2-fnix07"><para> Information on Caldera can
be found at <emphasis>http://www.caldera.com/</emphasis>.</para></footnote></para><para>Today, therefore, Linux supports a wide range of services that allow
systems to be integrated with existing Novell-based networks.</para><sect2><title>Caldera Support</title><para><indexterm significance="normal"><primary>Caldera (Linux distribution)</primary><secondary>NetWare support</secondary></indexterm>
<indexterm significance="normal"><primary>Noorda, Ray</primary></indexterm>
Although we don't detail the Caldera NetWare support in this
chapter, it is important that we talk about it. Caldera was founded
by Ray Noorda, the former CEO of Novell. The Caldera NetWare support is a
commercial product and fully supported by Caldera. Caldera provides the
NetWare support as a component of their own Linux distribution called
Caldera OpenLinux. The Caldera solution is an ideal way of introducing Linux
into environments that demand both commercial support and the ability to
integrate into existing or new Novell networks.</para><para>The Caldera NetWare support is fully licensed by Novell, providing a
high degree of certainty that the two companies' products will be
interoperable.  The two exceptions to this certainty are "pure IP" operation for the client, and NDS server, though neither of these were available at
the time of writing. NetWare client and NetWare server are both available. A
suite of management tools is also provided that can simplify
management of not only your Linux-based NetWare machines, but your
Novell NetWare machines, too, by bringing the power of Unix scripting
languages to the task. More information on Caldera can be found at
their web site.</para></sect2><sect2><title>More on NDS Support</title><para><indexterm significance="normal"><primary>NetWare Directory Service (NDS)</primary></indexterm>
Along with Version 4 of NetWare, Novell introduced a feature called
the NetWare Directory Service (NDS). The NDS specifications are not
available without a nondisclosure agreement, a restriction that
hampers development of free support. Only Version 2.2.0 or later of
the <filename moreinfo="none">ncpfs</filename> package, which we'll discuss later, has
any support for NDS. This support was developed by reverse engineering
the NDS protocol. The support seems to work, but is still officially
considered experimental. You can use the non-NDS tools with NetWare 4
servers, provided they have bindery emulation mode
enabled.</para><para>The Caldera software has full support for NDS because their implementation
is licensed from Novell. This implementation is not free, however. So
you will not have access to the source code and will not be able to
freely copy and distribute the software.</para></sect2></sect1><sect1 id="x-087-2-ipx.kernel"><title>Configuring the Kernel for IPX<?lb?>and NCPFS</title><indexterm significance="normal"><primary>kernels</primary><secondary>configuring for IPX and NCPFS</secondary></indexterm><indexterm significance="normal"><primary>IPX (Internet Packet eXchange)</primary><secondary>kernel configuration</secondary></indexterm><indexterm significance="normal"><primary>NCPFS (NetWare Core Protocol Filesystem)</primary><secondary>kernel configuration</secondary></indexterm><para>Configuring the kernel for IPX and the NCP filesystem is simply a matter of
selecting the appropriate kernel options at kernel build time. As with many
other parts of the kernel, IPX and NCPFS kernel components can be built into
the kernel, or compiled as modules and loaded using the
<command moreinfo="none">insmod</command> command when you need them.</para><para>The following options must be selected if you want to have Linux support and
route the IPX protocol:

<screen format="linespecific">General setup  ---
    [*] Networking support

Networking options  ---
    * The IPX protocol

Network device support  ---
    [*] Ethernet (10 or 100Mbit)
	... and appropriate Ethernet device drivers</screen>

If you want Linux to support the NCP filesystem so it can mount remote
NetWare volumes, you must additionally select these options:

<screen format="linespecific">Filesystems  ---
    [*] /proc filesystem support
    * NCP filesystem support (to mount NetWare volumes)</screen>

When you've compiled and installed your new kernel, you're ready to
run IPX.</para></sect1><sect1 id="x-087-2-ipx.interfaces"><title>Configuring IPX Interfaces</title><indexterm significance="normal" class="startofrange" id="idx-ipxinterfaces"><primary>interfaces</primary><secondary>configuring IPX</secondary></indexterm><para>Just as with TCP/IP, you must configure your IPX interfaces before you
can use them. The IPX protocol has some unique requirements;
consequently, a special set of configuration tools was developed. We
will use these tools to configure our IPX interfaces and routes.</para><sect2 id="x-087-2-ipx.devices"><title>Network Devices Supporting IPX</title><indexterm significance="normal"><primary>devices</primary><secondary>supporting IPX</secondary></indexterm><para>The IPX protocol assumes that any collection of hosts that can
transmit datagrams to each other without routing belong to the same
IPX network. All hosts belonging to a single Ethernet segment would
all belong to the same IPX network. Similarly (but less intuitively),
both hosts supporting a PPP-based serial link must belong to the IPX
network that is the serial link itself. In an Ethernet environment,
there are a number of different frame types that may be used to carry
IPX datagrams. The frame types represent different Ethernet protocols
and describe differing ways of carrying multiple protocols on the same
Ethernet network. The most common frame types you will encounter are
<literal moreinfo="none">802.2</literal> and <literal moreinfo="none">ethernet_II</literal>. We'll
talk more about frame types in the next section.</para><para>The Linux network devices that currently support the IPX protocol are the
Ethernet and PPP drivers. The Ethernet or PPP interface must be
active before it can be configured for IPX use. Typically, you configure an Ethernet device with both IP and IPX, so the device already exists, but if your 
network is IPX only, you need to use the <command moreinfo="none">ifconfig</command> to change the Ethernet device status to the following:

<screen format="linespecific"># <userinput moreinfo="none">ifconfig eth0 up</userinput></screen>
</para></sect2><sect2 id="x-087-2-ipx.tools"><title>IPX Interface Configuration Tools</title><indexterm significance="normal"><primary>IPX (Internet Packet eXchange)</primary><secondary>interface configuration tools</secondary></indexterm><para>Greg Page developed a set of configuration tools for IPX interfaces,
which is a precompiled package in modern distributions and may
also be obtained in source form by anonymous FTP from
<emphasis>http://metalab.unc.edu/</emphasis> in the
<filename moreinfo="none">/pub/Linux/system/filesystems/ncpfs/ipx.tgz</filename>
file.</para><para>An <filename moreinfo="none">rc</filename> script file usually runs the IPX tools at
boot time. Your distribution may already do this for you if you have
installed the prepackaged software.</para></sect2><sect2 id="x-087-2-ipx.ipx-configure"><title>The ipx_configure Command</title><indexterm significance="normal"><primary>ipx_configure command</primary></indexterm><para>Each IPX interface must know which IPX network it belongs to and which
frame type to use for IPX. Each host supporting IPX has at least one
interface that the rest of the network will use to refer to it, known
as the <firstterm>primary</firstterm> interface. The Linux kernel IPX
support provides a means of automatically configuring these
parameters; the <command moreinfo="none">ipx_configure</command> command enables or
disables this automatic configuration feature.</para><para>With no arguments, the <command moreinfo="none">ipx_configure</command> command displays the
current setting of the automatic configuration flags:

<screen format="linespecific"># <userinput moreinfo="none">ipx_configure</userinput>
Auto Primary Select is OFF
Auto Interface Create is OFF</screen></para><para>Both the Auto Primary and Auto Interface flags
are off by default. To set them and enable automatic configuration, you
simply supply arguments like these:

<screen format="linespecific"># <userinput moreinfo="none">ipx_configure --auto_interface=on --auto_primary=on</userinput></screen></para><para>When the <literal moreinfo="none">--auto_primary</literal> argument is set to
<literal moreinfo="none">on</literal>, the kernel will automatically ensure that at
least one active interface operates as the primary interface for the
host.</para><para>When the <literal moreinfo="none">--auto_interface</literal> argument is
set to <literal moreinfo="none">on</literal>, the kernel IPX driver will listen to all of the
frames received on the active network interfaces and attempt to determine
the IPX network address and frame type used.</para><para>The auto-detection mechanism works well on properly managed networks.
Sometimes network administrators take shortcuts and break rules, and
this can cause problems for the Linux auto-detection code. The most common
example of this is when one IPX network is configured to run over the same
Ethernet with multiple frame types. This is technically an invalid
configuration, as an <emphasis role="bold">802.2</emphasis> host cannot directly communicate with an
Ethernet-II host and therefore they cannot be on the same IPX network.
The Linux IPX network software listens on the segment to IPX datagrams
transmitted on it. From these, it attempts to identify which network
addresses are in use and which frame type is associated with each. If the
same network address is in use with multiple frame types or on multiple
interfaces, the Linux code detects this as a network address collision
and is unable to determine which is the correct frame type. You will know
this is occurring if you see messages in your system log that look like:

<screen format="linespecific">IPX: Network number collision 0x3901ab00
eth0 etherII and eth0 802.3</screen>

If you see this problem, disable the auto-detection
feature and configure the interfaces manually using the
<command moreinfo="none">ipx_interface</command> command described in the next section.</para></sect2><sect2 id="x-087-2-ipx.ipx-interface"><title>The ipx_interface Command</title><indexterm significance="normal"><primary>ipx_interface command</primary></indexterm><para>The <command moreinfo="none">ipx_interface</command> command is used to manually add,
modify, and delete IPX capability from an existing network device. You
should use <command moreinfo="none">ipx_interface</command> when the automatic
configuration method just described does not work for you, or if you
don't want to leave your interface configuration to
chance. <command moreinfo="none">ipx_interface</command> allows you to specify the IPX
network address, primary interface status, and IPX frame type that a
network device will use. If you are creating multiple IPX interfaces,
you need one <command moreinfo="none">ipx_interface</command> for each.</para><para>The command syntax to add IPX to an existing device is straightforward
and best explained with an example. Let's add IPX to an existing
Ethernet device:

<screen format="linespecific"># <userinput moreinfo="none">ipx_interface add -p eth0 etherII 0x32a10103</userinput></screen><?troff .Nd 10?>
The parameters in turn mean:

<variablelist><varlistentry><term>-p</term><listitem><para>This parameter specifies that this interface should be a primary interface.
This parameter is optional.</para></listitem></varlistentry><varlistentry><term>eth0</term><listitem><para>This is the name of the network device to which we are adding IPX support.</para></listitem></varlistentry><varlistentry><term>etherII</term><listitem><para>This parameter is the frame type, in this case Ethernet-II. This value
may also be coded as <literal moreinfo="none">802.2</literal>,
<literal moreinfo="none">802.3</literal>, or <literal moreinfo="none">SNAP</literal>.</para></listitem></varlistentry><varlistentry><term>0x32a10103</term><listitem><para>This is the IPX network address to which this interface belongs.</para></listitem></varlistentry></variablelist>
</para><para>The following command removes IPX from an interface:

<screen format="linespecific"># <userinput moreinfo="none">ipx_interface del eth0 etherII</userinput></screen></para><para>Lastly, to display the current IPX configuration of a network device,
use:

<screen format="linespecific"># <userinput moreinfo="none">ipx_interface check eth0 etherII</userinput></screen></para><para>The <command moreinfo="none">ipx_interface</command> command is explained more fully in its
manual page.</para></sect2><indexterm significance="normal" class="endofrange" startref="idx-ipxinterfaces"></indexterm></sect1><sect1 id="x-087-2-ipx.router"><title>Configuring an IPX Router</title><indexterm significance="normal" class="startofrange" id="idx-ipxrouter"><primary>routing</primary><secondary>IPX (Internet Packet eXchange)</secondary></indexterm><indexterm significance="normal" class="startofrange" id="ipx.routing"><primary>IPX (Internet Packet eXchange)</primary><secondary>routing</secondary></indexterm><indexterm significance="normal"><primary>Routing Information Protocol (RIP)</primary></indexterm><indexterm significance="normal"><primary>protocols</primary><secondary>Routing Information Protocol (RIP)</secondary></indexterm><para>You will recall from our short discussion of the protocols used in an
IPX environment that IPX is a routable protocol and that the Routing
Information Protocol (RIP) is used to propagate routing
information. The IPX version of RIP is quite similar to the IP
version. They operate in essentially the same way; routers
periodically broadcast the contents of their routing tables and other
routers learn of them by listening and integrating the information
they receive. Hosts need only know who their local network is and be
sure to send datagrams for all other destinations via their local
router. The router is responsible for carrying these datagrams and
forwarding them on to the next hop in the route.</para><para><indexterm significance="normal"><primary>Service Advertisement Protocol (SAP)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>Service Advertisement Protocol (SAP)</secondary></indexterm>
In an IPX environment, a second class of information must be
propagated around the network. The Service Advertisement Protocol
(SAP) carries information relating to which services are available at
which hosts around the network. It is the SAP protocol, for example,
that allows users to obtain lists of file or print servers on the
network. The SAP protocol works by having hosts that provide services
periodically broadcast the list of services they offer. The IPX
network routers collect this information and propagate it throughout
the network alongside the network routing information.  To be a
compliant IPX router, you must propagate both RIP and SAP information.</para><para><indexterm significance="normal"><primary>ipxd command</primary></indexterm>
Just like IP, IPX on Linux provides a routing daemon named
<command moreinfo="none">ipxd</command> to perform the tasks associated with managing
routing. Again, just as with IP, it is actually the kernel that
manages the forwarding of datagrams between IPX network interfaces,
but it performs this according to a set of rules called the IPX
routing table.  The <command moreinfo="none">ipxd</command> daemon keeps that set of
rules up to date by listening on each of the active network interfaces
and analyzing when a routing change is necessary. The
<command moreinfo="none">ipxd</command> daemon also answers requests from hosts on a
directly connected network that ask for routing information.</para><para>The <command moreinfo="none">ipxd</command> command is available prepackaged in some
distributions, and in source form by anonymous FTP from 
<emphasis>http://metalab.unc.edu/</emphasis> in the
<filename moreinfo="none">/pub/Linux/system/filesystems/ncpfs/ipxripd-x.xx.tgz</filename>
file.</para><para>No configuration is necessary for the <command moreinfo="none">ipxd</command> daemon.
When it starts, it automatically manages routing among the IPX
devices that have been configured. The key is to ensure that you have
your IPX devices configured correctly using the
<command moreinfo="none">ipx_interface</command> command before you start
<command moreinfo="none">ipxd</command>. While auto-detection may work, when you're
performing a routing function it's best not to take chances, so
manually configure the interfaces and save yourself the pain of nasty
routing problems. Every 30 seconds, <command moreinfo="none">ipxd</command>
rediscovers all of the locally attached IPX networks and automatically
manages them. This provides a means of managing networks on interfaces
that may not be active all of the time, such as PPP interfaces.</para><para>The <command moreinfo="none">ipxd</command> would normally be started at boot time from
an <filename moreinfo="none">rc</filename> boot script like this:

<screen format="linespecific"># <userinput moreinfo="none">/usr/sbin/ipxd</userinput></screen>

No <literal moreinfo="none"></literal> character is necessary because <command moreinfo="none">ipxd</command> will
move itself into the background by default. While the
<command moreinfo="none">ipxd</command> daemon is most useful on machines acting as
IPX routers, it is also useful to hosts on segments where there are
multiple routers present. When you specify the
<literal moreinfo="none">p</literal> argument, <command moreinfo="none">ipxd</command> will act
passively, listening to routing information from the segment and
updating the routing tables, but it will not transmit any routing
information. This way, a host can keep its routing tables up to date
without having to request routes each time it wants to contact a
remote host.</para><sect2><title>Static IPX Routing Using the ipx_route Command</title><para><indexterm significance="normal"><primary>ipx_route command</primary></indexterm>
There are occasions when we might want to hardcode an IPX
route. Just as with IP, we can do this with IPX. The
<command moreinfo="none">ipx_route</command> command writes a route into the IPX
routing table without it needing to have been learned by the
<command moreinfo="none">ipxd</command> routing daemon. The routing syntax is very
simple (since IPX does not support subnetworking) and looks like:

<screen format="linespecific"># <userinput moreinfo="none">ipx_route add 203a41bc 31a10103 00002a02b102</userinput></screen>

The command shown would add a route to the remote IPX network
<emphasis role="bold">203a41bc</emphasis> via the router on our local network
<emphasis role="bold">31a10103</emphasis> with node address <emphasis role="bold">00002a02b102</emphasis>.</para><para>You can find the node address of a router by making judicious use of
the <command moreinfo="none">tcpdump</command> command with the
<literal moreinfo="none">e</literal> argument to display link level
headers and look for traffic from the router. If the router is a Linux
machine, you can more simply use the <command moreinfo="none">ifconfig</command>
command to display it.</para><para>You can delete a route using the <command moreinfo="none">ipx_route</command> command:

<screen format="linespecific"># <userinput moreinfo="none">ipx_route del 203a41bc</userinput></screen></para><para><indexterm significance="normal"><primary sortas="proc/net/ipx_route">/proc/net/ipx_route file</primary></indexterm>
You can list the routes that are active in the kernel by looking at
the <filename moreinfo="none">/proc/net/ipx_route</filename> file. Our routing table
so far looks like this:

<screen format="linespecific"># <userinput moreinfo="none">cat ipx_route</userinput>
Network    Router_Net   Router_Node
203A41BC   31A10103     00002a02b102
31A10103   Directly     Connected</screen>

The route to the <emphasis role="bold">31A10103</emphasis> network was automatically created when we configured the IPX interface. Each of our local
networks will be represented by an <filename moreinfo="none">/proc/net/ipx_route</filename> 
entry like this one. Naturally, if our machine is to act as a router, it will 
need at least one other interface.</para></sect2><sect2><title>Internal IPX Networks and Routing</title><para><indexterm significance="normal" class="startofrange" id="ipx.internal.networks"><primary>IPX (Internet Packet eXchange)</primary><secondary>internal networks</secondary></indexterm>
IPX hosts with more than one IPX interface have a unique network/node
address combination for each of their interfaces. To connect to such a
host, you may use any of these network/node address combinations. When
SAP advertizes services, it supplies the network/node address
associated with the service that is offered. On hosts with multiple
interfaces, this means that one of the interfaces must be chosen as the
one to propagate; this is the function of the primary interface flag
we talked about earlier. But this presents a problem: the route to
this interface may not always be the optimal one, and if a network
failure occurs that isolates that network from the rest of the
network, the host will become unreachable even though there are other
<emphasis>possible</emphasis> routes to the other interfaces.  The
other routes are never known to other hosts because they are never
propagated, and the kernel has no way of knowing that it should choose
another primary interface. To avoid this problem, a device was
developed that allows an IPX host to be known by a single
route-independent network/node address for the purposes of SAP
propagation. This solves our problem because this new network/node
address is reachable via all of the host interfaces, and is the one
that is advertised by SAP.</para><para>To illustrate the problem and its solution, <xref linkend="x-087-2-ipx.internal.network"></xref> shows a server attached to two
IPX networks. The first network has no internal network, but the second
does. The host in diagram <xref linkend="x-087-2-ipx.internal.network"></xref> would 
choose one of its interfaces as its primary interface, let's assume
<emphasis role="bold">0000001a:0800000010aa</emphasis>, and that is what 
would be advertised as its service access point. This works well for hosts
on the <emphasis role="bold">0000001a</emphasis> network, but means that 
users on the <emphasis role="bold">0000002c</emphasis> network will route via 
the network to reach that port, despite the server having a port directly on 
that network if they've discovered this server from the SAP broadcasts.</para><figure float="0" id="x-087-2-ipx.internal.network"><title>IPX internal network</title><graphic fileref="lag2_1501.jpg"></graphic></figure><para>Allowing such hosts to have a virtual network with virtual host
addresses that are entirely a software construct solves this
problem. This virtual network is best thought of as being
<emphasis>inside</emphasis> the IPX host. The SAP information then
needs only to be propagated for this virtual network/node address
combination. This virtual network is known as an <emphasis>internal
network</emphasis>. But how do other hosts know how to reach this
internal network? Remote hosts route to the internal network via
the directly connected networks of the host. This means that you 
see routing entries that refer to the internal network of hosts
supporting multiple IPX interfaces. Those routes should choose the
optimal route available at the time, and should one fail, the routing is 
automatically updated to the next best interface and route. In
<xref linkend="x-087-2-ipx.internal.network"></xref>, we've configured an
internal IPX network of address <emphasis role="bold">0x10000010</emphasis> 
and used a host address of <emphasis role="bold">00:00:00:00:00:01</emphasis>. It is this address that will be our primary interface and will be advertised via SAP. Our routing will reflect this network as being reachable via
<emphasis>either</emphasis> of our real network ports, so hosts will
always use the best network route to connect to our server.</para><para>To create this internal network, use the
<command moreinfo="none">ipx_internal_net</command> command included in Greg Page's
IPX tools package. Again, a simple example demonstrates its use:

<screen format="linespecific"># <userinput moreinfo="none">ipx_internal_net add 10000010 000000000001</userinput></screen>

This command would create an IPX internal network with address
<emphasis role="bold">10000010</emphasis> and a node address of
<emphasis role="bold">000000000001</emphasis>. The network address, just like any other
IPX network address, must be unique on your network. The node address is
completely arbitrary, as there will normally be only one node on the network.
Each host may have only one IPX Internal Network, and if configured, the
Internal Network will always be the primary network.</para><para>To delete an IPX Internal Network, use:

<screen format="linespecific"># <userinput moreinfo="none">ipx_internal_net del</userinput></screen>
</para><para>An internal IPX network is of absolutely no use to you unless your host both
provides a service and has more than one IPX interface active.</para></sect2><indexterm significance="normal" class="endofrange" startref="ipx.internal.networks"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-ipxrouter"></indexterm><indexterm significance="normal" class="endofrange" startref="ipx.routing"></indexterm></sect1><sect1 id="x-087-2-ipx.ncpfs.client"><title>Mounting a Remote NetWare Volume</title><indexterm significance="normal" class="startofrange" id="idx-ipxncpfsclient"><primary>NCPFS (NetWare Core Protocol Filesystem)</primary><secondary>mounting volume on</secondary></indexterm><para>IPX is commonly used to mount NetWare volumes in the Linux
filesystem. This allows file-based data sharing between other
operating systems and Linux. Volker Lendecke developed the NCP client
for Linux and a suite of associated tools that make data sharing
possible.</para><para>In an NFS environment, we'd use the Linux <command moreinfo="none">mount</command>
command to mount the remote filesystem. Unfortunately, the NCP
filesystem has unique requirements that make it impractical to build
it into the normal <command moreinfo="none">mount</command>. Linux has an
<command moreinfo="none">ncpmount</command> command that we will use instead. The
<command moreinfo="none">ncpmount</command> command is one of the tools in Volker's
<filename moreinfo="none">ncpfs</filename> package, which is available prepackaged in
most modern distributions or in source form from <systemitem moreinfo="none" role="sitename">ftp.gwdg.de</systemitem> in the
<filename moreinfo="none">/pub/linux/misc/ncpfs/</filename> directory. The version
current at the time of writing is 2.2.0.</para><para>Before you can mount remote NetWare volumes, you must ensure your IPX network
interface is configured correctly (as described earlier). Next, you must know
your login details on the NetWare server you wish to mount; this includes
the user ID and password. Lastly, you need to know which volume you wish
to mount and what local directory you wish to mount it under.</para><sect2><title>A Simple ncpmount Example</title><para><indexterm significance="normal"><primary>ncpmount command</primary><secondary>simple example</secondary></indexterm>
A simple example of <command moreinfo="none">ncpmount</command> usage looks like this:

<screen format="linespecific"># <userinput moreinfo="none">ncpmount -S ALES_F1 -U rick -P d00-b-gud /mnt/brewery</userinput></screen>

This command mounts all volumes of the <literal moreinfo="none">ALES_F1</literal>
fileserver under the <filename moreinfo="none">/mnt/brewery</filename> directory,
using the NetWare login <literal moreinfo="none">rick</literal> with the password
<literal moreinfo="none">d00-b-gud</literal>.</para><para>The <command moreinfo="none">ncpmount</command> command is normally setuid to
<systemitem moreinfo="none" role="userid">root</systemitem> and may therefore be used
by any Linux user. By default, that user owns the connection and
only he or the <systemitem moreinfo="none" role="userid">root</systemitem> user will
be able to unmount it.</para><para>NetWare embodies the notion of a <emphasis>volume</emphasis>, which is
analogous to a filesystem in Linux. A NetWare volume is the logical
representation of a NetWare filesystem, which might be a single disk
partition be spread across many partitions. By default, the
Linux NCPFS support treats volumes as subdirectories of a larger
logical filesystem represented by the whole fileserver. The
<command moreinfo="none">ncpmount</command> command causes each of the NetWare
volumes of the mounted fileserver to appear as a subdirectory under
the mount point. This is convenient if you want access to the whole
server, but for complex technical reasons you will be unable to
re-export these directories using NFS, should you wish to do so. We'll
discuss a more complex alternative that works around this problem in a
moment.</para></sect2><sect2><title>The ncpmount Command in Detail</title><para><indexterm significance="normal"><primary>ncpmount command</primary><secondary>command-line arguments</secondary></indexterm>
The <command moreinfo="none">ncpmount</command> has a large number of command line options
that allow you quite a lot of flexibility in how you manage your NCP mounts.
The most important of these are described in
<xref linkend="x-087-2-ipx.ncpmount.args"></xref>.</para><table tocentry="1" id="x-087-2-ipx.ncpmount.args"><title>ncpmount Command Arguments</title><tgroup cols="2"><colspec colwidth="1.25i"></colspec><colspec colwidth="3.25i"></colspec><thead><row><entry>Argument</entry><entry>Description</entry></row></thead><tbody><row><entry><para>S <replaceable>server</replaceable></para></entry><entry><para>The name of the fileserver to mount.</para></entry></row><row><entry><para>U <replaceable>user_name</replaceable></para></entry><entry><para>The NetWare user ID to use when logging in to the fileserver.</para></entry></row><row><entry><para>P  <replaceable>password</replaceable></para></entry><entry><para>The password to use for the NetWare login.</para></entry></row><row><entry>n</entry><entry><para>This option must be used for NetWare logins that don't have a password
associated with them.</para></entry></row><row><entry>C</entry><entry><para>This argument disables automatic conversion of passwords to uppercase.</para></entry></row><row><entry>c <replaceable>client_name</replaceable></entry><entry><para>This option allows you to specify who owns the connection to the
fileserver. This is useful for NetWare printing, which we will discuss in
more detail later.</para></entry></row><row><entry>u <replaceable>uid</replaceable></entry><entry><para>The Linux user ID that should be shown as the owner of files in the
mounted directory.  If this is not specified, it defaults to the
user ID of the user who invokes the <command moreinfo="none">ncpmount</command>
command.</para></entry></row><row><entry>g <replaceable>gid</replaceable></entry><entry><para>The Linux group ID that should be shown as the owner of files in the
mounted directory.  If this is not specified, it will default to the
group ID of the user who invokes the <command moreinfo="none">ncpmount</command>
command.</para></entry></row><row><entry>f <replaceable>file_mode</replaceable></entry><entry><para>This option allows you to specify the file mode (permissions) that
files in the mounted directory should have. The value should be
specified in octal, e.g., <literal moreinfo="none">0664</literal>. The permissions
that you will actually have are the file mode permissions
specified with this option masked with the permissions that your
NetWare login ID has for the files on the fileserver.  You must have
rights on the server and rights specified by this option in order to
access a file. The default value is derived from the current
<literal moreinfo="none">umask</literal>.</para></entry></row><row><entry>d <replaceable>dir_mode</replaceable></entry><entry><para>This option allows you to specify the directory permissions in the
mounted directory. It behaves in the same way as the
<emphasis>f</emphasis> option, except that the default permissions are
derived from the current <literal moreinfo="none">umask</literal>. Execute permissions
are granted where read access is granted.</para></entry></row><row><entry>V <replaceable>volume</replaceable></entry><entry><para>This option allows you to specify the name of a single NetWare
volume to mount under the mount point, rather than mounting all volumes of
the target server. This option is necessary if you wish to re-export a
mounted NetWare volume using NFS.</para></entry></row><row><entry>t <replaceable>time_out</replaceable></entry><entry><para>This option allows you to specify the time that the NCPFS client will wait
for a response from a server. The default value is 60mS and the timeout is
specified in hundredths of a second. If you experience any stability problems
with NCP mounts, you should try increasing this value.</para></entry></row><row><entry>r <replaceable>retry_count</replaceable></entry><entry><para>The NCP client code attempts to resend datagrams to the server
a number of times before deciding the connection is dead. This option allows
you to change the retry count from the default of 5.</para></entry></row></tbody></tgroup></table></sect2><sect2><title>Hiding Your NetWare Login Password</title><para><indexterm significance="normal"><primary>passwords</primary><secondary>hiding NetWare</secondary></indexterm>
It is somewhat of a security risk to be putting a password on the
command line, as we did with the <command moreinfo="none">ncpmount</command> command.
Other active, concurrent users could see the password if they happen
to be running a program like <command moreinfo="none">top</command> or
<command moreinfo="none">ps</command>. To reduce the risk of others seeing and
stealing NetWare login passwords, <command moreinfo="none">ncpmount</command> is able
to read certain details from a file in a user's home directory. In
this file, the user keeps the login name and password associated with
each of the fileservers he or she intends to mount. The file is called
<filename moreinfo="none">~/.nwclient</filename> and it must have permissions of
<literal moreinfo="none">0600</literal> to ensure that others cannot read it. If the
permissions are not correct, the <command moreinfo="none">ncpmount</command> command
will refuse to use it.</para><para>The file has a very simple syntax. Any lines beginning with a #
character are treated as comments and ignored.
The remainder of the lines have the syntax:

<screen format="linespecific"><replaceable>fileserver</replaceable>/<replaceable>userid</replaceable> <replaceable>password</replaceable></screen>

The <replaceable>fileserver</replaceable> is the name of the
fileserver supporting the volumes you wish to mount. The
<replaceable>userid</replaceable> is the login name of your account on
that server. The <replaceable>password</replaceable> field is
optional. If it is not supplied, the <command moreinfo="none">ncpmount</command>
command prompts users for the password when they attempt the
mount. If the <replaceable>password</replaceable> field is specified
as the  character, no password is used; this is equivalent
to the <literal moreinfo="none">n</literal> command-line argument.</para><para>You can supply any number of entries, but the fileserver field must be
unique. The first fileserver entry has special significance. The
<command moreinfo="none">ncpmount</command> command uses the <literal moreinfo="none">S</literal>
command-line argument to determine which of the entries in
<filename moreinfo="none">~/.nwclient</filename> to use. If no server is specified
using the <literal moreinfo="none">S</literal> argument, the first server entry
in <filename moreinfo="none">~/.nwclient</filename> is assumed, and is treated as your
preferred server. You should place the fileserver you mount most
frequently in the first position in the file.</para></sect2><sect2><title>A More Complex ncpmount Example</title><para><indexterm significance="normal"><primary>ncpmount command</primary><secondary>complex example</secondary></indexterm>
<indexterm significance="normal"><primary>NCPFS (NetWare Core Protocol Filesystem)</primary><secondary sortas="nwclient">~/.nwclient file</secondary></indexterm>
Let's look at a more complex <command moreinfo="none">ncpmount</command> example involving
a number of the features we've described. First, let's build a simple
<filename moreinfo="none">~/.nwclient</filename> file:

<screen format="linespecific"># NetWare login details for the Virtual Brewery and Winery
#
# Brewery Login
ALES_F1/MATT staoic1
#
# Winery Login
REDS01/MATT staoic1
#</screen><?troff .Nd 10?>
Make sure its permissions are correct:

<screen format="linespecific">$ <userinput moreinfo="none">chmod 600 ~/.nwclient</userinput></screen>
</para><para>Let's mount one volume of the Winery's server under a subdirectory of a
shared directory, specifying the file and directory permissions such that
others may share the data from there:

<screen format="linespecific">$ ncpmount -S REDS01 -V RESEARCH -f 0664 -d 0775 /usr/share/winery/data/</screen>

This command, in combination with the <filename moreinfo="none">~/.nwclient</filename> file
shown, would mount the <literal moreinfo="none">RESEARCH</literal> volume of the
<literal moreinfo="none">REDS01</literal> server onto the
<filename moreinfo="none">/usr/share/winery/data/</filename> directory using the NetWare
login ID of <literal moreinfo="none">MATT</literal> and the password retrieved
from the <filename moreinfo="none">~/.nwclient</filename> file. The permissions of the
mounted files are <literal moreinfo="none">0664</literal> and the directory permissions
are <literal moreinfo="none">0775</literal>.</para></sect2><indexterm significance="normal" class="endofrange" startref="idx-ipxncpfsclient"></indexterm></sect1><sect1 id="x-087-2-ipx.othertools"><title>Exploring Some of the Other IPX Tools</title><para>The <filename moreinfo="none">ncpfs</filename> package contains a number of useful
tools that we haven't described yet. Many of these tools emulate the
tools that are supplied with NetWare. We'll look at the most useful
ones in this section.</para><sect2><title>Server List</title><para><indexterm significance="normal"><primary>IPX (Internet Packet eXchange)</primary><secondary>tools</secondary><tertiary>slist</tertiary></indexterm>
<indexterm significance="normal"><primary>slist command</primary></indexterm>
The <command moreinfo="none">slist</command> command lists all of the fileservers accessible
to the host. The information is actually retrieved from the nearest
IPX router. This command was probably originally intended to allow users to
see what fileservers were available to mount. But it has become useful as a
network diagnosis tool, allowing network admins to see where SAP information
is being propagated:</para><screen format="linespecific">$ slist
NPPWR-31-CD01                               23A91330  000000000001
V242X-14-F02                                A3062DB0  000000000001
QITG_284ELI05_F4                            78A20430  000000000001
QRWMA-04-F16                                B2030D6A  000000000001
VWPDE-02-F08                                35540430  000000000001
NMCS_33PARK08_F2                            248B0530  000000000001
NCCRD-00-CD01                               21790430  000000000001
NWGNG-F07                                   53171D02  000000000001
QCON_7TOMLI04_F7                            72760630  000000000001
W639W-F04                                   D1014D0E  000000000001
QCON_481GYM0G_F1                            77690130  000000000001
VITG_SOE-MAIL_F4R                           33200C30  000000000001</screen><para><command moreinfo="none">slist</command> accepts no arguments. The output displays
the fileserver name, the IPX network address, and the host address.</para></sect2><sect2><title>Send Messages to NetWare Users</title><para><indexterm significance="normal"><primary>nsend command</primary></indexterm>
<indexterm significance="normal"><primary>IPX (Internet Packet eXchange)</primary><secondary>tools</secondary><tertiary>nsend</tertiary></indexterm>
NetWare supports a mechanism to send messages to logged-in users. The
<command moreinfo="none">nsend</command> command implements this feature in Linux. You must
be logged in to the server to send messages, so you need to supply the
fileserver name and login details on the command line with the destination
user and the message to send:</para><screen format="linespecific"># <userinput moreinfo="none">nsend -S vbrew_f1 -U gary -P j0yj0y supervisor
      Join me for a lager before we do the print queues!</userinput></screen><para>Here a user with login name <literal moreinfo="none">gary</literal> sends a tempting
invitation to the person using the <literal moreinfo="none">supervisor</literal>
account on the <literal moreinfo="none">ALES_F1</literal> fileserver. Our default
fileserver and login credentials will be used if we don't supply them.</para></sect2><sect2><title>Browsing and Manipulating Bindery Data</title><para><indexterm significance="normal"><primary>bindery manipulation tools</primary></indexterm>
Each NetWare fileserver maintains a database of information about its
users and configuration. This database is called the
<emphasis>bindery</emphasis>. Linux supports a set of tools that allow
you to read it, and if you have supervisor permissions on the server, to set
and remove it. A summary of these tools is listed in 
<xref linkend="x-087-2-chix-binderytools"></xref>.</para><table id="x-087-2-chix-binderytools"><title>Linux Bindery Manipulation Tools</title><tgroup cols="2"><colspec colwidth="1i"></colspec><colspec colwidth="3i"></colspec><thead><row><entry>Command Name</entry><entry>Command Description</entry></row></thead><tbody><row><entry><command moreinfo="none">nwfstime</command></entry><entry><para>Display or set a NetWare server's date and time</para></entry></row><row><entry><command moreinfo="none">nwuserlist</command></entry><entry><para>List users logged in at a NetWare server</para></entry></row><row><entry><command moreinfo="none">nwvolinfo</command></entry><entry><para>Display info about NetWare volumes</para></entry></row><row><entry><command moreinfo="none">nwbocreate</command></entry><entry><para>Create a NetWare bindery object</para></entry></row><row><entry><command moreinfo="none">nwbols</command></entry><entry><para>List NetWare bindery objects</para></entry></row><row><entry><command moreinfo="none">nwboprops</command></entry><entry><para>List properties of a NetWare bindery object</para></entry></row><row><entry><command moreinfo="none">nwborm</command></entry><entry><para>Remove a NetWare bindery object</para></entry></row><row><entry><command moreinfo="none">nwbpcreate</command></entry><entry><para>Create a NetWare bindery property</para></entry></row><row><entry><command moreinfo="none">nwbpvalues</command></entry><entry><para>Print a NetWare bindery property's contents</para></entry></row><row><entry><command moreinfo="none">nwbpadd</command></entry><entry><para>Set the value of a NetWare bindery property</para></entry></row><row><entry><command moreinfo="none">nwbprm</command></entry><entry><para>Remove a NetWare bindery property</para></entry></row></tbody></tgroup></table></sect2></sect1><sect1 id="x-087-2-ipx.ncpfs.printing"><title>Printing to a NetWare Print Queue</title><indexterm significance="normal" class="startofrange" id="idx-ipxncpfsprinting"><primary>NetWare</primary><secondary>print queue, printing to</secondary></indexterm><indexterm significance="normal"><primary>print queues, NetWare</primary></indexterm><indexterm significance="normal"><primary>nprint command</primary></indexterm><para>The <filename moreinfo="none">ncpfs</filename> package contains a small utility called
<command moreinfo="none">nprint</command> that sends print jobs across an NCP
connection to a NetWare print queue.  This command creates the
connection if it doesn't currently exist and uses the
<filename moreinfo="none">~/.nwclient</filename> file that we described earlier to
hide the username and password from prying eyes. The command-line
arguments used to manage the login process are the same as those used
by the <command moreinfo="none">ncpmount</command>, so we won't go through those again
here.  We will cover the most important command-line options in our
examples; refer to the <filename moreinfo="none">nprint(1)</filename> manual page for
details.</para><para>The only required option for <command moreinfo="none">nprint</command> is the name of
the file to print. If the filename specified is  or if no filename
is specified at all, <command moreinfo="none">nprint</command> will accept the print job
from <literal moreinfo="none">stdin</literal>. The most important <command moreinfo="none">nprint</command>
options specify the fileserver and print queue to which you wish the job to be
sent. <xref linkend="x-087-2-ipx.nprint.options"></xref> lists the most
important options.</para><table id="x-087-2-ipx.nprint.options"><title>nprint Command-Line Options</title><tgroup cols="2"><colspec colwidth="1i"></colspec><colspec colwidth="3.25i"></colspec><thead><row><entry>Option</entry><entry>Description</entry></row></thead><tbody><row><entry>-S <replaceable>server_name</replaceable></entry><entry><para>The name of the NetWare fileserver supporting the print queue to which you wish
to print. Usually it is convenient for the server to have an entry in
<filename moreinfo="none">~/.nwclient</filename>. This option is mandatory.</para></entry></row><row><entry>-q <replaceable>queue_name</replaceable></entry><entry><para>The print queue to which to send the print job. This option is mandatory.</para></entry></row><row><entry>-d <replaceable>job_description</replaceable></entry><entry><para>Text that will appear in the print console utility when displaying the
list of queued jobs.</para></entry></row><row><entry>-l <replaceable>lines</replaceable></entry><entry><para>The number of lines per printed page. This defaults to 66.</para></entry></row><row><entry>-r <replaceable>columns</replaceable></entry><entry><para>The number of columns per printed page. This defaults to 80.</para></entry></row><row><entry>-c <replaceable>copies</replaceable></entry><entry><para>The number of copies of the job that will be printed. The default is 1.</para></entry></row></tbody></tgroup></table><para>A simple example using <command moreinfo="none">nprint</command> would look like:

<screen format="linespecific">$ nprint -S REDS01 -q PSLASER -c 2 /home/matt/ethylene.ps</screen>

This command would print two copies of the file
<filename moreinfo="none">/home/matt/ethylene.ps</filename> to the printer named
<literal moreinfo="none">PSLASER</literal> on the <literal moreinfo="none">REDS01</literal>
fileserver using a username and password obtained from the
<filename moreinfo="none">~/.nwclient</filename> file.</para><sect2><title>Using nprint with the Line Printer Daemon</title><para><indexterm significance="normal"><primary>nprint command</primary><secondary>using lpd (line printer daemon)</secondary></indexterm>
<indexterm significance="normal"><primary>lpd (line printer daemon)</primary></indexterm>
You will recall we previously mentioned that the
<option>c</option> option for the <command moreinfo="none">ncpmount</command>
is useful for printing. At last we'll explain why and how.</para><para>Linux usually uses BSD-style line printer software. The line printer daemon
(<command moreinfo="none">lpd</command>) is a daemon that checks a local spool directory
for queued jobs that are to be printed. <command moreinfo="none">lpd</command> reads the
printer name and some other parameters from the specially formatted spool
file and writes the data to the printer, optionally passing the data
through a filter to transform or manipulate it in some way.</para><para>The <command moreinfo="none">lpd</command> daemon uses a simple database called
<filename moreinfo="none">/etc/printcap</filename> to store printer configuration
information, including what filters are to be
run. <command moreinfo="none">lpd</command> usually runs with the permissions of a
special system user called <systemitem moreinfo="none" role="userid">lp</systemitem>.</para><para>You could configure <command moreinfo="none">nprint</command> as a filter for
the <command moreinfo="none">lpd</command> to use, which allows users of your Linux machine to
output directly to remote printers hosted by a NetWare fileserver. To do this,
the <systemitem moreinfo="none" role="userid">lp</systemitem> user must be able to write NCP
requests to the NCP connection to the server.</para><para>An easy way to achieve this without requiring the
<systemitem moreinfo="none" role="userid">lp</systemitem> user to establish its own connection
and login is to specify <systemitem moreinfo="none" role="userid">lp</systemitem> as the owner
of a connection established by another user. A complete example of how to set 
up the Linux printing system to handle print jobs from clients over NetWare is listed in three steps:</para><orderedlist inheritnum="ignore" continuation="restarts"><listitem><para>Write a wrapper script.</para><para>The <filename moreinfo="none">/etc/printcap</filename> file doesn't permit options to
be supplied to filters. Therefore, you need to write a short script
that invokes the command you want along with its options.  The wrapper
script could be as simple as:
<screen format="linespecific">#!/bin/sh
# p2pslaser - simple script to redirect stdin to the
# PSLASER queue on the REDS01 server
#
/usr/bin/nprint -S REDS01 -U stuart -q PSLASER
#</screen></para><para>Store the script in the file <filename moreinfo="none">/usr/local/bin/p2pslaser</filename>.</para></listitem><listitem><para>Write the <filename moreinfo="none">/etc/printcap</filename> entry.</para><para>We'll need to configure the <filename moreinfo="none">p2pslaser</filename> script we
created as the output filter in the <filename moreinfo="none">/etc/printcap</filename>.
This would look something like:

<screen format="linespecific">pslaser|Postscript Laser Printer hosted by NetWare server:\                     
:lp=/dev/null:\                                                         
:sd=/var/spool/lpd/pslaser:\                                            
:if=/usr/local/bin/p2pslaser:\
:af=/var/log/lp-acct:\
:lf=/var/log/lp-errs:\
:pl#66:\                                                                
:pw#80:\                                                                
:pc#150:\                                                               
:mx#0:\                                                                 
:sh:                                                                    </screen></para></listitem><listitem><para>Add the <option>c</option> option to the <command moreinfo="none">ncpmount</command>.</para><screen format="linespecific">ncpmount -S REDS01 .... -c lp ....</screen><?troff .Nd 10?><para>Our local user <systemitem moreinfo="none" role="userid">stuart</systemitem> must specify
the <systemitem moreinfo="none" role="userid">lp</systemitem> user as the owner of the
connection when he mounts the remote NetWare server.</para></listitem></orderedlist><para>Now any Linux user may choose to specify <literal moreinfo="none">pslaser</literal> as the printer name
when invoking <emphasis role="bold">lp</emphasis>. The print job will be sent
to the specified NetWare server and spooled for printing.</para></sect2><sect2><title>Managing Print Queues</title><para><indexterm significance="normal"><primary>IPX (Internet Packet eXchange)</primary><secondary>tools</secondary><tertiary>pqlist</tertiary></indexterm>
<indexterm significance="normal"><primary>pqlist command</primary></indexterm>
The <command moreinfo="none">pqlist</command> command lists all of the print queues available
to you on the specified server. If you do not specify a fileserver on
the command line using the <option>-S</option> option, or a login name and
password, these will be taken from the default entry in your
<filename moreinfo="none">~/.nwclient</filename> file:</para><screen format="linespecific"># <userinput moreinfo="none">pqlist -S vbrew_f1 -U guest -n</userinput>
Server: ALES_F1
Print queue name                                    Queue ID  
------------------------------------------------------------
TEST                                                AA02009E
Q2                                                  EF0200D9
NPI223761_P1                                        DA03007C
Q1                                                  F1060004
I-DATA                                              0D0A003B
NPI223761_P3                                        D80A0031</screen><para>Our example shows a list of the print queues available to the
<literal moreinfo="none">guest</literal> user on the <literal moreinfo="none">ALES_F1</literal>
fileserver.<footnote id="x-087-2-fnix09"><para> It looks like the
system administrators had been sampling some of the Virtual Brewery's
wares before they chose some of those print queue names. Hopefully
your print queue names are more meaningful!</para></footnote></para><para><indexterm significance="normal"><primary>pqstat command</primary></indexterm>
To view the print jobs on a print queue, use the
<command moreinfo="none">pqstat</command> command. It takes the
print queue name as an argument and lists all of the jobs in that queue.
You may optionally supply another argument indicating how many of the jobs
in the queue you'd like to list. The following sample output has been
compressed a bit to fit the width of this book's page:

<screen format="linespecific">$ pqstat -S ALES_F1 NPI223761_P1

Server: ALES_F1     Queue: NPI223761_P1          Queue ID: 6A0E000C
   Seq  Name      Description                    Status   Form  Job ID  
------------------------------------------------------------------------
     1  TOTRAN    LyX document - proposal.lyx    Active      0  02660001</screen></para><para>We can see just one print job in the queue, owned by user
<literal moreinfo="none">TOTRAN</literal>. The rest of the options include a
description of the job, its status, and its job identifier.</para><?troff .Nd 10?><para>The <command moreinfo="none">pqrm</command> command is used to remove print jobs from
a specified print queue. To remove the job in the queue we've just
obtained the status of, we'd use:</para><screen format="linespecific">$ pqrm -S ALES_F1 NPI223761_P1 02660001</screen><para>The command is pretty straightforward but is clumsy to use in a hurry. It
would be a worthwhile project to write a basic script to simplify this
operation.</para></sect2><indexterm significance="normal" class="endofrange" startref="idx-ipxncpfsprinting"></indexterm></sect1><sect1 id="x-087-2-ipx.ncpfs.server"><title>NetWare Server Emulation</title><para><indexterm significance="normal" class="startofrange" id="idx-ipxncpfsserver"><primary>NCPFS (NetWare Core Protocol Filesystem)</primary><secondary>server emulation</secondary></indexterm>
<indexterm significance="normal"><primary>IPX-HOWTO</primary></indexterm>
<indexterm significance="normal"><primary>HOWTOs</primary><secondary>IPX</secondary></indexterm>
<indexterm significance="normal"><primary>Stover, Martin</primary></indexterm>
<indexterm significance="normal"><primary>Dryak, Ales</primary></indexterm>
There are two free software emulators for NetWare fileservers under
Linux. <command moreinfo="none">lwared</command> was developed by Ales Dryak and
<command moreinfo="none">mars_nwe</command> was developed by Martin Stover. Both of
these packages provide elementary NetWare fileserver emulation under
Linux, allowing NetWare clients to mount Linux directories exported as
NetWare volumes. While the <command moreinfo="none">lwared</command> server is 
simpler to configure, the <command moreinfo="none">mars_nwe</command> server is 
more fully featured. The installation and configuration of these packages is
beyond the scope of this chapter, but both are described in the
IPX-HOWTO.</para><indexterm significance="normal" class="endofrange" startref="idx-ipxncpfsserver"></indexterm></sect1></chapter><chapter id="x-087-2-uucp"><title>Managing<?lb?>Taylor UUCP</title><indexterm significance="normal" class="startofrange" id="idx-configuringuucp-1"><primary>configuring</primary><secondary>Taylor UUCP</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-uucp-2"><primary>Taylor UUCP</primary></indexterm><para>UUCP was designed in the late seventies by Mike Lesk at ATT Bell
Laboratories to provide a simple dialup network over public telephone
lines. Despite the popularity of dialup PPP and SLIP connections to the
Internet, many people who want to have email and Usenet News on their home
machine still use UUCP because it is often cheaper, especially in countries
where Internet users have to pay by the minute for local telephone calls, or 
where they do not have a local ISP and must pay long distance toll rates to 
connect. Although there are many implementations of UUCP running on a wide 
variety of hardware platforms and operating systems, overall, they are highly 
compatible.</para><para>However, as with most software that has somehow become standard
over the years, there is no UUCP that one would call <emphasis>the</emphasis>
UUCP. It has undergone a steady evolution since the first version was
implemented in 1976.  Currently, there are two major species that differ
mainly in their hardware support and configuration. Of these two,
various implementations exist, each varying slightly from its siblings.</para><para>One species is known as Version 2 UUCP, which dates back to a 1977
implementation by Mike Lesk, David A. Novitz, and Greg Chesson. Although it
is fairly old, it is still frequently used. Recent implementations of
Version 2 provide much of the comfort that the newer UUCP species do.</para><para>The second species was developed in 1983 and is commonly referred to
as BNU (Basic Networking Utilities) or HoneyDanBer UUCP. The latter
name is derived from the authors' names (P. Honeyman, D. A. Novitz,
and B. E. Redman) and is often shortened further to HDB, which is the
term we'll use in this chapter. HDB was conceived to eliminate some of
Version 2 UUCP's deficiencies.  For example, new transfer protocols
were added, and the spool directory was split so that now there is one
directory for each site with which you have UUCP traffic.</para><para><indexterm significance="normal"><primary>Taylor, Ian</primary></indexterm>
The implementation of UUCP currently distributed with Linux is Taylor
UUCP 1.06, which is the version this
chapter is based upon.<footnote id="x-087-2-fnuu01"><para>Written and copyrighted by Ian Taylor, 1995.</para></footnote>  Taylor UUCP Version 1.06 was released in August 1995.
Apart from traditional configuration files, Taylor UUCP can also be compiled
to understand the newstylea.k.a. Taylorconfiguration files.</para><para>Taylor UUCP is usually compiled for HDB compatibility, the Taylor 
configuration scheme, or both.  Because the Taylor scheme is much more 
flexible and probably easier to understand than the often obscure HDB 
configuration files, we will describe the Taylor scheme below.</para><para>This chapter is not designed to exhaustively describe the command-line
options for the UUCP commands and what they do, but to give you an
introduction to how to set up a working UUCP node. The first section gives
a gentle introduction about how UUCP implements remote execution and file
transfers. If you are not entirely new to UUCP, you might want to skip to
the section <xref linkend="x-087-2-uucp.config.files"></xref> later in this 
chapter, which explains the various files used to set up UUCP.</para><para>We will, however, assume that you are familiar with the user programs of
the UUCP suite, <command moreinfo="none">uucp</command> and <command moreinfo="none">uux</command>.
For a description, refer to the online manual pages.</para><para><indexterm significance="normal"><primary>uucico command</primary></indexterm>
Besides the publicly accessible programs <command moreinfo="none">uucp</command> and
<command moreinfo="none">uux</command>, the UUCP suite contains a number of commands used
for administrative purposes only. They are used to monitor UUCP traffic
across your node, remove old log files, or compile statistics. None of these
will be described here because they are peripheral to the main tasks of UUCP.
Besides, they're well documented and fairly easy to understand; refer to 
the manual pages for more information. However, there
is a third category, which comprise the actual UUCP
work horses.  They are called <command moreinfo="none">uucico</command>
(where <emphasis>cico</emphasis> stands for copy-in copy-out), and
<command moreinfo="none">uuxqt</command>, which executes jobs sent from remote systems.
We concentrate on these two important programs in this chapter.</para><para>If you're not satisfied with our coverage of these topics, you should read
the documentation that comes with the UUCP package.  This is a set of
Texinfo files that describe the setup using the Taylor configuration
scheme. You can convert the Texinfo files into a <command moreinfo="none">dvi</command> file 
using the <command moreinfo="none">texi2dvi</command> (found in the Texinfo package in your 
distribution) and view the <command moreinfo="none">dvi</command> file using the 
<command moreinfo="none">xdvi</command> command.</para><para><indexterm significance="normal"><primary>HOWTOs</primary><secondary>UUCP</secondary></indexterm>
Guylhem Aznar's UUCP-HOWTO is another good source for information about UUCP 
in a Linux environment. It is available at any Linux Documentation
Project mirror and is posted regularly to
<systemitem moreinfo="none" role="newsgroup">comp.os.linux.answers</systemitem>.</para><para><indexterm significance="normal"><primary>newsgroups</primary><secondary>comp.mail.uucp</secondary></indexterm> 
<indexterm significance="normal"><primary>comp.mail.uucp</primary></indexterm>
There's also a newsgroup for the discussion of UUCP called <systemitem moreinfo="none" role="newsgroup">comp.mail.uucp</systemitem>. If you have questions
specific to Taylor UUCP, you may be better off asking them there,
rather than on the <systemitem moreinfo="none" role="newsgroup">comp.os.linux.*</systemitem> groups.</para><sect1 id="x-087-2-uucp.intro.grades"><title>UUCP Transfers and Remote Execution</title><para><indexterm significance="normal"><primary>jobs (UUCP)</primary></indexterm> 
<indexterm significance="normal"><primary>UUCP</primary><secondary>jobs</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>job</secondary></indexterm>
The concept of jobs is vital to understanding UUCP.
Every transfer that a user initiates with <command moreinfo="none">uucp</command> or
<command moreinfo="none">uux</command> is called a <command moreinfo="none">job</command>. It is made up of 
a command to be executed on a remote system, a collection of files to 
be transferred between sites, or both.</para><para>As an example, the following command makes UUCP copy the file
<filename moreinfo="none">netguide.ps</filename> to a remote host named
<systemitem moreinfo="none" role="sitename">pablo</systemitem> and execute the
<command moreinfo="none">lpr</command> command on
<systemitem moreinfo="none" role="sitename">pablo</systemitem>
to print the file:</para><para><screen format="linespecific">$ <userinput moreinfo="none">uux -r pablo!lpr !netguide.ps</userinput></screen></para><para><indexterm significance="normal"><primary>spool directory</primary></indexterm> 
<indexterm significance="normal"><primary>spooling</primary></indexterm> 
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>spool directory</secondary></indexterm>
UUCP does not generally call the remote system immediately to execute a job
(or else you could make do with <command moreinfo="none">kermit</command>). Instead, it
temporarily stores the job description away. This is called
<emphasis>spooling</emphasis>. The directory tree under which jobs are stored
is therefore called the <emphasis>spool directory</emphasis> and is generally
located in <filename moreinfo="none">/var/spool/uucp</filename>. In our example, the job
description would contain information about the remote command to be executed
(<command moreinfo="none">lpr</command>), the user who requested the execution, and a couple
of other items. In addition to the job description, UUCP has to store the
input file <filename moreinfo="none">netguide.ps</filename>.</para><para>The exact location and naming of spool files may vary, depending on
some compile-time options. HDB-compatible UUCPs generally store spool
files in a <filename moreinfo="none">/var/spool/uucp</filename> subdirectory with the name
of the remote site. When compiled for Taylor configuration, UUCP creates
subdirectories below the site-specific spool directory for different types
of spool files.</para><para>At regular intervals, UUCP dials up the remote system.  When a connection to
the remote machine is established, UUCP transfers the files describing the
job, plus any input files.  The incoming jobs will not be executed
immediately, but only after the connection terminates. Execution is handled 
by <command moreinfo="none">uuxqt</command>, which also takes care of forwarding any jobs that
are designated for another site.</para><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>priorities</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>spool grade</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>job</secondary></indexterm>
To distinguish between more and less important jobs, UUCP associates a
<emphasis>grade</emphasis> with each job. This is a single digit ranging
from 0 through 9, A through Z, and a through z, in decreasing precedence. Mail
is customarily spooled with grade B or C, while news is spooled with grade
N. Jobs with higher grades are transferred earlier. Grades may be assigned
using the <option>g</option> flag when invoking <command moreinfo="none">uucp</command>
or <command moreinfo="none">uux</command>.</para><para>You can also prohibit the transfer of jobs below a given grade at certain
times. To do this we set the <emphasis>maximum spool grade</emphasis>
that will be prohibited during a conversation. The maximum spool grade 
defaults to z, meaning all grades will be transferred every time. Note the 
semantic ambiguity here: a file is transferred only if it has a grade 
<emphasis>equal to</emphasis> or <emphasis>above</emphasis> the maximum spool grade threshold.</para><sect2 id="x-087-2-uucico.connect"><title>The Inner Workings of uucico</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>uucico</secondary></indexterm>
<indexterm significance="normal"><primary>uucico command</primary></indexterm> 
To understand why <command moreinfo="none">uucico</command> needs to know particular 
information, a quick description of how it actually connects to a remote 
system is helpful.</para><para><indexterm significance="normal"><primary>gethostbyname()</primary><secondary>uucico and</secondary></indexterm> 
When you execute <command moreinfo="none">uucico -s <replaceable>system</replaceable></command>
from the command line, <command moreinfo="none">uucico</command> first has to connect
physically. The actions taken depend on the type of connection to
open. Thus, when using a telephone line, it has to find a modem and dial
out. Over TCP, it has to call <function moreinfo="none">gethostbyname</function> to convert
the name to a network address, find out which port to open, and bind the
address to the corresponding socket.</para><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>master</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>slave</secondary></indexterm>
A successful connection is followed by authorization. This procedure 
generally consists of the remote system
asking for a login name and possibly a password. This exchange is commonly
called the <emphasis>login chat</emphasis>. The authorization procedure is
performed either by the usual
<command moreinfo="none">getty/login</command> suite,
or on TCP sockets by <command moreinfo="none">uucico</command> itself.  If authorization
succeeds, the remote end fires up <command moreinfo="none">uucico</command>. The local copy of
<command moreinfo="none">uucico</command> that initiated the connection is referred to as
<emphasis>master</emphasis>, and the remote copy as <emphasis>slave</emphasis>.</para><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>call sequence check</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>handshake</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>protocols</secondary></indexterm>
<indexterm significance="normal"><primary>call sequence checks</primary></indexterm> 
Next follows the <emphasis>handshake phase</emphasis>: the master sends
its hostname plus several flags.  The slave checks this hostname for
permission to log in, send, and receive files, etc.  The flags describe
(among other things) the maximum grade of spool files to transfer. If
enabled, a conversation count or <emphasis>call sequence number</emphasis>
check takes place here. With this feature, both sites maintain a count of
successful connections, which are compared. If they do not match, the
handshake fails. This is useful to protect yourself against impostors.</para><para>Finally, the two <command moreinfo="none">uucico</command>s try to agree on a common
<emphasis>transfer protocol</emphasis>. This protocol governs the way data is
transferred, checked for consistency, and retransmitted in case of an error.
There is a need for different protocols because of the differing types of
connections supported. For example, telephone lines require a
safe protocol, which is pessimistic about errors, while TCP
transmission is inherently reliable and can use a more efficient protocol that
foregoes most extra error checking.</para><para>After the handshake is complete, the actual transmission phase begins.
Both ends turn on the selected protocol driver. At this point, the drivers
possibly perform a protocol-specific initialization sequence.</para><para>The master then sends all files queued for the remote system whose
spool grade is high enough. When it has finished, it informs the slave
that it is done and that the slave may now hang up. The slave now can
either agree to hang up or take over the conversation.  This is a
change of roles: now the remote system becomes master, and the local one
becomes slave. The new master now sends its files.  When done, both
<command moreinfo="none">uucico</command>s exchange termination messages and close the
connection.</para><para>If you need additional information on UUCP, please refer to the
source code. There is also a really antique article floating around the Net, 
written by David A. Novitz, which gives a detailed description of the UUCP
protocol.<footnote id="x-087-2-fnuu02"><para>It's also included in the 4.4BSD <emphasis>System Manager's Manual</emphasis>.</para></footnote> The Taylor UUCP FAQ also
discusses some details UUCP's implementation. It is posted to
<systemitem moreinfo="none" role="newsgroup">comp.mail.uucp</systemitem> regularly.

</para></sect2><sect2><title>uucico Command-line Options</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>calling out</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>logging and debugging</secondary></indexterm>
<indexterm significance="normal"><primary>debugging</primary><secondary>UUCP setup</secondary></indexterm>
<indexterm significance="normal"><primary>uucico command</primary><secondary>command-line options</secondary></indexterm> 
In this section, we describe the most important command-line options for
<command moreinfo="none">uucico</command>:</para><para><variablelist><varlistentry><term><option>  system, s <replaceable>system</replaceable></option></term><listitem><para>Calls the named <replaceable>system</replaceable> unless prohibited by call-time
restrictions.</para></listitem></varlistentry><varlistentry><term><option>S <replaceable>system</replaceable></option></term><listitem><para>Calls the named <replaceable>system</replaceable> unconditionally.</para></listitem></varlistentry><varlistentry><term><option> master, r1</option></term><listitem><para>Starts <command moreinfo="none">uucico</command> in master mode. This is the default when
<option>s</option> or <option>S</option> is given. All by itself,
the <option>r1</option> option causes <command moreinfo="none">uucico</command> to try
to call all systems in the <filename moreinfo="none">sys</filename> file described in the 
next section of this chapter, unless prohibited by call or retry time 
restrictions.</para></listitem></varlistentry><varlistentry><term><option> slave, r0</option></term><listitem><para>Starts <command moreinfo="none">uucico</command> in slave mode. This is the default
when no <option>s</option> or <option>S</option> is
given.  In slave mode, either standard input/output are assumed to be
connected to a serial port, or the TCP port specified by the
<option>p</option> option is used.</para></listitem></varlistentry><varlistentry><term><option> ifwork, C</option></term><listitem><para>This option supplements <option>s</option> or
<option>S</option> and tells <command moreinfo="none">uucico</command> to call the
named system only if there are jobs spooled for it.</para></listitem></varlistentry><varlistentry><term><option> debug <replaceable>type</replaceable>, x <replaceable>type</replaceable></option>, <option>X <replaceable>type</replaceable></option></term><listitem><para>Turns on debugging of the specified type. Several types can be given as a
comma-separated list. The following types are valid:
<systemitem moreinfo="none" role="keyword">abnormal</systemitem>,
<systemitem moreinfo="none" role="keyword">chat</systemitem>,
<systemitem moreinfo="none" role="keyword">handshake</systemitem>,
<systemitem moreinfo="none" role="keyword">uucp-proto</systemitem>,
<systemitem moreinfo="none" role="keyword">proto</systemitem>,
<systemitem moreinfo="none" role="keyword">port</systemitem>,
<systemitem moreinfo="none" role="keyword">config</systemitem>,
<systemitem moreinfo="none" role="keyword">spooldir</systemitem>,
<systemitem moreinfo="none" role="keyword">execute</systemitem>,
<systemitem moreinfo="none" role="keyword">incoming</systemitem>, and
<systemitem moreinfo="none" role="keyword">outgoing</systemitem>.
Using <systemitem moreinfo="none" role="keyword">all</systemitem> turns on all options.  For
compatibility with other UUCP implementations, a number may be specified
instead, which turns on debugging for the first <replaceable>n</replaceable>
items from the above list.</para><para>Debugging messages will be logged to the <filename moreinfo="none">Debug</filename>
file below <filename moreinfo="none">/var/spool/uucp</filename>.</para></listitem></varlistentry></variablelist></para></sect2></sect1><sect1 id="x-087-2-uucp.config.files"><title>UUCP Configuration Files</title><para><indexterm significance="normal" class="startofrange" id="chuu.config.files.uucp"><primary>configuration files</primary><secondary>UUCP</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-uucpconfigurationfiles-1"><primary>Taylor UUCP</primary><secondary>configuration files</secondary></indexterm>
In contrast to simpler file transfer programs, UUCP was designed to be
able to handle all transfers automatically. Once it is set up
properly, interference by the administrator should not be necessary on
a day-to-day basis. The information required for automated transfer is
kept in a couple of configuration files that reside in the
<filename moreinfo="none">/usr/lib/uucp</filename> directory. Most of these files are
used only when dialing out.</para><sect2><title>A Gentle Introduction to Taylor UUCP</title><para>To say that UUCP configuration is difficult would be an understatement. It 
is really a hairy subject, and the sometimes terse format of the 
configuration files doesn't make things easier (although the Taylor format is 
almost easy reading compared to the older formats in HDB or Version 2).</para><para>To give you a feel for how all the configuration files interact, we will
introduce you to the most important ones and have a look at sample entries
from these files. We won't explain everything in detail now; a more accurate
account is given in separate sections that follow. If you want to set up your
machine for UUCP, you had best start with some sample files and adapt
them gradually.  You can pick either those shown below or those included in
your favorite Linux distribution.</para><para>All files described in this section are kept in
<filename moreinfo="none">/etc/uucp</filename> or a subdirectory thereof. Some Linux
distributions contain UUCP binaries that have support for both HDB and Taylor
configuration enabled, and use different subdirectories for each configuration
file set. There will usually be a <filename moreinfo="none">README</filename> file in
<filename moreinfo="none">/usr/lib/uucp</filename>.</para><para>For UUCP to work properly, these files must be owned by the
<systemitem moreinfo="none" role="userid">uucp</systemitem> user. Some of them contain
passwords and telephone numbers, and therefore should have permissions
of 600. Note that although most UUCP commands must be setuid to
<systemitem moreinfo="none" role="userid">uucp</systemitem>, you must make sure the
<command moreinfo="none">uuchk</command> program is
<emphasis>not</emphasis>. Otherwise, users will be able to display
system passwords even though the files have mode 600.</para><para>The central UUCP configuration file is
<filename moreinfo="none">/etc/uucp/config</filename>, which is used to set general
parameters.  The most important of them (and for now, the only one) is
your host's UUCP name. At the Virtual Brewery, they use <systemitem moreinfo="none" role="sitename">vstout</systemitem> as their UUCP gateway:</para><para><screen format="linespecific"># /etc/uucp/config - UUCP main configuration file
nodename         vstout</screen></para><para><?troff .hw specific?>The <filename moreinfo="none">sys</filename> file is the next important configuration file. It
contains all the system-specific information of sites to which you are linked. 
This includes the site's name and information on the link itself, such as the
telephone number when using a modem link.  A typical entry for a
modem-connected site called <systemitem moreinfo="none" role="sitename">pablo</systemitem> 
would look like this:</para><para><screen format="linespecific"># /usr/lib/uucp/sys - name UUCP neighbors
# system: pablo
system          pablo
time            Any
phone           555-22112
port            serial1
speed           38400
chat            ogin: vstout ssword: lorca</screen></para><?troff .Nd 10?><para><systemitem moreinfo="none" role="keyword">time</systemitem> specifies the times at
which the remote system may be called.  <systemitem moreinfo="none" role="keyword">chat</systemitem> describes the login chat
scriptsthe sequence of strings that must be exchanged to allow
<command moreinfo="none">uucico</command> to log into <systemitem moreinfo="none" role="sitename">pablo</systemitem>. We will get back to chat scripts
later. The <systemitem moreinfo="none" role="keyword">port</systemitem> keyword simply
names an entry in the <filename moreinfo="none">port</filename> file.  (Refer to <xref linkend="x-087-2-uucp.fig.files"></xref>.) You can assign whatever name you
like as long as it refers to a valid entry in
<filename moreinfo="none">port</filename>.</para><para>The <filename moreinfo="none">port</filename> file holds information specific to the
link itself. For modem links, it describes the device special file to
be used, the range of speeds supported, and the type of dialing
equipment connected to the port. The following entry describes
<filename moreinfo="none">/dev/ttyS1</filename> (a.k.a. COM 2), to which the
administrator has connected a NakWell modem capable of running at
speeds up to 38,400 bps. The port's name is chosen to match the port
name given in the <filename moreinfo="none">sys</filename> file:</para><para><screen format="linespecific"># /etc/uucp/port - UUCP ports
# /dev/ttyS1 (COM2)
port            serial1
type            modem
device          /dev/ttyS1
speed           38400
dialer          nakwell</screen></para><para>The information pertaining to the dialers is kept in yet another file
calledyou guessed it<filename moreinfo="none">dial</filename>. For each dialer
type, it basically contains the sequence of commands that are issued to dial up
a remote site, given the telephone number. Again, this is specified as a chat
script. For example, the entry for NakWell might look like this:</para><para><screen format="linespecific"># /etc/uucp/dial - per-dialer information
# NakWell modems
dialer          nakwell
chat            "" ATF OK ATDT\T CONNECT</screen></para><para>The line starting with <systemitem moreinfo="none" role="keyword">chat</systemitem>
specifies the modem chat, which is the sequence of commands sent to
and received from the modem to initialize it and make it dial the
desired number. The <systemitem moreinfo="none" role="keyword">\T</systemitem>
sequence will be replaced with the phone number by
<command moreinfo="none">uucico</command>.</para><para>To give you a rough idea how <command moreinfo="none">uucico</command> deals with these
configuration files, assume you issue the following command:

<screen format="linespecific">$ <userinput moreinfo="none">uucico -s pablo</userinput></screen></para><para>The first thing <command moreinfo="none">uucico</command> does is look up <systemitem moreinfo="none" role="sitename">pablo</systemitem> in the <filename moreinfo="none">sys</filename>
file. From the <filename moreinfo="none">sys</filename> file entry for <systemitem moreinfo="none" role="sitename">pablo</systemitem>, it sees that it should use the
<systemitem moreinfo="none" role="keyword">serial1</systemitem> port to establish the
connection.  The <filename moreinfo="none">port</filename> file tells
<command moreinfo="none">uucico</command> that this is a modem port, and that it has a
NakWell modem attached.</para><para><command moreinfo="none">uucico</command> now searches <filename moreinfo="none">dial</filename> for
the entry describing the NakWell modem, and having found one, opens
the serial port <filename moreinfo="none">/dev/cua1</filename> and executes the dialer
chat. That is, it sends <command moreinfo="none">ATF</command>, waits for the
<command moreinfo="none">OK</command> response, etc. When encountering the string
<systemitem moreinfo="none" role="keyword">\T</systemitem>, it substitutes the phone
number (555-22112) extracted from the <filename moreinfo="none">sys</filename> file.</para><para>After the modem returns <command moreinfo="none">CONNECT</command>, the connection has been
established, and the modem chat is complete. <command moreinfo="none">uucico</command> now
returns to the <filename moreinfo="none">sys</filename> file and executes the login chat. In
our example, it would wait for the <command moreinfo="none">login:</command> prompt, then send
its username (<emphasis role="bold">vstout</emphasis>), wait for the
<command moreinfo="none">password:</command> prompt, and send its password
(<command moreinfo="none">lorca</command>).</para><para><?troff .hw section?>After completing authorization, the remote end is assumed to fire up its own
<command moreinfo="none">uucico</command>. The two then enter the handshake phase
described in the previous section.</para><para><xref linkend="x-087-2-uucp.fig.files"></xref> illustrates the dependencies among 
configuration files.</para><figure float="0" id="x-087-2-uucp.fig.files"><title>Interaction of Taylor UUCP configuration files</title><graphic fileref="lag2_1601.jpg"></graphic></figure></sect2><sect2 id="x-087-2-uucp.starting.parameters"><title>What UUCP Needs to Know</title><para>Before you start writing the UUCP configuration files, you have to gather some
information that UUCP requires.</para><para>First, you have to figure out what serial device your modem is
attached to.  Usually, the (DOS) ports COM1: through COM4: map to the
device special files <filename moreinfo="none">/dev/ttyS0</filename> through
<filename moreinfo="none">/dev/ttyS3</filename>.  Some distributions, such as
Slackware, create a link called <filename moreinfo="none">/dev/modem</filename> to the
appropriate <filename moreinfo="none">ttyS*</filename> device file, and configure
<command moreinfo="none">kermit</command>, <command moreinfo="none">seyon</command>, and any other
communication programs to use this generic file. In this case, you
should use <filename moreinfo="none">/dev/modem</filename> in your UUCP configuration,
too.</para><para>The reason for using a symbolic link is that all dial-out programs use
so-called <emphasis>lock files</emphasis> to signal when a serial port is
in use. The names of these lock files are a concatenation of the string
<filename moreinfo="none">LCK..</filename> and the device filename, for instance
<filename moreinfo="none">LCK..ttyS1</filename>. If programs use different names for the
same device, they will fail to recognize each other's lock files.  As a
consequence, they will disrupt each other's session when started at the
same time. This is quite possible when you schedule your UUCP calls
using a <filename moreinfo="none">crontab</filename> entry.
For details on serial port setup, please refer to
<xref linkend="x-087-2-serial"></xref>.</para><para>Next, you must find out at what speed your modem and Linux will communicate.
You have to set this speed to the maximum effective transfer rate you expect
to get. The effective transfer rate may be much higher than the raw physical
transfer rate your modem is capable of. For instance, many modems send and
receive data at 56 kbps. Using compression protocols such as V.42bis, the
actual transfer rate may climb over 100 kbps.</para><para>Of course, if UUCP is to do anything at all, you need the phone number 
of a system to call.  Also, you need a valid login ID and possibly a 
password for the remote machine.<footnote id="x-087-2-fnuu04"><para>If you're just going to try out UUCP, get the number of an archive site near
you. Write down the login and passwordthey're public to make anonymous
downloads possible. In most cases, they're something like
<systemitem moreinfo="none" role="userid">uucp/uucp</systemitem> or
<systemitem moreinfo="none" role="userid">nuucp/uucp</systemitem>.</para></footnote>
</para><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>logging in</secondary></indexterm>
You also have to know <emphasis>exactly</emphasis> how to log into the
system. Do you have to press the Enter key before the login prompt appears?
Does it display <literal moreinfo="none">login:</literal> or <literal moreinfo="none">user:</literal>? This
is necessary for composing the <emphasis>chat script</emphasis>. If you don't
know, or if the usual chat script fails, try to call the system with a terminal
program like <command moreinfo="none">kermit</command> or <command moreinfo="none">minicom</command> and 
record exactly what you have to do.</para></sect2><sect2 id="x-087-2-uucp.starting.sitename"><title>Site Naming</title><para><indexterm significance="normal"><primary>addresses</primary><secondary>UUCP hostname</secondary></indexterm>
<indexterm significance="normal"><primary>choosing</primary><secondary>UUCP hostname</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>hostname</secondary></indexterm>
<indexterm significance="normal"><primary>hostname</primary><secondary>UUCP</secondary></indexterm>
As with TCP/IP-based networking, your host has to have a name for UUCP
networking. As long as you simply want to use UUCP for file transfers to or
from sites you dial up directly, or on a local network, this name does not
have to meet any standards.<footnote id="x-087-2-fnuu05"><para>The only limitation is that it shouldn't be longer than seven characters, so
as to not confuse UUCP implementations that run on an operating system that
imposes a narrow limit on filenames. Names that are longer than seven
characters are often truncated by UUCP. Some versions even limit the name to
six characters.</para></footnote>
</para><para>However, if you use UUCP for a mail or news link, you should think
about having the name registered with the UUCP Mapping Project.<footnote id="x-087-2-fnuu06"><para> The UUCP Mapping Project
registers all UUCP hostnames worldwide and makes sure they are
unique.  </para></footnote> The UUCP Mapping Project is described in
<xref linkend="x-087-2-mail"></xref>. Even if you participate in a domain,
you might consider having an official UUCP name for your site.</para><para>Frequently, people choose their UUCP name to match the first component of
their fully qualified domain name. Suppose your site's domain address is
<systemitem moreinfo="none" role="sitename">swim.twobirds.com</systemitem>; then your UUCP
hostname would be <systemitem moreinfo="none" role="sitename">swim</systemitem>. Think of UUCP
sites as knowing each other on a first-name basis.  Of course, you can also
use a UUCP name completely unrelated to your fully qualified domain name.</para><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>Mapping Project</secondary></indexterm>
However, make sure not to use the unqualified site name in mail addresses
unless you have registered it as your official UUCP
name. At the very best, mail to an unregistered UUCP host will vanish in some big black bit bucket. If you use a name already held by some other site, this 
mail will be routed to that site and cause its postmaster a lot of headaches.</para><para>By default, the UUCP suite uses the name set by <command moreinfo="none">hostname</command> as
the site's UUCP name. This name is commonly set by a command on the boot
time <filename moreinfo="none">rc</filename> scripts, and is usually stored in the
<filename moreinfo="none">/etc/hostname</filename>. If your UUCP name is different from what
you set your hostname to, you have to use the
<command moreinfo="none">hostname</command> option in the
<filename moreinfo="none">config</filename> file to tell <command moreinfo="none">uucico</command> about your
UUCP name. This is described next.</para></sect2><sect2><title>Taylor Configuration Files</title><para><indexterm significance="normal"><primary>configuration files</primary><secondary>Taylor UUCP</secondary></indexterm> 
We now return to the configuration files. Taylor UUCP gets its information
from the following files:

<variablelist><varlistentry><term><filename moreinfo="none">config</filename></term><listitem><para>This is the main configuration file. You can define your site's UUCP name here.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">sys</filename></term><listitem><para>This file describes all known sites.  For each site, it specifies its
name, what times to call it, which number to dial (if any), what type of device
to use, and how to log on.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">port</filename></term><listitem><para>This file contains entries describing each available port, together with the line speed
supported and the dialer to be used.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">dial</filename></term><listitem><para>This file describes dialers used to establish a telephone connection.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">dialcode</filename></term><listitem><para>This file contains expansions for symbolic dial codes.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">call</filename></term><listitem><para>This file contains the login name and password to be used when calling a system.
Rarely used.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">passwd</filename></term><listitem><para>This file contains login names and passwords that systems may use when logging in. It is used only when <command moreinfo="none">uucico</command> does its own password
checking.</para></listitem></varlistentry></variablelist></para><para>Taylor configuration files are generally made up of lines containing
keyword-value pairs. A hash sign introduces a comment that extends to the
end of the line. To use a hash sign to mean itself, escape it with a
backslash like this: <literal moreinfo="none">\#</literal>.</para><para>There are quite a number of options you can tune with these configuration
files.  We can't go into all the parameters, but we will cover the
most important ones here. Then you should be able to configure a modem-based 
UUCP link. Additional sections describe the modifications necessary if you
want to use UUCP over TCP/IP or over a direct serial line. A complete
reference is given in the Texinfo documents that accompany the Taylor UUCP
sources.</para><para><indexterm significance="normal"><primary>displaying</primary><secondary>UUCP configuration</secondary></indexterm>
<indexterm significance="normal"><primary>checking</primary><secondary>UUCP</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>checking</secondary></indexterm>
When you think you have configured your UUCP system completely, you can check
your configuration using the <command moreinfo="none">uuchk</command> tool (located in
<filename moreinfo="none">/usr/lib/uucp</filename>). <command moreinfo="none">uuchk</command> reads your
configuration files and prints out a detailed report of the configuration
values used for each system.</para></sect2><sect2><title>General Configuration Options Using the config File</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>configuration files</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>hostname</secondary></indexterm>
You won't generally use this file to describe much beside your UUCP hostname.
By default, UUCP will use the name you set with the <command moreinfo="none">hostname</command>
command, but it is generally a good idea to set the UUCP name explicitly. Here's a sample <filename moreinfo="none">config</filename> file:

<screen format="linespecific"># /usr/lib/uucp/config - UUCP main configuration file
hostname        vstout</screen></para><para>A number of miscellaneous parameters can be set here too, such as the name of
the spool directory or access rights for anonymous UUCP. The latter will be
described later in this chapter in the section Anonymous UUCP.</para></sect2><sect2 id="x-087-2-uucp.systems.file"><title>How to Tell UUCP About Other Systems Using the <?lb?>sys File</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>sys file</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-uucpremotesystem-1"><primary>Taylor UUCP</primary><secondary>remote system</secondary></indexterm>
The <filename moreinfo="none">sys</filename> file describes the systems that your
machine knows about. An entry is introduced by the <systemitem moreinfo="none" role="keyword">system</systemitem> keyword; the subsequent lines up to
the next <systemitem moreinfo="none" role="keyword">system</systemitem> directive
detail the parameters specific to that site. Commonly, a system entry
defines parameters such as the telephone number and login chat.</para><para>Parameters before the very first <systemitem moreinfo="none" role="keyword">system</systemitem> line set default values used for
all systems. Usually, you set protocol parameters and the like in
the defaults section.</para><para>
The most prominent fields are discussed in detail in the following sections.</para><?troff .Nd 10?><sect3><title>System name</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>remote system</secondary></indexterm>
The <emphasis>system</emphasis> command names the remote
system. You must specify the correct name of the remote system, not an alias
you invented, because <command moreinfo="none">uucico</command> will check it against what
the remote system says it is called when you log
on.<footnote id="x-087-2-fnuu07"><para>Older Version 2 UUCPs don't broadcast their name when being called; however,
newer implementations often do, and so does Taylor UUCP.</para></footnote>
</para><para>Each system name can appear only once. If you want to use several sets of
configurations for the same system (such as different telephone numbers
<command moreinfo="none">uucico</command> should try in turn), you can specify
<emphasis>alternates</emphasis>, which we'll describe after the basic 
configuration options.</para></sect3><sect3><title>Telephone number</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>phone number</secondary></indexterm>
If the remote system is to be reached over a telephone line, the
<systemitem moreinfo="none" role="keyword">phone</systemitem> field specifies the number the
modem should dial. It may contain several tokens interpreted by
<command moreinfo="none">uucico</command>'s dialing procedure. An equal sign (=) means wait
for a secondary dial tone, and a dash (-) generates a one-second pause. Some 
telephone installations choke when you don't pause between
dialing a special access code and the telephone
number.<footnote id="x-087-2-fnuu08"><para>For instance, most companies' private installations require you to dial a 0 or
9 to get a line to the outside.</para></footnote>
</para><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>dialcode file</secondary></indexterm>
It is often convenient to use names instead of numbers to describe
area dialing codes. The <filename moreinfo="none">dialcode</filename> file allows you to
associate a name with a code that you may subsequently use when specifying
telephone numbers for remote hosts. Suppose you have the following
<filename moreinfo="none">dialcode</filename> file:</para><para><screen format="linespecific"># /usr/lib/uucp/dialcode - dialcode translation
Bogoham         024881
Coxton          035119</screen></para><para>With these translations, you can use a phone number such as
<systemitem moreinfo="none" role="keyword">Bogoham7732</systemitem> in the
<filename moreinfo="none">sys</filename> file, which will probably make things a little more
legible and a whole lot easier to update should the dialing code for
Bogoham ever change.</para></sect3><sect3><title>port and speed</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>device</secondary></indexterm>
The <systemitem moreinfo="none" role="keyword">port</systemitem> and <systemitem moreinfo="none" role="keyword">speed</systemitem> options are used to select the
device used for calling the remote system and the maximum speed to
which the device should be set.<footnote id="x-087-2-fnuu09"><para>The bit rate of the <emphasis>tty</emphasis> must be at least as high as the maximum
transfer speed.</para></footnote>
A <systemitem moreinfo="none" role="keyword">system</systemitem> entry may
use either option alone or both options in conjunction. When looking
up a suitable device in the <filename moreinfo="none">port</filename> file, only ports that have a matching port name and/or speed range are selected.</para><para>Generally, using the <systemitem moreinfo="none" role="keyword">speed</systemitem>
option only should suffice. If you have only one serial device defined
in <filename moreinfo="none">port</filename>, <command moreinfo="none">uucico</command> always picks the right one anyway, so you only have to give it the desired
speed. If you have several modems attached to your systems, you still
often don't want to name a particular port, because if
<command moreinfo="none">uucico</command> finds that there are several matches, it
tries each device in turn until it finds an unused one.</para></sect3><sect3><title>The login chat</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>logging in</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>login chat</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>chat scripts</secondary></indexterm>
<indexterm significance="normal"><primary>chat script</primary><secondary>UUCP</secondary></indexterm>
We already encountered the login chat script, which tells
<command moreinfo="none">uucico</command> how to log in to the remote system. It
consists of a list of tokens specifying strings expected and sent by
the local <command moreinfo="none">uucico</command> process. <command moreinfo="none">uucico</command>
waits until the remote machine sends a login prompt, then returns the
login name, waits for the remote system to send the password prompt,
and sends the password. Expect and send strings appear in alternation
in the script.  <command moreinfo="none">uucico</command> automatically appends a
carriage return character (<systemitem moreinfo="none" role="keyword">\r</systemitem>)
to any send string. Thus, a simple chat script would look like:

<screen format="linespecific"> ogin: vstout ssword: catch22</screen></para><para>You will probably notice that the expect fields don't contain the
whole prompts. This ensures that the login succeeds, even if the
remote system transmits <command moreinfo="none">Login:</command> instead of
<command moreinfo="none">login:</command>. If the string you are expecting or sending
contains spaces or other white-space characters, you must use quotes
to surround the text.</para><para><command moreinfo="none">uucico</command> also allows for some sort of conditional execution. 
Let's say the remote machine's <command moreinfo="none">getty</command>
needs to be reset before sending a prompt. For this, you can attach a subchat
to an expect string, set off by a dash.  The subchat is executed only if the
main expect fails, i.e., a timeout occurs.  One way to use this feature is to
send a BREAK if the remote site doesn't display a login prompt. The following
example gives a general-purpose chat script that should also work in case you
have to press Enter before the login appears. The empty first argument,
<literal moreinfo="none">""</literal>, tells UUCP to not wait for anything, but to continue 
with the next send string:

<screen format="linespecific"> "" \n\r\d\r\n\c ogin:-BREAK-ogin: vstout ssword: catch22</screen></para><para>A couple of special strings and escape characters can occur in the chat
script. The following is a partial list of characters legal in expect strings:

<variablelist><varlistentry><term><literal moreinfo="none">""</literal></term><listitem><para>The empty string. It tells <command moreinfo="none">uucico</command> to not wait for anything,
but to proceed with the next send string immediately.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">\t</systemitem></term><listitem><para>Tab character.</para></listitem></varlistentry><?troff .wcon_off?><varlistentry><term><systemitem moreinfo="none" role="keyword">\r</systemitem></term><listitem><para>Carriage return character.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">\s</systemitem></term><listitem><para>Space character. You need this to embed spaces in a chat string.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">\n</systemitem></term><listitem><para>Newline character.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">\\</systemitem></term><listitem><para>Backslash character.</para></listitem></varlistentry></variablelist></para><para>On send strings, the following escape characters and strings are legal in
addition to the above:

<variablelist><varlistentry><term><systemitem moreinfo="none" role="keyword">EOT</systemitem></term><listitem><para>End of transmission character (<command moreinfo="none">^D</command>).</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">BREAK</systemitem></term><listitem><para>Break character.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">\c</systemitem></term><listitem><para>Suppress sending of carriage return at end of string.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">\d</systemitem></term><listitem><para>Delay sending for 1 second.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">\E</systemitem></term><listitem><para>Enable echo checking. This requires <command moreinfo="none">uucico</command> to wait for the
echo of everything it writes to be read back from the device before it can
continue with the chat. It is primarily useful when used in modem chats
(which we will encounter later). Echo checking is off by default.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">\e</systemitem></term><listitem><para>Disable echo checking.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">\K</systemitem></term><listitem><para>Same as <systemitem moreinfo="none" role="keyword">BREAK</systemitem>.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">\p</systemitem></term><listitem><para>Pause for fraction of a second.</para></listitem></varlistentry></variablelist></para></sect3><sect3><title>Alternates</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>alternates</secondary></indexterm>
Sometimes you want to have multiple entries for a single system, for
instance if the system can be reached on different modem lines. With Taylor
UUCP, you can do this by defining a so-called <emphasis>alternate</emphasis>.</para><para>An alternate entry retains all settings from the main system entry and
specifies only those values that should be overridden in the default system
entry or added to it.  An alternate is offset from the system entry by a
line containing the keyword <systemitem moreinfo="none" role="keyword">alternate</systemitem>.</para><para>To use two phone numbers for <systemitem moreinfo="none" role="sitename">pablo</systemitem>,
you would modify its <filename moreinfo="none">sys</filename> entry in the following way:

<screen format="linespecific">system       pablo
phone        123-456
.. entries as above ...
alternate
phone        123-455</screen></para><para>When calling <systemitem moreinfo="none" role="sitename">pablo</systemitem>,
<command moreinfo="none">uucico</command> will first dial 123-456, and if this fails, it will
try the alternate.  The alternate entry retains all settings from the main
system entry and overrides the telephone number only.</para></sect3><sect3><title>Restricting call times</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>restrict</secondary><tertiary>call time</tertiary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>call time</secondary></indexterm>
Taylor UUCP provides a number of ways you may restrict the times when calls
can be placed to a remote system.  You might do this either because of
limitations the remote host places on its services during business hours, or
simply to avoid times with high call rates. Note that it is always possible
to override call-time restrictions by giving <command moreinfo="none">uucico</command> the
<option>S</option> or <option>f</option> option.</para><para>By default, Taylor UUCP disallows connections at any time, so you
<emphasis>have</emphasis> to use some sort of time specification in the
<filename moreinfo="none">sys</filename> file. If you don't care about call time restrictions,
you can specify the <command moreinfo="none">time</command> option with a
value of <systemitem moreinfo="none" role="keyword">Any</systemitem> in your
<filename moreinfo="none">sys</filename> file.</para><para>The simplest way to restrict call time is to include a
<systemitem moreinfo="none" role="keyword">time</systemitem> entry, followed by a string made
up of a day and a time subfield. Day may be any combination of
<systemitem moreinfo="none" role="keyword">Mo, Tu, We, Th, Fr, Sa,</systemitem> and <systemitem moreinfo="none" role="keyword">Su</systemitem>. You can 
also specify <systemitem moreinfo="none" role="keyword">Any</systemitem>,
<systemitem moreinfo="none" role="keyword">Never</systemitem>, or
<systemitem moreinfo="none" role="keyword">Wk</systemitem> for weekdays. The time consists of
two 24-hour clock values, separated by a dash. They specify the range during
which calls may be placed. The combination of these tokens is written without
white space in between.  Any number of day and time specifications may be
grouped together with commas, as this line shows:

<screen format="linespecific">time            MoWe0300-0730,Fr1805-2200</screen></para><para>This example allows calls on Mondays and Wednesdays from 3:00 a.m. to 7:30 a.m.,
and on Fridays between 6:05 p.m. and 10:00 p.m. When a time field spans
midnight, say <systemitem moreinfo="none" role="keyword">Mo1830-0600</systemitem>, it actually
means Monday, between midnight and 6:00 a.m. and between 6:30 p.m. and midnight.</para><para>The special time strings <systemitem moreinfo="none" role="keyword">Any</systemitem> and
<systemitem moreinfo="none" role="keyword">Never</systemitem> mean what they say: calls may be
placed at any or no time, respectively.</para><para>Taylor UUCP also has a number of special tokens you may use in time strings,
such as <systemitem moreinfo="none" role="keyword">NonPeak</systemitem> and
<systemitem moreinfo="none" role="keyword">Night</systemitem>.  These special tokens are shorthand for
<systemitem moreinfo="none" role="keyword">Any2300-0800,SaSu0800-1700</systemitem> and
<systemitem moreinfo="none" role="keyword">Any1800-0700,SaSu</systemitem>, respectively.</para><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>retry interval</secondary></indexterm>
The <emphasis>time</emphasis> command takes an optional
second argument that describes a retry time in minutes. When an attempt to
establish a connection fails, <command moreinfo="none">uucico</command> will not allow another
attempt to dial up the remote host within a certain interval. For instance,
when you specify a retry time of 5 minutes, <command moreinfo="none">uucico</command> will
refuse to call the remote system within 5 minutes after the last failure. By
default, <command moreinfo="none">uucico</command> uses an exponential backoff scheme, where
the retry interval increases with each repeated failure.</para><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>priorities</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>spool grade</secondary></indexterm>
The <command moreinfo="none">timegrade</command> command allows you to
attach a maximum spool grade to a schedule. For instance, assume you have the
following <command moreinfo="none">timegrade</command> commands in a
<systemitem moreinfo="none" role="keyword">system</systemitem> entry:

<screen format="linespecific">timegrade           N Wk1900-0700,SaSu 
timegrade           C Any</screen></para><?troff .Nd 10?><para>This allows jobs with a spool grade of C or higher (usually mail is queued
with grade B or C) to be transferred whenever a call is established, while
news (usually queued with grade N) are transferred only during the night
and at weekends.</para><para>Just like <command moreinfo="none">time</command>, the <command moreinfo="none">timegrade</command> command takes a retry interval in minutes as an optional third argument.</para><para>However, a caveat about spool grades is in order here. First, the
<command moreinfo="none">timegrade</command> option applies only to what
<emphasis>your</emphasis> systems sends; the remote system may still transfer
anything it likes.  You can use the
<command moreinfo="none">call-timegrade</command> option to explicitly
request it to send only jobs above some given spool grade; but there's no
guarantee it will obey this request.<footnote id="x-087-2-fnuu10"><para>If the remote system runs Taylor UUCP, it will obey.</para></footnote></para><para>Similarly, the <replaceable>timegrade</replaceable> field is not
checked when a remote system calls in, so any jobs queued for the calling
system will be sent. However, the remote system can explicitly request your
<command moreinfo="none">uucico</command> to restrict itself to a certain spool grade.
<indexterm significance="normal" class="endofrange" startref="idx-uucpremotesystem-1"></indexterm></para></sect3></sect2><sect2><title>Identifying Available Devices Through the port File</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>port file</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>device</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>modem</secondary></indexterm>
The <filename moreinfo="none">port</filename> file tells <command moreinfo="none">uucico</command> about the
available ports. These are usually modem ports, but other types, such as direct
serial lines and TCP sockets, are supported as well.</para><para>Like the <filename moreinfo="none">sys</filename> file, <filename moreinfo="none">port</filename>
consists of separate entries starting with the keyword
<systemitem moreinfo="none" role="keyword">port</systemitem> followed by the port name. This
name may be used in the <filename moreinfo="none">sys</filename> file's
<systemitem moreinfo="none" role="keyword">port</systemitem> statement. The name need not
be unique; if there are several ports with the same name,
<command moreinfo="none">uucico</command> will try each in turn until it finds one that
is not currently being used.</para><para>The <command moreinfo="none">port</command> command should be followed
immediately by the <systemitem moreinfo="none" role="keyword">type</systemitem> statement,
which indicates what type of port is described. Valid types are
<systemitem moreinfo="none" role="keyword">modem</systemitem>,
<systemitem moreinfo="none" role="keyword">direct</systemitem> for direct connections, and
<systemitem moreinfo="none" role="keyword">tcp</systemitem> for TCP sockets. If the
<command moreinfo="none">port</command> command is missing, the port
type defaults to modem.</para><para>In this section, we cover only modem ports; TCP ports and direct lines are
discussed in a later section.</para><?troff .wcon_off?><para>For modem and direct ports, you have to specify the device for calling out
using the <systemitem moreinfo="none" role="keyword">device</systemitem> directive. Usually,
this is the name of a device special file in the <filename moreinfo="none">/dev</filename>
directory, like <filename moreinfo="none">/dev/ttyS1</filename>.</para><para>In the case of a modem device, the port entry also determines what type of
modem is connected to the port.  Different types of modems have to be
configured differently. Even modems that claim to be Hayes-compatible aren't
always really compatible with one another. Therefore, you have to tell
<command moreinfo="none">uucico</command> how to initialize the modem and make it dial
the desired number. Taylor UUCP keeps the descriptions of all dialers in a<?troff .ne 10?>
file named <filename moreinfo="none">dial</filename>.  To use any of these, you have to specify
the dialer's name using the <command moreinfo="none">dialer</command>
command.</para><para>Sometimes, you will want to use a modem in different ways, depending on which
system you call.  For instance, some older modems don't understand when a
high-speed modem attempts to connect at 56 kbps; they simply drop the line
instead of negotiating a connect at 9,600 bps, for instance. When you know site
<systemitem moreinfo="none" role="sitename">drop</systemitem> uses such a dumb modem, you have
to set up your modem differently when calling them. For this, you need an
additional port entry in the <filename moreinfo="none">port</filename> file that specifies a
different dialer. Now you can give the new port a different name, such as
<systemitem moreinfo="none" role="keyword">serial1-slow</systemitem>, and use the
<systemitem moreinfo="none" role="keyword">port</systemitem> directive in the
<systemitem moreinfo="none" role="sitename">drop</systemitem> system entry in
<filename moreinfo="none">sys</filename>.</para><para>A better to distinguish the ports is by the speeds they support. For
instance, the two port entries for the above situation may look like this:

<screen format="linespecific"># NakWell modem; connect at high speed
port            serial1         # port name
type            modem           # modem port
device          /dev/ttyS1      # this is COM2
speed           115200          # supported speed
dialer          nakwell         # normal dialer
# NakWell modem; connect at low speed
port            serial1         # port name
type            modem           # modem port
device          /dev/ttyS1      # this is COM2
speed           9600            # supported speed
dialer          nakwell-slow    # don't attempt fast connect</screen></para><para>The system entry for site <systemitem moreinfo="none" role="sitename">drop</systemitem> would
now give <systemitem moreinfo="none" role="keyword">serial1</systemitem> as the port name, but
request to use it at only 9,600 bps.  <command moreinfo="none">uucico</command> then
automatically uses the second port entry. All remaining sites that have a
speed of 115,200 bps in the system entry will be called using the first port
entry. By default, the first entry with a matching speed will be used.</para></sect2><sect2><title>How to Dial a Number Using the dial File</title><para>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>dial file</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-uucpmodem-1"><primary>Taylor UUCP</primary><secondary>modem</secondary></indexterm>
The <filename moreinfo="none">dial</filename> file describes the way various dialers are used.
Traditionally, UUCP talks of dialers rather than modems, because in earlier
times, it was usual practice to have one (expensive) automatic dialing device
serve a whole bank of modems. Today, most modems have dialing support built
in, so this distinction gets a little blurred.</para><?troff .wcon_off?><para>Nevertheless, different dialers or modems may require a different
configuration. You can describe each of them in the
<filename moreinfo="none">dial</filename> file. Entries in <filename moreinfo="none">dial</filename>
start with the <command moreinfo="none">dialer</command> command
that gives the dialer's name.</para><para>The most important entry besides <command moreinfo="none">dialer</command> is the modem chat, specified by the <command moreinfo="none">chat</command> command. Similar to the
login chat, it consists of a sequence of strings
<command moreinfo="none">uucico</command> sends to the dialer and the responses it
expects in return. It is commonly used to reset the modem to some
known state and dial the number. The following sample <systemitem moreinfo="none" role="keyword">dialer</systemitem> entry shows a typical modem chat
for a Hayes-compatible modem:</para><screen format="linespecific"># NakWell modem; connect at high speed
dialer          nakwell         # dialer name
chat            "" ATF OK\r ATH1E0Q0 OK\r ATDT\T CONNECT
chat-fail       BUSY
chat-fail       ERROR
chat-fail       NO\sCARRIER
dtr-toggle      true</screen><para>The modem chat begins with <literal moreinfo="none">""</literal>, the empty expect
string.  <command moreinfo="none">uucico</command> therefore sends the first
command <command moreinfo="none">ATF</command> right
away. <command moreinfo="none">ATF</command> is the Hayes command to reset the
modem to factory default configuration.  <command moreinfo="none">uucico</command>
then waits until the modem has sent <literal moreinfo="none">OK</literal> and sends
the next command, which turns off local echo and the like. After the
modem returns <literal moreinfo="none">OK</literal> again, <command moreinfo="none">uucico</command>
sends the dialing command <command moreinfo="none">ATDT</command>.  The escape
sequence <literal moreinfo="none">\T</literal> in this string is replaced with the
phone number taken from the system entry <filename moreinfo="none">sys</filename>
file. <command moreinfo="none">uucico</command> then waits for the modem to return the
string <literal moreinfo="none">CONNECT</literal>, which signals that a connection
with the remote modem has been established successfully.</para><para>Sometimes the modem fails to connect to the remote system; for instance,
if the other system is talking to someone else and the line is busy. In this
case, the modem returns an error message indicating the reason. Modem
chats are not capable of detecting such messages; <command moreinfo="none">uucico</command> 
continues to wait for the expected string until it times out. The UUCP
log file therefore only shows a bland timed out in chat
script instead of the specific reason.</para><para>However, Taylor UUCP allows you to tell <command moreinfo="none">uucico</command> about these
error messages using the <command moreinfo="none">chat-fail</command>
command as shown above. When <command moreinfo="none">uucico</command> detects a chat-fail
string while executing the modem chat, it aborts the call and logs the error
message in the UUCP log file.</para><para>The last command in the example shown above tells UUCP to toggle the Data Terminal Ready (DTR) control line before starting the modem chat. Normally, 
the serial driver raises DTR when a process opens the device to tell the 
attached modem that someone wants to talk to it. The 
<systemitem moreinfo="none" role="keyword">dtr-toggle</systemitem> feature then drops DTR, 
waits a moment, and raises it again.  Many modems can be configured 
to react to a drop of DTR by going off-hook, entering command state, or 
resetting themselves.<footnote id="x-087-2-fnuu11"><para>Some modems don't seem to like this and occasionally hang.</para></footnote>
</para><indexterm significance="normal" class="endofrange" startref="idx-uucpmodem-1"></indexterm></sect2><sect2><title>UUCP Over TCP</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>over TCP/IP</secondary></indexterm>
<indexterm significance="normal"><primary>TCP (Transmission Control Protocol)</primary><secondary>UUCP</secondary></indexterm>
Absurd as it may sound, using UUCP to transfer data over TCP is not that bad
an idea, especially when transferring large amounts of data such as Usenet
news.  On TCP-based links, news is generally exchanged using the NNTP
protocol, through which articles are requested and sent individually without
compression or any other optimization. Although adequate for large sites
with several concurrent newsfeeds, this technique is very unfavorable for
small sites that receive their news over a relatively slow connection such
as ISDN. These sites will usually want to combine the qualities of TCP with
the advantages of sending news in large batches, which can be compressed and
thus transferred with very low overhead. A common way to transfer these
batches is to use UUCP over TCP.</para><para>In <filename moreinfo="none">sys</filename>, you would specify a system to be called via TCP 
like this:

<screen format="linespecific">system          gmu
address         news.groucho.edu
time            Any
port            tcp-conn
chat            ogin: vstout word: clouseau</screen></para><para>The <command moreinfo="none">address</command> command gives the
IP address of the host or its fully qualified domain name.  The
corresponding <filename moreinfo="none">port</filename> entry would read:

<screen format="linespecific">port            tcp-conn
type            tcp
service         540</screen></para><para>The entry states that a TCP connection should be used when a
<filename moreinfo="none">sys</filename> entry references
<systemitem moreinfo="none" role="keyword">tcp-conn</systemitem>, and that
<command moreinfo="none">uucico</command> should attempt to connect to the TCP network port
540 on the remote host. This is the default port number of the UUCP service.
Instead of the port number, you may also give a symbolic port name to the
<command moreinfo="none">service</command> command. The port number
corresponding to this name will be looked up in
<filename moreinfo="none">/etc/services</filename>. The common name for the UUCP service is
<systemitem moreinfo="none" role="keyword">uucpd</systemitem>.</para></sect2><sect2><title>Using a Direct Connection</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>direct lines</secondary></indexterm>
Assume you use a direct line to connect your system
<systemitem moreinfo="none" role="sitename">vstout</systemitem> to
<systemitem moreinfo="none" role="sitename">tiny</systemitem>. Much like in the modem case,
you have to write a system entry in the <filename moreinfo="none">sys</filename> file. The
<command moreinfo="none">port</command> command identifies the serial port
<systemitem moreinfo="none" role="keyword">tiny</systemitem> is hooked up to:

<screen format="linespecific">system          tiny
time            Any
port            direct1
speed           38400
chat            ogin: cathcart word: catch22</screen></para><para>In the <filename moreinfo="none">port</filename> file, you have to describe the serial port
for the direct connection. A <systemitem moreinfo="none" role="keyword">dialer</systemitem>
entry is not needed because there's no need for dialing:

<screen format="linespecific">port            direct1
type            direct
speed           38400
device		    /dev/ttyS1</screen></para><indexterm significance="normal" class="endofrange" startref="idx-uucpconfigurationfiles-1"></indexterm><indexterm significance="normal" class="endofrange" startref="chuu.config.files.uucp"></indexterm></sect2></sect1><sect1 id="x-087-2-uucp.permissions"><title>Controlling Access to UUCP Features</title><para><indexterm significance="normal" class="startofrange" id="idx-securityuucp-1"><primary>security</primary><secondary>UUCP</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-accessuucp-1"><primary>access</primary><secondary>UUCP</secondary></indexterm>
UUCP is quite a flexible system. With that flexibility comes a need to
carefully control access to its features to prevent abuse, whether it be 
intentional or accidental. The primary features of concern to the UUCP 
administrator are remote command execution, file transfer, and forwarding. 
Taylor UUCP provides a means of limiting the freedom that remote UUCP hosts 
have in exercising each of these features. With careful selection of 
permissions, the UUCP administrator can ensure that the host's security is 
preserved.</para><sect2><title>Command Execution</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>restrict</secondary><tertiary>command execution</tertiary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>command execution</secondary></indexterm>
UUCP's task is to copy files from one system to another and to request
execution of certain commands on remote hosts. Of course, you as an
administrator would want to control what rights you grant other
systemsallowing them to execute any command they choose on your system 
is definitely not a good idea.</para><para><indexterm significance="normal"><primary>SMTP (Simple Mail Transfer Protocol)</primary><secondary>batched</secondary></indexterm>
<indexterm significance="normal"><primary>rmail command</primary></indexterm>
<indexterm significance="normal"><primary>rnews command</primary></indexterm>
<indexterm significance="normal"><primary>rsmtp</primary><secondary>command</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>mail</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>news</secondary></indexterm>
By default, the only commands Taylor UUCP allows other systems to execute on
your machine are <command moreinfo="none">rmail</command> and <command moreinfo="none">rnews</command>, which
are commonly used to exchange email and Usenet News over UUCP. To change the
set of commands for a particular system, you can use the
<systemitem moreinfo="none" role="keyword">commands</systemitem> keyword in the
<filename moreinfo="none">sys</filename> file. Similarly, you may want to limit the search
path to just those directories containing the allowed commands. You can
change the search path allowed for a remote host with the
<systemitem moreinfo="none" role="keyword">command-path</systemitem> statement. For instance,
you may want to allow system
<systemitem moreinfo="none" role="sitename">pablo</systemitem> to execute the
<command moreinfo="none">bsmtp</command> command in addition to <command moreinfo="none">rmail</command>
and <command moreinfo="none">rnews</command>:<footnote id="x-087-2-fnuu12"><para><command moreinfo="none">bsmtp</command> is used to deliver mail with batched SMTP.</para></footnote>

<screen format="linespecific">system          pablo
...
commands        rmail rnews bsmtp</screen></para></sect2><sect2><title>File Transfers</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>restrict</secondary><tertiary>file transfer</tertiary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>file transfer</secondary></indexterm>
Taylor UUCP also allows you to fine-tune file transfers in great
detail. At one extreme, you can disable transfers to and from a
particular system. Just set <systemitem moreinfo="none" role="keyword">request</systemitem> to <systemitem moreinfo="none" role="keyword">no</systemitem>, and the remote system will not be able
to either retrieve files from your system or send it any
files. Similarly, you can prohibit your users from transferring files
to or from a system by setting <systemitem moreinfo="none" role="keyword">transfer</systemitem> to <systemitem moreinfo="none" role="keyword">no</systemitem>.  By default, users on both the local
and the remote system are allowed to upload and download files.</para><para>In addition, you can configure the directories that files may be
copied to and from. Usually you will want to restrict access from
remote systems to a single directory hierarchy, but still allow your
users to send files from their home directory. Commonly, remote users are 
allowed to receive files only from the public UUCP directory
<filename moreinfo="none">/var/spool/uucppublic</filename>.  This is the traditional
place to make files publicly available, very much like FTP servers on
the Internet.<footnote id="x-087-2-uucp-fnuu13"><para> You may use a
tilde (<literal moreinfo="none">~</literal>) character to refer to the UUCP public
directory, but only in UUCP configuration files; outside it usually
translates to the user's home directory.</para></footnote></para><para>Taylor UUCP provides four different commands to configure the
directories for sending and receiving files. They are: 
<command moreinfo="none">local-send</command>, which specifies the list of
directories a user may ask UUCP to send files from; 
<command moreinfo="none">local-receive</command>, which gives the list of
directories a user may ask to receive files to; and 
<command moreinfo="none">remote-send</command> and <command moreinfo="none">remote-receive</command>, 
which do the analogous for
requests from a foreign system. Consider the following example:

<screen format="linespecific">system          pablo
...
local-send      /home ~
local-receive   /home ~/receive
remote-send     ~ !~/incoming !~/receive
remote-receive  ~/incoming</screen></para><para>The <command moreinfo="none">local-send</command> command allows
users on your host to send any files below <filename moreinfo="none">/home</filename>
and from the public UUCP directory to <systemitem moreinfo="none" role="sitename">pablo</systemitem>. The <command moreinfo="none">local-receive</command> 
command allows them to
receive files either to the world-writable
<filename moreinfo="none">receive</filename> directory in the
<filename moreinfo="none">uucppublic</filename>, or any world-writable directory below
<filename moreinfo="none">/home</filename>. The <command moreinfo="none">remote-send</command> 
directive allows <systemitem moreinfo="none" role="sitename">pablo</systemitem> to request files from
<filename moreinfo="none">/var/spool/uucppublic</filename>, except for files from the
<filename moreinfo="none">incoming</filename> and <filename moreinfo="none">receive</filename>
directories.  This is signaled to <command moreinfo="none">uucico</command> by
preceding the directory names with exclamation marks. Finally, the
last line allows <systemitem moreinfo="none" role="sitename">pablo</systemitem> to
upload files to <systemitem moreinfo="none" role="sitename">incoming</systemitem>.</para><para>A major problem with file transfers using UUCP is that it receives files
only to directories that are world-writable. This may tempt some users to set
up traps for other users. However, there's no way to escape this problem
outside of disabling UUCP file transfers altogether.</para></sect2><sect2><title>Forwarding</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>restrict</secondary><tertiary>forwarding</tertiary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>forwarding</secondary></indexterm>
UUCP provides a mechanism to have other systems execute file transfers on your
behalf. For instance, suppose your system has <command moreinfo="none">uucp</command> access 
to a system called <systemitem moreinfo="none" role="sitename">seci</systemitem>, but not to 
another system called <systemitem moreinfo="none" role="sitename">uchile</systemitem>. This 
allows you to make <systemitem moreinfo="none" role="sitename">seci</systemitem> retrieve a 
file from <systemitem moreinfo="none" role="sitename">uchile</systemitem> for you and send it 
to your system. The following command would achieve this:

<screen format="linespecific">$ <userinput moreinfo="none">uucp -r seci!uchile!~/find-ls.gz ~/uchile.files.gz</userinput></screen></para><para>This technique of passing a job through several systems is called
<emphasis>forwarding</emphasis>. On your own UUCP system, you would want to 
limit the forwarding service to a few hosts you trust not to run up a 
horrendous phone bill by making you download the latest X11R6 source release 
for them.</para><para>By default, Taylor UUCP prohibits forwarding altogether. To enable
forwarding for a particular system, you can use the 
<command moreinfo="none">forward</command> command. This command specifies a
list of sites the system may request you to forward jobs to and
from. For instance, the UUCP administrator of <systemitem moreinfo="none" role="sitename">seci</systemitem> would have to add the following
lines to the <filename moreinfo="none">sys</filename> file to allow <systemitem moreinfo="none" role="sitename">pablo</systemitem> to request files from <systemitem moreinfo="none" role="sitename">uchile</systemitem>:

<screen format="linespecific">####################
# pablo
system          pablo
...
forward         uchile
####################
# uchile
system          uchile
...
forward-to      pablo</screen></para><para>The <systemitem moreinfo="none" role="keyword">forward-to</systemitem> entry for
<systemitem moreinfo="none" role="sitename">uchile</systemitem> is necessary so that any files
returned by it are actually passed on to
<systemitem moreinfo="none" role="sitename">pablo</systemitem>. Otherwise UUCP would drop them.
This entry uses a variation of the
<command moreinfo="none">forward</command> command that permits
<systemitem moreinfo="none" role="sitename">uchile</systemitem> to send files only to
<systemitem moreinfo="none" role="sitename">pablo</systemitem> through
<systemitem moreinfo="none" role="sitename">seci</systemitem>, not the other way round.</para><para>To permit forwarding to any system, use the special keyword
<systemitem moreinfo="none" role="keyword">ANY</systemitem> (capital letters required).</para></sect2></sect1><sect1 id="x-087-2-uucp.dialin"><title>Setting Up Your System for Dialing In</title><para><indexterm significance="normal" class="startofrange" id="idx-uucpconfigureasserver-1"><primary>Taylor UUCP</primary><secondary>configure as server</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>calling in</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-serveruucp-1"><primary>servers</primary><secondary>UUCP</secondary></indexterm>
If you want to set up your site for dialing in, you have to permit logins on
your serial port and customize some system files to provide UUCP accounts, 
which we will cover in this section. </para><sect2 id="x-087-2-uucp.dialin.accounts"><title>Providing UUCP Accounts</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>accounts</secondary></indexterm>
<indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>set up logins</secondary></indexterm>
To begin with, you have to set up user accounts that let remote sites log into
your system and establish a UUCP connection. Generally, you will provide
a separate login name to each system that polls you. When setting up an
account for system <systemitem moreinfo="none" role="sitename">pablo</systemitem>, you might
give it the username <systemitem moreinfo="none" role="userid">Upablo</systemitem>. There is
no enforced policy on login names; they can be just about anything, but it
will be convenient for you if the login name is easily related to the remote
host name.</para><para>For systems that dial in through the serial port, you usually have to add
these accounts to the system password file <filename moreinfo="none">/etc/passwd</filename>.
It is good practice to put all UUCP logins in a special group, such as
<systemitem moreinfo="none" role="userid">uuguest</systemitem>. The account's home directory
should be set to the public spool directory
<filename moreinfo="none">/var/spool/uucppublic</filename>; its login shell must be
<command moreinfo="none">uucico</command>.</para><para><indexterm significance="normal"><primary sortas="etc/inetd.conf file">/etc/inetd.conf file</primary></indexterm> 
To serve UUCP systems that connect to your site over TCP, you have to
set up <command moreinfo="none">inetd</command> to handle incoming connections on the
<systemitem moreinfo="none" role="keyword">uucp</systemitem> port by adding the
following line to
<filename moreinfo="none">/etc/inetd.conf</filename>:<footnote id="x-087-2-fnuu14"><para> Note that <command moreinfo="none">tcpd</command> usually
has mode 700, so that you must invoke it as user <systemitem moreinfo="none" role="userid">root</systemitem>, not <systemitem moreinfo="none" role="userid">uucp</systemitem>. <command moreinfo="none">tcpd</command> is discussed
in more detail in <xref linkend="x-087-2-appl"></xref>.</para></footnote>

<screen format="linespecific">uucp   stream  tcp   nowait  root  /usr/sbin/tcpd  /usr/lib/uucp/uucico -l</screen></para><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>passwd file</secondary></indexterm>
<indexterm significance="normal"><primary sortas="usr/lib/uucp/passwd file">/usr/lib/uucp/passwd file</primary></indexterm> <?troff .ffn?>
The <option>l</option> option makes <command moreinfo="none">uucico</command> perform
its own login authorization. It prompts for a login name and a password
just like the standard <command moreinfo="none">login</command> program, but relies on its
private password database instead of <filename moreinfo="none">/etc/passwd</filename>. This
private password file is named <filename moreinfo="none">/etc/uucp/passwd</filename> and
contains pairs of login names and passwords:

<screen format="linespecific">Upablo  IslaNegra
Ulorca  co'rdoba</screen></para><para>This file must be owned by
<systemitem moreinfo="none" role="userid">uucp</systemitem> and have permissions of 600.</para><para><indexterm significance="normal"><primary>mgetty program</primary></indexterm>
Does this database sound like such a good idea that you would like to use
it on normal serial logins, too? Well, in some cases you can. What you
need is a <command moreinfo="none">getty</command> program that you can tell to invoke
<command moreinfo="none">uucico</command> instead of <command moreinfo="none">/bin/login</command> for
your UUCP users.<footnote id="x-087-2-fnuu15"><para>Gert Doering's <command moreinfo="none">mgetty</command> is such a beast. It runs on a
variety of platforms, including SCO Unix, AIX, SunOS, HP-UX, and Linux.</para></footnote> The invocation of
<command moreinfo="none">uucico</command> would look like this:

<screen format="linespecific">/usr/lib/uucp/uucico -l -u <replaceable>user</replaceable></screen>

The <option>u</option> option tells it to use the specified user
name rather than prompting for it.<footnote id="x-087-2-fnuu16"><para>This option is not present in Version 1.04.</para></footnote>
</para><para>To protect your UUCP users from callers who might give a false system name and
snarf all their mail, you should add
<command moreinfo="none">called-login</command> commands to each system
entry in the <filename moreinfo="none">sys</filename> file. This is described in the next
section.</para></sect2><sect2 id="x-087-2-uucp.security.called-login"><title>Protecting Yourself Against Swindlers</title><para><indexterm significance="normal" class="startofrange" id="idx-uucploginsecurity-1"><primary>Taylor UUCP</primary><secondary>login security</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="chuu.uucp.security"><primary>UUCP</primary><secondary>security</secondary></indexterm> 
A major problem with UUCP is that the calling system can lie about its name;
it announces its name to the called system after logging in, but the server
doesn't have any way to check it. Thus, an attacker could log into his or her
own UUCP account, pretend to be someone else, and pick up that other site's
mail. This is particularly troublesome if you offer login via anonymous UUCP,
where the password is made public.</para><?troff .Nd 10?><para>You <emphasis>must</emphasis> guard against this sort of impostor. The cure
for this disease is to require each system to use a particular login name
by specifying a <systemitem moreinfo="none" role="keyword">called-login</systemitem> in
<filename moreinfo="none">sys</filename>. A sample system entry may look like this:

<screen format="linespecific">system          pablo
... usual options ...
called-login    Upablo</screen></para><para>The upshot is that whenever a system logs in and pretends it is
<systemitem moreinfo="none" role="sitename">pablo</systemitem>,
<command moreinfo="none">uucico</command> checks whether it has logged in as
<systemitem moreinfo="none" role="userid">Upablo</systemitem>. If it hasn't, the
calling system is turned down, and the connection is dropped. You
should make it a habit to add the <command moreinfo="none">called-login</command> command to every system entry
you add to your <filename moreinfo="none">sys</filename> file. It is important that
you do this for <emphasis>all</emphasis> systems in your
<command moreinfo="none">sys</command> file, regardless of whether they will ever call
your site or not. For those sites that never call you, you should
probably set <systemitem moreinfo="none" role="keyword">called-login</systemitem> to
some totally bogus user name, such as <systemitem moreinfo="none" role="userid">neverlogsin</systemitem>.</para></sect2><sect2><title>Be Paranoid: Call Sequence Checks</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>call sequence check</secondary></indexterm>
Another way to fend off and detect impostors is to use <command moreinfo="none">call sequence 
checks</command>. These help you protect against intruders who somehow manage to find out the password with which you log into your UUCP system.</para><para>When using call sequence checks, both machines keep track of the number of
connections established so far. The counter is incremented with each 
connection. After logging in, the caller sends its call sequence number, and 
the receiver checks it against its own number. If they don't match, the 
connection attempt is rejected. If the initial number is chosen at 
random, attackers will have a hard time guessing the correct call sequence 
number.</para><para>But call sequence checks do more for you. Even if some very clever
person should detect your call sequence number as well as your password, you
will find out. When the attacker calls your UUCP feed and steals your
mail, this will increase the feeds call sequence number by one. The next time
<emphasis>you</emphasis> call your feed and try to log in, the remote
<command moreinfo="none">uucico</command> will refuse you, because the numbers don't match
anymore!</para><para>If you have enabled call sequence checks, you should check your log files
regularly for error messages that hint at possible attacks. If your system
rejects the call sequence number the calling system offers,
<command moreinfo="none">uucico</command> will put a message into the log file saying
something like, Out of sequence call rejected. If your system
is rejected by its feed because the sequence numbers are out of sync, it
will put a message in the log file saying, Handshake failed
(RBADSEQ).</para><para>To enable call sequence checks, add the following command to the
system entry:

<screen format="linespecific"># enable call sequence checks
sequence        true</screen></para><para><indexterm significance="normal"><primary sortas="Sequence file">.Sequence file</primary></indexterm>
In addition, you have to create the file containing the sequence
number itself.  Taylor UUCP keeps the sequence number in a file called
<filename moreinfo="none">.Sequence</filename> in the remote site's spool
directory. It <emphasis>must</emphasis> be owned by <systemitem moreinfo="none" role="userid">uucp</systemitem> and must be mode 600 (i.e., readable
and writeable only by <systemitem moreinfo="none" role="userid">uucp</systemitem>). It
is best to initialize this file with an arbitrary, previously
agreed-upon start value. A simple way to create this file is:

<screen format="linespecific"># <userinput moreinfo="none">cd /var/spool/uucp/pablo</userinput>
# <userinput moreinfo="none">echo 94316  .Sequence</userinput>
# <userinput moreinfo="none">chmod 600 .Sequence</userinput>
# <userinput moreinfo="none">chown uucp.uucp .Sequence</userinput></screen></para><para>Of course, the remote site has to enable call sequence checks as well and
start by using exactly the same sequence number as you.</para><indexterm significance="normal" class="endofrange" startref="idx-uucploginsecurity-1"></indexterm><indexterm significance="normal" class="endofrange" startref="chuu.uucp.security"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-serveruucp-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-securityuucp-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-accessuucp-1"></indexterm></sect2><sect2><title>Anonymous UUCP</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>anonymous</secondary></indexterm>
<indexterm significance="normal"><primary>anonymous UUCP</primary></indexterm>
<indexterm significance="normal"><primary>UUCP</primary><secondary>anonymous</secondary></indexterm> 
If you want to provide anonymous UUCP access to your system, you first have to
set up a special account for it as previously described.  A common practice 
is to give the anonymous account a login name and a password of
<systemitem moreinfo="none" role="userid">uucp</systemitem>.</para><para>In addition, you have to set a few of the security options for unknown systems.
For instance, you may want to prohibit them from executing any commands on
your system. However, you cannot set these parameters in a
<filename moreinfo="none">sys</filename> file entry because the
<command moreinfo="none">system</command> command requires the system's
name, which you don't have. Taylor UUCP solves this dilemma through the
<command moreinfo="none">unknown</command> command.
<command moreinfo="none">unknown</command> can be used in the
<filename moreinfo="none">config</filename> file to specify any command that can usually
appear in a system entry:

<screen format="linespecific">unknown         remote-receive ~/incoming
unknown         remote-send ~/pub
unknown         max-remote-debug none
unknown         command-path /usr/lib/uucp/anon-bin
unknown         commands rmail</screen></para><para>This will restrict unknown systems to downloading files from below the
<filename moreinfo="none">pub</filename> directory and uploading files to the
<filename moreinfo="none">incoming</filename> directory below
<filename moreinfo="none">/var/spool/uucppublic</filename>. The next line will make
<command moreinfo="none">uucico</command> ignore any requests from the remote system to
turn on debugging locally. The last two lines permit unknown systems to
execute <command moreinfo="none">rmail</command>; but the command path specified makes
<command moreinfo="none">uucico</command> look for the <command moreinfo="none">rmail</command> command in
a private directory named <filename moreinfo="none">anon-bin</filename> only. This restriction
allows you to provide some special <command moreinfo="none">rmail</command> that, for instance,
forwards all mail to the superuser for examination. This allows anonymous
users to reach the maintainer of the system, but at the same time prevents 
them from injecting any mail to other sites.</para><para>To enable anonymous UUCP, you must specify at least one
<systemitem moreinfo="none" role="keyword">unknown</systemitem> statement in
<filename moreinfo="none">config</filename>. Otherwise <command moreinfo="none">uucico</command> will
reject all unknown systems.</para><indexterm significance="normal" class="endofrange" startref="idx-uucpconfigureasserver-1"></indexterm></sect2></sect1><sect1 id="x-087-2-uucp.protocols"><title>UUCP Low-Level Protocols</title><para><indexterm significance="normal" class="startofrange" id="idx-uucpprotocol-1"><primary>UUCP</primary><secondary>protocols</secondary></indexterm>
To negotiate session control and file transfers with the remote end,
<command moreinfo="none">uucico</command> uses a set of standardized messages. This is often
referred to as the <command moreinfo="none">high-level protocol</command>. During the 
initialization phase and the hangup phase these are simply sent across as 
strings. However, during the real transfer phase, an additional low-level 
protocol that is mostly transparent to the higher levels is employed. This 
protocol offers some added benefits, such as allowing error checks on data 
sent over unreliable links.</para><sect2><title>Protocol Overview</title><para><indexterm significance="normal"><primary>protocols</primary><secondary>UUCP</secondary></indexterm>
UUCP is used over different types of connections, such as serial lines, TCP, 
or sometimes even X.25; it is advantageous to transport UUCP within
protocols designed specifically for the underlying network protocol. In
addition, several implementations of UUCP have introduced different
protocols that do roughly the same thing.</para><para>Protocols can be divided into two categories: <command moreinfo="none">streaming</command> 
and <command moreinfo="none">packet</command> protocols. Protocols of the streaming variety 
transfer a file as a whole, possibly computing a checksum over it. This is 
nearly free of overhead, but requires a reliable connection because any 
error will cause the whole file to be retransmitted. These protocols are 
commonly used over TCP connections but are not suitable for use over 
telephone lines. Although modern modems do quite a good job at error 
correction, they are not perfect, nor is there any error detection between 
your computer and the modem.</para><para>On the other hand, packet-oriented protocols split up the file into
several chunks of equal size. Each packet is sent and received
separately, a checksum is computed, and an acknowledgment is returned
to the sender. To make this more efficient, sliding-window protocols
have been invented, which allow for a limited number (a window) of
outstanding acknowledgments at any time. This greatly reduces the
amount of time <command moreinfo="none">uucico</command> has to wait during a
transmission. Still, the relatively large overhead compared to a
streaming protocol makes packet protocols inefficient for TCP use, but
ideal for telephone lines.</para><para>The width of the data path also makes a difference. Sometimes sending 8-bit
characters over a serial connection is impossible; for instance, the
connection could go through a stupid terminal server that strips off the eighth
bit. When you transmit 8-bit characters over a 7-bit connection, they have to
be quoted on transmission. In the worst-case scenerio, quoting doubles the 
amount of data to be transmitted, although compression done by the hardware may
compensate. Lines that can transmit arbitrary 8-bit characters
are usually called <emphasis>8-bit clean</emphasis>. This is the case for all
TCP connections, as well as for most modem connections.</para><para>Taylor UUCP 1.06 supports a wide variety of UUCP protocols. The most common
of these are:

<variablelist><varlistentry><term><emphasis>g</emphasis></term><listitem><para>This is the most common protocol and should be understood by virtually all
<command moreinfo="none">uucico</command>s. It does thorough error checking and is therefore
well suited for noisy telephone links. <emphasis>g</emphasis> requires an
8-bit clean connection. It is a packet-oriented protocol that uses a
sliding-window technique.</para></listitem></varlistentry><varlistentry><term><emphasis>i</emphasis></term><listitem><para>This is a bidirectional packet protocol, which can send and receive files at
the same time. It requires a full-duplex connection and an 8-bit clean data
path. It is currently understood by Taylor UUCP only.</para></listitem></varlistentry><varlistentry><term><emphasis>t</emphasis></term><listitem><para>This protocol is intended for use over a TCP connection or other truly
error-free networks.  It uses packets of 1,024 bytes and requires an 8-bit
clean connection.</para></listitem></varlistentry><varlistentry><term><emphasis>e</emphasis></term><listitem><para><?troff .hw connections?>This should basically do the same as <emphasis>t</emphasis>. The main
difference is that <emphasis>e</emphasis> is a streaming protocol and is
thus suited only to reliable network connections.</para></listitem></varlistentry><varlistentry><term><emphasis>f</emphasis></term><listitem><para>This is intended for use with reliable X.25 connections. It is a streaming
protocol and expects a 7-bit data path. 8-bit characters are quoted, which
can make it very inefficient.</para></listitem></varlistentry><varlistentry><term><emphasis>G</emphasis></term><listitem><para>This is the System V Release 4 version of the <emphasis>g</emphasis> protocol.
It is also understood by some other versions of UUCP.</para></listitem></varlistentry><varlistentry><term><emphasis>a</emphasis></term><listitem><para>This protocol is similiar to ZMODEM. It requires an 8-bit connection, but
quotes certain control characters like XON and XOFF.</para></listitem></varlistentry></variablelist></para></sect2><sect2><title>Tuning the Transmission Protocol</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>protocols</secondary><tertiary>tuning</tertiary></indexterm>
All protocols allow for some variation in packet sizes, timeouts, etc. 
Usually, the defaults work well under standard circumstances, but may
not be optimal for your situation.  The <emphasis>g</emphasis> protocol, for
instance, uses window sizes from 1 to 7, and packet sizes in powers of 2
ranging from 64 through 4096. If your telephone line is usually so noisy that
it drops more than 5 percent of all packets, you should probably lower the
packet size and shrink the window. On the other hand, on very good telephone
lines the protocol overhead of sending acknowledgments for every 128 bytes may
prove wasteful, so you might increase the packet size to 512 or even 1,024.
Most binaries included in Linux distributions default to a window size of 7
and 128-byte packets.</para><para>Taylor UUCP lets you tune parameters with the 
<command moreinfo="none">protocol-parameter</command> command in the
<filename moreinfo="none">sys</filename> file.  For instance, to set the
<emphasis>g</emphasis> protocol's packet size to 512 when talking to
<systemitem moreinfo="none" role="sitename">pablo</systemitem>, you have to add:

<screen format="linespecific">system          pablo
...
protocol-parameter g  packet-size  512</screen></para><para>The tunable parameters and their names vary from protocol to protocol. For a
complete list of them, refer to the documentation enclosed in the Taylor UUCP
source.</para></sect2><sect2><title>Selecting Specific Protocols</title><para><indexterm significance="normal"><primary>UUCP</primary><secondary>protocols</secondary><tertiary>selection</tertiary></indexterm>
Not every implementation of <command moreinfo="none">uucico</command> speaks and understands
each protocol, so during the initial handshake phase, both processes have to
agree on a common one.  The master <command moreinfo="none">uucico</command> offers the
slave a list of supported protocols by sending
<literal moreinfo="none">P</literal><replaceable>protlist</replaceable>, from which the slave
may pick one.</para><para>Based on the type of port used (modem, TCP, or direct),
<command moreinfo="none">uucico</command> will compose a default list of
protocols. For modem and direct connections, this list usually
comprises <emphasis>i</emphasis>, <emphasis>a</emphasis>,
<emphasis>g</emphasis>, <emphasis>G</emphasis>, and
<emphasis>j</emphasis>.  For TCP connections, the list is
<emphasis>t</emphasis>, <emphasis>e</emphasis>,
<emphasis>i</emphasis>, <emphasis>a</emphasis>,
<emphasis>g</emphasis>, <emphasis>G</emphasis>,
<emphasis>j</emphasis>, and <emphasis>f</emphasis>. You can override
this default list with the <command moreinfo="none">protocols</command> command, which may be specified
in a system entry as well as a port entry. For instance, you might
edit the <filename moreinfo="none">port</filename> file entry for your modem port like
this:

<screen format="linespecific">port            serial1
...
protocols       igG</screen></para><para>This will require any incoming or outgoing connection through this port to use
<emphasis>i</emphasis>, <emphasis>g</emphasis>, or <emphasis>G</emphasis>. If
the remote system does not support any of these, the conversation will fail.</para><indexterm significance="normal" class="endofrange" startref="idx-uucpprotocol-1"></indexterm></sect2></sect1><sect1 id="x-087-2-uucp.misc.faq"><title>Troubleshooting</title><para><indexterm significance="normal"><primary>UUCP</primary><secondary>troubleshooting</secondary></indexterm>
This section describes what may go wrong with your UUCP connection and makes
location suggestions to fix the error. Although these problems are 
encountered on a regular basis, there is much more that can go wrong
than what we have listed.</para><para><indexterm significance="normal"><primary>UUCP</primary><secondary>checking</secondary></indexterm>
If you have a problem, enable debugging with <option>xall</option>,
and take a look at the output in <filename moreinfo="none">Debug</filename> in the spool
directory. The file should help you to quickly recognize the problem. It is 
often helpful to turn on the modem's speaker when it doesn't 
connect. With Hayes-compatible modems, you can turn on the speaker by adding
<literal moreinfo="none">ATL1M1 OK</literal> to the modem chat in the
<filename moreinfo="none">dial</filename> file.</para><para>The first check should always be whether all file permissions are set
correctly. <command moreinfo="none">uucico</command> should be setuid <systemitem moreinfo="none" role="userid">uucp</systemitem>, and all files in
<filename moreinfo="none">/usr/lib/uucp</filename>,
<filename moreinfo="none">/var/spool/uucp</filename>, and
<filename moreinfo="none">/var/spool/uucppublic</filename> should be owned by
<systemitem moreinfo="none" role="userid">uucp</systemitem>. There are also some
hidden files in the spool directory which must be owned by <systemitem moreinfo="none" role="userid">uucp</systemitem> as well.<footnote id="x-087-2-fnuu17"><para> That is, files with names beginning with a
dot. Such files aren't normally displayed by the <command moreinfo="none">ls</command>
command.</para></footnote></para><para>When you're sure you have the permissions of all files set correctly, and
you're still experiencing problems, you can then begin to take error
messages more literally. We'll now look at some of the more common errors
and problems.</para><sect2><title>uucico Keeps Saying Wrong Time to Call</title><para>This probably means that in the system entry in <filename moreinfo="none">sys</filename>, you
didn't specify a <command moreinfo="none">time</command> command that
details when the remote system may be called, or you gave one that actually
forbids calling at the current time. If no call schedule is given,
<command moreinfo="none">uucico</command> assumes the system can never be called.</para></sect2><sect2><title>uucico Complains That the Site Is Already Locked</title><para>This means that <command moreinfo="none">uucico</command> detects a lock file for the remote
system in <filename moreinfo="none">/var/spool/uucp</filename>. The lock file may be from an
earlier call to the system that crashed or was killed. Another possible
explanation is that there's another <command moreinfo="none">uucico</command> process
sitting around that is trying to dial the remote system and has gotten stuck
in a chat script, or stalled for some other reason.</para><para>To correct this error, kill all <command moreinfo="none">uucico</command> processes
open for the site with a hangup signal, and remove all lock files that
they have left lying around.</para></sect2><sect2><title>You Can Connect to the Remote Site, but the Chat Script Fails</title><para>Look at the text you receive from the remote site. If it's garbled, you might
have a speed-related problem. Otherwise, confirm that it really agrees with what
your chat script expects.  Remember, the chat script starts with an expect
string. If you receive the login prompt and send your name, but never get the
password prompt, insert some delays before sending it, or even in between the
letters. You might be too fast for your modem.</para></sect2><sect2><title>Your Modem Does Not Dial</title><para>If your modem doesn't indicate that the DTR line has been raised when
<command moreinfo="none">uucico</command> calls out, you might not have given the
right device to <command moreinfo="none">uucico</command>. If your modem recognizes
DTR, check with a terminal program that you can write to the modem. If
this works, turn on echoing with <systemitem moreinfo="none" role="keyword">\E</systemitem> at the start of the modem chat. If the
modem doesn't echo your commands during the modem chat, check if your
line speed is too high or low. If you see the echo, check if you have
disabled modem responses or set them to number codes.  Verify that the
chat script itself is correct. Remember that you have to write two
backslashes to send one to the modem.</para></sect2><sect2><title>Your Modem Tries to Dial but Doesn't Get Out</title><para>Insert a delay into the phone number, especially if you have to dial a
special sequence to gain an outside line from a corporate telephone network.
Make sure you are using the correct dial type, as some telephone networks
support only one type of dialing. Additionally, double check the telephone
number to make sure it's correct.</para></sect2><sect2><title>Login Succeeds, but the Handshake Fails</title><para>Well, there can be a number of problems in this situation. The output in the 
log file should tell you a lot. Look at what protocols the remote site 
offers (it sends a string <literal moreinfo="none">P</literal>
<replaceable>protlist</replaceable> during the handshake). For the handshake 
to succeed, both ends must support at least one common protocol, so check 
that they do.</para><para>If the remote system sends <command moreinfo="none">RLCK</command>, there is a stale lockfile
for you on the remote system already connected to the remote system on a 
different line.  Otherwise, ask the remote system administrator to remove the 
file.</para><para>If the remote system sends <command moreinfo="none">RBADSEQ</command>, it has conversation 
count checks enabled for you, but the numbers didn't match. If it sends
<command moreinfo="none">RLOGIN</command>, you were not permitted to log in under this ID.</para></sect2></sect1><sect1><title>Log Files and Debugging</title><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>logging and debugging</secondary></indexterm>
<indexterm significance="normal"><primary>Log file (UUCP)</primary></indexterm>
<indexterm significance="normal"><primary>log files, debugging</primary></indexterm>
When compiling the UUCP suite to use Taylor-style logging, you have only three
global log files, all of which reside in the spool directory. The main log
file is named <filename moreinfo="none">Log</filename> and contains all the information about
established connections and transferred files. A typical excerpt looks like
this (after a little reformatting to make it fit the page):

<screen format="linespecific">uucico pablo - (1994-05-28 17:15:01.66 539) Calling system pablo (port cua3)
uucico pablo - (1994-05-28 17:15:39.25 539) Login successful
uucico pablo - (1994-05-28 17:15:39.90 539) Handshake successful
               (protocol 'g' packet size 1024 window 7)
uucico pablo postmaster (1994-05-28 17:15:43.65 539) Receiving D.pabloB04aj
uucico pablo postmaster (1994-05-28 17:15:46.51 539) Receiving X.pabloX04ai
uucico pablo postmaster (1994-05-28 17:15:48.91 539) Receiving D.pabloB04at
uucico pablo postmaster (1994-05-28 17:15:51.52 539) Receiving X.pabloX04as
uucico pablo postmaster (1994-05-28 17:15:54.01 539) Receiving D.pabloB04c2
uucico pablo postmaster (1994-05-28 17:15:57.17 539) Receiving X.pabloX04c1
uucico pablo - (1994-05-28 17:15:59.05 539) Protocol 'g' packets: sent 15,
                resent 0, received 32
uucico pablo - (1994-05-28 17:16:02.50 539) Call complete (26 seconds)
uuxqt pablo postmaster (1994-05-28 17:16:11.41 546) Executing X.pabloX04ai
               (rmail okir)
uuxqt pablo postmaster (1994-05-28 17:16:13.30 546) Executing X.pabloX04as
               (rmail okir)
uuxqt pablo postmaster (1994-05-28 17:16:13.51 546) Executing X.pabloX04c1
               (rmail okir)</screen></para><?troff .Nd 10?><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>statistics</secondary></indexterm>
The next important log file is <filename moreinfo="none">Stats</filename>, which lists file
transfer statistics. The section of <filename moreinfo="none">Stats</filename> corresponding
to the above transfer looks like this (again, the lines have been split to fit
the page):

<screen format="linespecific">postmaster pablo (1994-05-28 17:15:44.78)
                  received 1714 bytes in 1.802 seconds (951 bytes/sec)
postmaster pablo (1994-05-28 17:15:46.66)
                  received 57 bytes in 0.634 seconds (89 bytes/sec)
postmaster pablo (1994-05-28 17:15:49.91)
                  received 1898 bytes in 1.599 seconds (1186 bytes/sec)
postmaster pablo (1994-05-28 17:15:51.67)
                  received 65 bytes in 0.555 seconds (117 bytes/sec)
postmaster pablo (1994-05-28 17:15:55.71)
                  received 3217 bytes in 2.254 seconds (1427 bytes/sec)
postmaster pablo (1994-05-28 17:15:57.31)
                  received 65 bytes in 0.590 seconds (110 bytes/sec)</screen></para><para>The third file is <filename moreinfo="none">Debug</filename>. Debugging information is 
written here. If you use debugging, make sure this file
has protection mode 600. Depending on the debug mode you select, it may
contain the login and password you use to connect to the remote system.</para><para><indexterm significance="normal"><primary>Taylor UUCP</primary><secondary>HDB</secondary></indexterm>
If you have some tools around that expect your log files to be in the 
traditional format used by HDB-compatible UUCP implementations, you can also
compile Taylor UUCP to produce HDB-style logs. This is simply a matter of 
enabling a compile-time option in <filename moreinfo="none">config.h</filename>.</para><indexterm significance="normal" class="endofrange" startref="idx-uucp-2"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-configuringuucp-1"></indexterm></sect1></chapter><chapter id="x-087-2-mail"><title>Electronic Mail</title><indexterm significance="normal" class="startofrange" id="chem.email.1"><primary>email</primary></indexterm><para>Electronic mail transport has been one of the most prominent uses of
networking since the first networks were devised. Email started as a
simple service that copied a file from one machine to another and
appended it to the recipient's <emphasis>mailbox</emphasis> file. The
concept remains the same, although an ever-growing net, with its
complex routing requirements and its ever increasing load of messages,
has made a more elaborate scheme necessary.</para><para><indexterm significance="normal"><primary>multimedia mail</primary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>multimedia</secondary></indexterm>
<indexterm significance="normal"><primary>RFC-822</primary></indexterm> 
Various standards of mail exchange have been devised. Sites on the
Internet adhere to one laid out in RFC-822, augmented by some RFCs
that describe a machine-independent way of transferring just about
<emphasis>anything</emphasis>, including graphics, sound files, and
special characters sets, by email.<footnote id="x-087-2-fnma01"><para>Read RFC-1437 if you don't believe this statement!  </para></footnote>
CCITT has defined another standard, X.400. It is still used in some
large corporate and government environments, but is progressively being
retired.</para><para><indexterm significance="normal"><primary>email</primary><secondary>sendmail</secondary></indexterm> 
<indexterm significance="normal"><primary>sendmail</primary></indexterm>
<indexterm significance="normal"><primary>Allman, Eric</primary></indexterm>
Quite a number of mail transport programs have been implemented for
Unix systems. One of the best known is <command moreinfo="none">sendmail</command>,
which was developed by Eric Allman at the University of California at
Berkeley. Eric Allman now offers <command moreinfo="none">sendmail</command> through a
commercial venture, but the program remains free
software. <command moreinfo="none">sendmail</command> is supplied as the standard mail
agent in some Linux distributions. We describe <command moreinfo="none">sendmail</command>
configuration in <xref linkend="x-087-2-sendmail"></xref>.</para><para><indexterm significance="normal"><primary>email</primary><secondary>Exim</secondary></indexterm> 
<indexterm significance="normal"><primary>Exim</primary></indexterm>
<indexterm significance="normal"><primary>Hazel, Philip</primary></indexterm>
Linux also uses <command moreinfo="none">Exim</command>, written by Philip
Hazel of the University of Cambridge. We describe <command moreinfo="none">Exim</command>
configuration in <xref linkend="x-087-2-exim"></xref>.</para><para>Compared to <command moreinfo="none">sendmail</command>, <command moreinfo="none">Exim</command> is rather
young. For the vast bulk of sites with email requirements, their capabilities
are pretty close.</para><para>Both <command moreinfo="none">Exim</command> and <command moreinfo="none">sendmail</command> support a
set of configuration files that have to be customized for your
system. Apart from the information that is required to make the mail
subsystem run (such as the local hostname), there are many parameters
that may be tuned. <command moreinfo="none">sendmail</command>'s main
configuration file is very hard to understand at first. It looks as if
your cat has taken a nap on your keyboard with the shift key pressed.
<command moreinfo="none">Exim</command> configuration files are more structured and
easier to understand than
<command moreinfo="none">sendmail</command>'s. <command moreinfo="none">Exim</command>,
however, does not provide direct support for UUCP and handles only
domain addresses. Today that isn't as big a limitation as it once might 
have been; most sites stay within <command moreinfo="none">Exim</command>'s
limitations.  However, for most sites, the work required in setting up
either of them is roughly the same.</para><para>In this chapter, we deal with what email is and what issues administrators 
have to deal with. 
<xref linkend="x-087-2-sendmail"></xref> and <xref linkend="x-087-2-exim"></xref> provide instructions on setting
up <command moreinfo="none">sendmail</command> and <command moreinfo="none">Exim</command> and for the
first time.  The included information should help smaller sites 
become operational, but there are several more options and you can
spend many happy hours in front of your computer configuring the
fanciest features.</para><para>Toward the end of this chapter we briefly cover setting up
<command moreinfo="none">elm</command>, a very common mail user agent on many
Unix-like systems, including Linux.</para><para><indexterm significance="normal"><primary>HOWTOs</primary><secondary>electronic mail</secondary></indexterm> 
For more information about issues specific to electronic mail on Linux, please
<indexterm significance="normal"><primary>Aznar, Guylhem</primary></indexterm>
refer to the Electronic Mail HOWTO by
Guylhem Aznar,<footnote id="x-087-2-fnma02"><para>Guylhem can be reached at
<systemitem moreinfo="none" role="email">guylhem@danmark.linux.eu.org</systemitem>.</para></footnote>
which is posted to
<systemitem moreinfo="none" role="newsgroup">comp.os.linux.answers</systemitem> regularly.
The source distributions of <command moreinfo="none">elm</command>, <command moreinfo="none">Exim</command>,
and <command moreinfo="none">sendmail</command> also contain extensive documentation
that should answer most questions on setting them up, and we provide
references to this documentation in their respective chapters. If you need 
general information on email, a number of RFCs deal with this
topic. They are listed in the bibliography at the end of the book.</para><sect1 id="x-087-2-mail.message-format"><title>What Is a Mail Message?</title><indexterm significance="normal"><primary>email</primary><secondary>message format</secondary></indexterm><indexterm significance="normal" class="startofrange" id="chem.msgs.email"><primary>messages, email</primary></indexterm><para>A mail message generally consists of a message body, which is the text
of the message, and special administrative data specifying recipients,
transport medium, etc., like what you see when you look at a physical
letter's envelope.</para><para><indexterm significance="normal"><primary>envelope</primary></indexterm> 
This administrative data falls into two categories. In the first category is
any data that is specific to the transport medium, like the address of sender
and recipient. It is therefore called the <emphasis>envelope</emphasis>. It
may be transformed by the transport software as the message is passed along.</para><para><indexterm significance="normal"><primary>email</primary><secondary>message body</secondary></indexterm> 
<indexterm significance="normal"><primary>email</primary><secondary>message headers</secondary></indexterm>
The second variety is any data necessary for handling the mail message, which
is not particular to any transport mechanism, such as the message's subject
line, a list of all recipients, and the date the message was sent. In many
networks, it has become standard to prepend this data to the mail message,
forming the so-called <emphasis>mail header</emphasis>. It is offset from the
<emphasis>mail body</emphasis> by an empty
line.<footnote id="x-087-2-fnma03"><para>It is customary to append a <emphasis>signature</emphasis> or
<filename moreinfo="none">.sig</filename> to a mail message, usually containing information
on the author along with a joke or a motto. It is offset from the mail
message by a line containing <literal moreinfo="none">--</literal> followed
by a space.</para></footnote></para><indexterm significance="normal"><primary>RFC-822</primary></indexterm><para>Most mail transport software in the Unix world use a header format outlined
in RFC-822. Its original purpose was to specify a standard for use on the
ARPANET, but since it was designed to be independent from any environment, it
has been easily adapted to other networks, including many UUCP-based networks.</para><para>RFC-822 is only the lowest common denominator, however. More recent
standards have been conceived to cope with growing needs such as
data encryption, international character set support, and MIME
<indexterm significance="normal"><primary>MIME (Multipurpose Internet Mail Extensions)</primary></indexterm>
<indexterm significance="normal"><primary>RFC-1341</primary></indexterm>
(Multipurpose Internet Mail Extensions, described in RFC-1341 and other RFCs).</para><para>In all these standards, the header consists of several lines separated
by an end-of-line sequence. A line is made up of a field name, beginning in
column one, and the field itself, offset by a colon and white space. The
format and semantics of each field vary depending on the field name. A
header field can be continued across a newline if the next line begins
with a whitespace character such as tab. Fields can appear in any order.</para><para>A typical mail header may look like this:

<screen format="linespecific">Return-Path: ph10@cus.cam.ac.uk
Received: ursa.cus.cam.ac.uk (cusexim@ursa.cus.cam.ac.uk [131.111.8.6])
    by al.animats.net (8.9.3/8.9.3/Debian 8.9.3-6) with ESMTP id WAA04654
    for terry@animats.net; Sun, 30 Jan 2000 22:30:01 +1100
Received: from ph10 (helo=localhost) by ursa.cus.cam.ac.uk with local-smtp
    (Exim 3.13 #1) id 12EsYC-0001eF-00; Sun, 30 Jan 2000 11:29:52 +0000
Date: Sun, 30 Jan 2000 11:29:52 +0000 (GMT)
From: Philip Hazel ph10@cus.cam.ac.uk
Reply-To: Philip Hazel ph10@cus.cam.ac.uk
To: Terry Dawson terry@animats.net, Andy Oram andyo@oreilly.com
Subject: Electronic mail chapter
In-Reply-To: 38921283.A58948F2@animats.net
Message-ID: Pine.SOL.3.96.1000130111515.5800A-200000@ursa.cus.cam.ac.uk</screen></para><para>Usually, all necessary header fields are generated by the mailer interface you
use, like <command moreinfo="none">elm</command>, <command moreinfo="none">pine</command>,
<command moreinfo="none">mush</command>, or <command moreinfo="none">mailx</command>. However, some are
optional and may be added by the user. <command moreinfo="none">elm</command>, for example,
allows you to edit part of the message header. Others are added by the mail
transport software. If you look into a local mailbox file, you may see each
mail message preceded by a From line (note: no colon). This is
<emphasis>not</emphasis> an RFC-822 header; it has been inserted by your mail
software as a convenience to programs reading the mailbox. To avoid potential
trouble with lines in the message body that also begin with
From, it has become standard procedure to escape any such
occurrence by preceding it with a  character.</para><para>This list is a collection of common header fields and their meanings:

<indexterm significance="normal"><primary>email</primary><secondary>message headers</secondary></indexterm>
<variablelist><varlistentry><term><literal moreinfo="none">From:</literal></term><listitem><para>This contains the sender's email address and possibly the
real name. A complete zoo of formats is used here.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">To:</literal></term><listitem><para>This is a list of recipient email addresses. Multiple recipient addresses
are separated by a comma.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">Cc:</literal></term><listitem><para>This is a list of email addresses that will receive carbon copies
of the message. Multiple recipient addresses are separated by a comma.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">Bcc:</literal></term><listitem><para>This is a list of email addresses that will receive carbon copies
of the message. The key difference between a Cc: and a
Bcc: is that the addresses listed in a Bcc: will
not appear in the header of the mail messages delivered to any
recipient. It's a way of alerting recipients that you've sent copies of the
message to other people without telling them who those others are. Multiple
recipient addresses are separated by a comma.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">Subject:</literal></term><listitem><para>Describes the content of the mail in a few words.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">Date:</literal></term><listitem><para>Supplies the date and time the mail was sent.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">Reply-To:</literal></term><listitem><para>Specifies the address the sender wants the recipient's reply directed to.
This may be useful if you have several accounts, but want to receive the bulk
of mail only on the one you use most frequently. This field is optional.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">Organization:</literal></term><listitem><para>The organization that owns the machine from which the mail originates. If your
machine is owned by you privately, either leave this out, or insert
private or some complete nonsense. This field is not described
by any RFC and is completely optional. Some mail programs support it directly,
many don't.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">Message-ID:</literal></term><listitem><para>A string generated by the mail transport on the originating system. It uniquely
identifies this message.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">Received:</literal></term><listitem><para>Every site that processes your mail (including the machines of sender and
recipient) inserts such a field into the header, giving its site name, a
message ID, time and date it received the message, which site it is from,
and which transport software was used. These lines allow you to trace which
route the message took, and you can complain to the person responsible if
something went wrong.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">X-</literal><replaceable>anything:</replaceable></term><listitem><para>No mail-related programs should complain about any header that starts
with <literal moreinfo="none">X-</literal>. It is used to implement
additional features that have not yet made it into an RFC, or never
will. For example, there was once a very large Linux mailing list server that
allowed you to specify which channel you wanted the mail to go to by
adding the string <userinput moreinfo="none">X-Mn-Key:</userinput> followed by the channel name.</para></listitem></varlistentry></variablelist></para><indexterm significance="normal" class="endofrange" startref="chem.msgs.email"></indexterm></sect1><sect1 id="x-087-2-mail.delivery"><title>How Is Mail Delivered?</title><indexterm significance="normal"><primary>email</primary><secondary>composing</secondary></indexterm><indexterm significance="normal"><primary>email</primary><secondary>delivering</secondary></indexterm><indexterm significance="normal"><primary>delivering</primary><secondary>email</secondary></indexterm><indexterm significance="normal"><primary>exchanging</primary><secondary>email</secondary></indexterm><indexterm significance="normal"><primary>/usr/sbin/sendmail</primary></indexterm><para><indexterm significance="normal"><primary>mail user agent (MUA)</primary></indexterm> 
<indexterm significance="normal"><primary>mail transport agent (MTA)</primary></indexterm> 
Generally, you will compose mail using a mailer interface like
<command moreinfo="none">mail</command> or <command moreinfo="none">mailx</command>, or more
sophisticated ones like <command moreinfo="none">mutt</command>, <command moreinfo="none">tkrat</command>,
or <command moreinfo="none">pine</command>. These programs are called
<emphasis>mail user agents</emphasis>, or MUAs.  If you send a mail
message, the interface program will in most cases hand it to another
program for delivery. This is called the <emphasis>mail transport
agent</emphasis>, or MTA. On most systems the same MTA is used for both
local and remote delivery and is usually invoked as
<command moreinfo="none">/usr/sbin/sendmail</command>, or on non-FSSTND compliant systems as
<command moreinfo="none">/usr/lib/sendmail</command>. On UUCP systems it is not uncommon to
see mail delivery handled by two separate programs: <command moreinfo="none">rmail</command>
for remote mail delivery and <command moreinfo="none">lmail</command> for local mail delivery.</para><para><indexterm significance="normal"><primary>email</primary><secondary>bounced</secondary></indexterm>
<indexterm significance="normal"><primary>bounced mail</primary></indexterm>
Local delivery of mail is, of course, more than just appending the
incoming message to the recipient's mailbox. Usually, the local MTA understands aliasing (setting up local recipient addresses
pointing to other addresses) and forwarding (redirecting a user's mail
to some other destination). Also, messages that cannot be delivered
must usually be <emphasis>bounced</emphasis>, that is, returned to the
sender along with some error message.</para><para><indexterm significance="normal"><primary>SMTP (Simple Mail Transfer Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>protocols</primary><secondary>SMTP</secondary></indexterm> 
For remote delivery, the transport software used depends on the nature
of the link. Mail delivered over a network using TCP/IP commonly uses
<emphasis>Simple Mail Transfer Protocol</emphasis> (SMTP), which is
described in RFC-821. SMTP was designed to deliver
<indexterm significance="normal"><primary>RFC-821</primary></indexterm> mail directly to a
recipient's machine, negotiating the message transfer with the remote
side's SMTP daemon. Today it is common practice for organizations to
establish special hosts that accept all mail for recipients in the
organization and for that host to manage appropriate delivery to the
intended recipient.</para><para><indexterm significance="normal"><primary>remote</primary><secondary>execution</secondary></indexterm>
<indexterm significance="normal"><primary>UUCP</primary><secondary>mail</secondary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>over UUCP</secondary></indexterm>
Mail is usually not delivered directly in UUCP networks, but
rather is forwarded to the destination host by a number of intermediate
systems. To send a message over a UUCP link, the sending MTA usually executes <command moreinfo="none">rmail</command> on the forwarding system using
<command moreinfo="none">uux</command>, and feeds it the message on standard input.</para><para><indexterm significance="normal"><primary>bsmtp program</primary></indexterm>
<indexterm significance="normal"><primary>SMTP (Simple Mail Transfer Protocol)</primary><secondary>batched</secondary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>batching</secondary></indexterm>
<indexterm significance="normal"><primary>batching</primary><secondary>email</secondary></indexterm>
<indexterm significance="normal"><primary>rsmtp</primary><secondary>program</secondary></indexterm>
Since <command moreinfo="none">uux</command> is invoked for each message separately, it may
produce a considerable workload on a major mail hub, as well as clutter the
UUCP spool queues with hundreds of small files taking up a disproportionate
amount of disk space.<footnote id="x-087-2-fnma04"><para>This is because disk space is usually allocated in blocks of 1,024 bytes. So
even a message of a few dozen bytes will eat a full kilobyte.</para></footnote> Some MTAs
therefore allow you to collect several messages for a remote system in a
single batch file. The batch file contains the SMTP commands that the local
host would normally issue if a direct SMTP connection were used. This is
called BSMTP, or <emphasis>batched</emphasis> SMTP. The batch is then fed
to the <command moreinfo="none">rsmtp</command> or <command moreinfo="none">bsmtp</command> program on the
remote system, which processes the input almost as if a normal SMTP
connection has occurred.
</para></sect1><sect1 id="x-087-2-mail.address"><title>Email Addresses</title><indexterm significance="normal" class="startofrange" id="idx-mailaddressformats-1"><primary>email</primary><secondary>address formats</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-addressmail-1"><primary>addresses</primary><secondary>email</secondary></indexterm><para>Email addresses are made up of at least two parts. One part is the
name of a <emphasis>mail domain</emphasis> that will ultimately
translate to either the recipient's host or some host that accepts
mail on behalf of the recipient. The other part is some form of unique
user identification that may be the login name of that user, the real
name of that user in Firstname.Lastname format, or an
arbitrary alias that will be translated into a user or list of
users. Other mail addressing schemes, like X.400, use a more general
set of attributes that are used to look up the
recipient's host in an X.500 directory server.</para><para>How email addresses are interpreted depends greatly on what type of
network you use. We'll concentrate on how TCP/IP and UUCP networks
interpret email addresses.</para><sect2 id="x-087-2-mail.address.rfc822"><title>RFC-822</title><para><indexterm significance="normal"><primary>RFC-822</primary></indexterm> 
<indexterm significance="normal"><primary>absolute mail address</primary></indexterm> 
Internet sites adhere to the RFC-822 standard, which requires the
familiar notation of <systemitem moreinfo="none" role="emailaddr">user@host.domain</systemitem>, for which <systemitem moreinfo="none" role="emailaddr">host.domain</systemitem> is the host's fully
qualified domain name. The character separating the two is properly
called a commercial at sign, but it helps if you read it
as at. This notation does not specify a route to the
destination host. Routing of the mail message is left to the
mechanisms we'll describe shortly.</para><para>You will see a lot of RFC-822 if you run an Internet connected site. Its
use extends not only to mail, but has also spilled over into other services,
such as news. We discuss how RFC-822 is used for news in
<xref linkend="x-087-2-news"></xref>.</para></sect2><sect2 id="x-087-2-mail.address.obsolete"><title>Obsolete Mail Formats</title><para><indexterm significance="normal"><primary>! (in email address)</primary></indexterm> 
<indexterm significance="normal"><primary>exclamation point (in email address)</primary></indexterm> 
<indexterm significance="normal"><primary>email</primary><secondary>bang path notation</secondary></indexterm>
<indexterm significance="normal"><primary>addresses</primary><secondary>bang path</secondary></indexterm>
In the original UUCP environment, the prevalent form was
<systemitem moreinfo="none" role="emailaddr">path!host!user</systemitem>, for which 
<systemitem moreinfo="none" role="emailaddr">path</systemitem> described a sequence of hosts
the message had to travel through before reaching the destination
<systemitem moreinfo="none" role="emailaddr">host</systemitem>. This construct is called
the <emphasis>bang path</emphasis> notation, because an exclamation mark
is colloquially called a bang. Today, many UUCP-based networks
have adopted RFC-822 and understand domain-based addresses.</para><para><indexterm significance="normal"><primary>RFC-822</primary></indexterm> 
Other networks have still different means of addressing. DECnet-based
networks, for example, use two colons as an address separator,
yielding an address of <systemitem moreinfo="none" role="emailaddr">host::user</systemitem>.<footnote id="x-087-2-fnma05"><para> When trying to reach a DECnet address from
an RFC-822 environment, you can use <systemitem moreinfo="none" role="emailaddr">host::user"@relay</systemitem>, for which 
<systemitem moreinfo="none" role="emailaddr">relay</systemitem> is the name of a known
Internet-DECnet relay.</para></footnote>
The X.400 standard uses an entirely different scheme, describing a
recipient by a set of attribute-value pairs, like country and organization.  </para><para>Lastly, on FidoNet, each user is identified by a code like <systemitem moreinfo="none" role="sitename">2:320/204.9</systemitem>, consisting of four numbers
denoting zone (2 is for Europe), net (320 being Paris and Banlieue),
node (the local hub), and point (the individual user's PC). Fidonet
addresses can be mapped to RFC-822; the above, for example, would be written as <systemitem moreinfo="none" role="emailaddr">Thomas.Quinot@p9.f204.n320.z2.fidonet.org</systemitem>. Now didn't we say domain names were easy to remember?</para></sect2><sect2 id="x-087-2-mail.address.mixing"><title>Mixing Different Mail Formats</title><para>It is inevitable that when you bring together a number of different
systems and a number of clever people, they will seek ways to
interconnect the differing systems so they are capable of
internetworking. Consequently, there are a number of different mail
gateways that are able to link two different email systems together so
that mail may be forwarded from one to another. Addressing is the
critical question when linking two systems. We won't look at the
gateways themselves in any detail, but let's take a look at some of
the addressing complications that may arise when gateways of this sort
are used.</para><para><indexterm significance="normal"><primary>ampersand (in email address)</primary></indexterm> 
<indexterm significance="normal"><primary> (in email address)</primary></indexterm> 
<indexterm significance="normal"><primary>addresses</primary><secondary>hybrid</secondary></indexterm>
Consider mixing the UUCP style bang-path notation and RFC-822. These
two types of addressing don't mix too well. Assume there is an address
of <systemitem moreinfo="none" role="emailaddr">domainA!user@domainB</systemitem>. It
is not clear whether the <systemitem moreinfo="none" role="emailaddr">@</systemitem>
sign takes precedence over the path, or vice versa: do we have to send
the message to <systemitem moreinfo="none" role="emailaddr">domainB</systemitem>,
which mails it to <systemitem moreinfo="none" role="emailaddr">domainA!user</systemitem>, or should it be sent to
<systemitem moreinfo="none" role="emailaddr">domainA</systemitem>, which forwards it
to <systemitem moreinfo="none" role="emailaddr">user@domainB</systemitem>?</para><para><indexterm significance="normal"><primary>hybrid addresses</primary></indexterm> 
Addresses that mix different types of address operators are called
<emphasis>hybrid addresses</emphasis>. The most common type, which we
just illustrated, is usually resolved by giving the <systemitem moreinfo="none" role="emailaddr">@</systemitem> sign precedence over the path. In
<systemitem moreinfo="none" role="emailaddr">domainA!user@domainB</systemitem>, this
means sending the message to <systemitem moreinfo="none" role="emailaddr">domainB</systemitem> first.</para><para><indexterm significance="normal"><primary>source-routed address</primary></indexterm>
However, there is a way to specify routes in RFC-822 conformant ways:
<systemitem moreinfo="none" role="emailaddr">@domainA,@domainB:user@domainC</systemitem> denotes the address of <systemitem moreinfo="none" role="emailaddr">user</systemitem> on
<systemitem moreinfo="none" role="emailaddr">domainC</systemitem>, where
<systemitem moreinfo="none" role="emailaddr">domainC</systemitem> is to be reached through
<systemitem moreinfo="none" role="emailaddr">domainA</systemitem> and
<systemitem moreinfo="none" role="emailaddr">domainB</systemitem> (in that order). This type
of address is frequently called a <emphasis>source routed</emphasis> address.
It's not a good idea to rely on this behavior, as revisions to the
RFCs describing mail routing recommend that source routing in a mail
address be ignored and instead an attempt should be made to deliver directly
to the remote destination.</para><para><indexterm significance="normal"><primary>% (in email address)</primary></indexterm> 
<indexterm significance="normal"><primary>percent sign (in email address)</primary></indexterm> 
<indexterm significance="normal"><primary>Ye Olde ARPAnet kludge</primary></indexterm>
Then there is the <systemitem moreinfo="none" role="emailaddr">%</systemitem> address
operator: <systemitem moreinfo="none" role="emailaddr">user%domainB@domainA</systemitem> is first sent
to <systemitem moreinfo="none" role="emailaddr">domainA</systemitem>, which expands
the rightmost (in this case, the only) percent sign to an <systemitem moreinfo="none" role="emailaddr">@</systemitem> sign. The address is now <systemitem moreinfo="none" role="userid">user@domainB</systemitem>, and the mailer happily
forwards your message to <systemitem moreinfo="none" role="emailaddr">domainB</systemitem>, which delivers it to
<systemitem moreinfo="none" role="emailaddr">user</systemitem>. This type of address
is sometimes referred to as Ye Olde ARPAnet Kludge, and
its use is discouraged.</para><para>There are some implications to using these different types of
addressing that will be described throughout the following
sections. In an RFC-822 environment, you should avoid using anything
other than absolute addresses, such as <systemitem moreinfo="none" role="emailaddr">user@host.domain</systemitem>.</para></sect2><indexterm significance="normal" class="endofrange" startref="idx-mailaddressformats-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-addressmail-1"></indexterm></sect1><sect1 id="x-087-2-mail.routing"><title>How Does Mail Routing Work?</title><indexterm significance="normal" class="startofrange" id="idx-mailrouting-1"><primary>email</primary><secondary>routing</secondary></indexterm><para>The process of directing a message to the recipient's host is called
<emphasis>routing</emphasis>. Apart from finding a path from the sending
site to the destination, it involves error checking and may involve speed and
cost optimization.</para><para>There is a big difference between the way a UUCP site handles routing
and the way an Internet site does. On the Internet, the main job of
directing data to the recipient host (once it is known by its
IP address) is done by the IP networking layer, while in the UUCP zone,
the route has to be supplied by the user or generated by the mail
transfer agent.</para><sect2 id="x-087-2-mail.routing.internet"><title>Mail Routing on the Internet</title><indexterm significance="normal"><primary>email</primary><secondary>routing</secondary><tertiary>on Internet</tertiary></indexterm><indexterm significance="normal"><primary>email</primary><secondary>domain-based routing</secondary></indexterm><indexterm significance="normal"><primary>email</primary><secondary>centralizing</secondary></indexterm><indexterm significance="normal"><primary>centralized mail handling</primary></indexterm><indexterm significance="normal"><primary>Internet</primary><secondary>email routing</secondary></indexterm><indexterm significance="normal"><primary>Mail Exchanger (DNS record)</primary></indexterm><indexterm significance="normal"><primary>MX (DNS record)</primary></indexterm><indexterm significance="normal"><primary>email</primary><secondary>gateway</secondary></indexterm><indexterm significance="normal"><primary>gateways</primary><secondary>email</secondary></indexterm><para>On the Internet, the destination host's configuration determines
whether any specific mail routing is performed. The default is to
deliver the message to the destination by first determining what host
the message should be sent to and then delivering it directly to that
host.
<indexterm significance="normal"><primary>email</primary><secondary>routing</secondary><tertiary>between Internet and UUCP</tertiary></indexterm> 
Most Internet sites want to direct all inbound mail to a highly
available mail server that is capable of handling all this traffic and
have it distribute the mail locally. To announce this service, the
site publishes a so-called MX record for its local domain in its DNS
database. MX stands for <emphasis>Mail Exchanger</emphasis> and
basically states that the server host is willing to act as a mail
forwarder for all mail addresses in the domain. MX records can also be
used to handle traffic for hosts that are not connected to the
Internet themselves, like UUCP networks or FidoNet hosts that must
have their mail passed through a gateway.</para><para>MX records are always assigned a <emphasis>preference</emphasis>. This
is a positive integer. If several mail exchangers exist for one host,
the mail transport agent will try to transfer the message to the
exchanger with the lowest preference value, and only if this fails
will it try a host with a higher value. If the local host is itself a
mail exchanger for the destination address, it is allowed to forward
messages only to MX hosts with a lower preference than its own; this
is a safe way of avoiding mail loops. If there is no MX record for a
domain, or no MX records left that are suitable, the mail transport
agent is permitted to see if the domain has an IP address associated
with it and attempt delivery directly to that host.</para><para>Suppose that an organization, say Foobar, Inc., wants all its mail
handled by its machine <systemitem moreinfo="none" role="sitename">mailhub</systemitem>.
It will then have MX records like this in the DNS database:
<screen format="linespecific">green.foobar.com.        IN   MX      5    mailhub.foobar.com.</screen></para><para>This announces <systemitem moreinfo="none" role="sitename">mailhub.foobar.com</systemitem> as
a mail exchanger for <systemitem moreinfo="none" role="sitename">green.foobar.com</systemitem>
with a preference of 5. A host that wishes to deliver a message to
<systemitem moreinfo="none" role="emailaddr">joe@green.foobar.com</systemitem> checks DNS and finds the MX record pointing at
<systemitem moreinfo="none" role="sitename">mailhub</systemitem>.
If there's no MX with a preference smaller than 5, the message is delivered to <systemitem moreinfo="none" role="sitename">mailhub</systemitem>, which then
dispatches it to <systemitem moreinfo="none" role="sitename">green</systemitem>.</para><para><indexterm significance="normal"><primary>RFC-974</primary></indexterm>
<indexterm significance="normal"><primary>RFC-821</primary></indexterm>
<indexterm significance="normal"><primary>RFC-1123</primary></indexterm>
This is a very simple description of how MX records work. For more information
on mail routing on the Internet, refer to RFC-821, RFC-974, and RFC-1123.</para></sect2><sect2 id="x-087-2-mail.routing.uucp"><title>Mail Routing in the UUCP World</title><indexterm significance="normal"><primary>email</primary><secondary>routing</secondary><tertiary>UUCP networks</tertiary></indexterm><indexterm significance="normal"><primary>email</primary><secondary>bang path notation</secondary></indexterm><indexterm significance="normal"><primary>addresses</primary><secondary>bang path</secondary></indexterm><indexterm significance="normal"><primary>UUCP</primary><secondary>email routing</secondary></indexterm><para>Mail routing on UUCP networks is much more complicated than on the
Internet because the transport software does not perform any routing
itself.  In earlier times, all mail had to be addressed using bang paths.
Bang paths specified a list of hosts through which to forward the
message, separated by exclamation marks and followed by the user's
name.  To address a letter to a user called Janet on a machine named
<systemitem moreinfo="none" role="sitename">moria</systemitem>, you would use the path
<systemitem moreinfo="none" role="emailaddr">eek!swim!moria!janet</systemitem>. This would 
send the mail from your host to
<systemitem moreinfo="none" role="sitename">eek</systemitem>, from there on to
<systemitem moreinfo="none" role="sitename">swim</systemitem>, and finally to
<systemitem moreinfo="none" role="sitename">moria</systemitem>.</para><para>The obvious drawback of this technique is that it requires you to
remember much more about network topology, fast links, etc. than
Internet routing requires. Much worse than that, changes in the
network topologylike links being deleted or hosts being
removedmay cause messages to fail simply because you aren't
aware of the change. And finally, in case you move to a different
place, you will most likely have to update all these routes.</para><para><indexterm significance="normal"><primary>hostname</primary><secondary>ambiguous</secondary></indexterm>
One thing, however, that made the use of source routing necessary was
the presence of ambiguous hostnames. For instance, assume there are two
sites named <systemitem moreinfo="none" role="sitename">moria</systemitem>, one in the U.S.
and one in France. Which site does
<systemitem moreinfo="none" role="emailaddr">moria!janet</systemitem> refer to now? This can
be made clear by specifying what path to reach
<systemitem moreinfo="none" role="sitename">moria</systemitem> through.</para><para><indexterm significance="normal"><primary>UUCP</primary><secondary>Mapping Project</secondary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>maps</secondary></indexterm>
<indexterm significance="normal"><primary>Usenet</primary><secondary>maps</secondary></indexterm>
<indexterm significance="normal"><primary>maps, Usenet</primary></indexterm>
The first step in disambiguating hostnames was the founding of the UUCP
Mapping Project. It is located at Rutgers University and registers all
official UUCP hostnames, along with information on their UUCP neighbors
and their geographic location, making sure no hostname is used twice. The
information gathered by the Mapping Project is published as the
<emphasis>Usenet Maps</emphasis>, which are distributed regularly through
Usenet. A typical system entry in a
map (after removing the comments) looks like this:<footnote id="x-087-2-fnma06"><para><?troff .hw networks?>Maps for sites registered with the UUCP Mapping Project are distributed
through the newsgroup <systemitem moreinfo="none" role="newsgroup">comp.mail.maps</systemitem>;
other organizations may publish separate maps for their networks.</para></footnote>

<screen format="linespecific">moria
        bert(DAILY/2),
        swim(WEEKLY)</screen></para><para>This entry says <systemitem moreinfo="none" role="sitename">moria</systemitem> has a link
to <systemitem moreinfo="none" role="sitename">bert</systemitem>, which it calls twice a day,
and <systemitem moreinfo="none" role="sitename">swim</systemitem>, which it calls weekly. We
will return to the map file format in more detail later.</para><para><indexterm significance="normal"><primary>email</primary><secondary>paths file</secondary></indexterm>
<indexterm significance="normal"><primary>pathalias database</primary></indexterm>
<indexterm significance="normal"><primary>paths file</primary></indexterm>
Using the connectivity information provided in the maps, you can
automatically generate the full paths from your host to any
destination site. This information is usually stored in the
<filename moreinfo="none">paths</filename> file, also called the <emphasis>pathalias
database</emphasis>. Assume the maps state that you can reach
<systemitem moreinfo="none" role="sitename">bert</systemitem> through <systemitem moreinfo="none" role="sitename">ernie</systemitem>; a pathalias entry for <systemitem moreinfo="none" role="sitename">moria</systemitem> generated from the previous map
snippet may then look like this:

<screen format="linespecific">moria           ernie!bert!moria!%s</screen></para><para>If you now give a destination address of
<systemitem moreinfo="none" role="emailaddr">janet@moria.uucp</systemitem>, your MTA will pick
the route shown above and send the message to
<systemitem moreinfo="none" role="sitename">ernie</systemitem> with an envelope address of
<systemitem moreinfo="none" role="emailaddr">bert!moria!janet</systemitem>.</para><para><indexterm significance="normal"><primary>email</primary><secondary>routing</secondary><tertiary>smart host</tertiary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>default route</secondary></indexterm>
<indexterm significance="normal"><primary>default email route</primary></indexterm>
<indexterm significance="normal"><primary>smart host routing</primary></indexterm>
<indexterm significance="normal"><primary>routing</primary><secondary>smart host</secondary></indexterm>
<indexterm significance="normal"><primary>leaf sites</primary></indexterm>
<indexterm significance="normal"><primary>sites</primary><secondary>leaf</secondary></indexterm>
Building a <filename moreinfo="none">paths</filename> file from the full Usenet maps is not
a very good idea, however. The information provided in them is usually rather
distorted and occasionally out of date.  Therefore, only a number of major
hosts use the complete UUCP world maps to build their
<filename moreinfo="none">paths</filename> files. Most sites maintain routing information only
for sites in their neighborhood and send any mail to sites they don't
find in their databases to a smarter host with more complete routing
information. This scheme is called <emphasis>smart-host routing</emphasis>.
Hosts that have only one UUCP mail link (so-called
<emphasis>leaf sites</emphasis>) don't do any routing of their own; they
rely entirely on their smart host.</para></sect2><sect2><title>Mixing UUCP and RFC-822</title><indexterm significance="normal"><primary>email</primary><secondary>centralizing</secondary></indexterm><indexterm significance="normal"><primary>centralized mail handling</primary></indexterm><indexterm significance="normal"><primary>email</primary><secondary>routing</secondary><tertiary>domain-based</tertiary></indexterm><indexterm significance="normal"><primary>domains</primary><secondary>mail routing</secondary></indexterm><para>The best cure for the problems of mail routing in UUCP networks so far is the
adoption of the domain name system in UUCP networks. Of course, you can't
query a name server over UUCP. Nevertheless, many UUCP sites have formed small
domains that coordinate their routing internally. In the maps, these domains
announce one or two hosts as their mail gateways so that there doesn't have to
be a map entry for each host in the domain. The gateways handle all mail that
flows into and out of the domain. The routing scheme inside the domain is
completely invisible to the outside world.</para><?troff .wcon_off?><para>This works very well with the smart-host routing scheme.
Global routing information is maintained by the gateways only; minor hosts
within a domain get along with only a small, handwritten
<filename moreinfo="none">paths</filename> file that lists the routes inside their domain and
the route to the mail hub.  Even<?troff .ne 10?> the mail gateways do not need routing information for every single UUCP host in the world anymore. Besides
the complete routing information for the domain they serve, they only need to
have routes to entire domains in their databases now. For instance, this
pathalias entry will route all mail for sites in the
<systemitem moreinfo="none" role="sitename">sub.org</systemitem> domain to
<systemitem moreinfo="none" role="sitename">smurf</systemitem>:

<screen format="linespecific">.sub.org        swim!smurf!%s</screen></para><para>Mail addressed to <systemitem moreinfo="none" role="emailaddr">claire@jones.sub.org</systemitem>
will be sent to <systemitem moreinfo="none" role="sitename">swim</systemitem> with an envelope
address of <systemitem moreinfo="none" role="emailaddr">smurf!jones!claire</systemitem>.</para><para>The hierarchical organization of the domain namespace allows mail
servers to mix more specific routes with less specific ones. For
instance, a system in France may have specific routes for subdomains
of <systemitem moreinfo="none" role="sitename">fr</systemitem>, but route any mail for hosts
in the <systemitem moreinfo="none" role="sitename">us</systemitem> domain toward some system
in the U.S.  In this way, domain-based routing (as this technique is called)
greatly reduces the size of routing databases, as well as the administrative
overhead needed.</para><para>The main benefit of using domain names in a UUCP environment, however, is that
compliance with RFC-822 permits easy gatewaying between UUCP networks and the
Internet. Many UUCP domains nowadays have a link with an Internet gateway that
acts as their smart host. Sending messages across the Internet is faster, and
routing information is much more reliable because Internet hosts can use DNS
instead of the Usenet Maps.</para><para>In order to be reachable from the Internet, UUCP-based domains usually
have their Internet gateway announce an MX record for them (MX records
were described previously in the section <xref linkend="x-087-2-mail.routing.internet"></xref>). For instance, assume that
<systemitem moreinfo="none" role="sitename">moria</systemitem> belongs to the
<systemitem moreinfo="none" role="sitename">orcnet.org</systemitem> domain.
<systemitem moreinfo="none" role="sitename">gcc2.groucho.edu</systemitem> acts as its Internet
gateway. <systemitem moreinfo="none" role="sitename">moria</systemitem> would therefore use
<systemitem moreinfo="none" role="sitename">gcc2</systemitem> as its smart host so that all
mail for foreign domains is delivered across the Internet. On the other hand,
<systemitem moreinfo="none" role="sitename">gcc2</systemitem> would announce an MX record for
<systemitem moreinfo="none" role="sitename">*.orcnet.org</systemitem> and deliver all incoming
mail for <systemitem moreinfo="none" role="sitename">orcnet</systemitem> sites to
<systemitem moreinfo="none" role="sitename">moria</systemitem>. The asterisk in
<systemitem moreinfo="none" role="sitename">*.orcnet.org</systemitem> is a wildcard that
matches all hosts in that domain that don't have any other record associated
with them. This should normally be the case for UUCP-only domains.</para><para>The only remaining problem is that the UUCP transport programs can't deal
with fully qualified domain names.  Most UUCP suites were designed to cope
with site names of up to eight characters, some even less, and using
nonalphanumeric characters such as dots is completely out of the question
for most.</para><indexterm significance="normal"><primary>RFC-822</primary><secondary>names</secondary></indexterm><para>Therefore, we need mapping between RFC-822 names and UUCP hostnames.
This mapping is completely implementation-dependent. One
common way of mapping FQDNs to UUCP names is to use the pathalias file:

<screen format="linespecific">moria.orcnet.org  ernie!bert!moria!%s</screen></para><?troff .Nd 10?><indexterm significance="normal"><primary>uucpxtable</primary></indexterm><para>This will produce a pure UUCP-style bang path from an address that specifies
a fully qualified domain name. Some mailers provide a special file for this;
<command moreinfo="none">sendmail</command>, for instance, uses the
<filename moreinfo="none">uucpxtable</filename>.</para><para>The reverse transformation (colloquially called
<emphasis>domainizing</emphasis>) is sometimes required when sending
mail from a UUCP network to the Internet. As long as the mail sender
uses the fully qualified domain name in the destination address, this
problem can be avoided by not removing the domain name from the
envelope address when forwarding the message to the smart
host. However, there are still some UUCP sites that are not part of
any domain. They are usually domainized by appending the pseudo-domain
<systemitem moreinfo="none" role="sitename">uucp</systemitem>.</para><indexterm significance="normal" class="endofrange" startref="idx-mailrouting-1"></indexterm><indexterm significance="normal" class="startofrange" id="idx-mailfilenamepathsfilenamefile-1"><primary>email</primary><secondary>paths file</secondary></indexterm><indexterm significance="normal"><primary>paths file</primary></indexterm><indexterm significance="normal"><primary>pathalias command</primary></indexterm><para>The pathalias database provides the main routing information in
UUCP-based networks. A typical entry looks like this (site name
and path are separated by tabs):

<screen format="linespecific">moria.orcnet.org  ernie!bert!moria!%s
moria             ernie!bert!moria!%s</screen></para><para>This makes any message to <systemitem moreinfo="none" role="sitename">moria</systemitem> be
delivered via <systemitem moreinfo="none" role="sitename">ernie</systemitem> and
<systemitem moreinfo="none" role="sitename">bert</systemitem>. Both
<systemitem moreinfo="none" role="sitename">moria</systemitem>'s fully qualified name and
its UUCP name have to be given if the mailer does not have a separate way to
map between these namespaces.</para><para><indexterm significance="normal"><primary>email</primary><secondary>centralizing</secondary></indexterm>
<indexterm significance="normal"><primary>centralized mail handling</primary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>domain-based routing</secondary></indexterm>
If you want to direct all messages to hosts inside a domain to its
mail relay, you may also specify a path in the pathalias database,
giving the domain name preceded by a dot as the target. For example, if
all hosts in <systemitem moreinfo="none" role="sitename">sub.org</systemitem> can be reached
through <systemitem moreinfo="none" role="sitename">swim!smurf</systemitem>, the pathalias
entry might look like this:

<screen format="linespecific">.sub.org        swim!smurf!%s</screen></para><para>Writing a pathalias file is acceptable only when you are running a site
that does not have to do much routing.  If you have to do routing for a
large number of hosts, a better way is to use the <command moreinfo="none">pathalias</command>
command to create the file from map files. Maps can be maintained much more
easily, because you may simply add or remove a system by editing the system's
map entry and recreating the map file.  Although the maps published by the
Usenet Mapping Project aren't used for routing very much anymore, smaller
UUCP networks may provide routing information in their own set of maps.</para><para><indexterm significance="normal"><primary>email</primary><secondary>map files</secondary></indexterm>
<indexterm significance="normal"><primary>Usenet</primary><secondary>map files</secondary></indexterm>
<indexterm significance="normal"><primary>UUCP</primary><secondary>map files</secondary></indexterm>
<indexterm significance="normal"><primary>maps, Usenet</primary></indexterm>
A map file mainly consists of a list of sites that each system polls
or is polled by.  The system name begins in the first column and is
followed by a comma-separated list of links. The list may be continued
across newlines if the next line begins with a tab.  Each link
consists of the name of the site followed by a cost given in
brackets. The cost is an arithmetic expression made up of numbers and
symbolic expressions like DAILY or WEEKLY. Lines beginning with a hash
sign are ignored.</para><para>As an example, consider <systemitem moreinfo="none" role="sitename">moria</systemitem>, which
polls <systemitem moreinfo="none" role="sitename">swim.twobirds.com</systemitem> twice a day
and <systemitem moreinfo="none" role="sitename">bert.sesame.com</systemitem> once per week.
The link to <systemitem moreinfo="none" role="sitename">bert</systemitem> uses a
slow 2,400 bps modem. <systemitem moreinfo="none" role="sitename">moria</systemitem> would
publish the following maps entry:

<screen format="linespecific">moria.orcnet.org
        bert.sesame.com(DAILY/2),
        swim.twobirds.com(WEEKLY+LOW)
moria.orcnet.org = moria</screen></para><para>The last line makes <systemitem moreinfo="none" role="sitename">moria</systemitem> known
under its UUCP name, as well. Note that its cost must be specified as
<systemitem moreinfo="none" role="keyword">DAILY/2</systemitem> because calling
twice a day actually halves the cost for this link.</para><para>Using the information from such map files, <command moreinfo="none">pathalias</command> is
able to calculate optimal routes to any destination site listed in the paths
file and produce a pathalias database from this which can then be used
for routing to these sites.</para><para><indexterm significance="normal"><primary>pathalias command</primary></indexterm>
<command moreinfo="none">pathalias</command> provides a couple of other features like
site-hiding (i.e., making sites accessible only through a gateway). See
the <command moreinfo="none">pathalias</command> manual page for details and a
complete list of link costs.</para><indexterm significance="normal"><primary>uuwho command</primary></indexterm><para>Comments in the map file generally contain additional information on
the sites described in it. There is a rigid format in which to specify
this information so that it can be retrieved from the maps.  For
instance, a program called <command moreinfo="none">uuwho</command> uses a database
created from the map files to display this information in a nicely
formatted way. When you register your site with an organization that
distributes map files to its members, you generally have to fill out
such a map entry. Below is a sample map entry (in fact, it's the one
for Olaf's site):

<screen format="linespecific">#N      monad, monad.swb.de, monad.swb.sub.org
#S      AT 486DX50; Linux 0.99
#O      private
#C      Olaf Kirch
#E      okir@monad.swb.de
#P      Kattreinstr. 38, D-64295 Darmstadt, FRG
#L      49 52 03 N / 08 38 40 E
#U      brewhq
#W      okir@monad.swb.de (Olaf Kirch); Sun Jul 25 16:59:32 MET DST 1993
#
monad   brewhq(DAILY/2)
# Domains
monad = monad.swb.de
monad = monad.swb.sub.org</screen></para><para>The whitespace after the first two characters is a tab. The meaning of
most of the fields is pretty obvious; you will receive a detailed
description from whichever domain you register with. The
<systemitem moreinfo="none" role="keyword">L</systemitem> field is the most fun to find out:
it gives your geographical position in latitude/longitude and is used to
draw the PostScript maps that show all sites for each country, as well as
worldwide.<footnote id="x-087-2-fnma07"><para>They are posted regularly in
<systemitem moreinfo="none" role="newsgroup">news.lists.ps-maps</systemitem>.
Beware. They're HUGE.</para></footnote></para><indexterm significance="normal" class="endofrange" startref="idx-mailfilenamepathsfilenamefile-1"></indexterm></sect2></sect1><sect1 id="x-087-2-mail.elm"><title>Configuring elm</title><indexterm significance="normal" class="startofrange" id="idx-configuringcommandelmcommand-1"><primary>configuring</primary><secondary>elm (electronic mail)</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-commandelmcommand-1"><primary>elm (electronic mail)</primary></indexterm><indexterm significance="normal" class="startofrange" id="chem.email.elm"><primary>email</primary><secondary>elm</secondary></indexterm><para><command moreinfo="none">elm</command> stands for electronic mail and is one
of the more reasonably named Unix tools. It provides a full-screen interface
with a good help feature. We won't discuss how to use <command moreinfo="none">elm</command>
here, but only dwell on its configuration options.</para><para>Theoretically, you can run <command moreinfo="none">elm</command> unconfigured, and everything
works wellif you are lucky. But there are a few options that must be
set, although they are required only on occasion.</para><para>When it starts, <command moreinfo="none">elm</command> reads a set of configuration variables
from the <filename moreinfo="none">elm.rc</filename> file in <filename moreinfo="none">/etc/elm</filename>.
Then it attempts to read the file <filename moreinfo="none">.elm/elmrc</filename> in your
home directory. You don't usually write this file yourself. It is created when
you choose Save new options from <command moreinfo="none">elm</command>'s options
menu.</para><para>The set of options for the private <filename moreinfo="none">elmrc</filename> file is also
available in the global <filename moreinfo="none">elm.rc</filename> file. Most settings in
your private <filename moreinfo="none">elmrc</filename> file override those of the global file.</para><sect2 id="x-087-2-mail.elm.global"><title>Global elm Options</title><para><?troff .hw following?>In the global <filename moreinfo="none">elm.rc</filename> file, you must set the options
that pertain to your host's name. For example, at the Virtual Brewery, the file
for <systemitem moreinfo="none" role="sitename">vlager</systemitem> contains the following:

<screen format="linespecific">#
# The local hostname
hostname = vlager
#
# Domain name
hostdomain = .vbrew.com
#
# Fully qualified domain name
hostfullname = vlager.vbrew.com</screen></para><para>These options set <command moreinfo="none">elm</command>'s idea of the local hostname.
Although this information is rarely used, you should set the options.
Note that these particular options only take effect when giving them in
the global configuration file; when found in your private
<filename moreinfo="none">elmrc</filename>, they will be ignored.</para></sect2><sect2 id="x-087-2-mail.elm.charsets"><title>National Character Sets</title><indexterm significance="normal"><primary>elm (electronic mail)</primary><secondary>national character sets</secondary></indexterm><indexterm significance="normal"><primary>internationalization for elm</primary></indexterm><indexterm significance="normal"><primary>national character sets in elm</primary></indexterm><indexterm significance="normal"><primary>character set in elm</primary></indexterm><indexterm significance="normal"><primary>ISO-8859-1</primary></indexterm><indexterm significance="normal"><primary>Latin-1 character set</primary></indexterm><indexterm significance="normal"><primary>MIME (Multipurpose Internet Mail Extensions)</primary><secondary>format</secondary></indexterm><para>A set of standards and RFCs have been developed that amend the RFC-822
standard to support various types of messages, such as plain text,
binary data, PostScript files, etc. These standards are commonly
referred to as MIME, or Multipurpose Internet Mail Extensions. Among
other things, MIME also lets the recipient know if a character set
other than standard ASCII has been used when writing the message, for
example, using French accents or German
umlauts. <command moreinfo="none">elm</command> supports these characters to some
extent.</para><para>The character set used by Linux internally to represent characters is
usually referred to as ISO-8859-1, which is the name of the standard it
conforms to. It is also known as Latin-1.  Any message using characters
from this character set should have the following line in its header:

<screen format="linespecific">Content-Type: text/plain; charset=iso-8859-1</screen></para><para>The receiving system should recognize this field and take appropriate
measures when displaying the message. The default for
<systemitem moreinfo="none" role="keyword">text/plain</systemitem> messages is a
<systemitem moreinfo="none" role="keyword">charset</systemitem> value of
<systemitem moreinfo="none" role="keyword">us-ascii</systemitem>.</para><para>To be able to display messages with character sets other than ASCII,
<command moreinfo="none">elm</command> must know how to print these characters. By default,
when <command moreinfo="none">elm</command> receives a message with a
<replaceable>charset</replaceable> field other than
<systemitem moreinfo="none" role="keyword">us-ascii</systemitem> (or a content type other than
<systemitem moreinfo="none" role="keyword">text/plain</systemitem>, for that matter), it
tries to display the message using a command called
<command moreinfo="none">metamail</command>. Messages that require <command moreinfo="none">metamail</command>
to be displayed are shown with an <command moreinfo="none">M</command> in the very first
column in the overview screen.</para><para>Since Linux's native character set is ISO-8859-1, calling
<command moreinfo="none">metamail</command> is not necessary to display messages using
this character set. If <command moreinfo="none">elm</command> is told that the display
understands ISO-8859-1, it will not use <command moreinfo="none">metamail</command>,
but will display the message directly instead. This can be enabled by
setting the following option in the global
<filename moreinfo="none">elm.rc</filename>:

<screen format="linespecific">displaycharset = iso-8859-1</screen></para><para>Note that you should set this option even when you are never going to
send or receive any messages that actually contain characters other than
ASCII. This is because people who do send such messages usually
configure their mailer to put the proper <literal moreinfo="none">Content-Type:</literal>
field into the mail header by default, whether or not they are sending
ASCII-only messages.</para><para>However, setting this option in <filename moreinfo="none">elm.rc</filename> is not
enough. When displaying the message with its built-in pager,
<command moreinfo="none">elm</command> calls a library function for each character to
determine whether it is printable. By default, this function will only
recognize ASCII characters as printable and display all other
characters as <literal moreinfo="none">^?</literal>. You may overcome this function by setting
the environment variable <systemitem moreinfo="none" role="keyword">LC_CTYPE</systemitem> to <systemitem moreinfo="none" role="keyword">ISO-8859-1</systemitem>, which tells the library to
accept Latin-1 characters as printable. Support for this and other
features have been available since Version 4.5.8 of the Linux standard library.</para><para>When sending messages that contain special characters from ISO-8859-1,
you should make sure to set two more variables in the
<filename moreinfo="none">elm.rc</filename> file:

<screen format="linespecific">charset = iso-8859-1
textencoding = 8bit</screen></para><?troff .Nd 10?><para>This makes <command moreinfo="none">elm</command> report the character set as ISO-8859-1
in the mail header and send it as an 8-bit value (the default is to strip all
characters to 7-bit).</para><para>Of course, all character set options we've discussed here may also be
set in the private <filename moreinfo="none">elmrc</filename> file instead of the global one
so individual users can have their own default settings if the global one
doesn't suit them.</para><indexterm significance="normal" class="endofrange" startref="chem.email.elm"></indexterm><indexterm significance="normal" class="endofrange" startref="chem.email.1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-commandelmcommand-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-configuringcommandelmcommand-1"></indexterm></sect2></sect1></chapter><chapter id="x-087-2-sendmail"><title>Sendmail</title><indexterm significance="normal" class="startofrange" id="idx-configuringsendmail"><primary>configuring</primary><secondary>sendmail</secondary></indexterm><indexterm significance="normal" class="startofrange" id="idx-commandsendmailcommand-1"><primary>sendmail</primary></indexterm><sect1><title>Introduction to sendmail</title><para>It's been said that you aren't a <emphasis>real</emphasis> Unix system
administrator until you've edited a <filename moreinfo="none">sendmail.cf</filename> file.
It's also been said that you're crazy if you've attempted to do so twice.</para><para><command moreinfo="none">sendmail</command> is an incredibly powerful mail
program. It's also incredibly difficult to learn and understand. Any
program whose definitive reference (<command moreinfo="none">sendmail</command>, by
Bryan Costales and Eric Allman, published by O'Reilly) is 1,050 pages long scares most people
off. Information on the <command moreinfo="none">sendmail</command> reference is
contained in the bibliography at the end of this book.</para><para><indexterm significance="normal"><primary>sendmail.cf file</primary></indexterm>
Fortunately, new versions of sendmail are different. You no longer need to 
directly edit the cryptic <filename moreinfo="none">sendmail.cf</filename> file; the 
new version provides a configuration utility that will create the
<filename moreinfo="none">sendmail.cf</filename> file for you based on much simpler macro
files. You do not need to understand the
complex syntax of the <filename moreinfo="none">sendmail.cf</filename> file; the macro files 
don't require you to. Instead, you need only list items, such as the name of 
features you wish to include in your configuration, and specify some of the 
parameters that determine how that feature operates. A traditional 
Unix utility called <command moreinfo="none">m4</command> then takes your
macro configuration data and mixes it with the data it reads from template
files containing the actual <filename moreinfo="none">sendmail.cf</filename> syntax, to
produce your <filename moreinfo="none">sendmail.cf</filename> file.</para><para>In this chapter we introduce <command moreinfo="none">sendmail</command> and describe
how to install, configure and test it, using the Virtual Brewery as an
example. If the information presented here helps make the task of
configuring <command moreinfo="none">sendmail</command> less daunting for you, we hope
you'll gain the confidence to tackle more complex configurations on
your own.</para></sect1><sect1><title>Installing sendmail</title><para><indexterm significance="normal"><primary>sendmail</primary><secondary>installing</secondary></indexterm>
<indexterm significance="normal"><primary>installing</primary><secondary>sendmail</secondary></indexterm>
The <command moreinfo="none">sendmail</command> mail transport agent is included in
prepackaged form in most Linux distributions. Installation in this case is
relatively simple. Despite this fact, there are some good reasons to install
<command moreinfo="none">sendmail</command> from source, especially if you are security
conscious. The <command moreinfo="none">sendmail</command> program is very complex and has
earned a reputation over the years for containing bugs that allow security
breaches. One of the best known examples is the RTM Internet worm that
exploited a buffer overflow problem in early versions of
<command moreinfo="none">sendmail</command>. We touched on this briefly in 
<xref linkend="x-087-2-firewall"></xref>. Most security exploits involving buffer 
overflows rely on all copies of <command moreinfo="none">sendmail</command> on different 
machines being identical, as the exploits rely on data being stored in 
specific locations. This, of course, is precisely what happens with 
<command moreinfo="none">sendmail</command> installed from Linux distributions. Compiling 
<command moreinfo="none">sendmail</command> from source yourself can help reduce this risk. 
Modern versions of <command moreinfo="none">sendmail</command> are less vulnerable because 
they have come under exceedingly close scrutiny as security has become a more 
widespread concern throughout the Internet community.</para><para><indexterm significance="normal"><primary>code, obtaining for</primary><secondary>sendmail</secondary></indexterm>
The <command moreinfo="none">sendmail</command> source code is available via anonymous FTP from
<systemitem moreinfo="none" role="sitename">ftp.sendmail.org</systemitem>.</para><para>Compilation is very simple bceause the <command moreinfo="none">sendmail</command> source
package directly supports Linux. The steps involved in compiling
<command moreinfo="none">sendmail</command> are:

<screen format="linespecific"><userinput moreinfo="none"># cd /usr/local/src
# tar xvfz sendmail.8.9.3.tar.gz
# cd src
# ./Build</userinput></screen>

You need <literal moreinfo="none">root</literal> permissions to complete the installation
of the resulting binary files using:

<screen format="linespecific"><userinput moreinfo="none"># cd obj.Linux.2.0.36.i586
# make install</userinput></screen>

You have now installed the <command moreinfo="none">sendmail</command> binary into the 
<filename moreinfo="none">/usr/sbin</filename> directory. Several symbolic links to
the <command moreinfo="none">sendmail</command> binary will be installed into the
<filename moreinfo="none">/usr/bin/</filename> directory. We'll talk about those links when 
we discuss common tasks in running <command moreinfo="none">sendmail</command>.</para></sect1><sect1><title>Overview of Configuration Files</title><para><indexterm significance="normal" class="startofrange" id="sendmail.config.files"><primary>sendmail</primary><secondary>configuration files</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="config.files.sendmail"><primary>configuration files</primary><secondary>sendmail</secondary></indexterm>
Traditionally, <command moreinfo="none">sendmail</command> was set up through a system
configuration file (typically called
<filename moreinfo="none">/etc/mail/sendmail.cf</filename>, or in older distributions,
<filename moreinfo="none">/etc/sendmail.cf</filename>, or even
<filename moreinfo="none">/usr/lib/sendmail.cf</filename>) that is not
anything close to any language you've seen before. Editing the
<filename moreinfo="none">sendmail.cf</filename> file to provide customized behavior
can be a humbling experience.</para><para><?troff .hw understand?>Today <command moreinfo="none">sendmail</command> makes all configuration
options macro driven with an easy-to-understand syntax. The macro method 
generates configurations to cover most installations, but you always have
the option of tuning the resultant <filename moreinfo="none">sendmail.cf</filename> manually
to work in a more complex environment.</para></sect1><sect1><title>The sendmail.cf and sendmail.mc Files</title><para><indexterm significance="normal"><primary>m4 macro processor</primary></indexterm>
<indexterm significance="normal"><primary>sendmail.df file</primary></indexterm>
<indexterm significance="normal" class="startofrange" id="sendmail.cf.file"><primary>sendmail.cf file</primary></indexterm>
<indexterm significance="normal"><primary>sendmail.mc file</primary></indexterm>
The <command moreinfo="none">m4</command> macro processor program generates the 
<filename moreinfo="none">sendmail.df</filename> file when it processes the macro 
configuration file provided by the local system administrator. Throughout the 
remainder of this chapter we will refer to this configuration file as the 
<filename moreinfo="none">sendmail.mc</filename> file.</para><para>The configuration process is basically a matter of creating a suitable
<filename moreinfo="none">sendmail.mc</filename> file that includes macros that describe
your desired configuration. The macros are expressions that the
<command moreinfo="none">m4</command> macro processor understands and expands into
the complex <filename moreinfo="none">sendmail.cf</filename> syntax. The macro expressions
are made up of the macro name (the text in capital letters at the start),
which can be likened to a function in a programming language, and some
parameters (the text within brackets) that are used in the expansion. The
parameters may be passed literally into the <filename moreinfo="none">sendmail.cf</filename>
output or may be used to govern the way the macro processing occurs.</para><para>A <filename moreinfo="none">sendmail.mc</filename> file for a minimal configuration (UUCP or
SMTP with all nonlocal mail being relayed to a directly connected
smart host) can be as short as 10 or 15 lines, excluding comments.</para><sect2><title>Two Example sendmail.mc Files</title><para><indexterm significance="normal"><primary>sendmail.mc file</primary><secondary>two examples</secondary></indexterm>
If you're an administator of a number of different mail hosts, you might not
want to name your configuration file <filename moreinfo="none">sendmail.mc</filename>.
Instead, it is common practice to name it after the
host<filename moreinfo="none">vstout.m4</filename> in our case. The name doesn't
really matter as long as the output is called
<filename moreinfo="none">sendmail.cf</filename>. Providing a unique name for the
configuration file for each host allows you to keep all configuration files
in the same directory and is just an administrative convenience. Let's look
at two example macro configuration files so we know where we are
heading.</para><para><indexterm significance="normal"><primary>configuring</primary><secondary>sendmail</secondary><tertiary>for SMTP</tertiary></indexterm>
Most <command moreinfo="none">sendmail</command> configurations today use SMTP only. It is
very simple to configure <command moreinfo="none">sendmail</command> for SMTP. 
<xref linkend="x-087-2-sendmail.mc.smtp"></xref> expects a DNS name server to be 
available to resolve hosts and will attempt to accept and deliver all mail 
for hosts using just SMTP.</para><example id="x-087-2-sendmail.mc.smtp"><title>Sample Configuration File vstout.smtp.m4</title><screen format="linespecific">divert(-1)
#
# Sample configuration file for vstout - smtp only
#
divert(0)
VERSIONID(`@(#)sendmail.mc	8.7 (Linux) 3/5/96')
OSTYPE(`linux')
#
# Include support for the local and smtp mail transport protocols.
MAILER(`local')
MAILER(`smtp')
#
FEATURE(rbl)
FEATURE(access_db)
# end</screen></example><para>A <filename moreinfo="none">sendmail.mc</filename> file for
<systemitem moreinfo="none" role="sitename">vstout</systemitem> at the Virtual Brewery is shown
in <xref linkend="x-087-2-sendmail.mc.uucpsmtp"></xref>.
<systemitem moreinfo="none" role="sitename">vstout</systemitem> uses SMTP to talk to all hosts
on the Brewery's LAN, and you'll see the commonality with the generic SMTP-only 
configuration just presented. In addition, the 
<systemitem moreinfo="none" role="sitename">vstout</systemitem> configuration sends all mail 
for other destinations to <systemitem moreinfo="none" role="sitename">moria</systemitem>, 
its Internet relay host, via UUCP.</para><example id="x-087-2-sendmail.mc.uucpsmtp"><title>Sample Configuration File vstout.uucpsmtp.m4</title><screen format="linespecific">divert(-1)
#
# Sample configuration file for vstout
#
divert(0)
VERSIONID(`@(#)sendmail.mc	8.7 (Linux) 3/5/96')
OSTYPE(`linux')
dnl
# moria is our smart host, using the "uucp-new" transport.
define(`SMART_HOST', `uucp-new:moria')
dnl
# Support the local, smtp and uucp mail transport protocols.
MAILER(`local')
MAILER(`smtp')
MAILER(`uucp')
LOCAL_NET_CONFIG
# This rule ensures that all local mail is delivered using the
# smtp transport, everything else will go via the smart host.
R$*  @ $* .$m.  $*	$#smtp $@ $2.$m. $: $1  @ $2.$m.  $3
dnl
#
FEATURE(rbl)
FEATURE(access_db)
# end</screen></example><para>If you compare and contrast the two configurations, you might be able to
work out what each of the configuration parameters does. We'll explain them
all in detail.</para></sect2><sect2><title>Typically Used sendmail.mc Parameters</title><para><indexterm significance="normal" class="startofrange" id="sendmail.mc.parameters"><primary>sendmail.mc file</primary><secondary>parameters</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="macro.defs.sendmail"><primary>macro definitions, sendmail.mc file</primary></indexterm>
A few of the items in the <filename moreinfo="none">sendmail.mc</filename> file are required
all the time; others can be ignored if you can get away with defaults.
The general sequence of the definitions in the <filename moreinfo="none">sendmail.mc</filename>
is as follows:

<orderedlist inheritnum="ignore" continuation="restarts"><listitem><para><systemitem moreinfo="none" role="keyword">VERSIONID</systemitem></para></listitem><listitem><para><systemitem moreinfo="none" role="keyword">OSTYPE</systemitem></para></listitem><listitem><para><systemitem moreinfo="none" role="keyword">DOMAIN</systemitem></para></listitem><listitem><para><systemitem moreinfo="none" role="keyword">FEATURE</systemitem></para></listitem><listitem><para>Local macro definitions</para></listitem><listitem><para><systemitem moreinfo="none" role="keyword">MAILER</systemitem></para></listitem><listitem><para><systemitem moreinfo="none" role="keyword">LOCAL_*</systemitem> rulesets</para></listitem></orderedlist>

We'll talk about each of these in turn in the following sections and refer
to our examples in <xref linkend="x-087-2-sendmail.mc.smtp"></xref> and
<xref linkend="x-087-2-sendmail.mc.uucpsmtp"></xref>, when appropriate, to explain them.</para><sect3><title>Comments</title><para>Lines in the <filename moreinfo="none">sendmail.mc</filename> file that begin with the
<literal moreinfo="none">#</literal> character are not parsed by <command moreinfo="none">m4</command>, and
will by default be output directly into the
<filename moreinfo="none">sendmail.cf</filename> file. This is useful if you want to comment 
on what your configuration is doing in both the input and output files.</para><para>To allow comments in your <filename moreinfo="none">sendmail.mc</filename> that are 
<emphasis>not</emphasis> placed into the
<filename moreinfo="none">sendmail.cf</filename>, you can use the <command moreinfo="none">m4</command>
<systemitem moreinfo="none" role="keyword">divert</systemitem> and
<systemitem moreinfo="none" role="keyword">dnl</systemitem> tokens.
<systemitem moreinfo="none" role="keyword">divert(-1)</systemitem> will cause all output to
cease. <systemitem moreinfo="none" role="keyword">divert(0)</systemitem> will cause output to
be restored to the default. Any output generated by lines between
these will be discarded. In our example, we've used this mechanism to
provide a comment that appears only in the <filename moreinfo="none">sendmail.mc</filename>
file. To achieve the same result for a single line, you can use the
<systemitem moreinfo="none" role="keyword">dnl</systemitem> token that means, literally,
starting at the beginning of the next line, delete all characters up
to and including the next newline. We've used this in
our example, too.</para><para>These are standard <command moreinfo="none">m4</command> features, and you can obtain more
information on them from its manual page.</para></sect3><sect3><title>VERSIONID and OSTYPE</title><para><indexterm significance="normal"><primary>VERSIONID macro defintion</primary></indexterm>
<screen format="linespecific">VERSIONID(`@(#)sendmail.mc  8.9 (Linux) 01/10/98')</screen><?troff .Nd 10?>
The <literal moreinfo="none">VERSIONID</literal> macro is optional, but is useful to record
the version of the sendmail configuration in the
<filename moreinfo="none">sendmail.cf</filename> file. So you'll often encounter it, and we 
recommend it. In any case, be sure to include:</para><para><screen format="linespecific">OSTYPE(`linux')</screen>

<indexterm significance="normal"><primary>OSTYPE macro definition</primary></indexterm>
This is probably the most important definition. The
<literal moreinfo="none">OSTYPE</literal> macro causes a file of definitions to be
included that are good defaults for your operating system. Most of the
definitions in an <literal moreinfo="none">OSTYPE</literal> macro file set the
pathnames of various configuration files, mailer program paths and
arguments, and the location of directories sendmail uses to store
messages. The standard sendmail source code release includes such
a file for Linux, which would be included by the previous
example. Some Linux distributions, notably the Debian distribution,
include their own definition file that is completely Linux-FHS
compliant. When your distribution does this, you should probably use
its definition instead of the Linux default one.</para><para>The <systemitem moreinfo="none" role="keyword">OSTYPE</systemitem> definition should
be one of the first definitions to appear in your
<filename moreinfo="none">sendmail.mc</filename> file, as many other definitions
depend upon it.</para></sect3><sect3><title>DOMAIN</title><para><indexterm significance="normal"><primary>DOMAIN macro definition</primary></indexterm>
The <systemitem moreinfo="none" role="keyword">DOMAIN</systemitem> macro is useful
when you wish to configure a large number of machines on the same
network in a standard way. It you're configuring a small number of
hosts, it probably isn't worth bothering with. You typically configure
items, such as the name of mail relay hosts or hubs that all hosts on
your network will use.</para><para>The standard installation contains a directory of <command moreinfo="none">m4</command> macro 
templates used to drive the configuration process. This directory is usually 
named <filename moreinfo="none">/usr/share/sendmail.cf</filename> or something similar. Here 
you will find a subdirectory called <filename moreinfo="none">domain</filename> that 
contains domain-specific configuration templates. To make use of the 
<systemitem moreinfo="none" role="keyword">DOMAIN</systemitem> macro, you must create your 
own macro file containing the standard definitions you require for your site, 
and write it into the <filename moreinfo="none">domain</filename> subdirectory. You'd 
normally include only the macro definitions that were unique to your domain 
here, such as smart host definitions or relay hosts, but you are not limited 
to these.</para><para>The <command moreinfo="none">sendmail</command> source distribution comes with a number of
sample domain macro files that you can use to model your own.</para><para>If you saved your domain macro file as
<filename moreinfo="none">/usr/share/sendmail.cf/domain/vbrew.m4</filename>, you'd
include definitions in your <filename moreinfo="none">sendmail.mc</filename> using:

<screen format="linespecific">DOMAIN(`vbrew')</screen></para></sect3><sect3><title>FEATURE</title><para><indexterm significance="normal"><primary>FEATURE macro definition</primary></indexterm>
The <systemitem moreinfo="none" role="keyword">FEATURE</systemitem> macro enables you to
include predefined <command moreinfo="none">sendmail</command> features in your configuration.
These <command moreinfo="none">sendmail</command> features make the supported configurations
very simple to use. There are a large number, and throughout this
chapter we'll talk about only a few of the more useful and important ones.
You can find full details of the features available in the
<filename moreinfo="none">CF</filename> file included in the source package.</para><para>To use any of the features listed, you should include a line in your
<filename moreinfo="none">sendmail.mc</filename> that looks like:

<screen format="linespecific">FEATURE(<replaceable>name</replaceable>)</screen>

where <replaceable>name</replaceable> is substituted with the feature name. 
Some features take one optional parameter. If you wish to use
something other than the default, you should use an entry that looks like:

<screen format="linespecific">FEATURE(<replaceable>name</replaceable>, <replaceable>param</replaceable>)</screen>

where <replaceable>param</replaceable> is the parameter to supply.</para></sect3><sect3><title>Local macro definitions</title><para><indexterm significance="normal"><primary>local macro definitions</primary></indexterm>
The standard <command moreinfo="none">sendmail</command> macro configuration files provide
lots of hooks and variables with which you can customize your configuration.
These are called <command moreinfo="none">local macro definitions</command>. Many of them 
are listed in the <filename moreinfo="none">CF</filename> file in the 
<command moreinfo="none">sendmail</command> source package.</para><para>The local macro definitions are usually invoked by supplying the name of the
macro with an argument representing the value you wish to assign to the
variable the macro manages. Again, we'll explore some of the more common
local macro definitions in the examples we present later in the chapter.</para></sect3><sect3><title>Defining mail transport protocols</title><para><indexterm significance="normal"><primary>MAILER macro definition</primary></indexterm>
If you want <command moreinfo="none">sendmail</command> to transport mail in any way other
than by local delivery, you must tell it which transports to use. The
<literal moreinfo="none">MAILER</literal> macro makes this very easy. The current version of
<command moreinfo="none">sendmail</command> supports a variety of mail transport protocols;
some of these are experimental, others are probably rarely used.</para><para>In our network we need the SMTP transport to send and receive mail
among the hosts on our local area network, and the UUCP transport to send
and receive mail from our smart host. To achieve this, we simply include both
the <literal moreinfo="none">smtp</literal> and <literal moreinfo="none">uucp</literal> mail transports. The
<literal moreinfo="none">local</literal> mail transport is included by default, but may be
defined for clarity, if you wish. If you are including both the
<literal moreinfo="none">smtp</literal> and the <literal moreinfo="none">uucp</literal> mailers in your
configuration, you must always be sure to define the <literal moreinfo="none">smtp</literal>
mailer first.</para><para>The more commonly used transports available to you using the
<systemitem moreinfo="none" role="keyword">MAILER</systemitem> macro are described in the
following list:

<variablelist id="x-087-2-sendmail.mailers"><varlistentry><term><systemitem moreinfo="none" role="keyword">local</systemitem></term><listitem><para>	This transport includes both the local delivery agent used to send
	mail into the mailbox of users on this machine and the
	<systemitem moreinfo="none" role="keyword">prog</systemitem> mailer used to send messages
	to local programs. This transport is included by default.
	</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">smtp</systemitem></term><listitem><para>	This transport implements the Simple Mail Transport Protocol (SMTP),
	which is the most common means of transporting mail on the Internet.
	When you include this transport, four mailers are configured: 
        <literal moreinfo="none">smtp</literal> (basic SMTP), <literal moreinfo="none">esmtp</literal> (Extended SMTP), <literal moreinfo="none">smtp8</literal> (8bit binary clean SMTP), 
        and <literal moreinfo="none">relay</literal> (specifically designed for gatewaying 
        messages between hosts).
	</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">uucp</systemitem></term><listitem><para>	The <systemitem moreinfo="none" role="keyword">uucp</systemitem> transport provides
	support for two mailers: 
        <systemitem moreinfo="none" role="keyword">uucp-old</systemitem>, which is the 
        traditional UUCP, and
	<systemitem moreinfo="none" role="keyword">uucp-new</systemitem>, which allows multiple
	recipients to be handled in one transfer.
	</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">usenet</systemitem></term><listitem><para>	This mailer allows you to send mail messages directly into
	Usenet style news networks. Any local message directed to an address
	of <emphasis>news.group.usenet</emphasis> will be fed into the 
        news network for the <emphasis>news.group</emphasis> newsgroup.
	</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">fax</systemitem></term><listitem><para>	If you have the HylaFAX software installed, this mailer will
	allow you to direct email to it so that you may build an email-fax
	gateway. This feature is experimental at the time of writing and more
	information may be obtained from
	<systemitem moreinfo="none" role="url">http://www.vix.com/hylafax/</systemitem>.
	</para></listitem></varlistentry></variablelist></para><para>There are others, such as the <systemitem moreinfo="none" role="keyword">pop</systemitem>,
<systemitem moreinfo="none" role="keyword">procmail</systemitem>,
<systemitem moreinfo="none" role="keyword">mail11</systemitem>,
<systemitem moreinfo="none" role="keyword">phquery</systemitem>, and
<systemitem moreinfo="none" role="keyword">cyrus</systemitem> that are useful, but less
common. If your curiosity is piqued, you can read about these
in the sendmail book or the documentation supplied in the source package.</para></sect3><sect3><title>Configure mail routing for local hosts</title><para><indexterm significance="normal"><primary>LOCAL_NET_CONFIG macro definition</primary></indexterm>
The Virtual Brewery's configuration is probably more complex than most sites 
require. Most sites today would use the SMTP transport only and do not
have to deal with UUCP at all. In our configuration we've configured a
smart host that is used to handle all outgoing mail.
Since we are using the SMTP transport on our local network we must tell
<command moreinfo="none">sendmail</command> that it is not to send local mail via the
smart host. The <literal moreinfo="none">LOCAL_NET_CONFIG</literal> macro allows you to
insert sendmail rules directly into the output <filename moreinfo="none">sendmail.cf</filename>
to modify the way that local mail is handled. We'll talk more about rewrite
rules later on, but for the moment you should accept that the rule we've
supplied in our example specifies that any mail destined for hosts in the
<systemitem moreinfo="none" role="sitename">vbrew.com</systemitem> domain should be delivered
directly to the target hosts using the SMTP mail transport.</para></sect3><indexterm significance="normal" class="endofrange" startref="sendmail.mc.parameters"></indexterm><indexterm significance="normal" class="endofrange" startref="macro.defs.sendmail"></indexterm></sect2><indexterm significance="normal" class="endofrange" startref="sendmail.config.files"></indexterm><indexterm significance="normal" class="endofrange" startref="config.files.sendmail"></indexterm><indexterm significance="normal" class="endofrange" startref="sendmail.cf.file"></indexterm></sect1><sect1><title>Generating the sendmail.cf File</title><para><indexterm significance="normal"><primary>sendmail.cf file</primary><secondary>generating</secondary></indexterm>
When you have completed editing your <command moreinfo="none">m4</command> configuration file, you must process it
to produce the <filename moreinfo="none">/etc/mail/sendmail.cf</filename> file read by
<command moreinfo="none">sendmail</command>. This is straightforward, as illustrated by the 
following example:</para><screen format="linespecific"># <userinput moreinfo="none">cd /etc/mail</userinput>
# <userinput moreinfo="none">m4 /usr/share/sendmail.cf/m4/cf.m4 vstout.uucpsmtp.mc sendmail.cf</userinput></screen><para>This command invokes the <command moreinfo="none">m4</command> macro processor,
supplying it the name of two macro definition files to
process. <command moreinfo="none">m4</command> processes the files in the order
given. The first file is a standard <command moreinfo="none">sendmail</command> macro
template supplied with the <command moreinfo="none">sendmail</command> source package,
the second, of course, is the file containing our own macro
definitions. The output of the command is directed to the
<filename moreinfo="none">/etc/mail/sendmail.cf</filename> file, which is our target
file.</para><para>You may now start <command moreinfo="none">sendmail</command> with the new configuration.</para></sect1><sect1><title>Interpreting and Writing Rewrite Rules</title><para><indexterm significance="normal" class="startofrange" id="sendmail.rewrite.rules"><primary>sendmail</primary><secondary>rewrite rules</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="rewrite.rules"><primary>rewrite rules (sendmail)</primary></indexterm>
Arguably the most powerful feature of <command moreinfo="none">sendmail</command> is the
rewrite rule. Rewrite rules are used by <command moreinfo="none">sendmail</command> to
determine how to process a received mail message. <command moreinfo="none">sendmail</command>
passes the addresses from the <emphasis>headers</emphasis> of a mail message
through collections of rewrite rules called <emphasis>rulesets</emphasis> The
rewrite rules transform a mail address from one form to another and you can
think of them as being similar to a command in your editor that replaces all
text matching a specified pattern with another.</para><para>Each rule has a lefthand side and a righthand side, separated by at least
one tab character. When <command moreinfo="none">sendmail</command> is processing mail it
scans through the rewriting rules looking for a match on the lefthand side.
If an address matches the lefthand side of a rewrite rule, the address is
replaced by the righthand side and processed again.</para><sect2><title>sendmail.cf R and S Commands</title><para><indexterm significance="normal"><primary>sendmail.cf file</primary><secondary>R and S commands</secondary></indexterm>
In the <filename moreinfo="none">sendmail.cf</filename> file, the rulesets are defined using
commands coded as
<literal moreinfo="none">S</literal><replaceable>n</replaceable>, where
<replaceable>n</replaceable> specifies the ruleset that is
considered the current one.</para><para>The rules themselves appear in commands coded as
<command moreinfo="none">R</command>. As each <command moreinfo="none">R</command> command is read, it is 
added to the current ruleset.</para><para>If you're dealing only with the <filename moreinfo="none">sendmail.mc</filename> file,
you won't need to worry about <command moreinfo="none">S</command> commands at
all, as the macros will build those for you. You will need to manually code
your <command moreinfo="none">R</command> rules.</para><?troff .Nd 10?><para>A <command moreinfo="none">sendmail</command> ruleset therefore looks like:

<screen format="linespecific"><literal moreinfo="none">S</literal><replaceable>n</replaceable>
<literal moreinfo="none">R</literal><replaceable>lhs</replaceable> <replaceable>rhs</replaceable>
<literal moreinfo="none">R</literal><replaceable>lhs2</replaceable> <replaceable>rhs2</replaceable></screen></para></sect2><sect2><title>Some Useful Macro Definitions</title><para><command moreinfo="none">sendmail</command> uses a number of standard macro definitions
internally. The most useful of these in writing rulesets are:</para><variablelist><varlistentry><term>$j</term><listitem><para>The fully qualified domain name of this host.</para></listitem></varlistentry><varlistentry><term>$w</term><listitem><para>The hostname component of the FQDN.</para></listitem></varlistentry><varlistentry><term>$m</term><listitem><para>The domain name component of the FQDN.</para></listitem></varlistentry></variablelist><para>We can incorporate these macro definitions in our rewrite rules. Our
Virtual Brewery configuration uses the <literal moreinfo="none">$m</literal> macro.</para></sect2><sect2><title>The Lefthand Side</title><para>            
In the lefthand side of a rewriting rule, you specify a pattern that will
match an address you wish to transform. Most characters are matched literally,
but there are a number of characters that have special meaning; these are
described in the following list. The rewrite rules 
for the lefthand side are:</para><variablelist id="x-087-2-sendmail.rewrite.lhs"><varlistentry><term><literal moreinfo="none">$@</literal></term><listitem><para>Match exactly zero tokens</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">$*</literal></term><listitem><para>Match zero or more tokens</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">$+</literal></term><listitem><para>Match one or more tokens</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">$-</literal></term><listitem><para>Match exactly one token</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">$=</literal><replaceable>x</replaceable></term><listitem><para>Match any phrase in class <replaceable>x</replaceable></para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">$~</literal><replaceable>x</replaceable></term><listitem><para>Match any word not in class <replaceable>x</replaceable></para></listitem></varlistentry></variablelist><para>A token is a string of characters delimited by spaces. There is no way
to include spaces in a token, nor is it necessary, as the expression
patterns are flexible enough to work around this need. When a rule
matches an address, the text matched by each of the patterns in the
expression will be assigned to special variables that we'll use in the
righthand side. The only exception to this is the
<literal moreinfo="none">$@</literal>, which matches no tokens and therefore will
never generate text to be used on the righthand side.</para></sect2><sect2><title>The Righthand Side</title><para>When the lefthand side of a rewrite rule matches an address, the
original text is deleted and replaced by the righthand side of the
rule. All tokens in the righthand side are copied literally, unless
they begin with a dollar sign.  Just as for the lefthand side, a
number of metasymbols may be used on the righthand side. These are
described in the following list. The rewrite rules for the righthand
side are:</para><variablelist id="x-087-2-sendmail.rewrite.rhs"><varlistentry><term><literal moreinfo="none">$</literal><replaceable>n</replaceable></term><listitem><para>This metasymbol is replaced with the <replaceable>n</replaceable>'th
expression from the lefthand side.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">$[</literal><replaceable>name</replaceable><literal moreinfo="none">$]</literal></term><listitem><para>This metasymbol resolves hostname to canonical name. It is replaced
by the canonical form of the host name supplied.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">$(</literal><replaceable>map key</replaceable><literal moreinfo="none"> $@</literal><replaceable>arguments</replaceable><literal moreinfo="none"> $:</literal><replaceable>default</replaceable><literal moreinfo="none"> $)</literal></term><listitem><para>This is the more general form of lookup. The output is the result of
looking up <replaceable>key</replaceable> in the map named
<emphasis>map</emphasis> passing
<replaceable>arguments</replaceable> as arguments. The
<emphasis>map</emphasis> can be any of the maps that
<command moreinfo="none">sendmail</command> supports such as the
<literal moreinfo="none">virtusertable</literal> that we describe a little later. If
the lookup is unsuccessful, <replaceable>default</replaceable> will be
output. If a default is not supplied and lookup fails, the input is
unchanged and <replaceable>key</replaceable> is output.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">$</literal><replaceable>n</replaceable></term><listitem><para>This will cause the rest of this line to be parsed and then given to
ruleset <replaceable>n</replaceable> to evaluate. The output of the called
ruleset will be written as output to this rule. This is the mechanism
that allows rules to call other rulesets.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">$#</literal><replaceable>mailer</replaceable></term><listitem><para>This metasymbol causes ruleset evaluation to halt and specifies the
mailer that should be used to transport this message in the next step
of its delivery. This metasymbol should be called only from ruleset
0 or one of its subroutines. This is the final stage of address parsing
and should be accompanied by the next two metasymbols.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">$@</literal><replaceable>host</replaceable></term><listitem><para>This metasymbol specifies the host that this message will be forwarded to. If
the destination host is the local host, it may be omitted. The
<replaceable>host</replaceable> may be a colon-separated list of destination
hosts that will be tried in sequence to deliver the message.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">$:</literal><replaceable>user</replaceable></term><listitem><para>This metasymbol specifies the target user for the mail message.</para></listitem></varlistentry></variablelist><para>A rewrite rule that matches is normally tried repeatedly until it fails to
match, then parsing moves on to the next rule. This behavior can be changed
by preceding the righthand side with one of two special righthand side metaymbols described in the following list.
The rewrite rules for a righthand side loop control metasymbols are:</para><variablelist id="x-087-2-sendmail.rewrite.rhs.special"><varlistentry><term><literal moreinfo="none">$@</literal></term><listitem><para>This metasymbol causes the ruleset to return with the remainder of
the righthand side as the value. No other rules in the ruleset are
evaluated.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">$:</literal></term><listitem><para>This metasymbol causes this rule to terminate immediately, but the
rest of the current ruleset is evaluated.</para></listitem></varlistentry></variablelist></sect2><sect2><title>A Simple Rule Pattern Example</title><para>To better see how the macro substitution patterns operate, consider the
following rule lefthand side:

<screen format="linespecific">$*  $+ </screen></para><para>This rule matches Zero or more tokens, followed by the 
character, followed by one or more tokens, followed by the 
character.</para><para>If this rule were applied to <literal moreinfo="none">brewer@vbrew.com</literal> or
<literal moreinfo="none">Head Brewer  </literal>, the rule would not
match. The first string would not match because it does not include a
 character, and the second would fail because
<literal moreinfo="none">$+</literal> matches <emphasis>one or more</emphasis> tokens
and there are no tokens between the <literal moreinfo="none"></literal> characters. In any case
in which a rule does not match, the righthand side of the rule is not
used.</para><para>If the rule were applied to <literal moreinfo="none">Head Brewer  brewer@vbrew.com
</literal>, the rule would match, and on the righthand side
<literal moreinfo="none">$1</literal> would be substituted with <literal moreinfo="none">Head
Brewer</literal> and <literal moreinfo="none">$2</literal> would be substituted with
<literal moreinfo="none">brewer@vbrew.com</literal>.</para><para>If the rule were applied to <literal moreinfo="none"> brewer@vbrew.com
</literal> the rule would match because <literal moreinfo="none">$*</literal>
matches <emphasis>zero</emphasis> or more tokens, and on the righthand
side <literal moreinfo="none">$1</literal> would be substituted with the empty string.</para></sect2><sect2><title>Ruleset Semantics</title><para><indexterm significance="normal" class="startofrange" id="ruleset.semantics"><primary>ruleset semantics (sendmail)</primary></indexterm>
<indexterm significance="normal" class="startofrange" id="sendmail.ruleset.semantics"><primary>sendmail</primary><secondary>ruleset semantics</secondary></indexterm>
Each of the <command moreinfo="none">sendmail</command> rulesets is called upon to
perform a different task in mail processing. When you are writing
rules, it is important to understand what each of the rulesets are
expected to do.  We'll look at each of the rulesets that the
<command moreinfo="none">m4</command> configuration scripts allow us to modify:</para><variablelist><varlistentry><term>LOCAL_RULE_3</term><listitem><para><indexterm significance="normal"><primary>LOCAL_RULE_3 sendmail ruleset</primary></indexterm>
Ruleset 3 is responsible for converting an address in an arbitrary
format into a common format that <command moreinfo="none">sendmail</command> will then
process.  The output format expected is the familiar looking
<replaceable>local-part</replaceable><literal moreinfo="none">@</literal><replaceable>host-domain-spec</replaceable>.</para><para>Ruleset 3 should place the hostname part of the converted address inside the
<literal moreinfo="none"></literal> and <literal moreinfo="none"></literal> characters to make parsing by later rulesets easier. Ruleset
3 is applied before <command moreinfo="none">sendmail</command> does any other processing
of an email address, so if you want <command moreinfo="none">sendmail</command> to gateway mail from some system
that uses some unusual address format, you should add a rule using the
<literal moreinfo="none">LOCAL_RULE_3</literal> macro to convert addresses into the common 
format.</para></listitem></varlistentry><varlistentry><term>LOCAL_RULE_0 and LOCAL_NET_CONFIG</term><listitem><para><indexterm significance="normal"><primary>LOCAL_RULE_0 sendmail ruleset</primary></indexterm>
<indexterm significance="normal"><primary>LOCAL_NET_CONFIG macro definition</primary></indexterm>
Ruleset 0 is applied to recipient addresses by <command moreinfo="none">sendmail</command>
after Ruleset 3. The <literal moreinfo="none">LOCAL_NET_CONFIG</literal> macro causes rules to
be inserted into the <emphasis>bottom half</emphasis> of Ruleset 0.</para><para>Ruleset 0 is expected to perform the delivery of the message to the recipient,
so it must resolve to a triple that specifies each of the mailer, host, and
user. The rules will be placed before any smart host definition you may
include, so if you add rules that resolve addresses appropriately, any address
that matches a rule will not be handled by the smart host. This is how we
handle the direct <command moreinfo="none">smtp</command> for the users on our local LAN in 
our example.</para></listitem></varlistentry><varlistentry><term>LOCAL_RULE_1 and LOCAL_RULE_2</term><listitem><para><indexterm significance="normal"><primary>LOCAL_RULE_1 sendmail ruleset</primary></indexterm>
<indexterm significance="normal"><primary>LOCAL_RULE_2 sendmail ruleset</primary></indexterm>
Ruleset 1 is applied to all sender addresses and Ruleset 2 is applied to all
recipient addresses. They are both usually empty.</para></listitem></varlistentry></variablelist><sect3><title>Interpreting the rule in our example</title><para>Our sample in <xref linkend="x-087-2-sendmail.rewrite.example"></xref> uses the
<literal moreinfo="none">LOCAL_NET_CONFIG</literal> macro to declare a local rule that
ensures that any mail within our domain is delivered directly using the
<command moreinfo="none">smtp</command> mailer. Now that we've looked at how rewrite rules
are constructed, we will be able to understand how this rule works. Let's take
another look at it.</para><example id="x-087-2-sendmail.rewrite.example"><title>Rewrite Rule from vstout.uucpsmtp.m4</title><screen format="linespecific">LOCAL_NET_CONFIG
# This rule ensures that all local mail is delivered using the
# smtp transport, everything else will go via the smart host.
R$*  @ $* .$m.  $*  $#smtp $@ $2.$m. $: $1  @ $2.$m.  $3</screen></example><para>We know that the <literal moreinfo="none">LOCAL_NET_CONFIG</literal> macro will cause the
rule to be inserted somewhere near the end of ruleset 0, but before any
smart host definition. We also know that ruleset 0 is the last ruleset to
be executed and that it should resolve to a three-tuple specifying the
mailer, user, and host.</para><para>We can ignore the two comment lines; they don't do anything useful. The rule
itself is the line beginning with <literal moreinfo="none">R</literal>. We know
that the <literal moreinfo="none">R</literal> is a <command moreinfo="none">sendmail</command> command and that
it adds this rule to the current ruleset, in this case ruleset
<literal moreinfo="none">0</literal>. Let's look at the lefthand side and the righthand side
in turn.</para><para>The lefthand side looks like: 
<literal moreinfo="none">$*  @ $* .$m.  $*</literal>.</para><para>Ruleset 0 expects  and  characters because it is fed by ruleset 3.
Ruleset 3 converts addresses into a common form and to make parsing easier,
it also places the host part of the mail address inside s.</para><para>This rule matches any mail address that looks like:
<literal moreinfo="none">'DestUser  @ somehost.ourdomain.  Some Text'</literal>. That is, it matches mail for any user at any host within our domain.</para><para>You will remember that the text matched by metasymbols on the lefthand
side of a rewrite rule is assigned to macro definitions for use on the
righthand side. In our example, the first <literal moreinfo="none">$*</literal> matches 
all text from the start of the address until the  character.
All of this text is assigned to <literal moreinfo="none">$1</literal> for use on
the righthand side. Similarly the second <literal moreinfo="none">$*</literal> in our
rewrite rule is assigned to <literal moreinfo="none">$2</literal>, and the last is 
assigned to <literal moreinfo="none">$3</literal>.</para><para>We now have enough to understand the lefthand side. This rule matches
mail for any user at any host within our domain. It assigns the username to
$1, the hostname to <literal moreinfo="none">$2</literal>, and any trailing text to 
<literal moreinfo="none">$3</literal>. The righthand side is then invoked to process these.</para><para>Let's now look at what we're expecting to see outputed. The righthand side of
our example rewrite rule looks like:

<literal moreinfo="none">$#smtp $@ $2.$m. $: $1  @ $2.$m.  $3</literal>.</para><para>When the righthand side of our ruleset is processed, each of the metasymbols
are interpreted and relevant substitutions are made.</para><para>The <literal moreinfo="none">$#</literal> metasymbol causes this rule to resolve
to a specific mailer, <emphasis>smtp</emphasis> in our case.</para><para>The <literal moreinfo="none">$@</literal> resolves the target host. In our example,
the target host is specified as <literal moreinfo="none">$2.$m.</literal>, which
is the fully qualified domain name of the host on in our domain. The FQDN is
constructed of the hostname component assigned to 
<literal moreinfo="none">$2</literal> from our lefthand side with our domain
name (<literal moreinfo="none">.$m.</literal>) appended.</para><para>The <literal moreinfo="none">$:</literal> metasymbol specifies the target user,
which we again captured from the lefthand side and had stored in 
<literal moreinfo="none">$1</literal>.</para><para>We preserve the contents of the  section, and any
trailing text, using the data we collected from the lefthand side of the
rule.</para><para>Since this rule resolves to a mailer, the message is forwarded to the mailer
for delivery. In our example, the message would be forwarded to the destination
host using the SMTP protocol.</para></sect3></sect2><indexterm significance="normal" class="endofrange" startref="ruleset.semantics"></indexterm><indexterm significance="normal" class="endofrange" startref="sendmail.ruleset.semantics"></indexterm><indexterm significance="normal" class="endofrange" startref="sendmail.rewrite.rules"></indexterm><indexterm significance="normal" class="endofrange" startref="rewrite.rules"></indexterm></sect1><sect1><title>Configuring sendmail Options</title><para><indexterm significance="normal" class="startofrange" id="sendmail.config.options"><primary>sendmail</primary><secondary>options, configuring</secondary></indexterm>
<command moreinfo="none">sendmail</command> has a number of options that allow you to
customize the way it performs certain tasks. There are a large number of
these, so we've listed only a few of the more commonly used ones in
the upcoming list.</para><para><indexterm significance="normal"><primary>m4 macro processor</primary><secondary>configuring sendmail options</secondary></indexterm>
<indexterm significance="normal"><primary>sendmail.cf file</primary><secondary>configuring sendmail options</secondary></indexterm>
To configure any of these options, you may either define them in the
<command moreinfo="none">m4</command> configuration file, which is the preferable method,
or you may insert them directly into the <filename moreinfo="none">sendmail.cf</filename>
file. For example, if we wished to have <command moreinfo="none">sendmail</command> fork
a new job for each mail message to be delivered, we might add the following
line to our <command moreinfo="none">m4</command> configuration file:

<screen format="linespecific">define(confSEPARATE_PROC,true)</screen></para><para>The corresponding <filename moreinfo="none">sendmail.cf</filename> entry created is:

<screen format="linespecific">O ForkEachJob=true</screen></para><para><?troff .hw equivalents?><indexterm significance="normal"><primary>sendmail</primary><secondary>m4 options</secondary></indexterm>
The following list describes common <emphasis>sendmail m4</emphasis> options (and
<filename moreinfo="none">sendmail.cf</filename> equivalents):</para><variablelist id="x-087-2-sendmail.common.options"><varlistentry><term><literal moreinfo="none">confMIN_FREE_BLOCKS</literal>
<literal moreinfo="none">(MinFreeBlocks)</literal></term><listitem><para> There are
occasions when a problem might prevent the immediate delivery of mail
messages, causing messages to be queued in the mail spool. If your
mail host processes large volumes of mail, it is possible for the mail
spool to grow to such a size that it fills the filesystem supporting
the spool.  To prevent this, <command moreinfo="none">sendmail</command> provides this
option to specify the minimum number of free disk blocks that must
exist before a mail message will be accepted. This allows you to
ensure that <command moreinfo="none">sendmail</command> never causes your spool
filesystem to be filled (Default: 100).  </para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">confME_TOO</literal> <literal moreinfo="none">(MeToo)</literal></term><listitem><para>When a mail target such as an email alias is expanded, it is sometimes 
possible for the sender to appear in the
recipient list. This option determines whether the originators of an
email message will receive a copy if they appear in the expanded
recipient list. Valid values are true and
false (Default: false).</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">confMAX_DAEMON_CHILDREN</literal> <literal moreinfo="none">(MaxDaemonChildren)</literal></term><listitem><para>Whenever <command moreinfo="none">sendmail</command> receives an SMTP connection
from a remote host, it spawns a new copy of itself to deal with the
incoming mail message. This way, it is possible for
<command moreinfo="none">sendmail</command> to be processing multiple incoming mail messages
simulatanenously. While this is useful, each new copy of
<command moreinfo="none">sendmail</command> consumes memory in the host computer. If
an unusually large number of incoming connections are received,
by chance, because of a problem or a malicious attack, it
is possible for <command moreinfo="none">sendmail</command> daemons to consume all
system memory. This option provides you with a means of limiting the
maximum number of daemon children that will be spawned. When this
number is reached, new connections are rejected until some of
the existing children have terminated
(Default: undefined).</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">confSEPARATE_PROC</literal> <literal moreinfo="none">(ForkEachJob)</literal></term><listitem><para>When processing the mail queue and sending mail messages,
<command moreinfo="none">sendmail</command> processes one mail message at a time. When this
option is enabled, <command moreinfo="none">sendmail</command> will fork a new copy of
itself for each message to be delivered. This is particularly useful
when there are some mail messages that are stuck in the queue because
of a problem with the target host
(Default: false).</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">confSMTP_LOGIN_MSG</literal> <literal moreinfo="none">(SmtpGreetingMessage)</literal></term><listitem><para>Whenever a connection is made to <command moreinfo="none">sendmail</command>, a
greeting message is sent. By default, this message contains the hostname,
name of the mail transfer agent, the sendmail version number, the local
version number, and the current date. RFC821 specifies that the first word
of the greeting should be the fully qualified domain name of the host, but
the rest of the greeting can be configured however you please. You can specify
sendmail macros here and they will be expanded when used. The only people
who will see this message are suffering system administrators diagnosing
mail delivery problems or strongly curious people interested in discovering
how your machine is configured. You can relieve some of the tedium of their
task by customizing the welcome message with some witticisms; be nice.
The word EMSTP will be inserted between the first and second
words by <command moreinfo="none">sendmail</command>, as this is the signal to remote hosts
that we support the ESMTP protocol
(Default: <literal moreinfo="none">$j Sendmail $v/$Z; $b</literal>).</para></listitem></varlistentry></variablelist><indexterm significance="normal" class="endofrange" startref="sendmail.config.options"></indexterm></sect1><sect1><title>Some Useful sendmail Configurations</title><para><indexterm significance="normal" class="startofrange" id="sendmail.configs"><primary>sendmail</primary><secondary>important configurations</secondary></indexterm>
There are myriad possible <command moreinfo="none">sendmail</command> configurations.
In this space we'll illustrate just a few important types of configuration
that will be useful in many <command moreinfo="none">sendmail</command> installations.</para><sect2><title>Trusting Users to Set the From: Field</title><para>It is sometimes useful to overwrite the <literal moreinfo="none">From:</literal> field of
an outgoing mail message. Let's say you have a web-based program that 
generates email. Normally the
mail message would appear to come from the user who owned the web server
process. We might want to specify some other source address so that the mail
appears to have originated from some other user or address on that machine.
<command moreinfo="none">sendmail</command> provides a means of specifying which systems
users are to be entrusted with the ability to do this.</para><para>The <literal moreinfo="none">use_ct_file</literal> feature enables the specification and
use of a file that lists the names of trusted users. By default, a small
number of system users are trusted by <command moreinfo="none">sendmail</command>
(<literal moreinfo="none">root</literal>, for example). The default filename for this feature
is <filename moreinfo="none">/etc/mail/trusted-users</filename> in systems exploiting the
<filename moreinfo="none">/etc/mail/</filename> configuration directory and
<filename moreinfo="none">/etc/sendmail.ct</filename> in those that don't. You can specify
the name and location of the file by overriding the
<literal moreinfo="none">confCT_FILE</literal> definition.</para><para>Add FEATURE(use_ct_file) to your 
<filename moreinfo="none">sendmail.mc</filename> file to enable the feature.</para></sect2><sect2><title>Managing Mail Aliases</title><para><indexterm significance="normal"><primary>email</primary><secondary>aliases</secondary></indexterm>
<indexterm significance="normal"><primary>aliases</primary><secondary>email</secondary></indexterm>
<indexterm significance="normal"><primary>sendmail</primary><secondary>managaing email aliases</secondary></indexterm>
Mail aliases are a powerful feature that enable mail to be directed to
mailboxes that are alternate names for users or processes on a
destination host. For example, it is common practice to have feedback
or comments relating to a World Wide Web server to be directed to
webmaster. Often there isn't a user known as
webmaster on the target machine, instead it is an alias
of another system user. Another common use of mail aliases is
exploited by mailing list server programs in which an alias directs
incoming messages to the list server program for handling.</para><para><indexterm significance="normal"><primary>/etc/aliases file</primary></indexterm>
The <filename moreinfo="none">/etc/aliases</filename> file is where the aliases are stored.
The <command moreinfo="none">sendmail</command> program consults this file when determining
how to handle an incoming mail message. If it finds an entry in this file
matching the target user in the mail message, it redirects the message to
wherever the entry describes.</para><para>Specifically there are three things that aliases allow to happen:

<itemizedlist><listitem><para>They provide a shorthand or well-known name for mail to be addressed to in
order to go to one or more persons.</para></listitem><listitem><para><?troff .hw program?>They can invoke a program with the mail message as the input to the program.</para></listitem><listitem><para>They can send mail to a file.</para></listitem></itemizedlist></para><para><?troff .hw compliant?>All systems require aliases for
<systemitem moreinfo="none" role="userid">Postmaster</systemitem> and
<systemitem moreinfo="none" role="userid">MAILER-DAEMON</systemitem> to be RFC-compliant.</para><para>Always be extremely aware of security when defining aliases that invoke
programs or write to programs, since <command moreinfo="none">sendmail</command> generally
runs with <systemitem moreinfo="none" role="userid">root</systemitem> permissions.</para><para>Details concerning mail aliases may be found in the
<filename moreinfo="none">aliases(5)</filename> manual page. A sample
<filename moreinfo="none">aliases</filename> file is shown
in <xref linkend="x-087-2-samp.alias.fig"></xref>.</para><example id="x-087-2-samp.alias.fig"><title>Sample aliases File</title><screen format="linespecific">#
# The following two aliases must be present to be RFC-compliant.
# It is important to resolve them to 'a person' who reads mail routinely.
#
postmaster:    root                            # required entry
MAILER-DAEMON: postmaster                      # required entry
#
#
# demonstrate the common types of aliases
#
usenet:        janet                           # alias for a person
admin:         joe,janet                       # alias for several people
newspak-users: :include:/usr/lib/lists/newspak # read recipients from file
changefeed:    |/usr/local/lib/gup             # alias that invokes program
complaints:    /var/log/complaints             # alias writes mail to file
#</screen></example><?troff .Nd 10?><para>Whenever you update the <filename moreinfo="none">/etc/aliases</filename> file, be
sure to run the command:

<screen format="linespecific"># <userinput moreinfo="none">/usr/bin/newaliases</userinput></screen>

to rebuild the database that <command moreinfo="none">sendmail</command> uses internally.
The <command moreinfo="none">/usr/bin/newaliases</command> command is a symbolic link to the
<command moreinfo="none">sendmail</command> executable, and when invoked this way,
behaves exactly as though it were invoked as:

<screen format="linespecific"># <userinput moreinfo="none">/usr/lib/sendmail -bi</userinput></screen>

The <command moreinfo="none">newaliases</command> command is an alternative and more
convenient way to do this.</para></sect2><sect2><title>Using a Smart Host</title><para><indexterm significance="normal"><primary>smart host configurations</primary></indexterm>
<indexterm significance="normal"><primary>sendmail</primary><secondary>smart host configurations</secondary></indexterm>
Sometimes a host finds mail that it is unable to deliver directly to
the desired remote host. It is often convenient to have a single host on a
network take on the role of managing transmission of mail to remote hosts
that are difficult to reach, rather than have each local host try to do this
independently.</para><para>There are a few good reasons to have a single host take on mail
management.  You can simplify management by having only one host 
with a comprehensive mail configuration that knows how to handle all
of the different mail transport types, such as UUCP, Usenet, etc. All
other hosts need only a single tranport protocol to send their mail to
this central host. Hosts that fill this central mail routing and
forwarding role are called <emphasis>smart hosts</emphasis>.  If you
have a smart host that will accept mail from you, you can send it mail
of any sort and it will manage the routing and transmission of that
mail to the desired remote destinations.</para><para>Another good application for smart host configurations is to manage
transmission of mail across a private firewall. An organization may
elect to install a private IP network and use their own,
unregistered IP addresses.  The private network may be connected to
the Internet through a firewall.  Sending mail to and from hosts in
the private network to the outside world using SMTP would not be
possible in a conventional configuration because the hosts are not
able to accept or establish direct network connections to hosts on the
Internet. Instead, the organization could elect to have the firewall
provide a mail smart host function. The smart host running on the
firewall is able to establish direct network connections with hosts
both on the private network and on the Internet. The smart host would
accept mail from both hosts on the private network and the Internet,
store them in local storage and then manage the retransmission of that
mail to the correct host directly.</para><para>Smart hosts are usually used when all other methods of delivery have
failed.  In the case of the organization with the private network, it
would be perfectly reasonable to have the hosts attempt to deliver
mail directly first, and if that fails then to send it to the smart
host. This relieves the smart host of a lot of traffic because other
hosts can directly send mail to other hosts on the private network.</para><para><indexterm significance="normal"><primary>SMART_HOST macro</primary></indexterm>
<command moreinfo="none">sendmail</command> provides a simple method of configuring
a smart host using the <literal moreinfo="none">SMART_HOST</literal> feature; when 
implementing it in the Virtual Brewery configuration, we do exactly this. The 
relevant portions of our configuration that define the smart host are:

<screen format="linespecific">define(`SMART_HOST', `uucp-new:moria')
LOCAL_NET_CONFIG
# This rule ensures that all local mail is delivered using the
# smtp transport, everything else will go via the smart host.
R$*  @ $* .$m.  $*	$#smtp $@ $2.$m. $: $1  @ $2.$m.  $3</screen></para><para>The <literal moreinfo="none">SMART_HOST</literal> macro allows you to specify the host that
should relay all outgoing mail that you are unable to deliver directly,
and the mail transport protocol to use to talk to it.</para><para>In our configuration we are using the <literal moreinfo="none">uucp-new</literal> transport
to UUCP host <emphasis role="bold">moria</emphasis>. If we wanted to configure
<command moreinfo="none">sendmail</command> to use an SMTP-based Smart Host, we would instead
use something like:

<screen format="linespecific">
define(`SMART_HOST', `mail.isp.net')</screen>

We don't need to specify SMTP as the transport, as it is the default.</para><para>Can you guess what the <literal moreinfo="none">LOCAL_NET_CONFIG</literal> macro and the
rewrite rule might be doing?</para><para>The <literal moreinfo="none">LOCAL_NET_CONFIG</literal> macro allows you to add raw
<command moreinfo="none">sendmail</command> rewrite rules to your configuration that define
what mail should stay within the local mail system. In our example, we've used 
a rule that matches any email address where the host belongs to our
domain (<literal moreinfo="none">.$m.</literal>) and rewrite it so that it is sent directly 
to the <literal moreinfo="none">SMTP</literal> mailer.
This ensures that any message for a host on our local domain is directed
immediately to the SMTP mailer and forwarded to that host, rather than falling
through to our smart host, which is the default treatment.</para></sect2><sect2><title>Managing Unwanted or Unsolicited Mail (Spam)</title><para><indexterm significance="normal" class="startofrange" id="sendmail.spam"><primary>spamming</primary></indexterm>
<indexterm significance="normal" class="startofrange" id="unsol.mail.managing"><primary>unsolicited mail, managing</primary></indexterm>
<indexterm significance="normal" class="startofrange" id="email.unsolicited"><primary>email</primary><secondary>unsolicited</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="email.manag.spam"><primary>email</primary><secondary>managing spam</secondary></indexterm>
If you've subscribed to a mailing list, published your email address on a
web site, or posted an article to UseNet, you will most likely have
begun to receive unsolicited advertising email. It is commonplace now
for people to scour the net in search of email addresses to add to mailing
lists that they then sell to companies seeking to advertise their products.
This sort of mass-mailing behavior is commonly called spamming. </para><?troff .Nd 15?><para>The Free
On-line Dictionary of Computing offers a mail-specific definition of 
spam as:<footnote id="x-087-2-fnsd01"><para>The Free On-Line 
Dictionary of Computing can be found packaged in many Linux
distributions, or online at its home page at
<systemitem moreinfo="none" role="url">http://wombat.doc.ic.ac.uk/foldoc/</systemitem>.</para></footnote>
</para><blockquote><para>2. (A narrowing of sense 1, above) To indiscrimately send large amounts of
unsolicited e-mail meant to promote a product or service. Spam in this sense
is sort of like the electronic equivalent of junk mail sent to "Occupant."</para><para>In the 1990s, with the rise in commercial awareness of the net, there are
actually scumbags who offer spamming as a "service" to companies wishing to
advertise on the net. They do this by mailing to collections of e-mail
addresses, Usenet news, or mailing lists.  Such practises have caused outrage
and aggressive reaction by many net users against the individuals concerned.</para></blockquote><para>Fortunately, <command moreinfo="none">sendmail</command> includes some support for mechanisms
that can help you deal with unsolicited mail.</para><sect3><title>The Real-time Blackhole List</title><para><indexterm significance="normal"><primary>Real-time Blackhole List (RBL)</primary></indexterm>
The Real-time Blackhole List is a public facility provided to help reduce the
volume of unsolicited advertising you have to contend with. Known email
sources and hosts are listed in a queryable database on the Internet. They're
entered there by people who have received unsolicited advertising from some
email address. Major domains sometimes find themselves on the list because of 
slip-ups in shutting down spam. While some people complain about 
particular choices made by the maintainers of the list, it remains 
very popular and disagreements are usually worked out quickly. Full details 
on how the service is operated may be found
from the home site of the Mail Abuse Protection System at
<emphasis>http://maps.vix.com/rbl/</emphasis>.</para><para>If you enable this <command moreinfo="none">sendmail</command> feature, it will test the source
address of each incoming mail message against the Real-time Blackhole List to
determine whether to accept the message. If you run a large site
with many users, this feature could save a considerable volume of disk space.
This feature accepts a parameter to specify the name of the
server to use. The default is the main server at
<systemitem moreinfo="none" role="sitename">rbl.maps.vix.com</systemitem>.</para><para>To configure the Real-time Blackhole List feature, add the following
macro declaration to your <filename moreinfo="none">sendmail.mc</filename> file:

<screen format="linespecific">FEATURE(rbl)</screen></para><para>Should you wish to specify some other RBL server, you would use a
declaration that looks like:

<screen format="linespecific">FEATURE(rbl,`rbl.host.net')</screen></para></sect3><sect3 id="x-087-2-sendmail.accessdb"><title>The access database</title><para><indexterm significance="normal"><primary>sendmail</primary><secondary>access database</secondary></indexterm>
<indexterm significance="normal"><primary>access_db feature (sendmail)</primary></indexterm>
An alternative system that offers greater flexibility and control at
the cost of manual configuration is the <command moreinfo="none">sendmail</command>
<systemitem moreinfo="none" role="keyword">access_db</systemitem> feature. The access
database allows you to configure which hosts or users you will accept
mail from and which you will relay mail for.</para><para>Managing who you will relay mail for is important, as it is another technique
commonly employed by spamming hosts to circumvent systems such as the Real-time
Blackhole List just described. Instead of sending the mail to you directly,
spammers will relay the mail via some other unsuspecting host who allows it.
The incoming SMTP connection then doesn't come from the known spamming host,
it instead comes from the relay host. To ensure that your own mail hosts
aren't used in this way, you should relay mail only for known hosts. Versions
of <command moreinfo="none">sendmail</command> that are 8.9.0 or newer have
relaying disabled by default, so for those you'll need to use the access
database to enable individual hosts to relay.</para><para>The general idea is simple. When a new incoming SMTP connection is received,
<command moreinfo="none">sendmail</command> retrieves the message header information and then
consults the access database to see whether it should proceed to accept
the body of the message itself.</para><para>The access database is a collection of rules that describe what action should
be taken for messages received from nominated hosts. The default access control
file is called <filename moreinfo="none">/etc/mail/access</filename>. The table has a simple
format. Each line of the table contains an access rule. The lefthand side of
each rule is a pattern used to match the sender of an incoming mail message.
It may be a complete email address, a hostname, or an IP address. The 
righthand side is the action to take. There are five types of action you may
configure. These are:</para><variablelist><varlistentry><term>OK</term><listitem><para>Accept the mail message.</para></listitem></varlistentry><varlistentry><term>RELAY</term><listitem><para>Accept messages from this host or user even if they are not destined
for our host; that is, accept messages for relaying to other hosts from
this host.</para></listitem></varlistentry><varlistentry><term>REJECT</term><listitem><para>Reject the mail with a generic message.</para></listitem></varlistentry><varlistentry><term>DISCARD</term><listitem><para>Discard the message using the <literal moreinfo="none">$#discard</literal> mailer.</para></listitem></varlistentry><varlistentry><term>### any text</term><listitem><para>Return an error message using <replaceable>###</replaceable> as
the error code (which should be RFC-821 compliant) and any
text as the message.</para></listitem></varlistentry></variablelist><?troff .Nd 15?><para>An example <filename moreinfo="none">/etc/mail/access</filename> might look like:

<screen format="linespecific">friends@cybermail.com   REJECT
aol.com                 REJECT
207.46.131.30           REJECT
postmaster@aol.com      OK
linux.org.au            RELAY</screen></para><para>This example would reject any email received from
<systemitem moreinfo="none" role="email">friends@cybermail.com</systemitem>,
any host in the domain <emphasis role="bold">aol.com</emphasis>
and the host <emphasis role="bold">207.46.131.30</emphasis>.
The next rule would accept email from
<systemitem moreinfo="none" role="email">postmaster@aol.com</systemitem> despite the fact
that the domain itself has a reject rule. The last rule allows relaying
of mail from any host in the
<emphasis role="bold">linux.org.au</emphasis> domain.</para><para>To enable the access database feature, use the following declaration in your
<filename moreinfo="none">sendmail.mc</filename> file:

<screen format="linespecific">FEATURE(access_db)</screen></para><para>The default definition builds the database using
<literal moreinfo="none">hash -o /etc/mail/access</literal>, which generates
a simple hashed database from the plain text file. This is perfectly adequate
in most installations. There are other options that you should consider if
you intend to have a large access database. Consult the <emphasis>sendmail</emphasis> book or
other <command moreinfo="none">sendmail</command> documentation for details.</para></sect3><sect3><title>Barring users from receiving mail</title><para><indexterm significance="normal"><primary>email</primary><secondary>barring users from receiving</secondary></indexterm>
<indexterm significance="normal"><primary>blacklist_recipients feature (sendmail)</primary></indexterm>
If you have users or automated processes that send mail but will never
need to receive it, it is sometimes useful to refuse to accept mail destined
for them. This saves wasted disk-space storing mail that will never be
read. The <systemitem moreinfo="none" role="keyword">blacklist_recipients</systemitem>
feature, when used in combination with the
<systemitem moreinfo="none" role="keyword">access_db</systemitem> feature, allows you to
disable the receipt of mail for local users.</para><para>To enable the feature, you add the following lines to your
<filename moreinfo="none">sendmail.mc</filename> file, if they're not already there:

<screen format="linespecific">FEATURE(access_db)
FEATURE(blacklist_recipients)</screen></para><para>To disable receipt of mail for a local user, simply add his details
into the access database. Usually you would use the
<replaceable>###</replaceable> entry style that would return a
meaningful error message to the sender so they know why the mail is
not being delivered. This feature applies equally well to users in
virtual mail domains, and you must include the virtual mail domain
in the access database specification. Some sample
<filename moreinfo="none">/etc/mail/access</filename> entries might look like:

<screen format="linespecific">daemon          550 Daemon does not accept or read mail.
flacco          550 Mail for this user has been administratively disabled.
grump@dairy.org 550 Mail disabled for this recipient.</screen></para></sect3><indexterm significance="normal" class="endofrange" startref="sendmail.spam"></indexterm><indexterm significance="normal" class="endofrange" startref="unsol.mail.managing"></indexterm><indexterm significance="normal" class="endofrange" startref="email.unsolicited"></indexterm><indexterm significance="normal" class="endofrange" startref="email.manag.spam"></indexterm></sect2><sect2><title>Configuring Virtual Email Hosting</title><para><indexterm significance="normal"><primary>email</primary><secondary>virtual hosting</secondary></indexterm>
<indexterm significance="normal"><primary>sendmail</primary><secondary>virtual email hosting</secondary></indexterm>
Virtual email hosting provides a host the capability of accepting and
delivering mail on behalf of a number of different domains as though it were
a number of separate mail hosts. Most commonly, virtual hosting is exploited by
Internet Application Providers in combination with virtual web hosting, but
it's simple to configure and you never know when you might be in a position to
virtual host a mailing list for your favorite Linux project, so we'll
describe it here.</para><sect3><title>Accepting mail for other domains</title><para><indexterm significance="normal"><primary>virtual email hosting</primary><secondary>accepting mail for other domains</secondary></indexterm>
When <command moreinfo="none">sendmail</command> receives an email message, it compares the
destination host in the message headers to the local host name. If they
match, <command moreinfo="none">sendmail</command> accepts the message for local delivery;
if they differ, <command moreinfo="none">sendmail</command> may decide to accept the message
and attempt to forward it on to the final destination (See
<xref linkend="x-087-2-sendmail.accessdb"></xref> earlier in this chapter for details on how to configure
<command moreinfo="none">sendmail</command> to accept mail for forwarding).</para><para>If we wish to configure virtual email hosting, the first thing we need to do
is to convince <command moreinfo="none">sendmail</command> that it should also accept mail
for the domains that we are hosting. Fortunately, this is a very simple thing
to do.</para><para>The <command moreinfo="none">sendmail</command>
<systemitem moreinfo="none" role="keyword">use_cw_file</systemitem> feature allows us to
specify the name of a file where we store domain names for which 
<command moreinfo="none">sendmail</command> accepts mail. To configure the feature, add the 
feature declaration to your <filename moreinfo="none">sendmail.mc</filename> file:

<screen format="linespecific">FEATURE(use_cw_file)</screen></para><para>The default name of the file will be
<filename moreinfo="none">/etc/mail/local-host-names</filename> for distributions using
the <filename moreinfo="none">/etc/mail/</filename> configuration directory or
<filename moreinfo="none">/etc/sendmail.cw</filename> for those that don't. Alternatively,
you can specify the name and location of the file by overriding the
<literal moreinfo="none">confCW_FILE</literal> macro using a variation on:

<screen format="linespecific">define(`confCW_FILE',`/etc/virtualnames')</screen></para><para>To stick with the default filename, if we wished to offer virtual hosting to 
the <emphasis role="bold">bovine.net</emphasis>, <emphasis role="bold">dairy.org</emphasis>, and
<emphasis role="bold">artist.org</emphasis> domains, we would create a
<filename moreinfo="none">/etc/mail/local-host-names</filename> that looks like:

<screen format="linespecific">bovine.net
dairy.org
artist.org</screen></para><para>When this is done, and assuming appropriate DNS records exist that point those
domain names to our host, <command moreinfo="none">sendmail</command> will accept mail
messages for those domains as though they were destined for our real domain
name.</para></sect3><sect3><title>Forwarding virtual-hosted mail to other destinations</title><para><indexterm significance="normal"><primary>virtual email hosting</primary><secondary>forwarding mail to other destinations</secondary></indexterm>
<indexterm significance="normal"><primary>sendmail</primary><secondary>virtusertable feature</secondary></indexterm>
<indexterm significance="normal"><primary>virtusertable feature (sendmail)</primary></indexterm>
The <command moreinfo="none">sendmail</command>
<systemitem moreinfo="none" role="keyword">virtusertable</systemitem> feature configures
support for the virtual user table, where we configure virtual
email hosting. The virtual user table maps incoming mail destined for some 
<emphasis>user@host</emphasis> to some <emphasis>otheruser@otherhost</emphasis>.
You can think of this as an advanced mail alias feature, one that operates
using not just the destination user, but also the destination domain.</para><para>To configure the <systemitem moreinfo="none" role="keyword">virtusertable</systemitem>
feature, add the feature to your <filename moreinfo="none">sendmail.mc</filename>
configuration as shown:

<screen format="linespecific">FEATURE(virtusertable)</screen></para><para>By default, the file containing the rules to perform translations will be
<filename moreinfo="none">/etc/mail/virtusertable</filename>. You can override this by
supplying an argument to the macro definition; consult a
detailed <command moreinfo="none">sendmail</command> reference to learn about what options
are available.</para><para>The format of the virtual user table is very simple. The lefthand side of
each line contains a pattern representing the original destination mail
address; the righthand side has a pattern representing the mail address the
virtual hosted address will be mapped to.</para><para>The following example shows three possible types of entries:

<screen format="linespecific">samiam@bovine.net     colin
sunny@bovine.net      darkhorse@mystery.net
@dairy.org            mail@jhm.org
@artist.org           $1@red.firefly.com</screen>

In this example, we are virtual hosting three domains:
<emphasis role="bold">bovine.net</emphasis>, <emphasis role="bold">dairy.org</emphasis>, and
<emphasis role="bold">artist.org</emphasis>.</para><para>The first entry redirects mail sent to a user in the
<emphasis role="bold">bovine.net</emphasis> virtual domain to a local
user on the machine. The second entry redirects mail to a user in the same
virtual domain to a user in another domain. The third example redirects all
mail addressed to any user in the <emphasis role="bold">dairly.org</emphasis> virtual
domain to a single remote mail address. Finally, the last entry redirects
any mail to a user in the <emphasis role="bold">artist.org</emphasis> virtual domain to
the same user in another domain; for example,
<systemitem moreinfo="none" role="email">julie@artists.org</systemitem> would be redirected to
<systemitem moreinfo="none" role="email">julie@red.firefly.com</systemitem>.</para></sect3></sect2><indexterm significance="normal" class="endofrange" startref="sendmail.configs"></indexterm></sect1><sect1><title>Testing Your Configuration</title><para><indexterm significance="normal" class="startofrange" id="sendmail.testing.config"><primary>sendmail</primary><secondary>testing the configuration</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="testing.sendmail.config"><primary>testing</primary><secondary>sendmail configuration</secondary></indexterm>
The <command moreinfo="none">m4</command> command processes the macro definition files
according to its own syntax rules without understanding anything about correct
<command moreinfo="none">sendmail</command> syntax; so there won't be any error messages if
you've gotten anything wrong in your macro definition file. For this reason,
it is very important that you thoroughly test your configuration. Fortunately,
<command moreinfo="none">sendmail</command> provides a relatively easy way of doing this.</para><para><command moreinfo="none">sendmail</command> supports an address test mode that 
allows us to test our configuration and identify any errors. In this mode
of operation, we invoke <command moreinfo="none">sendmail</command> from the command line,
and it prompts us for a ruleset specification and a destination mail address.
<command moreinfo="none">sendmail</command> then processes that destination address using
the rules specified, displaying the output of each rewrite rule as it proceeds.
To place <command moreinfo="none">sendmail</command> into this mode, we invoke it with the
<literal moreinfo="none">bt</literal> argument: </para><screen format="linespecific"># <userinput moreinfo="none">/usr/sbin/sendmail -bt</userinput>
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter ruleset address
</screen><para>The default configuration file used is the
<filename moreinfo="none">/etc/mail/sendmail.cf</filename> file; you can specify an alternate
configuration file using the <literal moreinfo="none">C</literal> argument. To test our configuration, we need to select a number of addresses to process
that will tell us that each of our mail-handing requirements are met. To
illustrate this, we'll work through a test of our more complicated UUCP
configuration shown in <xref linkend="x-087-2-sendmail.mc.uucpsmtp"></xref>.</para><para>First we'll test that <command moreinfo="none">sendmail</command> is able to deliver mail to
local users on the system. In these tests we expect all addresses to be
rewritten to the <emphasis role="bold">local</emphasis> mailer on this machine:</para><screen format="linespecific"># <userinput moreinfo="none">/usr/sbin/sendmail -bt</userinput>
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter ruleset address
 <userinput moreinfo="none">3,0 isaac</userinput>
rewrite: ruleset   3   input: isaac
rewrite: ruleset  96   input: isaac
rewrite: ruleset  96 returns: isaac
rewrite: ruleset   3 returns: isaac
rewrite: ruleset   0   input: isaac
rewrite: ruleset 199   input: isaac
rewrite: ruleset 199 returns: isaac
rewrite: ruleset  98   input: isaac
rewrite: ruleset  98 returns: isaac
rewrite: ruleset 198   input: isaac
rewrite: ruleset 198 returns: $# local $: isaac
rewrite: ruleset   0 returns: $# local $: isaac</screen><para>This output shows us how <command moreinfo="none">sendmail</command> processes mail addressed
to <emphasis role="bold">isaac</emphasis> on this system. Each line shows us what information
has been supplied to a ruleset or the result obtained from processing by a
ruleset. We told <command moreinfo="none">sendmail</command> we wished to use rulesets 3 and
0 to process the address. Ruleset 0 is what is normally invoked and we forced
ruleset 3 because it is not tested by default. The last line shows us that
the result of ruleset 0 does indeed direct mail to <emphasis role="bold">isaac</emphasis> to the
<emphasis role="bold">local</emphasis> mailer.</para><?troff .Nd 15?><para>Next we'll test mail addressed to our SMTP address: <emphasis role="bold">isaac@vstout.vbrew.com</emphasis>. We should be able
to produce the same end result as our last example:</para><screen format="linespecific"># <userinput moreinfo="none">/usr/sbin/sendmail -bt</userinput>
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter ruleset address
 3,0 isaac@vstout.vbrew.com
rewrite: ruleset   3   input: isaac @ vstout . vbrew . com
rewrite: ruleset  96   input: isaac  @ vstout . vbrew . com 
rewrite: ruleset  96 returns: isaac  @ vstout . vbrew . com . 
rewrite: ruleset   3 returns: isaac  @ vstout . vbrew . com . 
rewrite: ruleset   0   input: isaac  @ vstout . vbrew . com . 
rewrite: ruleset 199   input: isaac  @ vstout . vbrew . com . 
rewrite: ruleset 199 returns: isaac  @ vstout . vbrew . com . 
rewrite: ruleset  98   input: isaac  @ vstout . vbrew . com . 
rewrite: ruleset  98 returns: isaac  @ vstout . vbrew . com . 
rewrite: ruleset 198   input: isaac  @ vstout . vbrew . com . 
rewrite: ruleset 198 returns: $# local $: isaac
rewrite: ruleset   0 returns: $# local $: isaac</screen><para>Again, this test passed. Next we'll test mail to our UUCP style address:
<emphasis role="bold">vstout!isaac</emphasis>.</para><screen format="linespecific"># <userinput moreinfo="none">/usr/sbin/sendmail -bt</userinput>
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter ruleset address
 3,0 vstout!isaac
rewrite: ruleset   3   input: vstout ! isaac
rewrite: ruleset  96   input: isaac  @ vstout . UUCP 
rewrite: ruleset  96 returns: isaac  @ vstout . vbrew . com . 
rewrite: ruleset   3 returns: isaac  @ vstout . vbrew . com . 
rewrite: ruleset   0   input: isaac  @ vstout . vbrew . com . 
rewrite: ruleset 199   input: isaac  @ vstout . vbrew . com . 
rewrite: ruleset 199 returns: isaac  @ vstout . vbrew . com . 
rewrite: ruleset  98   input: isaac  @ vstout . vbrew . com . 
rewrite: ruleset  98 returns: isaac  @ vstout . vbrew . com . 
rewrite: ruleset 198   input: isaac  @ vstout . vbrew . com . 
rewrite: ruleset 198 returns: $# local $: isaac
rewrite: ruleset   0 returns: $# local $: isaac</screen><para>This test has also passed. These tests confirm that any mail received
for local users on this machine will be properly delivered irrespective of
how the address is formatted. If you've defined any aliases for your machine, such as virtual hosts, you should repeat these tests for each of the
alternate names by which this host is known to ensure they also work correctly.</para><para>Next we will test that mail addressed to other hosts in the
<emphasis role="bold">vbrew.com</emphasis> domain is delivered
directly to that host using the SMTP mailer:</para><screen format="linespecific"># <userinput moreinfo="none">/usr/sbin/sendmail -bt</userinput>
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter ruleset address
 3,0 isaac@vale.vbrew.com
rewrite: ruleset   3   input: isaac @ vale . vbrew . com
rewrite: ruleset  96   input: isaac  @ vale . vbrew . com 
rewrite: ruleset  96 returns: isaac  @ vale . vbrew . com . 
rewrite: ruleset   3 returns: isaac  @ vale . vbrew . com . 
rewrite: ruleset   0   input: isaac  @ vale . vbrew . com . 
rewrite: ruleset 199   input: isaac  @ vale . vbrew . com . 
rewrite: ruleset 199 returns: isaac  @ vale . vbrew . com . 
rewrite: ruleset  98   input: isaac  @ vale . vbrew . com . 
rewrite: ruleset  98 returns: isaac  @ vale . vbrew . com . 
rewrite: ruleset 198   input: isaac  @ vale . vbrew . com . 
rewrite: ruleset 198 returns: $# smtp $@ vale . vbrew . com . /
    $: isaac  @ vale . vbrew . com . 
rewrite: ruleset   0 returns: $# smtp $@ vale . vbrew . com . /
    $: isaac  @ vale . vbrew . com . </screen><para>We can see that this test has directed the message to the SMTP mailer
to be forwarded directly to the <emphasis role="bold">vale.vbrew.com</emphasis> host and
specifies the user <emphasis role="bold">isaac</emphasis>. This test confirms that our
<literal moreinfo="none">LOCAL_NET_CONFIG</literal> definition works correctly. For
this test to succeed, the destination hostname must be able to be
resolved correctly, so it must either have an entry in our
<filename moreinfo="none">/etc/hosts</filename> file, or in our local DNS. We can see
what happens if the destination hostname isn't able to be resolved by
intentionally specifying an unknown host:</para><screen format="linespecific"># <userinput moreinfo="none">/usr/sbin/sendmail -bt</userinput>
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter ruleset address
 3,0 isaac@vXXXX.vbrew.com
rewrite: ruleset   3   input: isaac @ vXXXX . vbrew . com
rewrite: ruleset  96   input: isaac  @ vXXXX . vbrew . com 
vXXXX.vbrew.com: Name server timeout
rewrite: ruleset  96 returns: isaac  @ vXXXX . vbrew . com 
rewrite: ruleset   3 returns: isaac  @ vXXXX . vbrew . com 
== Ruleset 3,0 (3) status 75
rewrite: ruleset   0   input: isaac  @ vXXXX . vbrew . com 
rewrite: ruleset 199   input: isaac  @ vXXXX . vbrew . com 
rewrite: ruleset 199 returns: isaac  @ vXXXX . vbrew . com 
rewrite: ruleset  98   input: isaac  @ vXXXX . vbrew . com 
rewrite: ruleset  98 returns: isaac  @ vXXXX . vbrew . com 
rewrite: ruleset 198   input: isaac  @ vXXXX . vbrew . com 
rewrite: ruleset  95   input:  uucp-new : moria  isaac /
    @ vXXXX . vbrew . com 
rewrite: ruleset  95 returns: $# uucp-new $@ moria $: isaac /
    @ vXXXX . vbrew . com 
rewrite: ruleset 198 returns: $# uucp-new $@ moria $: isaac /
    @ vXXXX . vbrew . com 
rewrite: ruleset   0 returns: $# uucp-new $@ moria $: isaac /
    @ vXXXX . vbrew . com </screen><para>This result is very different. First, ruleset 3
returned an error message indicating the hostname could not be resolved.
Second, we deal with this situation by relying
on the other key feature of our configuration, the smart host. The smart host
will is to handle any mail that is otherwise undeliverable. The hostname
we specified in this test was unable to be resolved and the rulesets determined
that the mail should be forwarded to our smart host 
<emphasis role="bold">moria</emphasis> using
the <emphasis role="bold">uucp-new</emphasis> mailer. Our smart host might be better connected 
and know what to do with the address.</para><para>Our final test ensures that any mail addressed to a host not within our
domain is delivered to our smart host. This should produce a result similar
to our previous example:</para><screen format="linespecific"># <userinput moreinfo="none">/usr/sbin/sendmail -bt</userinput>
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter ruleset address
 3,0 isaac@linux.org.au
rewrite: ruleset   3   input: isaac @ linux . org . au
rewrite: ruleset  96   input: isaac  @ linux . org . au 
rewrite: ruleset  96 returns: isaac  @ linux . org . au . 
rewrite: ruleset   3 returns: isaac  @ linux . org . au . 
rewrite: ruleset   0   input: isaac  @ linux . org . au . 
rewrite: ruleset 199   input: isaac  @ linux . org . au . 
rewrite: ruleset 199 returns: isaac  @ linux . org . au . 
rewrite: ruleset  98   input: isaac  @ linux . org . au . 
rewrite: ruleset  98 returns: isaac  @ linux . org . au . 
rewrite: ruleset 198   input: isaac  @ linux . org . au . 
rewrite: ruleset  95   input:  uucp-new : moria  isaac /
    @ linux . org . au . 
rewrite: ruleset  95 returns: $# uucp-new $@ moria $: isaac /
    @ linux . org . au . 
rewrite: ruleset 198 returns: $# uucp-new $@ moria $: isaac /
    @ linux . org . au . 
rewrite: ruleset   0 returns: $# uucp-new $@ moria $: isaac /
    @ linux . org . au . </screen><para>The results of this test indicate that the hostname was resolved, and that the
message would still have been routed to our smart host. This proves that our
<literal moreinfo="none">LOCAL_NET_CONFIG</literal> definition works correctly and it handled
both cases correctly. This test was also successful, so we can happily assume
our configuration is correct and use it.</para><indexterm significance="normal" class="endofrange" startref="sendmail.testing.config"></indexterm><indexterm significance="normal" class="endofrange" startref="testing.sendmail.config"></indexterm></sect1><sect1><title>Running sendmail</title><para><indexterm significance="normal"><primary>sendmail</primary><secondary>running</secondary></indexterm>
The <command moreinfo="none">sendmail</command> daemon can be run in either of two
ways. One way is to have to have it run from the <command moreinfo="none">inetd</command>
daemon; the alternative, and more commonly used method is to run
<command moreinfo="none">sendmail</command> as a standalone daemon. It is also common for
mailer programs to invoke <command moreinfo="none">sendmail</command> as a user command
to accept locally generated mail for delivery.</para><para>When running <command moreinfo="none">sendmail</command> in standalone mode, place the command
in an <filename moreinfo="none">rc</filename> file so it starts at boot time. The syntax
used is commonly:

<screen format="linespecific">/usr/sbin/sendmail -bd -q10m</screen>

The <literal moreinfo="none">-bd</literal> argument tells <command moreinfo="none">sendmail</command> to run
as a daemon. It will fork and run in the background. The
<literal moreinfo="none">-q10m</literal> argument tells <command moreinfo="none">sendmail</command>
to check its queue every ten minutes. You may choose to use a different queue to check time.</para><para>To run <command moreinfo="none">sendmail</command> from the <command moreinfo="none">inetd</command> network
daemon, you'd use an entry like:

<screen format="linespecific">smtp  stream  tcp nowait  nobody  /usr/sbin/sendmail -bs</screen>

The <literal moreinfo="none">-bs</literal> argument here tells <command moreinfo="none">sendmail</command>
to use the SMTP protocol on stdin/stdout, which is required for use with
<command moreinfo="none">inetd</command>.</para><para>The <command moreinfo="none">runq</command> command is usually a symlink to the
<command moreinfo="none">sendmail</command> binary and is a more convenient form of:

<screen format="linespecific"># <userinput moreinfo="none">sendmail -q</userinput></screen></para><para>When <command moreinfo="none">sendmail</command> is invoked this way, it processes any mail
waiting in the queue to be transmitted. When running
<command moreinfo="none">sendmail</command> from <command moreinfo="none">inetd</command> you must also create
a <command moreinfo="none">cron</command> job that runs the <command moreinfo="none">runq</command> command
periodically to ensure that the mail spool is serviced periodically.</para><para>A suitable <command moreinfo="none">cron</command> table entry would be similar to:

<screen format="linespecific"># Run the mail spool every fifteen minutes
0,15,30,45     *     *     *     *     /usr/bin/runq</screen></para><para>In most installations <command moreinfo="none">sendmail</command> processes the queue
every 15 minutes as shown in our <filename moreinfo="none">crontab</filename> example,
attempting to transmit any messages there.</para></sect1><sect1><title>Tips and Tricks</title><para><indexterm significance="normal" class="startofrange" id="sendmail.mgmt.tools"><primary>sendmail</primary><secondary>management tools</secondary></indexterm>
There are a number of things you can do to make managing a
<command moreinfo="none">sendmail</command> site efficient. A number of management tools are
provided in the <command moreinfo="none">sendmail</command> package; let's look at the most
important of these.</para><sect2><title>Managing the Mail Spool</title><para><indexterm significance="normal"><primary>sendmail</primary><secondary>managing the mail spool</secondary></indexterm>
<indexterm significance="normal"><primary>mail spool, managing</primary></indexterm>
Mail is queued in the <filename moreinfo="none">/var/spool/mqueue</filename> directory
before being transmitted. This directory is called the mail spool.
The <command moreinfo="none">sendmail</command> program provides a means of displaying a
formatted list of all spooled mail messages and their status.</para><para>The <command moreinfo="none">/usr/bin/mailq</command> command is a symbolic link to the
<command moreinfo="none">sendmail</command> executable and behaves indentically to:

<screen format="linespecific"># <userinput moreinfo="none">sendmail -bp</userinput></screen>

The output displays the message ID, its size, the time it was placed in the
queue, who sent it, and a message indicating its current status. The following
example shows a mail message stuck in the queue with a  problem:

<screen format="linespecific">$ <userinput moreinfo="none">mailq</userinput>
                Mail Queue (1 request)
--Q-ID-- --Size-- -----Q-Time----- ------------Sender/Recipient------------
RAA00275      124 Wed Dec  9 17:47 root
                 (host map: lookup (tao.linux.org.au): deferred)
                                   terry@tao.linux.org.au</screen>

This message is still in the mail queue because the destination host
IP address could not be resolved.</para><para>We can force <command moreinfo="none">sendmail</command> to process the queue now by issuing
the <filename moreinfo="none">/usr/bin/runq</filename> command.</para><para>The <command moreinfo="none">runq</command> command produces no output.
<command moreinfo="none">sendmail</command> will begin processing the mail queue in the
background.</para></sect2><sect2><title>Forcing a Remote Host to Process its Mail Queue</title><para><indexterm significance="normal"><primary>email</primary><secondary>queue</secondary></indexterm>
<indexterm significance="normal"><primary>sendmail</primary><secondary>processing mail queues</secondary></indexterm>
If you use a temporary dial-up Internet connection with a
<emphasis>fixed</emphasis> IP address and rely on an MX host to collect your
mail while you are disconnected, you will find it useful to force the MX host
to process its mail queue soon after you establish your connection.</para><para>A small <command moreinfo="none">perl</command> program is included with the
<command moreinfo="none">sendmail</command> distribution that makes this simple for mail
hosts that support it. The <command moreinfo="none">etrn</command> script has much the same
effect on a remote host as the <command moreinfo="none">runq</command> command has on our
own. If we invoke the command as shown in this example:

<screen format="linespecific"># <userinput moreinfo="none">etrn vstout.vbrew.com</userinput></screen>

we will force the host <emphasis role="bold">vstout.vbrew.com</emphasis> to process any mail queued for our local machine.</para><para>Typically you'd add this command to your PPP <filename moreinfo="none">ip-up</filename> script
so that it is executed soon after your network connection is established.</para></sect2><sect2><title>Analyzing Mail Statistics</title><para><indexterm significance="normal"><primary>sendmail</primary><secondary>analyzing mail statistics</secondary></indexterm>
<command moreinfo="none">sendmail</command> collects data on mail traffic volumes and
some information on hosts to which it has delivered mail. There are
two commands available to display this information,
<command moreinfo="none">mailstats</command>, and <command moreinfo="none">hoststat</command>.</para><sect3><title>mailstats</title><para><indexterm significance="normal"><primary>mailstats command</primary></indexterm>
<indexterm significance="normal"><primary>sendmail</primary><secondary>mailstats command</secondary></indexterm>
The <command moreinfo="none">mailstats</command> command displays statistics on the
volume of mail processed by <command moreinfo="none">sendmail</command>. The time at
which data collection commenced is printed first, followed by a table
with one row for each configured mailer and one showing a summary
total of all mail. Each line presents eight items of information:

<informaltable><tgroup cols="2"><thead><row><entry>Field</entry><entry>Meaning</entry></row></thead><tbody><row><entry><literal moreinfo="none">M</literal></entry><entry>The mailer (transport protocol) number</entry></row><row><entry><literal moreinfo="none">msgsfr</literal></entry><entry>The number of messages received from the mailer</entry></row><row><entry><literal moreinfo="none">bytes_from</literal></entry><entry>The Kbytes of mail from the mailer</entry></row><row><entry><literal moreinfo="none">msgsto</literal></entry><entry>The number of messages sent to the mailer</entry></row><row><entry><literal moreinfo="none">bytes_to</literal></entry><entry>The Kbytes of mail sent to the mailer</entry></row><row><entry><literal moreinfo="none">msgsreg</literal></entry><entry>The number of messages rejected</entry></row><row><entry><literal moreinfo="none">msgsdis</literal></entry><entry>The number of messages discarded</entry></row><row><entry><literal moreinfo="none">Mailer</literal></entry><entry>The name of the mailer</entry></row></tbody></tgroup></informaltable>

A sample of the output of the <command moreinfo="none">mailstats</command> command is shown
in <xref linkend="x-087-2-sendmail.mailstats"></xref>.</para><example id="x-087-2-sendmail.mailstats"><title>Sample Output of the mailstats Command</title><screen format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">/usr/sbin/mailstats</userinput>
Statistics from Sun Dec 20 22:47:02 1998
 M   msgsfr  bytes_from   msgsto    bytes_to  msgsrej msgsdis  Mailer
 0        0          0K       19        515K        0       0  prog
 3       33        545K        0          0K        0       0  local
 5       88        972K      139       1018K        0       0  esmtp
=============================================================
 T      121       1517K      158       1533K        0       0</screen></example><para>This data is collected if the <emphasis>StatusFile</emphasis> option is enabled
in the <filename moreinfo="none">sendmail.cf</filename> file and the status file exists.
Typically you'd add the following to your <filename moreinfo="none">sendmail.cf</filename>
file:

<screen format="linespecific"># status file
O StatusFile=/var/log/sendmail.st</screen></para><para>To restart the statistics collection, you need to make the statistics
file zero length:

<screen format="linespecific"> /var/log/sendmail.st</screen>

and restart <command moreinfo="none">sendmail</command>.</para></sect3><sect3><title>hoststat</title><para><indexterm significance="normal"><primary>hostat command</primary></indexterm>
<indexterm significance="normal"><primary>sendmail</primary><secondary>hostat command</secondary></indexterm>
The <command moreinfo="none">hoststat</command> command displays information about the
status of hosts that
<command moreinfo="none">sendmail</command> has attempted to deliver mail to. The
<command moreinfo="none">hoststat</command> command is equivalent to invoking
<command moreinfo="none">sendmail</command> as:

<screen format="linespecific"><userinput moreinfo="none">sendmail -bh</userinput></screen></para><para>The output presents each host on a line of its own, and for each the
time since delivery was attempted to it, and the status message
received at that time.</para><para><xref linkend="x-087-2-sendmail.hoststat"></xref> shows the sort of output you can
expect from the <command moreinfo="none">hoststat</command> command. Note that most of the
results indicate successful delivery. The result for
<emphasis role="bold">earthlink.net</emphasis>, on the other hand, indicates
that delivery was unsuccessful. The status message can sometimes help 
determine the cause of the failure. In this case, the connection timed out, 
probably because the host was down or unreachable at the time delivery was 
attempted.</para><example id="x-087-2-sendmail.hoststat"><title>Sample Output of the oststat Command</title><screen format="linespecific"><prompt moreinfo="none">#</prompt> <userinput moreinfo="none">hoststat</userinput>
 -------------- Hostname ---------- How long ago ---------Results---------
 mail.telstra.com.au                    04:05:41 250 Message accepted for
 scooter.eye-net.com.au              81+08:32:42 250 OK id=0zTGai-0008S9-0
 yarrina.connect.com.a               53+10:46:03 250 LAA09163 Message acce
 happy.optus.com.au                  55+03:34:40 250 Mail accepted
 mail.zip.com.au                        04:05:33 250 RAA23904 Message acce
 kwanon.research.canon.com.au        44+04:39:10 250 ok 911542267 qp 21186
 linux.org.au                        83+10:04:11 250 IAA31139 Message acce
 albert.aapra.org.au                    00:00:12 250 VAA21968 Message acce
 field.medicine.adelaide.edu.au      53+10:46:03 250 ok 910742814 qp 721
 copper.fuller.net                   65+12:38:00 250 OAA14470 Message acce
 amsat.org                            5+06:49:21 250 UAA07526 Message acce
 mail.acm.org                        53+10:46:17 250 TAA25012 Message acce
 extmail.bigpond.com                 11+04:06:20 250 ok
 earthlink.net                       45+05:41:09 Deferred: Connection time </screen></example><para>The <command moreinfo="none">purgestat</command> command flushes the collected host data and
is equivalent to invoking sendmail as:

<screen format="linespecific"># <userinput moreinfo="none">sendmail -bH</userinput></screen>
</para><para>The statistics will continue to grow until you purge them. You might 
want to periodically run the <command moreinfo="none">purgestat</command> command to make it 
easier to search and find recent entries, especially if you have a busy site. 
You could put the command into a <filename moreinfo="none">crontab</filename> file so it 
runs automatically, or just do it yourself occasionally.</para></sect3></sect2><indexterm significance="normal" class="endofrange" startref="sendmail.mgmt.tools"></indexterm></sect1><indexterm significance="normal" class="endofrange" startref="idx-configuringsendmail"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-commandsendmailcommand-1"></indexterm></chapter><chapter id="x-087-2-exim"><title>Getting Exim<?lb?>Up and Running</title><para>This chapter gives you a quick introduction to setting up Exim and an overview
of its functionality. Although Exim is largely compatible with
<command moreinfo="none">sendmail</command> in its behavior, its configuration files are
completely different.</para><para><indexterm significance="normal"><primary>Exim</primary><secondary>configuration files</secondary></indexterm> 
The main configuration file is usually called
<filename moreinfo="none">/etc/exim.conf</filename> or <filename moreinfo="none">/etc/exim/config</filename>
in most Linux distributions, or <filename moreinfo="none">/usr/lib/exim/config</filename> in
older configurations. You can find out where the configuration file is by
running the command:

<screen format="linespecific">$ <userinput moreinfo="none">exim -bP configure_file</userinput></screen></para><para>You may have to edit the configuration file to reflect values specific to your
site. In most common configurations there isn't a great deal to change, and a
working configuration should rarely have to be modified.</para><para><indexterm significance="normal"><primary>email</primary><secondary>queue</secondary></indexterm>
By default, Exim processes and delivers all incoming mail immediately. If you
have relatively high traffic, you may instead have Exim collect all messages
in the so-called <emphasis>queue</emphasis>, and process them at regular
intervals only.</para><para><indexterm significance="normal"><primary>Exim</primary><secondary>daemon mode</secondary></indexterm>
When handling mail within a TCP/IP network, Exim is frequently run in daemon
mode: at system boot time, it is invoked from
<filename moreinfo="none">/etc/init.d/exim</filename><footnote id="x-087-2-fnex01"><para>Other possible locations are
<filename moreinfo="none">/etc/rc.d/init.d</filename> and
<filename moreinfo="none">rc.inet2</filename>. The latter is common on systems
using a BSD-style structure for system administration files in the
<filename moreinfo="none">/etc</filename> directory.</para></footnote>
and puts itself in the background, where it waits for incoming TCP connections
on the SMTP port (usually port 25). This is beneficial whenever you expect to
have a significant amount of traffic because Exim doesn't have to start up
for every incoming connection. Alternatively, <command moreinfo="none">inetd</command> could 
manage the SMTP port and have it spawn Exim whenever there is a connection 
on this port. This configuration might be useful when you have limited 
memory and low mail traffic volumes.</para><para><indexterm significance="normal"><primary>Exim</primary><secondary>utilities</secondary></indexterm>
<indexterm significance="normal"><primary>Exim</primary><secondary>symbolic links to</secondary></indexterm>
Exim has a complicated set of command-line options, including many
that match those of sendmail. Instead of trying to put together
exactly the right options for your needs, you can implement the most
common types of operation by invoking traditional commands like
<command moreinfo="none">rmail</command> or <command moreinfo="none">rsmtp</command>. These are
symbolic links to Exim (or if they're not, you can easily link
them to it). When you run one of the commands, Exim checks the
name you used to invoke it and sets the proper options itself.</para><para>There are two links to Exim that you should have under all circumstances:
<command moreinfo="none">/usr/bin/rmail</command> and <command moreinfo="none">/usr/sbin/sendmail</command>.<footnote id="x-087-2-fnex02"><para>This is the new standard location of <command moreinfo="none">sendmail</command> according to
the Linux File System Standard. Another common location is
<filename moreinfo="none">/usr/lib/sendmail</filename>, which is likely to be used by mail
programs that are not specially configured for Linux.
You can define both filenames as symbolic links to
Exim so that programs and scripts invoking <emphasis>sendmail</emphasis> will instead
invoke Exim to do the same things.</para></footnote>
When you compose and send a mail message with a user agent like
<command moreinfo="none">elm</command>, the message is piped to <command moreinfo="none">sendmail</command>
or <command moreinfo="none">rmail</command> for delivery, which is why both
<command moreinfo="none">/usr/sbin/sendmail</command> and <command moreinfo="none">/usr/bin/rmail</command>
should point to Exim. The list of recipients for the message is passed to Exim
on the command line.<footnote id="x-087-2-fnex03"><para>Some user agents, however, use the SMTP protocol to pass messages to the 
transport agent, calling it with the <option>bs</option> option.</para></footnote>
The same happens with mail coming in via UUCP. You can set up the required
pathnames to point to Exim by typing the following at a shell prompt:

<screen format="linespecific">$ <userinput moreinfo="none">ln -s /usr/sbin/exim /usr/bin/rmail</userinput>
$ <userinput moreinfo="none">ln -s /usr/sbin/exim /usr/sbin/sendmail</userinput></screen></para><para>If you want to dig further into the details of configuring Exim, you should
consult the full Exim specification. If this isn't included in your favorite
Linux distribution, you can get it from the source to Exim, or read it online
from Exim's web site at
<systemitem moreinfo="none" role="url">http://www.exim.org</systemitem>.</para><sect1><title>Running Exim</title><para><indexterm significance="normal"><primary>Exim</primary><secondary>running</secondary></indexterm>
To run Exim, you must first decide whether you want it to handle incoming SMTP
messages by running as a separate daemon, or whether to have
<command moreinfo="none">inetd</command> manage the SMTP port and invoke Exim only whenever an
SMTP connection is requested from a client. Usually, you will prefer daemon
operation on the mail server because it loads the machine far less than
spawning Exim over and over again for each connection. As the mail server also
delivers most incoming mail directly to the users, you should choose
<command moreinfo="none">inetd</command> operation on most other hosts.</para><para><indexterm significance="normal"><primary>SMTP (Simple Mail Transfer Protocol)</primary><secondary>service</secondary></indexterm>
<indexterm significance="normal"><primary sortas="etc/services file">/etc/services file</primary></indexterm> 
Whatever mode of operation you choose for each individual host, you
have to make sure you have the following entry in your
<filename moreinfo="none">/etc/services</filename> file:

<screen format="linespecific">smtp            25/tcp          # Simple Mail Transfer Protocol</screen></para><para>This defines the TCP port number that is used for SMTP conversations.
Port number 25 is the standard defined by the Assigned Numbers
RFC (RFC-1700).</para><para>When run in daemon mode, Exim puts itself in the background and waits for
connections on the SMTP port. When a connection occurs, it forks, and the
child process conducts an SMTP conversation with the peer process on the
calling host.  The Exim daemon is usually started by invoking it from the
<filename moreinfo="none">rc</filename> script at boot time using the following command:

<screen format="linespecific">/usr/sbin/exim -bd -q15m</screen></para><para>The <option>bd</option> flag turns on daemon mode, and
<option>q15m</option> makes it process whatever messages have
accumulated in the message queue every 15 minutes.</para><para><indexterm significance="normal"><primary>inetd super server</primary><secondary>running Exim under</secondary></indexterm>
<indexterm significance="normal"><primary sortas="etc/inetd.conf file">/etc/inetd.conf file</primary></indexterm> 
If you want to use <command moreinfo="none">inetd</command> instead, your
<filename moreinfo="none">/etc/inetd.conf</filename> file should contain a line like this:

<screen format="linespecific">smtp    stream  tcp nowait  root  /usr/sbin/exim  in.exim -bs</screen></para><para>Remember you have to make <command moreinfo="none">inetd</command> re-read
<filename moreinfo="none">inetd.conf</filename> by sending it an
<systemitem moreinfo="none" role="keyword">HUP</systemitem> signal after
making any changes.<footnote id="x-087-2-fnex04"><para>Use <literal moreinfo="none">kill HUP</literal> <replaceable>pid,</replaceable> for which <replaceable>pid</replaceable> is the process ID of the <command moreinfo="none">inetd</command> process retrieved from a 
<command moreinfo="none">ps</command> listing.</para></footnote></para><para>Daemon and <command moreinfo="none">inetd</command> modes are mutually exclusive. If
you run Exim in daemon mode, you should make sure to comment out any line in
<filename moreinfo="none">inetd.conf</filename> for the
<systemitem moreinfo="none" role="keyword">smtp</systemitem> service. Equivalently, when
having <command moreinfo="none">inetd</command> manage Exim, make sure that no
<filename moreinfo="none">rc</filename> script starts the Exim daemon.</para><para>You can check that Exim is correctly set up for receiving incoming SMTP
messages by telnetting to the SMTP port on your machine. This is what a
successful connect to the SMTP server looks like:

<screen format="linespecific">$ <userinput moreinfo="none">telnet localhost smtp</userinput>
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 richard.vbrew.com ESMTP Exim 3.13 #1 Sun, 30 Jan 2000 16:23:55 +0600
<userinput moreinfo="none">quit</userinput>
221 richard.brew.com closing connection
Connection closed by foreign host.</screen></para><para>If this test doesn't produce the SMTP banner (the line starting with the
220 code), check that you are either running an Exim daemon process or 
have <command moreinfo="none">inetd</command> correctly configured. If that doesn't reveal 
the problem, look in the Exim log files (described next) in case 
there is an error in Exim's configuration file.</para></sect1><sect1><title>If Your Mail Doesn't Get Through</title><para><indexterm significance="normal"><primary>Exim</primary><secondary>troubleshooting</secondary></indexterm>
<indexterm significance="normal"><primary>Exim</primary><secondary>log files</secondary></indexterm>
A number of features are available for troubleshooting installation problems.
The first place to check is Exim's log files. On Linux systems they are
normally kept in <filename moreinfo="none">/var/log/exim/log</filename> and are named
<filename moreinfo="none">exim_mainlog</filename>, <filename moreinfo="none">exim_rejectlog</filename>, and
<filename moreinfo="none">exim_paniclog</filename>. On other operating systems, they are
often kept in <filename moreinfo="none">/var/spool/exim/log</filename>. You can find out
where the log files are by running the command:

<screen format="linespecific">exim -bP log_file_path</screen></para><para>The main log lists all transactions, the reject log contains details of
messages that were rejected for policy reasons, and the panic log is
for messages related to configuration errors and the like.</para><para>Typical entries in the main log are shown below. Each entry in the log itself 
is a single line of text, starting with a date and time. They have
been split into several lines here in order to fit them on the page:

<screen format="linespecific">2000-01-30 15:46:37 12EwYe-0004WO-00 = jack@vstout.vbrew.com 
  H=vstout.vbrew.com [192.168.131.111] U=exim P=esmtp S=32100 
  id=38690D72.286F@vstout.vbrew.com
2000-01-30 15:46:37 12EwYe-0004WO-00 = jill jill@vbrew.com 
  D=localuser T=local_delivery
2000-01-30 15:46:37 12EwYe-0004WO-00 Completed</screen></para><para>These entries show that a message from
<systemitem moreinfo="none" role="emailaddr">jack@vstout.vbrew.com</systemitem> 
to <systemitem moreinfo="none" role="emailaddr">jill@vbrew.com</systemitem> was
successfully delivered to a mailbox on the local host. Message arrivals 
are flagged with <literal moreinfo="none">=</literal>, and deliveries with
<literal moreinfo="none">=</literal>.</para><para>There are two kinds of delivery errors: permanent and temporary. A permanent
delivery error is recorded in a log entry like this, flagged with
<literal moreinfo="none">**</literal>:

<screen format="linespecific">2000-01-30 14:48:28 12EvcH-0003rC-00 ** bill@lager.vbrew.com 
  R=lookuphost T=smtp: SMTP error from remote mailer after RCPT TO:
  bill@lager.vbrew.com: host lager.vbrew.com [192.168.157.2]: 
  550 bill@lager.vbrew.com... User unknown</screen></para><para>After a failure like this, Exim sends a delivery failure report, often called a
<emphasis>bounce message</emphasis> back to the sender.</para><para> Temporary errors are
flagged with <literal moreinfo="none">==</literal>:

<screen format="linespecific">2000-01-30 12:50:50 12E9Un-0004Wq-00 == jim@bitter.vbrew.com 
  T=smtp defer (145): Connection timed out</screen></para><para>This error is typical for a situation in which Exim properly recognizes
that the message should be delivered to a remote host, but is not able to
connect to the SMTP service on that host. The host may be down or there 
could be a network problem. Whenever a message is
<emphasis>deferred</emphasis> like this, it remains on Exim's queue and is
retried at intervals. However, if it fails to be delivered for a sufficiently
long time (usually several days), a permanent error occurs and the message is
bounced.</para><para>If you are unable to locate your problem from the error message Exim 
generates, you may want to turn on debugging messages. You can do this 
using the <option>d</option> flag, optionally followed by a number 
specifying the level of verbosity (a value of 9 gives maximum information). 
Exim then displays a report of its operation on the screen, which may 
give you more hints about what is going wrong.</para></sect1><sect1><title>Compiling Exim</title><para><indexterm significance="normal"><primary>Exim</primary><secondary>compiling</secondary></indexterm>
Exim is still under active development; the version of Exim included in
Linux distributions is probably not the latest release. If you need a 
feature or a bugfix found in a later release, you have to obtain a 
copy of the source code and compile it yourself. The latest release can be 
found via Exim's web page at 
<systemitem moreinfo="none" role="url">http://www.exim.org</systemitem>.</para><para>Linux is one of the many operating systems supported by the Exim source. To
compile Exim for Linux, you should edit the <filename moreinfo="none">src/EDITME</filename>
file and put the result in a file called <filename moreinfo="none">Local/Makefile</filename>.
There are comments in <filename moreinfo="none">src/EDITME</filename> that tell you what the
various settings are used for. Then run <command moreinfo="none">make</command>.  See the Exim
manual for detailed information on building Exim from source.</para></sect1><sect1 id="x-087-2-exim.queue"><title>Mail Delivery Modes</title><para><indexterm significance="normal"><primary>Exim</primary><secondary>mail delivery modes</secondary></indexterm>
<indexterm significance="normal"><primary>Exim</primary><secondary>queuing mail</secondary></indexterm>
<indexterm significance="normal"><primary>queuing mail</primary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>queue</secondary></indexterm>
As noted previously, Exim is able to deliver messages immediately or
queue them for later processing. All incoming mail is stored in the
<filename moreinfo="none">input</filename> directory below
<filename moreinfo="none">/var/spool/exim</filename>. When queueing is not in
operation, a delivery process is started for each message as soon as
it arrives. Otherwise, it is left on the queue until a
<emphasis>queue-runner</emphasis> process picks it up. Queueing can be
made unconditional by setting <option>queue_only</option> in the
configuration file, or it can be conditional on the 1-minute system
load by a setting such as:

<screen format="linespecific">queue_only_load = 4</screen>

which causes messages to be queued if the system load exceeds
4.<footnote><para>The system load is a standard Unix measure of the
average number of processes that are queued up, waiting to run. The
<command moreinfo="none">uptime</command> shows load averages taken over the previous
1, 5, and 15 minutes.</para></footnote></para><para>If your host is not permanently connected to the Internet, you may
want to turn on queueing for remote addresses, while allowing Exim to
perform local deliveries immediately. You can do this by setting:

<screen format="linespecific">queue_remote_domains = *</screen>

in the configuration file.</para><para><indexterm significance="normal"><primary>cron</primary><secondary>running</secondary><tertiary>Exim via</tertiary></indexterm> 
If you turn on any form of queuing, you have to make sure the queues
are checked regularly, probably every 10 or 15 minutes. Even without
any explicit queueing options, the queues need to be checked for
messages that have been deferred because of temporary delivery
failures. If you run Exim in daemon mode, you must add the
<option>q15m</option> option on the command line to process the
queue every 15 minutes.  You can also invoke <command moreinfo="none">exim
q</command> from <command moreinfo="none">cron</command> at these intervals.</para><para><indexterm significance="normal"><primary>Exim</primary><secondary>check mail queue</secondary></indexterm>
<indexterm significance="normal"><primary>checking</primary><secondary>mail queue</secondary></indexterm>
You can display the current mail queue by invoking Exim with the
<option>bp</option> option. Equivalently, you can make
<command moreinfo="none">mailq</command> a link to Exim, and invoke
<command moreinfo="none">mailq</command>:

<screen format="linespecific">$ <userinput moreinfo="none">mailq</userinput>
 2h   52K 12EwGE-0005jD-00 sam@vbrew.com
        D bob@vbrew.com
          harry@example.net  </screen></para><para><indexterm significance="normal"><primary>Exim</primary><secondary>log files</secondary></indexterm>
This shows a single message from <systemitem moreinfo="none" role="emailaddr">sam@vbrew.com</systemitem> to two recipients sitting
in the message queue. It has been successfully delivered to
<systemitem moreinfo="none" role="emailaddr">bob@vbrew.com</systemitem>, but has not
yet been delivered to <systemitem moreinfo="none" role="emailaddr">harry@example.net</systemitem>, though it has been on
the queue for two hours. The size of the message is 52K, and the ID by
which Exim identifies this message is
<literal moreinfo="none">12EwGE-0005jD-00</literal>. You can find out why the delivery
is not yet complete by looking at the message's individual log file,
which is kept in the <filename moreinfo="none">msglog</filename> directory in Exim's
spool directory. The <option>Mvl</option> option is an easy way
of doing this:

<screen format="linespecific">$ <userinput moreinfo="none">exim Mvl 12EwGE-0005jD-00</userinput>
2000-01-30 17:28:13 example.net [192.168.8.2]: Connection timed out
2000-01-30 17:28:13 harry@example.net: remote_smtp transport deferred: 
  Connection timed out</screen>

Individual log files keep a copy of log entries for each message so you can
easily inspect them. The same information could have been extracted from the
main log file using the <command moreinfo="none">exigrep</command> utility:

<screen format="linespecific">$ <userinput moreinfo="none">exigrep 12EwGE-0005jD-00 /var/log/exim/exim_mainlog</userinput></screen>

That would take longer, especially on a busy system where the log files
can get quite big. The <command moreinfo="none">exigrep</command> utility comes into its own
when looking for information about more than one message. Its first argument
is a regular expression, and it picks out all the log lines concerned with any
messages that have at least one log line that matches the expression. Thus it
can be used to pick out all messages for one specific address, or all those to
or from a specific host.</para><para>You can keep a general watch on what a running Exim is doing by running
<command moreinfo="none">tail</command> on its main log file. Another way of doing this is to
run the <command moreinfo="none">eximon</command> utility that comes with Exim. This is an X11
application that puts up a scrolling display of the main log, and also shows
a list of messages that are awaiting delivery, as well as some stripcharts
about delivery activity.</para></sect1><sect1 id="x-087-2-exim.options"><title>Miscellaneous config Options</title><para><indexterm significance="normal"><primary>Exim</primary><secondary>configuration files</secondary><tertiary>options</tertiary></indexterm>
Here are a few of the more useful options you can set in the
configuration file:

<variablelist><varlistentry><term><emphasis>message_size_limit</emphasis></term><listitem><para>Setting this option limits the size of message that Exim will accept.</para></listitem></varlistentry><varlistentry><term><emphasis>return_size_limit</emphasis></term><listitem><para>Setting this option limits the amount of an incoming message that Exim will 
return as part of a bounce message.</para></listitem></varlistentry><varlistentry><term><emphasis>deliver_load_max</emphasis></term><listitem><para>If the system load exceeds the value given for this option, all mail delivery 
is suspended, though messages are still accepted.</para></listitem></varlistentry><varlistentry><term><emphasis>smtp_accept_max</emphasis></term><listitem><para>This is the maximum number of simultaneous incoming SMTP calls Exim is prepared
to accept. </para></listitem></varlistentry><varlistentry><term><emphasis>log_level</emphasis></term><listitem><para>This option controls the amount of material that is written to the log. There 
are also some options with names beginning with <option>log_</option> that 
control the logging of specific information.</para></listitem></varlistentry></variablelist></para></sect1><sect1 id="x-087-2-exim.delivery"><title>Message Routing and Delivery</title><para>Exim splits up mail delivery into three different tasks: routing,
directing, and transporting. There are a number of code modules of
each type, and each is separately configurable. Usually a number of
different routers, directors, and transports are set up in the
configuration file.</para><para><indexterm significance="normal"><primary>Exim</primary><secondary>routers</secondary></indexterm>
Routers resolve remote addresses, determining which host the message
should be sent to and which transport should be used. In
Internet-connected hosts there is often just one router, which does
the resolution by looking up the domain in the DNS. Alternatively,
there may be one router that handles addresses destined for hosts on a
local LAN, and a second to send any other addresses to a single
<emphasis>smart host</emphasis>; for example, an ISP's mail server.</para><para><indexterm significance="normal"><primary>Exim</primary><secondary>directors</secondary></indexterm>
Local addresses are given to the directors, of which there are
normally several, to handle aliasing and forwarding as well as
identifying local mailboxes. Mailing lists can be handled by aliasing
or forwarding directors. If an address gets aliased or forwarded, any
generated addresses are handled independently by the routers or
directors, as necessary. By far the most common case will be delivery
to a mailbox, but messages may also be piped into a command or
appended to a file other than the default mailbox.</para><para><indexterm significance="normal"><primary>Exim</primary><secondary>transports</secondary></indexterm>
A transport is responsible for implementing a method of delivery; for
example, sending the message over an SMTP connection or adding it to
a specific mailbox. Routers and directors select which transport to
use for each recipient address. If a transport fails, Exim either
generates a bounce message or defers the address for a later retry.</para><para>With Exim, you have a lot of freedom in configuring these tasks. For each of 
them, a number of drivers are available, from which you can choose those you 
need. You describe them to Exim in different sections of its configuration 
file. The transports are defined first, followed by the directors, and then 
the routers. There are no built-in defaults, though Exim is distributed with 
a default configuration file that covers simple cases. If you want to change 
Exim's routing policy or modify a transport, it is easiest to start from the 
default configuration and make changes rather than attempt to set up a 
complete configuration from scratch.</para><sect2 id="x-087-2-exim.routing"><title>Routing Messages</title><para><indexterm significance="normal"><primary>Exim</primary><secondary>routing messages in</secondary></indexterm>
<indexterm significance="normal"><primary>local_domains configuration variable</primary></indexterm>
When given an address to deliver, Exim first checks whether the domain
is one that is handled on the local host by matching it against a
list in the <literal moreinfo="none">local_domains</literal> configuration
variable. If this option is not set, the local host name is used as
the only local domain. If the domain is local, the address is handed
to the directors. Otherwise, it is handed to the routers to find out
which host to forward a message to.<footnote id="x-087-2-fnex05"><para> This is a simplification. It is possible
for directors to pass addresses to transports that deliver to remote
hosts, and similarly, it is possible for routers to pass addresses to
local transports that write the messsage to a file or a pipe. It is
also possible for routers to pass addresses to the directors in some
circumstances.</para></footnote></para></sect2><sect2 id="x-087-2-exim.directors"><title>Delivering Messages to Local Addresses</title><para><indexterm significance="normal" class="startofrange" id="idx-commandeximcommandlocaladdresses-1"><primary>Exim</primary><secondary>delivering messages to local addresses</secondary></indexterm>
<indexterm significance="normal"><primary>local addresses</primary></indexterm>
Most commonly, a local address is just a user's login name, in which case
the message is delivered to the user's mailbox,
<filename moreinfo="none">/var/spool/mail</filename>/<replaceable>user-name</replaceable>.
Other cases include aliases, mailing list names, and mail forwarding by the
user. In these cases, the local address expands to a new list of addresses,
which may be either local or remote.</para><para>Apart from these normal addresses, Exim can handle other
types of local message destinations, like filenames and pipe commands.
When delivering to a file, Exim appends the message, creating the file
if necessary. File and pipe destinations are not addresses in their
own right, so you can't send mail to, say, <systemitem moreinfo="none" role="emailaddr">/etc/passwd@vbrew.com</systemitem> and expect to
overwrite the password file; deliveries to a specific file are valid
only if they come from forwarding or alias files.  Note, however, that
<systemitem moreinfo="none" role="emailaddr">/etc/passwd@vbrew.com</systemitem> is a
syntactically valid email address, but if Exim received it, it would
(typically) search for a user whose login name was <systemitem moreinfo="none" role="emailaddr">/etc/passwd</systemitem>, fail to find one, and
bounce the message.</para><para><indexterm significance="normal"><primary>Exim</primary><secondary>directing mail to a file</secondary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>directing to a file</secondary></indexterm>
<indexterm significance="normal"><primary sortas="forward file">.forward file</primary></indexterm> 
In an alias list or forwarding file, a <emphasis>filename</emphasis> is
anything that begins with a slash (/) that does not parse as a fully qualified
email address. For example, <filename moreinfo="none">/tmp/junk</filename> in a forwarding or
alias file is interpreted as a file name, but
<systemitem moreinfo="none" role="emailaddr">/tmp/junk@vbrew.com</systemitem>
is an email address, though it is not likely to be a very useful one. However, 
valid addresses of this type are seen when sending mail through X.400 gateways,
because X.400 addresses start with a slash.</para><para><indexterm significance="normal"><primary>Exim</primary><secondary>feeding mail to a command</secondary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>feeding to a command</secondary></indexterm>
Similarly, a <emphasis>pipe command</emphasis> may be any Unix command preceded
by the pipe symbol (|), unless the string parses as a valid email address
complete with domain. Unless you have changed the configuration, Exim does not 
use a shell to run the command; instead, it splits it up into a command name, arguments itself, and runs it directly. The message is fed to the command
on its standard input.</para><para>For example, to gate a mailing list into a local newsgroup, you might use a
shell script named <command moreinfo="none">gateit</command>, and set up a local alias that
delivers all messages from this mailing list to the script using
<literal moreinfo="none">|gateit</literal>. If the command line contains a comma, it and the 
preceding pipe symbol must be enclosed in double quotes. </para><sect3><title>Local users</title><para><indexterm significance="normal"><primary>Exim</primary><secondary>user mailboxes</secondary></indexterm>
<indexterm significance="normal"><primary>mailbox files</primary></indexterm>
A local address most commonly denotes a user's mailbox. This is normally
located in <filename moreinfo="none">/var/spool/mail</filename> and has the name of the
user, who also owns the file. If it does not exist, it is created by
Exim. </para><para>In some configurations, the group is set to the user's group and the
mode is 0600. In these cases, delivery processes are run as the user,
and the user may delete the mailbox entirely. In other
configurations, the mailbox's group is <systemitem moreinfo="none" role="userid">mail</systemitem>, and it has mode 660; delivery processes 
are run under a system uid and group <systemitem moreinfo="none" role="userid">mail</systemitem>, and users cannot delete their
mailbox files, though they can empty them.</para><para>Note that although <filename moreinfo="none">/var/spool/mail</filename> is currently
the standard place to put the mailbox files, some mail software may be
compiled to use different paths, for example,
<filename moreinfo="none">/usr/spool/mail</filename>. If delivery to users on your
machine fails consistently, you should see if it helps to make this a
symbolic link to <filename moreinfo="none">/var/spool/mail</filename>.</para><para>The addresses <systemitem moreinfo="none" role="userid">MAILER-DAEMON</systemitem> and
<systemitem moreinfo="none" role="userid">postmaster</systemitem> should normally
appear in your alias file, expanding into the email address of the
system administrator.  <systemitem moreinfo="none" role="userid">MAILER-DAEMON</systemitem> is used by Exim as the sender
address in bounce messages. It is also recommended that <systemitem moreinfo="none" role="userid">root</systemitem> be set up as an alias for an
administrator, especially when deliveries are being run under the
permissions of the recipient users, in order to avoid running any
delivery as <systemitem moreinfo="none" role="userid">root</systemitem>.</para></sect3><sect3><title>Forwarding</title><para><indexterm significance="normal"><primary>Exim</primary><secondary>forwarding mail</secondary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>forwarding</secondary></indexterm>
<indexterm significance="normal"><primary>forwarding</primary><secondary>mail</secondary></indexterm>
Users can redirect their mail to alternative addresses by creating a
<filename moreinfo="none">.forward</filename> file in their home directories. This contains 
a list of recipients separated by commas and/or newlines.
All lines of the file are read and interpreted. Any type of address may
be used. A practical example of a <filename moreinfo="none">.forward</filename>
file for vacations might be:

<screen format="linespecific">janet, "|vacation"</screen>

In other descriptions of <filename moreinfo="none">.forward</filename> files, you might 
see the username at the start preceded by a backslash. This was
necessary in some older MTAs to stop a search for a 
<filename moreinfo="none">.forward</filename> for the new name, which could lead to 
looping. The backslash is not necessary in Exim, which automatically 
avoids loops of this kind.<footnote><para>A director is skipped if the address it is about to process is one that 
it has previously processed in the course of generating the present 
address.</para></footnote>
However, a backslash is permitted, and in fact it does make a difference 
in configurations where several domains are being handled at once. 
Without a backslash, an unqualified username is qualified with a
default domain; with a backslash the incoming domain is preserved.</para><para>The first address in the forward file delivers the incoming message 
to <emphasis role="bold">janet</emphasis>'s mailbox, 
while the <command moreinfo="none">vacation</command> command returns a short notification to 
the sender.<footnote id="x-087-2-fnex07"><para>Please, if you choose to use a vacation program, make sure it will not reply
to messages sent from mailing lists! It is very annoying to discover that
someone has gone on vacation and find a vacation message for every message
they've received. Mailing list administrators: this is a good example of why it
is bad practice to force the <literal moreinfo="none">Reply-To:</literal> field of mailing list
messages to that of the list submission address.</para></footnote></para><para><?troff .hw flexibility?><indexterm significance="normal"><primary>Exim</primary><secondary>filter files</secondary></indexterm>
<indexterm significance="normal"><primary>filter files</primary></indexterm>
In addition to supporting traditional forwarding files,
Exim can be configured to allow more complex files called
<emphasis>filters</emphasis>.  Instead of being just a list of
forwarding addresses, a filter file can contain tests on the contents
of the incoming message so that, for example, messages could be
forwarded only if the subject contained the message urgent. The
system administrator must decide whether to allow users this
flexibility.</para></sect3><indexterm significance="normal" class="endofrange" startref="idx-commandeximcommandlocaladdresses-1"></indexterm></sect2><sect2><title>Alias Files</title><para><indexterm significance="normal"><primary>alias files for Exim</primary></indexterm>
<indexterm significance="normal"><primary>Exim</primary><secondary>alias files</secondary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>aliases</secondary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>forwarding</secondary></indexterm>
<indexterm significance="normal"><primary>forwarding</primary><secondary>mail</secondary></indexterm>
<indexterm significance="normal"><primary>aliases</primary><secondary>email</secondary></indexterm>
Exim is able to handle alias files compatible with Berkeley's
<command moreinfo="none">sendmail</command> alias files. Entries in the alias file can have 
the following form:

<screen format="linespecific"><replaceable>alias</replaceable>: <replaceable>recipients</replaceable></screen></para><para><replaceable>recipients</replaceable> is a comma-separated list of
addresses that will be substituted for the alias. The recipient list
may be continued across newlines if the next line begins with whitespace.</para><para>A special feature allows Exim to handle mailing lists that are held
separately from the alias file: if you specify
<literal moreinfo="none">:include:</literal><replaceable>filename</replaceable> as a
recipient, Exim reads the specified file and substitutes its contents
as a list of recipients. An alternative to handling mailing lists is
shown later in this chapter in <xref linkend="x-087-2-exim.director.mailing-lists"></xref>.</para><para><indexterm significance="normal"><primary sortas="etc/aliases file">/etc/aliases file</primary></indexterm>
The main aliases file is <filename moreinfo="none">/etc/aliases</filename>. If you
make this file world-writable or group-writeable, Exim will refuse to
use it and will defer local deliveries. You can control the test it
applies to the file's permissions by setting <option>modemask</option>
in the <filename moreinfo="none">system_aliases</filename> director.</para><para>This is a sample <filename moreinfo="none">aliases</filename> file:

<screen format="linespecific"># vbrew.com /etc/aliases file
hostmaster: janet
postmaster: janet
usenet: phil
# The development mailing list.
development: joe, sue, mark, biff,
        /var/mail/log/development
owner-development: joe
# Announcements of general interest are mailed to all
# of the staff
announce: :include: /etc/Exim/staff,
        /var/mail/log/announce
owner-announce: root
# gate the ppp mailing list to a local newsgroup
ppp-list: "|/usr/local/bin/gateit local.lists.ppp"</screen></para><para>When there are file names and pipe commands in an alias file, as here,
Exim needs to be told which userid to run the deliveries under. The
<option>user</option> option (and possibly <option>group</option>,
too) must be set in Exim's configuration file, either on the director
that is handling the aliases, or on the transports to which it directs
these items.</para><para>If an error occurs while delivering to an address generated from the
<filename moreinfo="none">aliases</filename> file, Exim will send a bounce message to
the sender of the message, as usual, but this might not be
appropriate. The <option>errors_to</option> option can be used to
specify that bounce messages are to be sent elsewhere; for example, to
the postmaster.</para></sect2><sect2 id="x-087-2-exim.director.mailing-lists"><title>Mailing Lists</title><para><indexterm significance="normal"><primary>Exim</primary><secondary>mailing lists</secondary></indexterm>
<indexterm significance="normal"><primary>mailing lists</primary><secondary>in Exim</secondary></indexterm> 
<indexterm significance="normal"><primary>forwardfile director</primary></indexterm>
Instead of the <filename moreinfo="none">aliases</filename> file, mailing lists may
also be managed by means a <filename moreinfo="none">forwardfile</filename> director. The
lists are all kept in a single directory such as
<filename moreinfo="none">/etc/exim/lists/</filename>, and a mailing list named
<systemitem moreinfo="none" role="keyword">nag-bugs</systemitem> is described by the file
<filename moreinfo="none">lists/nag-bugs</filename>. This should contain the members'
addresses separated by commas or newlines. Lines beginning with a hash sign
(<literal moreinfo="none">#</literal>) are treated as comments. A simple director to use such
data is as follows:

<screen format="linespecific">lists:
  driver = forwardfile
  file = /etc/exim/lists/${local_part}
  no_check_local_user
  errors_to = ${local_part}-request</screen>

When this director runs, the values of the <option>file</option> and 
<option>errors_to</option> options are <emphasis>expanded</emphasis>. 
Expansion causes certain portions of the strings beginning with dollar 
characters to be replaced every time the string is used. The simplest 
kind of expansion is the insertion of the value of one of Exim's 
variables, and this is what is happening here. The substring 
<literal moreinfo="none">${local_part}</literal> substitutes the value of the 
<literal moreinfo="none">$local_part</literal>, which is the local part of the address 
that is being processed.</para><para>For each mailing list, a user (or alias or mailing list) named
<replaceable>listname-request</replaceable> should exist; any errors
occurring when resolving an address or delivering to a list member are
reported to this address.</para></sect2></sect1><sect1><title>Protecting Against Mail Spam</title><para><indexterm significance="normal"><primary>Real-time Blackhole List (RBL)</primary></indexterm>
<indexterm significance="normal"><primary>spamming</primary></indexterm>
<indexterm significance="normal"><primary>unsolicited mail, managing</primary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>unsolicited</secondary></indexterm>
<indexterm significance="normal"><primary>email</primary><secondary>managing spam</secondary></indexterm>
<indexterm significance="normal"><primary>Mail Abuse Protection System (MAPS)</primary></indexterm>
<indexterm significance="normal"><primary>Dial-Up List (DUL)</primary></indexterm>
<option>Mail spam</option>, or unsolicited email advertising, is an
annoying problem for many users. A project has been formed to address
this problem called the Mail Abuse Protection System (MAPS), and a
mechanism has been built that reduces the problem, called the Real
Time Blackhole List (RBL).  Information on how the MAPS RBL works can
be obtained from its online documentation at <systemitem moreinfo="none" role="url">http://maps.vix.com/rbl/</systemitem>. The idea is
simple. Sites that are caught generating mail spam are added into the
database and mail transfer agents like Exim are able to query the
database to confirm that a source is not a spammer before accepting
mail from it.</para><para>Since the advent of the RBL, several other similar lists have been
created. One of the most useful is the Dial-Up List (DUL), which lists
the IP addresses of dial-up hosts. These should normally send outgoing
mail only to their ISP's mail servers. Many sites block mail from
external dial-ups because when such a host avoids its own ISP's
server, it is usually up to no good.</para><para>Exim provides support for the real-time and other blacklists. It is
very easily configured. To enable it, add the following lines to your
<filename moreinfo="none">/etc/exim.conf</filename> file:</para><screen format="linespecific"># Vixie / MAPS RBL (http://maps.vix.com/rbl)
rbl_domains = rbl.maps.vix.com : dul.maps.vix.com</screen><para>This example checks both the RBL and the DUL, rejecting any messages
from hosts that are on either list. The <option>rbl_hosts</option>
option allows you to specify groups of hosts to which RBL checking
does (or does not) apply. The default setting is:

<screen format="linespecific">rbl_hosts = *</screen>

which means that all hosts are subject to RBL checking. If you wanted to 
override blacklisting and accept mail from a specific host without 
performing the RBL checking you could, for example, use:

<screen format="linespecific">rbl_hosts = ! nocheck.example.com : *</screen>

The exclamation mark before the first item in this list indicates a 
negated item: if the calling host is 
<systemitem moreinfo="none" role="emailaddr">nocheck.example.com</systemitem>, 
it will match this item. But because of the negation, RBL checking is 
not performed. Any other host matches the second item in the list.
</para></sect1><sect1 id="x-087-2-exim.simple"><title>UUCP Setup</title><para><indexterm significance="normal"><primary>Exim</primary><secondary>UUCP setup</secondary></indexterm>
<indexterm significance="normal"><primary>UUCP</primary><secondary>Exim interface to</secondary></indexterm>
Exim does not have any specific code for transporting mail via UUCP, nor does 
it support UUCP bang path addresses. However, if domain addressing is being 
used, Exim can be interfaced to UUCP fairly simply. Here is a configuration 
fragment for sending certain domains to UUCP, taken from a real installation:</para><screen format="linespecific"># Transport
uucp:
  driver = pipe
  user = nobody
  command = "/usr/local/bin/uux -r - \
    ${substr_-5:$host}!rmail ${local_part}"
  return_fail_output = true

# Router
uucphost:
  transport = uucp
  driver = domainlist
  route_file = /usr/exim/uucphosts
  search_type = lsearch</screen><para>In a complete configuration file, the transport would be inserted
among the other transports, and the router probably defined as the
first router. The file <filename moreinfo="none">/usr/exim/uucphosts</filename>
contains entries like this:

<screen format="linespecific">darksite.example.com:           darksite.UUCP</screen>

which is interpreted to mean, Send mail addressed to the domain
<emphasis role="bold">darksite.example.com</emphasis> to the
UUCP host <emphasis role="bold">darksite</emphasis>.
This configuration could be set up more simply without the router
adding the suffix .UUCP to <emphasis role="bold">darksite</emphasis> only to have the transport take
it off again, but this way is useful because it makes clear the distinction between the
domain name <emphasis role="bold">darksite.example.com</emphasis> and the UUCP host
name <emphasis role="bold">darksite</emphasis>.</para><para>Whenever the router comes across a domain that is in the route file,
it will send the address to the UUCP transport, which subsequently pipes it to the
<command moreinfo="none">uux</command> command (described in <xref linkend="x-087-2-uucp"></xref>). If there is a problem,
<command moreinfo="none">uux</command> will generate some output and terminate with a
non-zero error code. The setting of
<literal moreinfo="none">return_fail_output</literal> makes sure that the output is
returned to the sender.</para><para>If incoming UUCP messages are grouped into files in batched SMTP
format, they can be passed directly to Exim using a command like this:

<screen format="linespecific">exim -bS /var/uucp/incoming/001</screen></para><?troff .Nd 15?><para><?troff .hw handled?>However, there is one catch. When Exim receives a message locally, it
insists that the sender is the logged-in user that calls it, but for a
UUCP batch we want the senders to be taken from the incoming
messages. Exim will do this if the process that calls it is running as
a <emphasis>trusted user</emphasis>. If you arrange for incoming UUCP
to be handled by a user called <systemitem moreinfo="none" role="userid">uucp</systemitem>, for example, you need to specify:

<screen format="linespecific">trusted_users = uucp</screen>

in the Exim configuration file to ensure that sender addresses are correctly 
handled.</para></sect1></chapter><chapter id="x-087-2-news"><title>Netnews</title><para><indexterm significance="normal" class="startofrange" id="usenet.news"><primary>Usenet</primary></indexterm>
Netnews, or Usenet news, remains one of the most important and highly
valued services on computer networks today. Dismissed by some as a
mire of unsolicited commercial email and pornography, Netnews still
maintains several cases of the high-quality discussion groups that
made it a critical resource in pre-web days. Even in these times of a
billion web pages, Netnews is still a source for online help and
community on many topics.</para><sect1 id="x-087-2-news.history"><title>Usenet History</title><para><indexterm significance="normal" class="startofrange" id="idx-news-1"><primary>news (network)</primary></indexterm>
The idea of network news was born in 1979 when two graduate students, Tom
Truscott and Jim Ellis, thought of using UUCP to connect machines for 
information exchange among Unix users. They set up
a small network of three machines in North Carolina.</para><para>Initially, traffic was handled by a number of shell scripts (later
rewritten in C), but they were never released to the public. They
were quickly replaced by A News, the first public release of news
software.</para><para>A News was not designed to handle more than a few articles
per group and day. When the volume continued to grow, it was rewritten
by Mark Horton and Matt Glickman, who called it the B release
(a.k.a. B News). The first public release of B News was version 2.1
in 1982. It was expanded continuously, with several new features 
added. Its current version is B News 2.11. It is slowly
becoming obsolete; its last official maintainer switched to
INN.</para><para><indexterm significance="normal"><primary>Collyer, Geoff</primary></indexterm>
<indexterm significance="normal"><primary>Spencer, Henry</primary></indexterm>
<indexterm significance="normal"><primary>C News</primary></indexterm>
Geoff Collyer and Henry Spencer rewrote B News and released it in 1987; this 
is release C, or C News. Since its release, there
have been a number of patches to C News, the most prominent being the
C News Performance Release. On sites that carry a large number of groups,
the overhead involved in frequently invoking <command moreinfo="none">relaynews</command>,
which is responsible for dispatching incoming articles to other hosts, is
significant. The Performance Release adds an option to
<command moreinfo="none">relaynews</command> that allows it to run in
<emphasis>daemon mode</emphasis>, through which the program puts
itself in the background. The Performance Release is the C News version
currently included in most Linux releases. We describe C News in detail in
<xref linkend="x-087-2-cnews"></xref>.</para><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>NNTP</secondary></indexterm> 
All news releases up to C were primarily targeted for UUCP networks,
although they could be used in other environments, as well. Efficient news
transfer over networks like TCP/IP or DECNet required a new scheme. So in
1986, the <emphasis>Network News Transfer Protocol</emphasis> (NNTP) was
introduced. It is based on network connections and specifies a number of
commands to interactively transfer and retrieve articles.</para><para><indexterm significance="normal"><primary>nntpd</primary></indexterm> 
There are a number of NNTP-based applications available from the Net. One of
them is the <command moreinfo="none">nntpd</command> package by Brian Barber and Phil Lapsley,
which you can use to provide newsreading service to a number of hosts inside a
local network. <command moreinfo="none">nntpd</command> was designed to complement news
packages, such as B News or C News, to give them NNTP features. If you want
to use NNTP with the C News server, you should read
<xref linkend="x-087-2-nntp"></xref>, which explains how to configure the
<command moreinfo="none">nntpd</command> daemon and run it with C News.</para><para><indexterm significance="normal"><primary>INN (Internet News)</primary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>Internet News</secondary></indexterm> 
An alternative package supporting NNTP is INN, or
<emphasis>Internet News</emphasis>. It is not just a frontend, but a news
system in its own right. It comprises a sophisticated news relay daemon that
can maintain several concurrent NNTP links efficiently, and is therefore the
news server of choice for many Internet sites. We discuss it in detail in
<xref linkend="x-087-2-inn"></xref>.</para></sect1><sect1 id="x-087-2-news.usenet"><title>What Is Usenet, Anyway?</title><para><indexterm significance="normal"><primary>news (network)</primary><secondary>Usenet</secondary></indexterm>
<indexterm significance="normal"><primary>Zen</primary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>exchanging</secondary></indexterm>
<indexterm significance="normal"><primary>exchanging</primary><secondary>news</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>feeding</secondary></indexterm>
One of the most astounding facts about Usenet is that it isn't part of
any organization, nor does it have any sort of centralized network management
authority. In fact, it's part of Usenet lore that except for a technical
description, you cannot define <emphasis>what</emphasis> it is; at the risk of sounding stupid, one might define Usenet as a collaboration
of separate sites that exchange Usenet news. To be a Usenet site, all you
have to do is find another Usenet site and strike an agreement with its
owners and maintainers to exchange news with you. Providing another site
with news is called <emphasis>feeding</emphasis> it, whence another
common axiom of Usenet philosophy originates: Get a feed, and you're
on it.</para><?troff .wcon_off?><para><?troff .hw consists?><indexterm significance="normal"><primary>news (network)</primary><secondary>articles</secondary></indexterm>
<indexterm significance="normal"><primary>articles (news)</primary></indexterm> 
The basic unit of Usenet news is the
<emphasis>article</emphasis>. This is a message a user writes and
posts to the net. In order to enable news systems to
deal with it, it is prepended with administrative information, the
so-called article header. It is very similar to the mail header format
laid down in the Internet mail standard RFC-822, in that it consists<?troff .ne 10?>
of several lines of text, each beginning with a field name terminated
by a colon, which is followed by the field's value.<footnote id="x-087-2-fnun01"><para> The format of Usenet news messages is
specified in RFC-1036, Standard for interchange of USENET
messages.</para></footnote>
</para><para><indexterm significance="normal"><primary>news (network)</primary><secondary>groups</secondary></indexterm>
<indexterm significance="normal"><primary>newsgroups</primary></indexterm> <?troff .ffn?>
Articles are submitted to one or more <emphasis>newsgroup</emphasis>. One may
consider a newsgroup a forum for articles relating to a common topic. All
newsgroups are organized in a hierarchy, with each group's name indicating
its place in the hierarchy. This often makes it easy to see what a group is
all about. For example, anybody can see from the newsgroup name that
<systemitem moreinfo="none" role="newsgroup">comp.os.linux.announce</systemitem> is used for
announcements concerning a computer operating system named Linux.</para><para><indexterm significance="normal"><primary>news (network)</primary><secondary>exchanging</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>feeding</secondary></indexterm>
These articles are then exchanged between all Usenet sites that are
willing to carry news from this group.  When two sites agree to exchange
news, they are free to exchange whatever newsgroups they like, and
may even add their own local news hierarchies. For example,
<systemitem moreinfo="none" role="sitename">groucho.edu</systemitem> might have a news link
to <systemitem moreinfo="none" role="sitename">barnyard.edu</systemitem>, which
is a major news feed, and several links to minor sites which it feeds
news. Now Barnyard College might receive all Usenet groups, while GMU
only wants to carry a few major hierarchies like
<systemitem moreinfo="none" role="newsgroup">sci</systemitem>,
<systemitem moreinfo="none" role="newsgroup">comp</systemitem>, or 
<systemitem moreinfo="none" role="newsgroup">rec</systemitem>. Some of the downstream
sites, say a UUCP site called <systemitem moreinfo="none" role="sitename">brewhq</systemitem>,
will want to carry even fewer groups, because they don't have the network or
hardware resources. On the other hand,
<systemitem moreinfo="none" role="sitename">brewhq</systemitem> might want to receive
newsgroups from the <systemitem moreinfo="none" role="newsgroup">fj</systemitem>
hierarchy, which GMU doesn't carry. It therefore maintains another link
with <systemitem moreinfo="none" role="sitename">gargleblaster.com</systemitem>, which carries
all <systemitem moreinfo="none" role="newsgroup">fj</systemitem> groups and feeds
them to <systemitem moreinfo="none" role="sitename">brewhq</systemitem>. The news flow is
shown in <xref linkend="x-087-2-news.fig.article-flow"></xref>.</para><figure float="0" id="x-087-2-news.fig.article-flow"><title>Usenet newsflow through Groucho Marx University</title><graphic fileref="lag2_2001.jpg"></graphic></figure><para>The labels on the arrows originating from
<systemitem moreinfo="none" role="sitename">brewhq</systemitem> may require some explanation,
though.  By default, it wants all locally generated news to be sent to
<systemitem moreinfo="none" role="sitename">groucho.edu</systemitem>.  However, as
<systemitem moreinfo="none" role="sitename">groucho.edu</systemitem> does not carry the
<systemitem moreinfo="none" role="newsgroup">fj</systemitem> groups, there's no point in
sending it any messages from those groups. Therefore, the feed from
<systemitem moreinfo="none" role="sitename">brewhq</systemitem> to GMU is labeled
<literal moreinfo="none">all,!fj</literal>, meaning that all groups
except those below <systemitem moreinfo="none" role="newsgroup">fj</systemitem> are sent to it.</para></sect1><sect1 id="x-087-2-news.algorithm"><title>How Does Usenet Handle News?</title><para><indexterm significance="normal" class="startofrange" id="idx-newsexchanging-1"><primary>news (network)</primary><secondary>exchanging</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-newsfeeding-1"><primary>news (network)</primary><secondary>feeding</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>flooding algorithm</secondary></indexterm>
<indexterm significance="normal"><primary>flooding algorithm</primary></indexterm>
Today, Usenet has grown to enormous proportions. Sites that carry the
whole of Netnews usually transfer something like a paltry 60 MB a day.<footnote id="x-087-2-fnun02"><para> Wait a minute: 60
Megs at 9,600 bps, that's 60 million multiplied by 1,024, that
is mutter, mutter Hey! That's 34 hours!</para></footnote> Of course, this requires much
more than pushing files around. So let's take a look at the way most Unix
systems handle Usenet news.</para><para> 
News begins when users create and post articles. Each user enters a 
message into a special application called a newsreader, which 
formats it appropriately for transmission to the local 
news server. In Unix environments the newsreader commonly uses the 
<command moreinfo="none">inews</command> command to transmit articles to the 
newsserver using the TCP/IP protocol. But it's also possible to 
write the article directly into a file in a special directory called 
the news spool. Once the posting is delivered to the local 
news server, it takes responsibility for delivering the article to 
other news users.</para><para><indexterm significance="normal"><primary>news feeds</primary></indexterm>
News is distributed through the net by various transports. The medium used to be UUCP, but today the main traffic is carried by Internet
sites. The routing algorithm used is called <emphasis>flooding</emphasis>.
Each site maintains a number of links (<emphasis>news feeds</emphasis>) to
other sites. Any article generated or received by the local news system is
forwarded to them, unless it has already been at that site, in which case it
is discarded. A site may find out about all other sites the article has
already traversed by looking at the <literal moreinfo="none">Path:</literal> header field. This
header contains a list of all systems through which the article has been 
forwarded in bang path notation.</para><para><indexterm significance="normal"><primary>news (network)</primary><secondary>message IDs</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>history</secondary></indexterm>
To distinguish articles and recognize duplicates, Usenet articles have
to carry a message ID (specified in the <literal moreinfo="none">Message-Id:</literal> header
field), which combines the posting site's name and a serial number into
<replaceable>serial</replaceable>@<replaceable>site</replaceable>.
For each article processed, the news system logs this ID into a
<emphasis>history</emphasis> file, against which all newly arrived articles
are checked.</para><para><indexterm significance="normal"><primary>news (network)</primary><secondary>limiting a feed</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>distribution</secondary></indexterm>
The flow between any two sites may be limited by two criteria. For one,
an article is assigned a distribution (in the <literal moreinfo="none">Distribution:</literal>
header field), which may be used to confine it to a certain group of
sites. On the other hand, the newsgroups exchanged may be limited by
both the sending and receiving systems.  The set of newsgroups and
distributions allowed to be transmitted to a site are usually kept in the
<filename moreinfo="none">sys</filename> file.</para><para><indexterm significance="normal"><primary>news (network)</primary><secondary>batching</secondary></indexterm>
<indexterm significance="normal"><primary>batching</primary><secondary>news</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-deliveringnews-1"><primary>delivering</primary><secondary>news</secondary></indexterm>
The sheer number of articles usually requires that improvements be made
to the above scheme. On UUCP networks, systems collect articles over a period 
of time and combine them into a single file, which is compressed and sent to 
the remote site. This is called
<emphasis>batching</emphasis>.</para><para><indexterm significance="normal"><primary>news (network)</primary><secondary>ihave/sendme</secondary></indexterm>
<indexterm significance="normal"><primary>ihave/sendme protocol (news)</primary></indexterm> 
An alternative technique is the <emphasis>ihave/sendme</emphasis> protocol that
prevents duplicate articles from being transferred,
thus saving net bandwidth. Instead of putting all articles in batch
files and sending them along, only the message IDs of articles are
combined into a giant ihave message and sent to the remote
site. The remote site reads this message, compares it to its history file,
and returns the list of articles it wants in a sendme message.
Only the requested articles are sent.</para><para>Of course, ihave/sendme makes sense only if it involves two big sites
that receive news from several independent feeds each, and that poll each
other often enough for an efficient flow of news.</para><para><indexterm significance="normal"><primary>news (network)</primary><secondary>NNTP</secondary></indexterm>
Sites that are on the Internet generally rely on TCP/IP-based software that
uses the Network News Transfer Protocol (NNTP). NNTP is described in RFC-977; 
it is responsible for the transfer of news between news servers and provides
Usenet access to single users on remote hosts.</para><para><indexterm significance="normal"><primary>news (network)</primary><secondary>pulling</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>pushing</secondary></indexterm>
NNTP knows three different ways to transfer news. One is a real-time version
of ihave/sendme, also referred to as <emphasis>pushing</emphasis> news. The
second technique is called <emphasis>pulling</emphasis> news, in which the
client requests a list of articles in a given newsgroup or hierarchy that have
arrived at the server's site after a specified date, and chooses those it
cannot find in its history file. The third technique is for interactive 
newsreading and allows you or your newsreader to retrieve articles from 
specified newgroups, as well as post articles with incomplete header 
information. </para><indexterm significance="normal" class="endofrange" startref="idx-deliveringnews-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-newsexchanging-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-newsfeeding-1"></indexterm><para><?troff .hw /var/spool/news/-comp/os/linux/misc?><indexterm significance="normal"><primary>news (network)</primary><secondary>spool</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>active file</secondary></indexterm>
At each site, news is kept in a directory hierarchy below
<filename moreinfo="none">/var/spool/news</filename>, each article in a separate file, and
each newsgroup in a separate directory. The directory name is made up of the
newsgroup name, with the components being the path components. Thus,
<systemitem moreinfo="none" role="newsgroup">comp.os.linux.misc</systemitem> articles are kept
in <filename moreinfo="none">/var/spool/news/comp/os/linux/misc</filename>. The articles in a
newsgroup are assigned numbers in the order they arrive. This number serves as
the file's name. The range of numbers of articles currently online is kept
in a file called <filename moreinfo="none">active</filename>, which at the same time serves
as a list of newsgroups your site knows.</para><?troff .Nd 10?><para><indexterm significance="normal"><primary>news (network)</primary><secondary>deleting old news</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>expiration of</secondary></indexterm>
Since disk space is a finite resource, you have to start throwing away
articles after some time.<footnote id="x-087-2-fnun03"><para>Some people claim that Usenet is a conspiracy by modem and hard disk vendors.</para></footnote> This is called
<emphasis>expiring</emphasis>. Usually, articles from certain groups and
hierarchies are expired at a fixed number of days after they arrive. This
may be overridden by the poster by specifying a date of expiration in the
<literal moreinfo="none">Expires:</literal> field of the article header.
</para><para>You now have enough information to choose what to read next. UUCP users 
should read about C-News in <xref linkend="x-087-2-cnews"></xref>. If you're using 
a TCP/IP network, read about NNTP in <xref linkend="x-087-2-nntp"></xref>. If you 
need to transfer moderate amounts of news over TCP/IP, the server described 
in that chapter may be enough for you. To install a heavy-duty news server 
that can handle huge volumes of material, go on to read about InterNet News 
in <xref linkend="x-087-2-inn"></xref>.</para><indexterm significance="normal" class="endofrange" startref="idx-news-1"></indexterm><indexterm significance="normal" class="endofrange" startref="usenet.news"></indexterm></sect1></chapter><chapter id="x-087-2-cnews"><title>C News</title><indexterm significance="normal" class="startofrange" id="idx-cnews-1"><primary>C News</primary></indexterm><para>One of the most popular software packages for Netnews is C News. It was
designed for sites that carry news over UUCP links. This chapter
will discuss the central concepts of C News, basic installation,
and maintenance tasks.</para><para><indexterm significance="normal"><primary>C News</primary><secondary>spool directory</secondary></indexterm>
<indexterm significance="normal"><primary>setnewsids (C News)</primary></indexterm>
C News stores its configuration files in
<filename moreinfo="none">/etc/news</filename>, and most of its binaries are kept
below the <filename moreinfo="none">/usr/lib/news/</filename> directory.  Articles are
kept below <filename moreinfo="none">/var/spool/news</filename>.  You should make sure
that virtually all files in these directories are owned by user
<systemitem moreinfo="none" role="userid">news</systemitem> or group <systemitem moreinfo="none" role="userid">news</systemitem>. Most problems arise from files being
inaccessible to C News. Use <command moreinfo="none">su</command> to become the user
<systemitem moreinfo="none" role="userid">news</systemitem> before you touch anything
in the directory.  The only exception is the
<command moreinfo="none">setnewsids</command> command, which is used to set the real
user ID of some news programs. It must be owned by <systemitem moreinfo="none" role="userid">root</systemitem> and have the setuid bit set.</para><para>In this chapter, we describe all C News configuration files in detail
and show you what you have to do to keep your site running.</para><sect1 id="x-087-2-cnews.rnews"><title>Delivering News</title><para><indexterm significance="normal"><primary>inews command</primary></indexterm>
<indexterm significance="normal"><primary>rnews command</primary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>delivering news in</secondary></indexterm> 
<indexterm significance="normal"><primary>newsrun command</primary></indexterm> 
<indexterm significance="normal"><primary>relaynews command</primary></indexterm> 
<indexterm significance="normal"><primary>delivering</primary><secondary>news</secondary></indexterm>
Articles can be fed to C News in several ways. When a local user posts
an article, the newsreader usually hands it to the
<command moreinfo="none">inews</command> command, which completes the header
information. News from remote sites, be it a single article or a whole
batch, is given to the <command moreinfo="none">rnews</command> command, which stores
it in the <filename moreinfo="none">/var/spool/news/in.coming</filename> directory,
from where it will be picked up at a later time by
<command moreinfo="none">newsrun</command>. With any of these two techniques, however,
the article will eventually be handed to the
<command moreinfo="none">relaynews</command> command.</para><para><indexterm significance="normal"><primary>C News</primary><secondary>relaynews command</secondary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>history file</secondary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>active file</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>active file</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>history</secondary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>receiving news</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>message IDs</secondary></indexterm>
For each article, the <command moreinfo="none">relaynews</command> command first checks if the
article has already been seen at the local site by looking up the message ID
in the <filename moreinfo="none">history</filename> file. Duplicate articles are dropped.
Then <command moreinfo="none">relaynews</command> looks at the <literal moreinfo="none">Newsgroups:</literal>
header line to find out if the local site requests articles from any of these
groups.  If it does, and the newsgroup is listed in the
<filename moreinfo="none">active</filename> file, <command moreinfo="none">relaynews</command> tries to store
the article in the corresponding directory in the news spool area. If this
directory does not exist, it is created. The article's message ID is then 
logged to the <filename moreinfo="none">history</filename> file.  Otherwise,
<command moreinfo="none">relaynews</command> drops the article.</para><para><indexterm significance="normal"><primary>junk newsgroup</primary></indexterm>
Sometimes <command moreinfo="none">relaynews</command> fails to store an incoming
article because a group to which it has been posted is not listed in
your <filename moreinfo="none">active</filename> file. In this case, the article is moved to the <systemitem moreinfo="none" role="newsgroup">junk</systemitem>
group.<footnote id="x-087-2-fncn01"><para> There may be a difference
between the groups that exist at your site and those that your site
is willing to receive. For example, the subscription list might
specify <systemitem moreinfo="none" role="newsgroup">comp.all</systemitem>, which
should send all newsgroups below the <systemitem moreinfo="none" role="newsgroup">comp</systemitem> hierarchy, but at your site you
might not list several of the <systemitem moreinfo="none" role="newsgroup">comp</systemitem> newsgroups in the
<filename moreinfo="none">active</filename> file. Articles posted to those groups will
be moved to <systemitem moreinfo="none" role="newsgroup">junk</systemitem>.</para></footnote>
<command moreinfo="none">relaynews</command> also checks for stale or misdated articles
and reject them. Incoming batches that fail for any other reason are moved
to <filename moreinfo="none">/var/spool/news/in.coming/bad</filename>, and an error message
is logged.</para><para>After this, the article is relayed to all other sites that request news
from these groups, using the transport specified for each particular site. To
make sure an article isn't sent to a site that has already seen it, each
destination site is checked against the article's <literal moreinfo="none">Path:</literal>
header field, which contains the list of sites the article has traversed so
far, written in the UUCP-style bang-path source-routing style described in
<xref linkend="x-087-2-mail"></xref>. If the destination site's name does not
appear in this list, the article is sent to it.</para><para><indexterm significance="normal"><primary>C News</primary><secondary>UUCP</secondary></indexterm>
<indexterm significance="normal"><primary>UUCP</primary><secondary>news</secondary></indexterm>
C News is commonly used to relay news between UUCP sites, although it is
also possible to use it in an NNTP environment. To deliver news to a remote
UUCP site, either in single articles or whole batches, <command moreinfo="none">uux</command>
is used to execute the <command moreinfo="none">rnews</command> command on the remote site and
feed the article or batch to it on standard input.
Refer to <xref linkend="x-087-2-uucp"></xref>, for more information on UUCP.</para><para><indexterm significance="normal"><primary>C News</primary><secondary>batching</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>batching</secondary></indexterm>
Batching is the term used to describe sending large bundles of
individual articles all in one transmission. When batching is
enabled for a given site, C News does not send any incoming article
immediately; instead, it appends its path name to a file, usually called
<filename moreinfo="none">out.going/site/togo</filename>. Periodically, a program is executed
from a <command moreinfo="none">crontab</command> entry by the <command moreinfo="none">cron</command> program,
which reads this file and bundles all of the listed articles into one or more
file, optionally compressing them and sending them to <command moreinfo="none">rnews</command>
at the remote site.<footnote id="x-087-2-fncn02"><para>Note that this should be the <command moreinfo="none">crontab</command> of
<systemitem moreinfo="none" role="userid">news</systemitem>; file permissions will not be 
mangled.</para></footnote>
</para><para><xref linkend="x-087-2-cnews.fig.flow"></xref> shows the news flow through
<command moreinfo="none">relaynews</command>. Articles may be relayed to the local site
(denoted by <systemitem moreinfo="none" role="keyword">ME</systemitem>), to a site named
<systemitem moreinfo="none" role="sitename">ponderosa</systemitem> via email, and a site
named <systemitem moreinfo="none" role="sitename">moria</systemitem>, for which batching is
enabled.</para><figure float="0" id="x-087-2-cnews.fig.flow"><title>News flow through relaynews</title><graphic fileref="lag2_2101.jpg"></graphic></figure></sect1><sect1><title>Installation</title><para><indexterm significance="normal" class="startofrange" id="idx-configuringcnews-1"><primary>configuring</primary><secondary>C News</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-configuringusenetnews-1"><primary>configuring</primary><secondary>Usenet news</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="chcn.cnews.install"><primary>C News</primary><secondary>installing</secondary></indexterm> 
C News should be available in a prepackaged format for any modern Linux
distribution, so installation will be easy. If not, or if you want to
install from the original source distribution, then of course you
can.<footnote id="x-087-2-fncn03"><para>You can obtain the C News source distribution from its home site at
<systemitem moreinfo="none" role="sitename">ftp.cs.toronto.edu</systemitem>
<filename moreinfo="none">/pub/c-news/c-news.tar.Z</filename></para></footnote> No matter how you install it, you will need to edit the C
News configuration files. Their formats are described in the following
list:</para><variablelist><varlistentry><term><filename moreinfo="none">sys</filename></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>sys file</secondary></indexterm>
The <filename moreinfo="none">sys</filename> file controls which newsgroups your site
receives and forwards. We discuss it in detail in the following
section.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">active</filename></term><listitem><para>Not usually edited by the administration; contains directions for handling 
articles in each newsgroup the site handles.
</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">organization</filename></term><listitem><para>This file should contain your organization's name, for example,
Virtual Brewery, Inc. On your home machine, enter
private site, or anything else you like. Most people
will not consider your site properly configured if you haven't customized
this file.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">newsgroups</filename></term><listitem><para>This file is a list of all newsgroups, with a one-line description of each
one's purpose. These descriptions are frequently used by your newsreader
when displaying the list of all groups to which you are subscribed.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">mailname</filename></term><listitem><para>Your site's mail name, e.g., <systemitem moreinfo="none" role="sitename">vbrew.com</systemitem>.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">whoami</filename></term><listitem><para>Your site's name for news purposes. Quite often, the UUCP site name is used,
e.g., <systemitem moreinfo="none" role="sitename">vbrew</systemitem>.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">explist</filename></term><listitem><para>You should probably edit this file to reflect your preferred expiration times
for special newsgroups. Disk space may play an important role in your choices.</para></listitem></varlistentry></variablelist><para><indexterm significance="normal"><primary>C News</primary><secondary>creating initial configuration</secondary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>active file</secondary></indexterm>
To create an initial hierarchy of newsgroups, obtain 
<filename moreinfo="none">active</filename> and <filename moreinfo="none">newsgroups</filename> files
from the site that feeds you. Install them in <filename moreinfo="none">/etc/news</filename>,
making sure they are owned by <systemitem moreinfo="none" role="userid">news</systemitem> and
have a mode of 644, using the <command moreinfo="none">chmod</command> command. Remove all
<systemitem moreinfo="none" role="newsgroup">to.*</systemitem> groups from the active file,
and add <systemitem moreinfo="none" role="newsgroup">to.my-site</systemitem>,
<systemitem moreinfo="none" role="newsgroup">to.feed-site</systemitem>,
<systemitem moreinfo="none" role="newsgroup">junk</systemitem>, and
<systemitem moreinfo="none" role="newsgroup">control</systemitem>. The
<systemitem moreinfo="none" role="newsgroup">to.*</systemitem> groups are normally used for
exchanging ihave/sendme messages, but you should list them regardless of
whether you plan to use ihave/sendme or not. Next, replace all article
numbers in the second and third field of <filename moreinfo="none">active</filename> using
the following commands:

<screen format="linespecific"># <userinput moreinfo="none">cp active active.old</userinput>
# <userinput moreinfo="none">sed 's/ [0-9]* [0-9]* / 0000000000 00001 /' active.old  active</userinput>
# <userinput moreinfo="none">rm active.old</userinput></screen></para><para><indexterm significance="normal"><primary>sed command (UNIX)</primary></indexterm> 
The second command invokes the <command moreinfo="none">sed</command> stream
editor. This invocation replaces two strings of digits with a string of
zeroes and the string <literal moreinfo="none">000001</literal>, respectively.</para><para>Finally, create the news spool directory and the subdirectories used for
incoming and outgoing news:

<screen format="linespecific"># <userinput moreinfo="none">cd /var/spool</userinput>
# <userinput moreinfo="none">mkdir news news/in.coming news/out.going news/out.master</userinput>
# <userinput moreinfo="none">chown -R news.news news</userinput>
# <userinput moreinfo="none">chmod -R 755 news</userinput></screen></para><?troff .wcon_off?><para>If you're using precompiled newsreaders sourced from a different
distribution to the C News server you have running, you may find that
some expect the news spool in <filename moreinfo="none">/usr/spool/news</filename>
rather than <filename moreinfo="none">/var/spool/news</filename>. If your newsreader
doesn't seem to find any articles, create a symbolic link from<?troff .ne 10?>
<filename moreinfo="none">/usr/spool/news</filename> to
<filename moreinfo="none">/var/spool/news</filename> like this:
<screen format="linespecific"># <userinput moreinfo="none">ln -sf /usr/spool/news /var/spool/news</userinput></screen></para><para>Now you are ready to receive news. Note that you don't have to create the
individual newsgroup spool directories. C News automatically creates
spool directories for any newsgroup it receives an article for, if one doesn't
already exist.</para><para>In particular, this happens to <emphasis>all</emphasis> groups to which an 
article has been cross-posted. So, after a while, you will find your news spool
cluttered with directories for newsgroups you have never subscribed
to, like <systemitem moreinfo="none" role="newsgroup">alt.lang.teco</systemitem>. You may
prevent this by either removing all unwanted groups from
<filename moreinfo="none">active</filename>, or by regularly running a shell script that 
removes all empty directories below <filename moreinfo="none">/var/spool/news</filename>
(except <filename moreinfo="none">out.going</filename> and <filename moreinfo="none">in.coming</filename>,
of course).</para><para><indexterm significance="normal"><primary>C News</primary><secondary>usenet</secondary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>newsmaster</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>newsmaster</secondary></indexterm>
<indexterm significance="normal"><primary>newsmaster</primary></indexterm>
C News needs a user to send error messages and status reports to. By
default, this is <systemitem moreinfo="none" role="userid">usenet</systemitem>. If you
use the default, you have to set up an alias for it that forwards all
of its mail to one or more responsible person. You may also override
this behavior by setting the environment variable <systemitem moreinfo="none" role="keyword">NEWSMASTER</systemitem> to the appropriate name. You
have to do so in <systemitem moreinfo="none" role="userid">news</systemitem>'s
<filename moreinfo="none">crontab</filename> file, as well as every time you invoke an
administrative tool manually, so installing an alias is probably
easier. Mail aliases are described in <xref linkend="x-087-2-sendmail"></xref>, and <xref linkend="x-087-2-exim"></xref>.</para><para><indexterm significance="normal"><primary sortas="etc/passwd file">/etc/passwd file</primary><secondary>real user names</secondary></indexterm>
<indexterm significance="normal"><primary>real user names</primary></indexterm>
<indexterm significance="normal"><primary>full user names</primary></indexterm>
While you're hacking <filename moreinfo="none">/etc/passwd</filename>, make sure that every
user has her real name in the <systemitem moreinfo="none" role="keyword">pw_gecos</systemitem>
field of the password file (this is the fourth field). It is a question of
Usenet netiquette that the sender's real name appears in the
<literal moreinfo="none">From:</literal> field of the article. Of course, you will want to
do so anyway when you use mail.</para><indexterm significance="normal" class="endofrange" startref="chcn.cnews.install"></indexterm></sect1><sect1 id="x-087-2-cnews.sys"><title>The sys File</title><para><indexterm significance="normal" class="startofrange" id="idx-cnewsfilenamesysfilenamefile-1"><primary>C News</primary><secondary>sys 
file</secondary></indexterm>
<indexterm significance="normal"><primary>sys file (/etc/news)</primary></indexterm>
The <filename moreinfo="none">sys</filename> file, located in
<filename moreinfo="none">/etc/news</filename>, controls which hierarchies you receive
and forward to other sites. Although there are maintenance tools named
<command moreinfo="none">addfeed</command> and <command moreinfo="none">delfeed</command>, we think
it's better to maintain this file by hand.</para><para>The <filename moreinfo="none">sys</filename> file contains entries for each site to
which you forward news, as well as a description of the groups you
will accept. The first line is a
<systemitem moreinfo="none" role="keyword">ME</systemitem> entry that describes your
system. It's a safe bet to use the following:

<screen format="linespecific">ME:all/all::</screen>

You also have to add a line for each site to which you feed news.
Each line looks like this:

<screen format="linespecific"><replaceable>site</replaceable>[/<replaceable>exclusions</replaceable>]:<replaceable>grouplist</replaceable>[/<replaceable>distlist</replaceable>][:<replaceable>flags</replaceable>[:<replaceable>cmds</replaceable>]]</screen></para><para>Entries may be continued across newlines using a backslash
(<systemitem moreinfo="none" role="keyword">\</systemitem>) at the end of the line to be
continued. A hash sign (<systemitem moreinfo="none" role="keyword">#</systemitem>) denotes a
comment.</para><variablelist><varlistentry><term><replaceable>site</replaceable></term><listitem><para>This is the name of the site the entry applies to. One usually
chooses the site's UUCP name for this.  There has to be an entry
for your site in the <filename moreinfo="none">sys</filename> file too, or you will not
receive any articles yourself.</para><para><indexterm significance="normal"><primary>C News</primary><secondary>receiving news</secondary></indexterm>
<indexterm significance="normal"><primary>receiving news</primary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>receiving</secondary></indexterm>
The special site name <systemitem moreinfo="none" role="keyword">ME</systemitem> denotes your
site. The <systemitem moreinfo="none" role="keyword">ME</systemitem> entry defines all groups
you are willing to store locally. Articles that aren't matched by the
<systemitem moreinfo="none" role="keyword">ME</systemitem> line will go to the
<systemitem moreinfo="none" role="newsgroup">junk</systemitem> group.</para><para><indexterm significance="normal"><primary>C News</primary><secondary>excluding sites</secondary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>hostname aliases</secondary></indexterm>
<indexterm significance="normal"><primary>aliases</primary><secondary>C News and</secondary></indexterm>
C News rejects any articles that have already passed through this site to
prevent loops. C News does this by ensuring that the local site name does not
appear in the <literal moreinfo="none">Path:</literal> of the article. Some sites may be known
by a number of valid names. For example, some sites use their fully qualified
domain name in this field, or an alias like
<literal moreinfo="none">news.</literal><replaceable>site.domain</replaceable>. To ensure the
loop prevention mechanism works, it is important to add all aliases to the 
exclusion list, separating them by commas.</para><para><?troff .hw contain?><?troff .hw orcnet?>For the entry applying to site <systemitem moreinfo="none" role="sitename">moria</systemitem>,
for instance, the <replaceable>site</replaceable> field would contain
<systemitem moreinfo="none" role="keyword">moria/moria.orcnet.org</systemitem>. If
<systemitem moreinfo="none" role="sitename">moria</systemitem> were also by an alias of
<systemitem moreinfo="none" role="sitename">news.orcnet.org</systemitem>, then our
<replaceable>site</replaceable> field would contain
<systemitem moreinfo="none" role="keyword">moria/moria.orcnet.org,news.orcnet.org</systemitem>.</para></listitem></varlistentry><varlistentry><term><replaceable>grouplist</replaceable></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>exchanging news</secondary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>limiting a feed</secondary></indexterm>
This is a comma-separated subscription list of groups and hierarchies
for this particular site. A hierarchy may be specified by giving the
hierarchy's prefix (such as <systemitem moreinfo="none" role="newsgroup">comp.os</systemitem> for all groups whose names start
with this prefix), optionally followed by the keyword <systemitem moreinfo="none" role="newsgroup">all</systemitem> (e.g., <systemitem moreinfo="none" role="newsgroup">comp.os.all</systemitem>).</para><para>You can exclude a hierarchy or group from forwarding by preceding it with an
exclamation mark. If a newsgroup is checked against the list, the longest
match applies. For example, if <replaceable>grouplist</replaceable>
contains this list:

<screen format="linespecific">!comp,comp.os.linux,comp.folklore.computers</screen>

no groups from the <systemitem moreinfo="none" role="newsgroup">comp</systemitem> hierarchy
except <systemitem moreinfo="none" role="newsgroup">comp.folklore.computers</systemitem> and
all groups below <systemitem moreinfo="none" role="newsgroup">comp.os.linux</systemitem> will
be fed to that site.</para><para>If the site requests to be forwarded all news you receive yourself, enter
<systemitem moreinfo="none" role="keyword">all</systemitem> as
<replaceable>grouplist</replaceable>.</para></listitem></varlistentry><varlistentry><term><replaceable>distlist</replaceable></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>limiting a feed</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>distribution</secondary></indexterm>
This value is offset from the <replaceable>grouplist</replaceable> by
a slash and contains a list of distributions to be forwarded. Again,
you may exclude certain distributions by preceding them with an
exclamation mark. All distributions are denoted by <systemitem moreinfo="none" role="keyword">all</systemitem>.  Omitting
<replaceable>distlist</replaceable> implies a list of <systemitem moreinfo="none" role="keyword">all</systemitem>.</para><?troff .wcon_off?><para>For example, you may use a distribution list of
<systemitem moreinfo="none" role="keyword">all,!local</systemitem> to prevent news meant only 
for local use from being sent to remote sites.</para><para>There are usually at least two distributions:
<systemitem moreinfo="none" role="keyword">world</systemitem>, which is often the default
distribution used when none is specified by the user, and
<systemitem moreinfo="none" role="keyword">local</systemitem>. There may be other
distributions that apply to a certain region, state, country,
etc. Finally, there are two distributions used by C News only;
these are <systemitem moreinfo="none" role="keyword">sendme</systemitem> and
<systemitem moreinfo="none" role="keyword">ihave</systemitem>, and are used for
the sendme/ihave protocol.</para><para>The use of distributions is a subject of debate. The distribution
field in a news article can be created arbitrarily, but for a
distribution to be effective, the news servers in the network must
know it. Some misbehaving newsreaders create bogus distributions by
simply assuming the top-level newsgroup hierarchy of the article
destination is a reasonable distribution.  For example, one might
assume <systemitem moreinfo="none" role="newsgroup">comp</systemitem> to be a
reasonable distribution to use when posting to the <systemitem moreinfo="none" role="newsgroup">comp.os.linux.networking</systemitem>
newsgroup. Distributions that apply to regions are often questionable,
too, because news may travel outside of your region when sent across
the Internet.<footnote id="x-087-2-fncn04"><para> It is not uncommon
for an article posted in say, Hamburg, to go to Frankfurt via
<systemitem moreinfo="none" role="sitename">reston.ans.net</systemitem> in the
Netherlands, or even via some site in the U.S.</para></footnote>
Distributions applying to an organization, however, are
very meaningful; e.g., to prevent confidential information from
leaving the company network.  This purpose, however, is generally
served better by creating a separate newsgroup or hierarchy.</para></listitem></varlistentry><varlistentry><term><replaceable>flags</replaceable></term><listitem><para>This option describes certain parameters for the feed. It may be
empty or a combination of the following:

 <variablelist><varlistentry><term><literal moreinfo="none">F</literal></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>batching</secondary></indexterm>
 This flag enables batching.
 </para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">f</literal></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>batching</secondary></indexterm>
 This is almost identical to the <literal moreinfo="none">F</literal> flag,
 but allows C News to calculate the size of outgoing batches more precisely,
 and should probably be used in preference.
 </para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">I</literal></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>ihave/sendme</secondary></indexterm>
 This flag makes C News produce an article list suitable
 for use by ihave/sendme. Additional modifications to the
 <filename moreinfo="none">sys</filename> and the <filename moreinfo="none">batchparms</filename> file are
 required to enable ihave/sendme.
 </para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">n</literal></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>NNTP support</secondary></indexterm>
 This creates batch files for active NNTP transfer clients like
 <command moreinfo="none">nntpxmit</command> (see <xref linkend="x-087-2-nntp"></xref>).
 The batch files contain the article's filename along with its message ID.
 </para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">L</literal></term><listitem><para> This tells C News to transmit only articles posted at your site. This flag
 may be followed by a decimal number <replaceable>n</replaceable>, which
 makes C News transfer articles posted only within <replaceable>n</replaceable>
 hops from your site. C News determines the number of hops from the
 <replaceable>Path:</replaceable> field.
 </para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">u</literal></term><listitem><para> This tells C News to batch only articles from unmoderated groups. 
 </para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">m</literal></term><listitem><para> This tells C News to batch only articles from moderated groups. 
 </para></listitem></varlistentry></variablelist></para><para>You may use at most one of <literal moreinfo="none">F</literal>,
<literal moreinfo="none">f</literal>,
<literal moreinfo="none">I</literal>, or
<literal moreinfo="none">n</literal>.</para></listitem></varlistentry><varlistentry><term><replaceable>cmds</replaceable></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>rnews command</secondary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>exchanging news</secondary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>sending news</secondary></indexterm>
This field contains a command that will be executed for each article,
unless you enable batching. The article will be fed to the command on
standard input. This should be used for very small feed only;
otherwise, the load on both systems will be too high.</para><para>The default command is:

<screen format="linespecific">uux - -r -z <replaceable>remote-system</replaceable>!rnews</screen></para><para>This invokes <command moreinfo="none">rnews</command> on the remote system, feeding it
the article on standard input.</para><para>The default search path for commands given in this field is
<filename moreinfo="none">/bin:/usr/bin:/usr/lib/news/batch</filename>. The latter
directory contains a number of shell scripts whose names start with
<command moreinfo="none">via</command>; they are briefly described later in this chapter.</para><para><indexterm significance="normal"><primary>C News</primary><secondary>batching</secondary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>togo file</secondary></indexterm>
If batching is enabled using one of the
<literal moreinfo="none">F</literal>,
<literal moreinfo="none">f</literal>,
<literal moreinfo="none">I</literal>, or
<literal moreinfo="none">n</literal> flags, C News expects to find a
filename in this field rather than a command. If the filename does not
begin with a slash (/), it is assumed to be relative to
<filename moreinfo="none">/var/spool/news/out.going</filename>. If the field is
empty, it defaults to <filename moreinfo="none">remote-system/togo</filename>. The file is
expected to be in the same format as the <filename moreinfo="none">remote-system/togo</filename> file and contain a list of articles to transmit.</para></listitem></varlistentry></variablelist><para>When setting up C News, you will most probably have to write your own
<filename moreinfo="none">sys</filename> file. Here is a sample file for
<systemitem moreinfo="none" role="sitename">vbrew.com</systemitem>, from which you may copy 
what you need:</para><screen format="linespecific"># We take whatever they give us.
ME:all/all::
# We send everything we receive to moria, except for local and
# brewery-related articles. We use batching.
moria/moria.orcnet.org:all,!to,to.moria/all,!local,!brewery:f:
# We mail comp.risks to jack@ponderosa.uucp
ponderosa:comp.risks/all::rmail jack@ponderosa.uucp
# swim gets a minor feed
swim/swim.twobirds.com:comp.os.linux,rec.humor.oracle/all,!local:f:
# Log mail map articles for later processing
usenet-maps:comp.mail.maps/all:F:/var/spool/uumaps/work/batch</screen><indexterm significance="normal" class="endofrange" startref="idx-cnewsfilenamesysfilenamefile-1"></indexterm></sect1><sect1 id="x-087-2-cnews.active"><title>The active File</title><para><indexterm significance="normal"><primary>C News</primary><secondary>active file</secondary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>list of current groups</secondary></indexterm>
<indexterm significance="normal"><primary>active.times file (/var/lib/news)</primary></indexterm> 
The <filename moreinfo="none">active</filename> file is located in
<filename moreinfo="none">/etc/</filename>, and lists all groups known at your site
and the articles currently online. You will rarely have to touch it, but
we explain it nevertheless for sake of completion. Entries take the
following form:

<screen format="linespecific"><replaceable>newsgroup</replaceable> <replaceable>high</replaceable> <replaceable>low</replaceable> <replaceable>perm</replaceable></screen></para><para><replaceable>newsgroup</replaceable> is the group's name.
<replaceable>low</replaceable> and <replaceable>high</replaceable> are the
lowest and highest numbers of articles currently available. If none are
available at the moment, <replaceable>low</replaceable> is equal to
<replaceable>high</replaceable>+1.</para><para><indexterm significance="normal"><primary>C News</primary><secondary>update low water mark</secondary></indexterm>
At least that's what the <replaceable>low</replaceable> field is meant to do.
However, for efficiency, C News doesn't update this field. This wouldn't be
such a big loss if there weren't newsreaders that depend on it. For
instance, <command moreinfo="none">trn</command> checks this field to see if it can purge any
articles from its thread database. To update the <replaceable>low</replaceable>
field, you therefore have to run the <command moreinfo="none">updatemin</command> command
regularly (or, in earlier versions of C News, the <command moreinfo="none">upact</command>
script).</para><para><replaceable>perm</replaceable> is a parameter detailing the access users are
granted to the group. It takes one of the following values:

<variablelist><varlistentry><term><systemitem moreinfo="none" role="keyword">y</systemitem></term><listitem><para>Users are allowed to post to this group.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">n</systemitem></term><listitem><para>Users are not allowed to post to this group. However, the group may still
be read.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">x</systemitem></term><listitem><para>This group has been disabled locally. This happens sometimes when news
administrators (or their superiors) take offense at articles posted to
certain groups.</para><para>Articles received for this group are not stored locally, although they are
forwarded to the sites that request them.</para></listitem></varlistentry><varlistentry><term><systemitem moreinfo="none" role="keyword">m</systemitem></term><listitem><para>This denotes a moderated group. When a user tries to post to this group,
an intelligent newsreader notifies her of this and send the article to
the moderator instead. The moderator's address is taken from the
<filename moreinfo="none">moderators</filename> file in <filename moreinfo="none">/var/lib/news</filename>.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">=</literal><replaceable>real-group</replaceable></term><listitem><para>This marks <replaceable>newsgroup</replaceable> as being a local alias for
another group, namely <replaceable>real-group</replaceable>. All articles
posted to <replaceable>newsgroup</replaceable> will be redirected to it.</para></listitem></varlistentry></variablelist></para><para>In C News, you will generally not have to access this file directly.
Groups can be added or deleted locally using
<command moreinfo="none">addgroup</command> and <command moreinfo="none">delgroup</command> (see the
section <xref linkend="x-087-2-cnews.maint"></xref> later in this chapter).  A
<systemitem moreinfo="none" role="keyword">newgroup</systemitem> control message adds
a group for the whole of Usenet, while a <systemitem moreinfo="none" role="keyword">rmgroup</systemitem> message deletes a group.
<emphasis>Never send such a message yourself!</emphasis> For
instructions on how to create a newsgroup, read the monthly postings
in <systemitem moreinfo="none" role="newsgroup">news.announce.newusers</systemitem>.</para><para><indexterm significance="normal"><primary>active.times file (/var/lib/news)</primary></indexterm> 
The <filename moreinfo="none">active.times</filename> file is closely related to the 
<filename moreinfo="none">active</filename> file. Whenever a group is created, C News logs
a message to this file containing the name of the group created, the date of
creation, whether it was done by a
<systemitem moreinfo="none" role="keyword">newgroup</systemitem> control message or locally,
and who did it. This is convenient for newsreaders that may notify
the user of any recently created groups. It is also used by the
<command moreinfo="none">NEWGROUPS</command> command of NNTP.</para></sect1><sect1 id="x-087-2-cnews.batcher"><title>Article Batching</title><para><indexterm significance="normal" class="startofrange" id="idx-cnewssendingnews-1"><primary>C News</primary><secondary>sending news</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-cnewsbatching-1"><primary>C News</primary><secondary>article batching</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="idx-batchingnews-1"><primary>batching</primary><secondary>news</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>articles</secondary><tertiary>batching</tertiary></indexterm>
<indexterm significance="normal"><primary>articles (news)</primary><secondary>batching</secondary></indexterm>
News batches follow a particular format that is the same for
B News, C News, and INN. Each article is preceded by a line like this:

<screen format="linespecific">#! rnews <replaceable>count</replaceable></screen></para><para><replaceable>count</replaceable> is the number of bytes in the article. When
you use batch compression, the resulting file is compressed as a whole and
preceded by another line, indicated by the message to be used for unpacking.
The standard compression tool is
<systemitem moreinfo="none" role="newsgroup">compress</systemitem>, which is marked by:

<screen format="linespecific">#! cunbatch</screen></para><para>Sometimes, when the news server sends batches via mail software that
removes the eighth bit from all data, a compressed batch may be
protected using what is called <emphasis>c7-encoding</emphasis>; these
batches will be marked by <command moreinfo="none">c7unbatch</command>.</para><para>When a batch is fed to <command moreinfo="none">rnews</command> on the remote site, it
checks for these markers and processes the batch appropriately.  Some
sites also use other compression tools, like <command moreinfo="none">gzip</command>,
and precede their gzipped files with the word
<command moreinfo="none">zunbatch</command> instead. C News does not recognize
nonstandard headers like these; you have to modify the source to
support them.</para><para><indexterm significance="normal"><primary>sendbatches command</primary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>sending news</secondary></indexterm>
In C News, article batching is performed by
<filename moreinfo="none">/usr/lib/news/batch/sendbatches</filename>,
which takes a list of articles from the <filename moreinfo="none">site/togo</filename> file
and puts them into several newsbatches.  It should be executed once per hour,
or even more frequently, depending on the volume of traffic. Its operation
is controlled by the <filename moreinfo="none">batchparms</filename> file in
<filename moreinfo="none">/var/lib/news</filename>. This file describes the maximum batch
size allowed for each site, the batching and optional compression program
to be used, and the transport for delivering it to the remote site. You
may specify batching parameters on a per-site basis, as well as a set of
default parameters for sites not explicitly mentioned.</para><para>When installing C News, you will most likely find a
<filename moreinfo="none">batchparms</filename> file in your distribution that contains
a reasonable default entry, so there's a good chance that you won't have
to touch the file. Just in case, we describe its format. Each line consists
of six fields, separated by spaces or tabs:

<screen format="linespecific"><replaceable>site</replaceable> <replaceable>size</replaceable> <replaceable>max</replaceable> <replaceable>batcher</replaceable> <replaceable>muncher</replaceable> <replaceable>transport</replaceable></screen></para><?troff .wcon_off?><variablelist><varlistentry><term><replaceable>site</replaceable></term><listitem><para><replaceable>site</replaceable> is the name of the site to which the entry 
applies. The <filename moreinfo="none">togo</filename> file for this site must reside in
<filename moreinfo="none">out.going/togo</filename> below the news spool. A site name of
<systemitem moreinfo="none" role="keyword">/default/</systemitem> denotes the default entry and
is to match any site not directly specified with an entry unique to it.</para></listitem></varlistentry><varlistentry><term><replaceable>size</replaceable></term><listitem><para><replaceable>size</replaceable> is the maximum size of article batches
created (before compression). For single articles larger than this, C News
makes an exception and puts each in a single batch by itself.</para></listitem></varlistentry><varlistentry><term><replaceable>max</replaceable></term><listitem><para><replaceable>max</replaceable> is the maximum number of batches created and
scheduled for transfer before batching stalls for this particular site. This
is useful in case the remote site should be down for a long time,
because it prevents C News from cluttering your UUCP spool directories 
with zillions of newsbatches.</para><para>C News determines the number of queued batches using the
<command moreinfo="none">queuelen</command> script in <filename moreinfo="none">/usr/lib/news/</filename>.
If you've installed C News in a prepackaged format, the script should not
need any editing, but if you choose to use a different flavor of spool
directories, for example, Taylor UUCP, you might have to write your
own. If you don't care about the number of spool files (because you're the only
person using your computer and you don't write articles by the megabyte),
you may replace the script's contents by a simple <command moreinfo="none">exit 0</command>
statement.</para></listitem></varlistentry><varlistentry><term><replaceable>batcher</replaceable></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>ihave/sendme</secondary></indexterm>
The <replaceable>batcher</replaceable> field contains the command used for
producing a batch from the list of articles in the <filename moreinfo="none">togo</filename>
file. For regular feeds, this is usually <command moreinfo="none">batcher</command>. For
other purposes, alternative batchers may be provided. For instance, the
ihave/sendme protocol requires the article list to be turned into 
<emphasis>ihave</emphasis> or <emphasis>sendme</emphasis> control messages, 
which are posted to the newsgroup
<systemitem moreinfo="none" role="newsgroup">to.site</systemitem>. This is performed by
<command moreinfo="none">batchih</command> and <command moreinfo="none">batchsm</command>.</para></listitem></varlistentry><varlistentry><term><replaceable>muncher</replaceable></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>compressing batches</secondary></indexterm>
The <replaceable>muncher</replaceable> field specifies the compression
command. Usually, this is <systemitem moreinfo="none" role="newsgroup">compcun</systemitem>, a script that produces a
compressed batch.<footnote id="x-087-2-fncn06"><para> As shipped with
C News, <systemitem moreinfo="none" role="newsgroup">compcun</systemitem> uses
<systemitem moreinfo="none" role="newsgroup">compress</systemitem> with the 12-bit
option, since this is the lowest common denominator for most
sites. You may produce a copy of the script, say <systemitem moreinfo="none" role="newsgroup">compcun16</systemitem>, for which you use 16-bit
compression. The improvement is not too impressive, though.</para></footnote>
 Alternatively, suppose you create a muncher that uses
<command moreinfo="none">gzip</command>, say <userinput moreinfo="none">gzipcun</userinput> (note that you
have to write it yourself).  You have to make sure that
<command moreinfo="none">uncompress</command> on the remote site is patched to
recognize files compressed with <command moreinfo="none">gzip</command>.</para><para>If the remote site does not have an <command moreinfo="none">uncompress</command> command,
you may specify <command moreinfo="none">nocomp</command>, which does not do any compression.</para></listitem></varlistentry><varlistentry><term><replaceable>transport</replaceable></term><listitem><para>The last field, <replaceable>transport</replaceable>, describes the
transport to be used. A number of standard commands for different
transports are available; their names begin with
<command moreinfo="none">via</command>.  <command moreinfo="none">sendbatches</command> passes them
the destination sitename on the command line. If the
<filename moreinfo="none">batchparms</filename> entry is not <systemitem moreinfo="none" role="keyword">/default/</systemitem>, <command moreinfo="none">sendbatches</command>
derives the sitename from the <replaceable>site</replaceable> field by
stripping it of anything after and including the first dot or
slash. If the <systemitem moreinfo="none" role="keyword">batchparms</systemitem> entry
is <systemitem moreinfo="none" role="keyword">/default/</systemitem>, the directory
names in <filename moreinfo="none">out.going</filename> are used.</para></listitem></varlistentry></variablelist><?troff .Nd 10?><para>To perform batching for a specific site, use the following command:

<screen format="linespecific"># <userinput moreinfo="none">su news -c "/usr/lib/news/batch/sendbatches site"</userinput></screen></para><para><indexterm significance="normal" class="startofrange" id="idx-cnewsbatchparameters-1"><primary>C News</primary><secondary>batch parameters</secondary></indexterm>
When invoked without arguments, <command moreinfo="none">sendbatches</command> handles all
batch queues. The interpretation of all depends on the presence
of a default entry in <filename moreinfo="none">batchparms</filename>. If one is found, all
directories in <filename moreinfo="none">/var/spool/news/out.going</filename> are checked;
otherwise, <command moreinfo="none">sendbatches</command> cycles through all entries in
<filename moreinfo="none">batchparms</filename>, processing just the sites found there.
Note that <command moreinfo="none">sendbatches</command>, when scanning the
<filename moreinfo="none">out.going</filename> directory, takes only those directories
that contain no dots or at signs (<systemitem moreinfo="none" role="keyword">@</systemitem>)
as sitenames.</para><para><indexterm significance="normal"><primary>rnews command</primary></indexterm>
<indexterm significance="normal"><primary>uux command</primary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>UUCP</secondary></indexterm>
There are two commands that use <command moreinfo="none">uux</command> to execute
<command moreinfo="none">rnews</command> on the remote system:
<command moreinfo="none">viauux</command> and <command moreinfo="none">viauuxz</command>. The latter
sets the <option>z</option> flag for <command moreinfo="none">uux</command> to
keep older versions from returning success messages for each article
delivered. Another command, <command moreinfo="none">viamail</command>, sends article
batches to the user <systemitem moreinfo="none" role="userid">rnews</systemitem> on
the remote system via mail.  Of course, this requires that the remote
system somehow feeds all mail for <systemitem moreinfo="none" role="userid">rnews</systemitem> to its local news system.  For a
complete list of these transports, refer to the
<filename moreinfo="none">newsbatch</filename> manual page.</para><para>All commands from the last three fields must be located in either
<filename moreinfo="none">out.going/site</filename> or
<filename moreinfo="none">/usr/lib/news/batch</filename>. Most of them are scripts; you 
can easily tailor new tools for your personal needs. They are
invoked through pipes. The list of articles is fed to the batcher on standard
input, which produces the batch on standard output. This is piped into the
muncher, and so on.</para><para>Here is a sample file:</para><screen format="linespecific"># batchparms file for the brewery
# site        | size   |max    |batcher  |muncher    |transport
#-------------+--------+-------+---------+-----------+-----------
/default/       100000  22      batcher   compcun     viauux
swim             10000  10      batcher   nocomp      viauux</screen><indexterm significance="normal" class="endofrange" startref="idx-cnewsbatchparameters-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-cnewssendingnews-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-cnewsbatching-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-batchingnews-1"></indexterm></sect1><sect1 id="x-087-2-cnews.explist"><title>Expiring News</title><para><indexterm significance="normal" class="startofrange" id="idx-cnewsexpiring-1"><primary>C News</primary><secondary>expiration of news in</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>expiration of</secondary></indexterm>
<indexterm significance="normal"><primary>cron</primary><secondary>expiring mail from</secondary></indexterm> 
In B News, expiration needs to be performed by a program called
<command moreinfo="none">expire</command>, which took a list of newsgroups as arguments,
along with a time specification after which articles had to be expired.
To have different hierarchies expire at different times, you had to write a
script that invoked <command moreinfo="none">expire</command> for each of them separately.
C News offers a more convenient solution. In a file called
<filename moreinfo="none">explist</filename>, you may specify newsgroups and expiration
intervals.  A command called <command moreinfo="none">doexpire</command> is usually run once
a day from <command moreinfo="none">cron</command> and processes all groups according to this
list.</para><para><indexterm significance="normal"><primary>C News</primary><secondary>archiving</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>archiving articles</secondary></indexterm>
Occasionally, you may want to retain articles from certain groups even
after they have been expired; for example, you might want to keep
programs posted to <systemitem moreinfo="none" role="newsgroup">comp.sources.unix</systemitem>.
This is called <emphasis>archiving</emphasis>. <filename moreinfo="none">explist</filename>
permits you to mark groups for archiving.</para><?troff .Nd 10?><para>An entry in <filename moreinfo="none">explist</filename> looks like this:

<screen format="linespecific"><replaceable>grouplist</replaceable> <replaceable>perm</replaceable> <replaceable>times</replaceable> <replaceable>archive</replaceable></screen></para><para><replaceable>grouplist</replaceable> is a comma-separated list of
newsgroups to which the entry applies. Hierarchies may be specified by
giving the group name prefix, optionally appended with <systemitem moreinfo="none" role="keyword">all</systemitem>. For example, for an entry applying to
all groups below <systemitem moreinfo="none" role="newsgroup">comp.os</systemitem>,
enter either <userinput moreinfo="none">comp.os</userinput> or
<userinput moreinfo="none">comp.os.all</userinput>.</para><para>When <emphasis>expiring</emphasis> news from a group, the name is
checked against all entries in <filename moreinfo="none">explist</filename> in the
order given. The first matching entry applies. For example, to throw
away the majority of <systemitem moreinfo="none" role="newsgroup">comp</systemitem>
after four days, except for <systemitem moreinfo="none" role="newsgroup">comp.os.linux.announce</systemitem>, which you want
to keep for a week, you simply have an entry for the latter, which
specifies a seven-day expiration period, followed by an expiration
period for <systemitem moreinfo="none" role="newsgroup">comp</systemitem>, which
specifies four days.</para><para>The <replaceable>perm</replaceable> field details if the entry applies to
moderated, unmoderated, or any groups. It may take the values
<systemitem moreinfo="none" role="keyword">m</systemitem>,
<systemitem moreinfo="none" role="keyword">u</systemitem>, or
<systemitem moreinfo="none" role="keyword">x</systemitem>, which denote moderated, unmoderated,
or any type.</para><para>The third field, <replaceable>times</replaceable>, usually contains
only a single number. This is the number of days after which articles 
expire if they haven't been assigned an artificial expiration
date in an <literal moreinfo="none">Expires:</literal> field in the article
header. Note that this is the number of days counting from its
<emphasis>arrival</emphasis> at your site, not the date of posting.</para><para>The <replaceable>times</replaceable> field may, however, be more
complex than that. It may be a combination of up to three numbers
separated from one another by dashes. The first denotes the number of
days that have to pass before the article is considered a candidate
for expiration, even if the <literal moreinfo="none">Expires:</literal> field would
have it expire already. It is rarely useful to use a value other than
zero. The second field is the previously mentioned default number of days
after which it will be expired. The third is the number of days after
which an article will be expired unconditionally, regardless of
whether it has an <literal moreinfo="none">Expires:</literal> field or not.  If only
the middle number is given, the other two take default values. These
may be specified using the special entry <systemitem moreinfo="none" role="keyword">/bounds/</systemitem>, which is described a little
later.</para><para>The fourth field, <replaceable>archive</replaceable>, denotes whether the
newsgroup is to be archived and where.  If no archiving is intended, a dash
should be used. Otherwise, you either use a full pathname (pointing to a
directory) or an at sign (@). The at sign denotes the default archive
directory, which must then be given to <command moreinfo="none">doexpire</command> by using
the <option>a</option> flag on the command line.  An archive directory
should be owned by <systemitem moreinfo="none" role="userid">news</systemitem>. When
<command moreinfo="none">doexpire</command> archives an article from say,
<systemitem moreinfo="none" role="newsgroup">comp.sources.unix</systemitem>, it stores it in
the directory <systemitem moreinfo="none" role="newsgroup">comp/sources/unix</systemitem> below
the archive directory, creating it if necessary. The archive directory itself,
however, will not be created.</para><para>There are two special entries in your <filename moreinfo="none">explist</filename> file that
<command moreinfo="none">doexpire</command> relies on.  Instead of a list of newsgroups, they
have the keywords <systemitem moreinfo="none" role="keyword">/bounds/</systemitem> and
<systemitem moreinfo="none" role="keyword">/expired/</systemitem>. The
<systemitem moreinfo="none" role="keyword">/bounds/</systemitem> entry contains the default
values for the three values of the <replaceable>times</replaceable> field
described previously.</para><para>The <systemitem moreinfo="none" role="keyword">/expired/</systemitem> field determines how
long C News will hold onto lines in the <filename moreinfo="none">history</filename> file. 
C News will not remove a line from the history file
once the corresponding article(s) have been expired, but will hold onto it
in case a duplicate should arrive after this date. If you are fed by only
one site, you can keep this value small. Otherwise, a couple of weeks is
advisable on UUCP networks, depending on the delays you experience with
articles from these sites.</para><para>Here is a sample <filename moreinfo="none">explist</filename> file with rather tight
expiry intervals:

<screen format="linespecific"># keep history lines for two weeks. No article gets more than three months
/expired/                       x       14      -
/bounds/                        x       0-1-90  -
# groups we want to keep longer than the rest
comp.os.linux.announce          m       10      -
comp.os.linux                   x       5       -
alt.folklore.computers          u       10      -
rec.humor.oracle                m       10      -
soc.feminism                    m       10      -
# Archive *.sources groups
comp.sources,alt.sources        x       5       @
# defaults for tech groups
comp,sci                        x       7       -
# enough for a long weekend
misc,talk                       x       4       -
# throw away junk quickly
junk                            x       1       -
# control messages are of scant interest, too
control                         x       1       -
# catch-all entry for the rest of it
all                             x       2       -</screen></para><para><indexterm significance="normal"><primary>C News</primary><secondary>update low water mark</secondary></indexterm>
Expiring presents several potential problems. One is that your newsreader
might rely on the third field of the <emphasis>active</emphasis> file 
described earlier, which contains the number
of the lowest article online. When expiring articles, C News does not update
this field. If you need (or want) to have this field represent the real
situation, you need to run a program called <command moreinfo="none">updatemin</command> after
each run of <command moreinfo="none">doexpire</command>. (In older versions of C News, a 
script called <command moreinfo="none">upact</command> did this.)</para><para><indexterm significance="normal"><primary>C News</primary><secondary>history file</secondary></indexterm>
C News does not expire by scanning the newsgroup's directory, but simply
checks the <filename moreinfo="none">history</filename> file if the article is due for
expiration.<footnote id="x-087-2-fncn07"><para>The article's date of arrival is kept in the middle field of the history
line and given in seconds since January 1, 1970.</para></footnote>
If your history file somehow gets out of sync, articles may be around on
your disk forever because C News has literally forgotten
them.<footnote id="x-087-2-fncn08"><para>I don't know <emphasis>why</emphasis> this happens, but it does from
time to time.</para></footnote>
You can repair this by using the <command moreinfo="none">addmissing</command> script in
<filename moreinfo="none">/usr/lib/news/maint</filename>, which will add missing articles
to the <filename moreinfo="none">history</filename> file or <command moreinfo="none">mkhistory</command>,
which rebuilds the entire file from scratch. Don't forget to become user
<systemitem moreinfo="none" role="userid">news</systemitem> before invoking it, or else you
will wind up with a <filename moreinfo="none">history</filename> file unreadable by
C News.

</para><indexterm significance="normal" class="endofrange" startref="idx-cnewsexpiring-1"></indexterm></sect1><sect1 id="x-087-2-cnews.misc"><title>Miscellaneous Files</title><para>There are a number of files that control the behavior of C News, but are not
essential. All of them reside in <filename moreinfo="none">/etc/news</filename>. We describe 
them briefly here:</para><variablelist><varlistentry><term><filename moreinfo="none">newsgroups</filename></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>list of current groups</secondary></indexterm>
<indexterm significance="normal"><primary>newsgroups</primary><secondary>file (/etc/news)</secondary></indexterm> 
This is a companion file of <filename moreinfo="none">active</filename> that contains a list
of each newsgroup name along with a one-line description of its main topic.
This file is automatically updated when C News receives a
<systemitem moreinfo="none" role="keyword">checknews</systemitem> control message.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">localgroups</filename></term><listitem><para><indexterm significance="normal"><primary>localgroups file (/etc/news)</primary></indexterm> 
If you have a lot of local groups, you can keep C News from complaining about 
them each time you receive a <literal moreinfo="none">checkgroups</literal> message by putting their names and descriptions in this file, just as they would
appear in <filename moreinfo="none">newsgroups</filename>.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">mailpaths</filename></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>moderated groups</secondary></indexterm>
<indexterm significance="normal"><primary>mailpaths file (/etc/news)</primary></indexterm> 
This file contains the moderator's address for each moderated group. Each
line contains the group name followed by the moderator's email address
(offset by a tab).</para><para>Two special entries are provided as defaults:
<systemitem moreinfo="none" role="keyword">backbone</systemitem> and
<systemitem moreinfo="none" role="keyword">internet</systemitem>. Both provide, in bang-path
notation, the path to the nearest backbone site and the site that understands
RFC-822 style addresses (<systemitem moreinfo="none" role="emailaddr">user@host</systemitem>).
The default entries are:

<screen format="linespecific">internet           backbone</screen></para><para>You do not have to change the <systemitem moreinfo="none" role="keyword">internet</systemitem> entry if you have
<command moreinfo="none">exim</command> or <command moreinfo="none">sendmail</command> installed; they
understand RFC-822 addressing.</para><para>The <systemitem moreinfo="none" role="keyword">backbone</systemitem> entry is used whenever a
user posts to a moderated group whose moderator is not listed explicitly. If
the newsgroup's name is <systemitem moreinfo="none" role="newsgroup">alt.sewer</systemitem>
and the <systemitem moreinfo="none" role="keyword">backbone</systemitem> entry contains
<systemitem moreinfo="none" role="emailaddr">path!%s</systemitem>, C News will mail the
article to <systemitem moreinfo="none" role="emailaddr">path!alt-sewer</systemitem>, hoping
that the backbone machine is able to forward the article. To find out which
path to use, ask the news-admin at the site that feeds you. As a last resort,
you can also use <systemitem moreinfo="none" role="emailaddr">uunet.uu.net!%s</systemitem>.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">distributions</filename></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>limiting a feed</secondary></indexterm>
This file is not really a C News file, but is used by some newsreaders
and <command moreinfo="none">nntpd</command>. It contains the list of distributions recognized
by your site and a description of their (intended) effects. For example,
Virtual Brewery has the following file:

<screen format="linespecific">world         everywhere in the world
local         Only local to this site
nl            Netherlands only
mugnet        MUGNET only
fr            France only
de            Germany only
brewery       Virtual Brewery only</screen></para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">log</filename></term><listitem><para><indexterm significance="normal"><primary>C News</primary><secondary>log files</secondary></indexterm>
This file contains a log of all C News activities. It is culled regularly by
running <command moreinfo="none">newsdaily</command>; copies of the old log files are kept in
<filename moreinfo="none">log.o</filename>, <filename moreinfo="none">log.oo</filename>, etc.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">errlog</filename></term><listitem><para>This is a log of all error messages created by C News. These messages do not include
logs of articles junked due to being sent to an invalid wrong group or other
user errors. This file is mailed to the newsmaster
(<systemitem moreinfo="none" role="userid">usenet</systemitem> by default)
automatically by <command moreinfo="none">newsdaily</command> if it is not found empty.</para><para><?troff .hw companions?><filename moreinfo="none">errlog</filename> is cleared by <command moreinfo="none">newsdaily</command>.
<filename moreinfo="none">errlog.o</filename> keeps old copies and companions.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">batchlog</filename></term><listitem><para>This file logs all runs of <command moreinfo="none">sendbatches</command>. It is usually of scant
interest. It is also attended by <command moreinfo="none">newsdaily</command>.</para></listitem></varlistentry><varlistentry><term><filename moreinfo="none">watchtime</filename></term><listitem><para>This is an empty file created each time <command moreinfo="none">newswatch</command> runs.</para></listitem></varlistentry></variablelist></sect1><sect1 id="x-087-2-cnews.control"><title>Control Messages</title><para><indexterm significance="normal"><primary>news (network)</primary><secondary>control messages</secondary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>control messages in</secondary></indexterm> 
The Usenet news protocol knows a special category of articles that
evoke certain responses or actions by the news system. These are called
<emphasis>control</emphasis> messages. They are recognized by the presence of a
<replaceable>Control:</replaceable> field in the article header, which contains the
name of the control operation to be performed. There are several types of them,
all of which are handled by shell scripts located in
<filename moreinfo="none">/usr/lib/news/ctl</filename>.</para><para>Most of these messages perform their action automatically at the time the article
is processed by C News without notifying the newsmaster. By default, only
<systemitem moreinfo="none" role="keyword">checkgroups</systemitem> messages will be handed
to the newsmaster, but you may change this by editing the scripts.</para><sect2 id="x-087-2-cnews.control.cancel"><title>The cancel Message</title><para><indexterm significance="normal"><primary>cancel control message</primary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>cancel article</secondary></indexterm>
The most widely known message is <systemitem moreinfo="none" role="keyword">cancel</systemitem>, with which a user can cancel an
article sent earlier. This effectively removes the article from the
spool directories, if it exists. The <systemitem moreinfo="none" role="keyword">cancel</systemitem> message is forwarded to all sites
that receive news from the groups affected, regardless of whether the
article has been seen already. This takes into account the possibility
that the original article has been delayed over the cancellation
message. Some news systems allow users to cancel other people's
messages; this is, of course, a definite no-no.</para></sect2><?troff .wcon_off?><sect2 id="x-087-2-cnews.control.addgroup"><title>newgroup and rmgroup</title><para><indexterm significance="normal"><primary>newgroup control message</primary></indexterm>
<indexterm significance="normal"><primary>rmgroup control message</primary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>adding new groups</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>removing old groups</secondary></indexterm>
<indexterm significance="normal"><primary>newsgroups</primary><secondary>creating</secondary></indexterm> 
<indexterm significance="normal"><primary>newsgroups</primary><secondary>deleting</secondary></indexterm> 
Two messages dealing with creation or removal of newsgroups are the
<systemitem moreinfo="none" role="keyword">newgroup</systemitem> and
<systemitem moreinfo="none" role="keyword">rmgroup</systemitem> messages. Newsgroups below the
usual hierarchies may be created only after a discussion and
voting has been held among Usenet readers. The rules applying to the
<systemitem moreinfo="none" role="newsgroup">alt</systemitem> hierarchy allow for something
close to anarchy. For more information, see the regular postings in
<systemitem moreinfo="none" role="newsgroup">news.announce.newusers</systemitem> and
<systemitem moreinfo="none" role="newsgroup">news.announce.newgroups</systemitem>.  Never send
a <systemitem moreinfo="none" role="keyword">newgroup</systemitem> or
<systemitem moreinfo="none" role="keyword">rmgroup</systemitem> message yourself unless you
definitely know that you are allowed to.</para></sect2><sect2 id="x-087-2-cnews.control.checkgroups"><title>The checkgroups Message</title><para><indexterm significance="normal"><primary>checkgroups control message</primary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>updating active files</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>updating active files</secondary></indexterm>
<systemitem moreinfo="none" role="keyword">checkgroups</systemitem> messages are sent by news
administrators to make all sites within a network synchronize their
<filename moreinfo="none">active</filename> files with the realities of Usenet. For example,
commercial Internet Service Providers might send out such a message to their
customers' sites.  Once a month, the official
<systemitem moreinfo="none" role="keyword">checkgroups</systemitem> message for the major
hierarchies is posted to
<systemitem moreinfo="none" role="newsgroup">comp.announce.newgroups</systemitem> by its
moderator. However, it is posted as an ordinary article, not as a control
message. To perform the <systemitem moreinfo="none" role="keyword">checkgroups</systemitem>
operation, save this article to a file, say <filename moreinfo="none">/tmp/check</filename>,
remove everything up to the beginning of the control message itself, and feed
it to the <systemitem moreinfo="none" role="keyword">checkgroups</systemitem> script using the
following command:

<screen format="linespecific"># <userinput moreinfo="none">su news -c "/usr/lib/news/ctl/checkgroups"  /tmp/check</userinput></screen></para><para>This will update your <filename moreinfo="none">newsgroups</filename> file from the new list 
of groups, adding the groups
listed in <filename moreinfo="none">localgroups</filename>. The old
<filename moreinfo="none">newsgroups</filename> file will be moved to
<filename moreinfo="none">newsgroups.bac</filename>. Note that posting the message locally 
rarely works, because <command moreinfo="none">inews</command>, the command that accepts 
and posts articles from users, refuses to accept that large an article.</para><para>If C News finds mismatches between the
<systemitem moreinfo="none" role="keyword">checkgroups</systemitem> list and the
<filename moreinfo="none">active</filename> file, it produces a list of commands that
would bring your site up to date and mails it to the news administrator. </para><para>The output typically looks like this:

<screen format="linespecific">From news Sun Jan 30 16:18:11 1994
Date: Sun, 30 Jan 94 16:18 MET
From: news (News Subsystem)
To: usenet
Subject: Problems with your active file
The following newsgroups are not valid and should be removed.
        alt.ascii-art
        bionet.molbio.gene-org
        comp.windows.x.intrisics
        de.answers
You can do this by executing the commands:
         /usr/lib/news/maint/delgroup alt.ascii-art
         /usr/lib/news/maint/delgroup bionet.molbio.gene-org
         /usr/lib/news/maint/delgroup comp.windows.x.intrisics
         /usr/lib/news/maint/delgroup de.answers
The following newsgroups were missing.
        comp.binaries.cbm
        comp.databases.rdb
        comp.os.geos
        comp.os.qnx
        comp.unix.user-friendly
        misc.legal.moderated
        news.newsites
        soc.culture.scientists
        talk.politics.crypto
        talk.politics.tibet</screen></para><para>When you receive a message like this from your news system, don't
believe it automatically. Depending on who sent the
<systemitem moreinfo="none" role="keyword">checkgroups</systemitem> message, it may lack a few
groups or even entire hierarchies; you should be careful about removing
any groups. If you find groups are listed as missing that you want to carry
at your site, you have to add them using the <command moreinfo="none">addgroup</command>
script. Save the list of missing groups to a file and feed it to the
following little script:

<programlisting format="linespecific">#!/bin/sh
#
WHOIAM=`whoami`
if [ "$WHOIAM" != "news" ]
then
	echo "You must run $0 as user 'news'" 2
	exit 1
fi
#
cd /usr/lib/news
while read group; do
    if grep -si "^$group[[:space:]].*moderated" newsgroup; then
        mod=m
    else
        mod=y
    fi
    /usr/lib/news/maint/addgroup $group $mod
done</programlisting>
</para></sect2><sect2 id="x-087-2-cnews.control.sendsys"><title>sendsys, version, and senduuname</title><para><indexterm significance="normal"><primary>checkgroups control message</primary></indexterm>
Finally, there are three messages that can be used to find out about
the network's topology. These are <systemitem moreinfo="none" role="keyword">sendsys</systemitem>, <systemitem moreinfo="none" role="keyword">version</systemitem>, and <systemitem moreinfo="none" role="keyword">senduuname</systemitem>. They cause C News to return
the <filename moreinfo="none">sys</filename> file to the sender, as well as a software
version string and the output of <command moreinfo="none">uuname</command>,
respectively. C News is very laconic about <systemitem moreinfo="none" role="keyword">version</systemitem> messages; it returns a simple,
unadorned <literal moreinfo="none">C</literal>.</para><para>Again, you should <emphasis>never</emphasis> issue such a message unless you
have made sure that it cannot leave your (regional) network. Replies to
<systemitem moreinfo="none" role="keyword">sendsys</systemitem> messages can quickly bring down
a UUCP network.<footnote id="x-087-2-fncn09"><para>I wouldn't try this on the Internet, either.</para></footnote></para></sect2></sect1><sect1 id="x-087-2-cnews.nfs"><title>C News in an NFS Environment</title><para><indexterm significance="normal"><primary>configuring</primary><secondary>C News</secondary><tertiary>on a LAN</tertiary></indexterm>
<indexterm significance="normal"><primary>C News</primary><secondary>in NFS</secondary></indexterm>
<indexterm significance="normal"><primary>NFS (Network File System)</primary><secondary>C News in</secondary></indexterm> 
<indexterm significance="normal"><primary>Local Area Networks (LANs)</primary><secondary>news</secondary></indexterm>
A simple way to distribute news within a local network is to keep all
news on a central host and export the relevant directories via NFS so
that newsreaders may scan the articles directly. The overhead involved
in retrieving and threading articles is significantly lower than
NNTP. NNTP, on the other hand, wins in a heterogeneous network where
equipment varies widely among hosts, or where users don't have
equivalent accounts on the server machine.</para><para>When you use NFS, articles posted on a local host have to be forwarded to
the central machine because accessing adminstrative files might
otherwise expose the system to race conditions that leave the files
inconsistent. Also, you might want to protect your news spool area by
exporting it read-only, which also requires forwarding to the central
machine.</para><para>C News handles this central machine configuration transparently to the user.
When you post an article, your newsreader usually invokes
<command moreinfo="none">inews</command> to inject the article into the news system. This
command runs a number of checks on the article, completes the header, and
checks the file <filename moreinfo="none">server</filename> in <filename moreinfo="none">/etc/news</filename>.
If this file exists and contains a hostname different from the local host's
name, <command moreinfo="none">inews</command> is invoked on that server host via
<command moreinfo="none">rsh</command>. Since the <command moreinfo="none">inews</command> script uses a
number of binary commands and support files from C News, you have to either
have C News installed locally or mount the news software from the server.</para><para>For the <command moreinfo="none">rsh</command> invocation to work properly, each user who
posts news must have an equivalent account on the server system, i.e., one
to which she can log in without being asked for a password.</para><para>Make sure that the hostname given in <filename moreinfo="none">server</filename> literally
matches the output of the <command moreinfo="none">hostname</command> command on the server
machine, or else C News will loop forever in an attempt to deliver the article.
We discuss NFS is detail in <xref linkend="x-087-2-nfs"></xref>.</para></sect1><sect1 id="x-087-2-cnews.maint"><title>Maintenance Tools and Tasks</title><para><indexterm significance="normal"><primary>cron</primary><secondary>running</secondary><tertiary>newsdaily in</tertiary></indexterm> 
Despite the complexity of C News, a news administrator's life can be fairly
easy; C News provides you with a wide variety of maintenance tools.
Some of these are intended to be run regularly from <command moreinfo="none">cron</command>,
like <command moreinfo="none">newsdaily</command>.  Using these scripts greatly reduces
daily care and feeding requirements of your C News installation.</para><?troff .wcon_off?><para>Unless stated otherwise, these commands are located in
<filename moreinfo="none">/usr/lib/news/maint</filename>.  (Note that you must become user
<systemitem moreinfo="none" role="userid">news</systemitem> before invoking these commands.
Running them as a superuser may render critical newsfiles inaccessible to C News.):</para><variablelist><varlistentry><term><command moreinfo="none">newsdaily</command></term><listitem><para>The name already says it: run this once a day.  It is an important script
that helps you keep log files small, retaining copies of each from the last
three runs.  It also tries to sense anomalies, like stale batches in the
incoming and outgoing directories, postings to unknown or moderated newsgroups,
etc. Resulting error messages are mailed to the newsmaster.</para></listitem></varlistentry><?troff .sp -1p?><varlistentry><term><command moreinfo="none">newswatch</command></term><listitem><para>This script should be run regularly to look for anomalies in the
news system, once an hour or so. It is intended to detect problems that will
have an immediate effect on the operability of your news system, in which case it mails a trouble report to the newsmaster. Things checked include stale lock files
that don't get removed, unattended input batches, and disk space shortage.</para></listitem></varlistentry><?troff .sp -1p?><varlistentry><term><command moreinfo="none">addgroup</command></term><listitem><para>This script adds a group to your site locally. The proper invocation is:

<screen format="linespecific">addgroup <replaceable>groupname</replaceable> y|n|m|=<replaceable>realgroup</replaceable></screen></para><para>The second argument has the same meaning as the flag in the
<filename moreinfo="none">active</filename> file, meaning that anyone may post to the group
(<systemitem moreinfo="none" role="keyword">y</systemitem>), that no one may post
(<systemitem moreinfo="none" role="keyword">n</systemitem>), that it is moderated
(<systemitem moreinfo="none" role="keyword">m</systemitem>), or that it is an alias for another
group (<systemitem moreinfo="none" role="keyword">=</systemitem><replaceable>realgroup</replaceable>).  You might also want to use <command moreinfo="none">addgroup</command> when the 
first articles in a newly created group arrive earlier than the
<systemitem moreinfo="none" role="keyword">newgroup</systemitem> control message that is
intended to create it.</para></listitem></varlistentry><?troff .sp -1p?><varlistentry><term><command moreinfo="none">delgroup</command></term><listitem><para>This script allows you to delete a group locally. Invoke it as:

<screen format="linespecific">delgroup <replaceable>groupname</replaceable></screen></para><para>You still have to delete the articles that remain in the newsgroup's spool
directory. Alternatively, you might leave it to the natural course of events
(i.e., expiration) to make them go away.</para></listitem></varlistentry><?troff .sp -1p?><varlistentry><term><command moreinfo="none">addmissing</command></term><listitem><para>This script adds missing articles to the <filename moreinfo="none">history</filename> 
file. Run it when there are articles that seem to hang around forever.</para></listitem></varlistentry><?troff .sp -1p?><varlistentry><term><command moreinfo="none">newsboot</command></term><listitem><para>This script should be run at system boot time. It removes any lock files
left over when news processes were killed at shutdown, and closes and executes
any batches left over from NNTP connections that were terminated when shutting
down the system.</para></listitem></varlistentry><?troff .sp -1p?><varlistentry><term><command moreinfo="none">newsrunning</command></term><listitem><para>This script resides in <filename moreinfo="none">/usr/lib/news/input</filename> and may be used to disable unbatching of incoming news, for instance during work hours. You may turn off unbatching by invoking:

<screen format="linespecific"><?troff .sp -1p?>/usr/lib/news/input/newsrunning off<?troff .sp -1p?></screen></para><para>It is turned on by using <systemitem moreinfo="none" role="keyword">on</systemitem> instead of
<systemitem moreinfo="none" role="keyword">off</systemitem>.</para></listitem></varlistentry></variablelist><indexterm significance="normal" class="endofrange" startref="idx-configuringcnews-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-configuringusenetnews-1"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-cnews-1"></indexterm></sect1></chapter><chapter id="x-087-2-nntp"><title>NNTP and the<?lb?>nntpd Daemon</title><indexterm significance="normal" class="startofrange" id="idx-configuringnntp-1"><primary>configuring</primary><secondary>NNTP</secondary></indexterm><indexterm significance="normal"><primary>servers</primary><secondary>NNTP</secondary></indexterm><indexterm significance="normal" class="startofrange" id="protocols.nntp"><primary>protocols</primary><secondary>NNTP</secondary></indexterm><indexterm significance="normal" class="startofrange" id="ch18.nntp.desc"><primary>NNTP (Network News Transfer Protocol)</primary></indexterm><para>Network News Transfer Protocol (NNTP) provides for a vastly different 
approach to news exchange from C News and other news servers without native 
NNTP support. Rather than rely on a batch technology like UUCP to transfer 
news articles between machines, it allows articles to be exchanged via an 
interactive network connection. NNTP is not a particular software package, 
but an Internet standard described in RFC-977. It is based on a 
stream-oriented connection, usually over TCP, between a client anywhere in 
the network and a server on a host that keeps Netnews on disk storage. The 
stream connection allows the client and server to interactively negotiate 
article transfer with nearly no turnaround delay, thus keeping the number of 
duplicate articles low. Together with the Internet's high-transfer rates, 
this adds up to a news transport that surpasses the original UUCP networks by 
far. While some years ago it was not uncommon for an article to take two 
weeks or more before it arrived in the last corner of Usenet; it is now often 
less than two days. On the Internet itself, it is even within the range of 
minutes.</para><para>Various commands allow clients to retrieve, send, and post articles. The
difference between sending and posting is that the latter may involve articles
with incomplete header information; it generally means that the user has just 
written the article.<footnote id="x-087-2-fnnn01"><para> When posting an 
article over NNTP, the server always adds at least one header field, <literal moreinfo="none">NNTP-Posting-Host:</literal>. The field contains the client's hostname.</para></footnote>
Article retrieval may be used by news transfer clients as well as newsreaders.
This makes NNTP an excellent tool for providing news access to many clients on
a local network without going through the contortions that are necessary when
using NFS.</para><para><indexterm significance="normal"><primary>news (network)</primary><secondary>pushing</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>pulling</secondary></indexterm>
<indexterm significance="normal"><primary>pushing news</primary></indexterm> 
<indexterm significance="normal"><primary>pulling news</primary></indexterm> 
<indexterm significance="normal"><primary>ihave command (NNTP)</primary></indexterm>
<indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>ihave command</secondary></indexterm>
NNTP also provides for an active and a passive way to transfer news,
colloquially called pushing and pulling. Pushing
is basically the same as the ihave/sendme protocol used by C News (described in
<xref linkend="x-087-2-cnews"></xref>). The client offers an article to the server
through the <command moreinfo="none">IHAVE msgid</command> 
command, and the server returns a response code that indicates whether
it already has the article or if it wants it. If the server wants the 
article, the client sends the article, terminated by a single dot on a 
separate line.</para><para>Pushing news has the single disadvantage that it places a heavy load on
the server system, since the system has to search its history database for 
every single article.</para><para><indexterm significance="normal"><primary>newnews command (NNTP)</primary></indexterm>
<indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>newnews command</secondary></indexterm>
The opposite technique is pulling news, in which the client requests a
list of all (available) articles from a group that have arrived after a
specified date. This query is performed by the
<command moreinfo="none">NEWNEWS</command> command. From the returned
list of message IDs, the client selects those articles it does not yet have,
using the <command moreinfo="none">ARTICLE</command> command for
each of them in turn.</para><para>Pulling news needs tight control by the server over which groups and 
distributions it allows a client to request. For example, it has to make 
sure that no confidential material from newsgroups local to the site is sent 
to unauthorized clients.</para><para>There are also a number of convenience commands for newsreaders that
permit them to retrieve the article header and body separately, or even
single header lines from a range of articles. This lets you keep all
news on a central host, with all users on the (presumably local) network
using NNTP-based client programs for reading and posting. This is an
alternative to exporting the news directories via NFS, as described
in <xref linkend="x-087-2-cnews"></xref>.</para><para><indexterm significance="normal"><primary>news (network)</primary><secondary>faking</secondary></indexterm>
<indexterm significance="normal"><primary>news faking</primary></indexterm> 
An overall problem of NNTP is that it allows a knowledgeable person to insert
articles into the news stream with false sender specification. This is
called <emphasis>news faking</emphasis> or
<emphasis>spoofing</emphasis>.<footnote id="x-087-2-fnnn02"><para>The same problem exists with the Simple Mail Transfer Protocol (SMTP), although
most mail transport agents now provide mechanisms to prevent spoofing.</para></footnote>
An extension to NNTP allows you to require user authentication for
certain commands, providing some measure of protection against people abusing
your news server in this way.</para><para><indexterm significance="normal"><primary>nntpd</primary><secondary>components</secondary></indexterm>
<indexterm significance="normal"><primary>Lapsley, Phil</primary></indexterm>
<indexterm significance="normal"><primary>Barber, Stan</primary></indexterm>
There are a number of NNTP packages. One of the more widely known is
the NNTP daemon, also known as the
<emphasis>reference implementation</emphasis>.
Originally, it was written by Stan Barber and Phil Lapsley to illustrate the
details of RFC-977. As with much of the good software available today, you may
find it prepackaged for your Linux distribution, or you can obtain the source
and compile it yourself. If you choose to compile it yourself, you will need to
be quite familiar with your distribution to ensure you configure all of the
file paths correctly.</para><para>The <command moreinfo="none">nntpd</command> package has a server, two clients for
pulling and pushing news, and an <command moreinfo="none">inews</command>
replacement. They live in a B News environment, but with a little
tweaking, they will be happy with C News, too.  However, if you plan to
use NNTP for more than offering newsreaders access to your news server,
the reference implementation is not really an option.  We will therefore
discuss only the NNTP daemon contained in the <command moreinfo="none">nntpd</command> package
and leave out the client programs.</para><para><indexterm significance="normal"><primary>Salz, Rich</primary></indexterm>
<indexterm significance="normal"><primary>INN (Internet News)</primary><secondary>NNTP and</secondary></indexterm>
If you wish to run a large news site, you should look at
the <emphasis>InterNet News</emphasis> package, or INN, that was written by
Rich Salz. It provides both NNTP and UUCP-based news transport. News transport is definitely better than
<command moreinfo="none">nntpd</command>. We discuss INN in detail in
<xref linkend="x-087-2-inn"></xref>.</para><sect1 id="x-087-2-nntp.protocol"><title>The NNTP Protocol</title><para>We've mentioned two NNTP commands that are key to how news articles are pushed
or pulled between servers. Now we'll look at these in the context of an actual
NNTP session to show you how simple the protocol is. For the purposes of our
illustration, we'll use a simple <command moreinfo="none">telnet</command> client to connect to
an INN-based news server at the Virtual Brewery called
<emphasis role="bold">news.vbrew.com</emphasis>. The server is running
a minimal configuration to keep the examples short. We'll look at how to
complete the configuration of this server in <xref linkend="x-087-2-inn"></xref>.
In our testing we'll be very careful to generate articles in the
<emphasis>junk</emphasis> newsgroup only, to avoid 
disturbing anyone else.</para><sect2><title>Connecting to the News Server</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>connecting to a news server</secondary></indexterm>
Connecting to the news server is a simple as opening a TCP connection to
its NNTP port. When you are connected, you will be greeted with a welcome
banner. One of the first commands you might try is <systemitem moreinfo="none" role="keyword">help</systemitem>. The response you get generally depends upon whether
the server believes you are a remote NNTP server or a newsreader, as there are
different command sets required. You can change your operating mode using the
<command moreinfo="none">mode</command> command; we'll look at that in a
moment:</para><screen format="linespecific">$ <userinput moreinfo="none">telnet news.vbrew.com nntp</userinput>
Trying 172.16.1.1...
Connected to localhost.
Escape character is '^]'.
200 news.vbrew.com InterNetNews server INN 1.7.2 08-Dec-1997 ready
<userinput moreinfo="none">help</userinput>
100 Legal commands
        authinfo
		help
		ihave
		check
		takethis
		list
		mode
		xmode
		quit
		head
		stat
		xbatch
		xpath
		xreplic
For more information, contact "usenet" at this machine.
.</screen><para>The responses to NNTP commands always end with a period (.) on a
line by itself. The numbers you see in the output listing are 
<emphasis>response codes</emphasis> and are used by the server to indicate success or
failure of a command. The response codes are described in RFC-977; we'll talk
about the most important ones as we proceed.</para></sect2><sect2><title>Pushing a News Article onto a Server</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>ihave command</secondary></indexterm>
<indexterm significance="normal"><primary>ihave command (NNTP)</primary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>articles</secondary><tertiary>pushing news</tertiary></indexterm>
<indexterm significance="normal"><primary>pushing news</primary></indexterm>
We mentioned the <command moreinfo="none">IHAVE</command> command
when we talked about pushing news articles onto a news server. Let's
now have a look at how the <command moreinfo="none">IHAVE</command> command actually works:</para><screen format="linespecific"><userinput moreinfo="none">ihave 123456@gw.vk2ktj.ampr.org</userinput>
335
<userinput moreinfo="none">From: terry@gw.vk2ktj.ampr.org
Subject: test message sent with ihave
Newsgroups: junk
Distribution: world
Path: gw.vk2ktj.ampr.org
Date: 26 April 1999
Message-ID: 123456@gw.vk2ktj.ampr.org
Body: 

This is a test message sent using the NNTP IHAVE command.

.</userinput>
235</screen><para>All NNTP commands are case insensitive, so you may enter them in
either upper- or lowercase. The <command moreinfo="none">IHAVE</command> command takes one 
mandatory argument, it being the Message ID of the article that is being pushed. Every news article is assigned a unique message ID when
it is created. The <command moreinfo="none">IHAVE</command> command provides a way of the NNTP server to say which articles it has
when it wants to push articles to another server. The sending server
will issue an <command moreinfo="none">IHAVE</command> command
for each article it wishes to push. If the command response code
generated by the receiving NNTP server is in the 3xx
range, the sending NNTP server will transmit the complete article,
including it's full header, terminating the article with a period on a
line by itself. If the response code was in the 4xx
range, the receiving server has chosen not to accept this article,
possibly because it already has it, or because of some problem, such
as running out of disk space.</para><para>When the article has been transmitted, the receiving serve issues another
response code indicating whether the article transmission was successful.</para></sect2><sect2><title>Changing to NNRP Reader Mode</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>changing to NNRP reader mode</secondary></indexterm>
<indexterm significance="normal"><primary>newsreaders</primary><secondary>changing to NNRP reader mode</secondary></indexterm>
Newsreaders use their own set of commands when talking to a
news server. To activate these commands, the news server has to be
operating in <emphasis>reader</emphasis> mode. Most news servers default
to reader mode, unless the IP address of the connecting host is listed
as a news-forwarding peer.  In any case, NNTP provides a command to
explicitly switch into reader mode:</para><screen format="linespecific"><userinput moreinfo="none">mode reader</userinput>
200 news.vbrew.com InterNetNews NNRP server INN 1.7.2 08-Dec-1997 ready/
    (posting ok).
<userinput moreinfo="none">help</userinput>
100 Legal commands
  authinfo user Name|pass Password|generic prog args
  article [MessageID|Number]
  body [MessageID|Number]
  date
  group newsgroup
  head [MessageID|Number]
  help
  ihave
  last
  list [active|active.times|newsgroups|distributions|distrib.pats|/
      overview.fmt|subscriptions]
  listgroup newsgroup
  mode reader
  newgroups yymmdd hhmmss ["GMT"] [distributions]
  newnews newsgroups yymmddhhmmss ["GMT"] [distributions]
  next
  post
  slave
  stat [MessageID|Number]
  xgtitle [group_pattern]
  xhdr header [range|MessageID]
  xover [range]
  xpat header range|MessageID pat [morepat...]
  xpath MessageID
Report problems to usenet@vlager.vbrew.com
.</screen><para>NNTP reader mode has a lot of commands. Many of these are designed to
make the life of a newsreader easier. We mentioned earlier that there are
commands that instruct the server to send the head and the body of articles
separately. There are also commands that list the available groups and 
articles, and others that allow posting, an alternate means of sending news 
articles to the server.</para></sect2><sect2><title>Listing Available Groups</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>listing groups</secondary></indexterm>
<indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>list command</secondary></indexterm>
<indexterm significance="normal"><primary>list command (NNTP)</primary></indexterm>
<indexterm significance="normal"><primary>newsgroups</primary><secondary>listing</secondary></indexterm>
The <command moreinfo="none">list</command> command lists a number
of different types of information; notably the groups supported by the server:</para><screen format="linespecific"><userinput moreinfo="none">list newsgroups</userinput>
215 Descriptions in form "group description".
control                 News server internal group
junk                    News server internal group
local.general           General local stuff
local.test              Local test group
.</screen></sect2><sect2><title>Listing Active Groups</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>list active command</secondary></indexterm>
<indexterm significance="normal"><primary>list active command (NNTP)</primary></indexterm>
<option>list active</option> shows each supported group and provides information
about them. The two numbers in each line of the output are the high-water
mark and the low-water markthat is, the highest numbered article and
lowest numbered article in each group. The newsreader is able to form an
idea of the number of articles in the group from these. We'll talk a little
more about these numbers in a moment. The last field in the output displays flags
that control whether posting is allowed to the group, whether the group is
moderated, and whether articles posted are actually stored or
just passed on. These flags are described in detail in <xref linkend="x-087-2-inn"></xref>. 
An example looks like this:</para><screen format="linespecific"><userinput moreinfo="none">list active</userinput>
215 Newsgroups in form "group high low flags".
control 0000000000 0000000001 y
junk 0000000003 0000000001 y
alt.test 0000000000 0000000001 y
.</screen></sect2><sect2><title>Posting an Article</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>post command</secondary></indexterm>
<indexterm significance="normal"><primary>post command (NNTP)</primary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>articles</secondary><tertiary>posting</tertiary></indexterm>
<indexterm significance="normal"><primary>articles (news)</primary><secondary>posting</secondary></indexterm>
We mentioned there was a difference between pushing an article and posting
an article. When you are pushing an article, there is an implicit assumption 
that the article already exists, that it has a message identifier that has 
been uniquely assigned to it by the server to which it was originally posted, 
and that it has a complete set of headers. When posting an article, you are 
creating the article for the first time and the only headers you supply are 
those that are meaningful to you, such as the Subject and the Newgroups to 
which you are posting the article. The news server you post the article on 
will add all the other headers for you and create a message ID that it will 
use when pushing the article onto other servers.</para><para>All of this means that posting an article is even easier than pushing one.
An example posting looks like this:</para><screen format="linespecific"><userinput moreinfo="none">post</userinput>
340 Ok
<userinput moreinfo="none">From: terry@richard.geek.org.au
Subject: test message number 1
Newsgroups: junk
Body: 

This is a test message, please feel free to ignore it.

.</userinput>
240 Article posted</screen><para>We've generated two more messages like this one to give our following examples
some realism.</para></sect2><sect2><title>Listing New Articles</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>newnews command</secondary></indexterm>
<indexterm significance="normal"><primary>newnews command (NNTP)</primary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>articles</secondary><tertiary>listing</tertiary></indexterm>
<indexterm significance="normal"><primary>articles (news)</primary><secondary>listing</secondary></indexterm>
When a newsreader first connects to a new server and the user chooses a
newsgroup to browse, the newsreader will want to retrieve a list of new
articles, those posted or received since the last login by the user. The
<option>newnews</option> command is used for this
purpose. Three mandatory arguments must be supplied: the name of
the group or groups to query, the start date, and the start time from which
to list. The date and time are each specified as six-digit numbers, with the
most significant information first; 
<replaceable>yymmdd</replaceable> and
<replaceable>hhmmss</replaceable>, respectively:</para><screen format="linespecific"><userinput moreinfo="none">newnews junk 990101 000000</userinput>
230 New news follows
7g2o5r$aa$6@news.vbrew.com
7g5bhm$8f$2@news.vbrew.com
7g5bk5$8f$3@news.vbrew.com
.</screen></sect2><sect2><title>Selecting a Group on Which to Operate</title><para><indexterm significance="normal"><primary>newsgroups</primary><secondary>selecting</secondary></indexterm>
<indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>group command</secondary></indexterm>
<indexterm significance="normal"><primary>group command (NNTP)</primary></indexterm>
When the user selects a newsgroup to browse, the newsreader may tell the
news server that the group was selected. This simplifies the interaction
between newsreader and news server; it removes the need to constantly 
send the name of the newsgroup with each command. The 
<option>group</option> command simply takes the name of the selected group as 
an argument. Many following commands use the group selected as the 
default, unless another newsgroup is specified explicitly:</para><screen format="linespecific"><userinput moreinfo="none">group junk</userinput>
211 3 1 3 junk</screen><para>The <option>group</option> command returns a message
indicating the number of active messages, the low-water mark, the high-water
mark, and the name of the group, respectively. Note that while the number of
active messages and the high-water mark are the same in our example, this is
not often the case; in an active news server, some articles may have expired
or been deleted, lowering the number of active messages but leaving the 
high-water mark untouched.</para></sect2><sect2><title>Listing Articles in a Group</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>listgroup command</secondary></indexterm>
<indexterm significance="normal"><primary>listgroup command (NNTP)</primary></indexterm>
<indexterm significance="normal"><primary>newsgroups</primary><secondary>listing articles</secondary></indexterm>
To address newsgroup articles, the newsreader must know
which article numbers represent active articles. The 
<option>listgroup</option> command offers a list of the active 
article numbers in the current group, or an explicit group if the group name is 
supplied:</para><screen format="linespecific"><userinput moreinfo="none">listgroup junk</userinput>
211 Article list follows
1
2
3
.</screen></sect2><sect2><title>Retrieving an Article Header Only</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>head command</secondary></indexterm>
<indexterm significance="normal"><primary>head command (NNTP)</primary></indexterm>
<indexterm significance="normal"><primary>articles (news)</primary><secondary>retrieving headers/message body</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>articles</secondary><tertiary>retrieving headers/message body</tertiary></indexterm>
The user must have some information about an article before she can know
whether she wishes to read it. We mentioned earlier that some commands allow the article header and body to be transferred separately. The
<option>head</option> command is used to request that the server transmit 
just the header of the specified article to the newsreader. If the user 
doesn't want to read this article, we haven't wasted time and network 
bandwidth transferring a potentially large article body unnecessarily.</para><para>Articles may be referenced using either their number (from the 
<option>listgroup</option> command) or their message identifier:</para><screen format="linespecific"><userinput moreinfo="none">head 2</userinput>
221 2 7g5bhm$8f$2@news.vbrew.com head
Path: news.vbrew.com!not-for-mail
From: terry@richard.geek.org.au
Newsgroups: junk
Subject: test message number 2
Date: 27 Apr 1999 21:51:50 GMT
Organization: The Virtual brewery
Lines: 2
Message-ID: 7g5bhm$8f$2@news.vbrew.com
NNTP-Posting-Host: localhost
X-Server-Date: 27 Apr 1999 21:51:50 GMT
Body: 
Xref: news.vbrew.com junk:2
.</screen></sect2><sect2><title>Retrieving an Article Body Only</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>body command</secondary></indexterm>
<indexterm significance="normal"><primary>body command (NNTP)</primary></indexterm>
If, on the other hand, the user decides she does want to read the article, her
newsreader needs a way of requesting that the message body be transmitted. The
<option>body</option> command is used for this purpose. It operates in much 
the same way as the <option>head</option> command, except that only the message 
body is returned:</para><screen format="linespecific"><userinput moreinfo="none">body 2</userinput>
222 2 7g5bhm$8f$2@news.vbrew.com body
This is another test message, please feel free to ignore it too.

.</screen></sect2><sect2><title>Reading an Article from a Group</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>article command</secondary></indexterm>
<indexterm significance="normal"><primary>article command (NNTP)</primary></indexterm>
<indexterm significance="normal"><primary>leafnode (NNTP cache program)</primary></indexterm>
<indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>leafnode</secondary></indexterm>
While it is normally most efficient to separately transfer the headers
and bodies of selected articles, there are occasions when we are better off
transferring the complete article. A good example of this is in applications
through which we want to transfer all of the artices in a group without any sort of
preselection, such as when we are using an NNTP cache program like
<command moreinfo="none">leafnode</command>.<footnote id="x-087-2-fnnn03"><para><emphasis>leafnode</emphasis> is available by anonymous FTP from
<emphasis role="bold">wpxx02.toxi.uni-wuerzburg.de</emphasis>
in the <filename moreinfo="none">/pub/</filename> directory.</para></footnote>
</para><para>Naturally, NNTP provides a means of doing this, and not surprisingly, it
operates almost identically to the <option>head</option> command as well. 
The <option>article</option> command also accepts an article number or 
message ID as an argument, but returns the whole article including its header:</para><screen format="linespecific"><userinput moreinfo="none">article 1</userinput>
220 1 7g2o5r$aa$6@news.vbrew.com article
Path: news.vbrew.com!not-for-mail
From: terry@richard.geek.org.au
Newsgroups: junk
Subject: test message number 1
Date: 26 Apr 1999 22:08:59 GMT
Organization: The Virtual brewery
Lines: 2
Message-ID: 7g2o5r$aa$6@news.vbrew.com
NNTP-Posting-Host: localhost
X-Server-Date: 26 Apr 1999 22:08:59 GMT
Body: 
Xref: news.vbrew.com junk:1

This is a test message, please feel free to ignore it.

.</screen><para>If you attempt to retrieve an unknown article, the server will return
a message with an appropriately coded response code and perhaps a readable 
text message:</para><screen format="linespecific"><userinput moreinfo="none">article 4</userinput>
423 Bad article number</screen><para>We've described how the most important NNTP commands are used in this section.
If you're interested in developing software that implements the NNTP protocol,
you should refer to the relevant RFC documents; they provide a great deal of
detail that we couldn't include here.</para><para>Let's now look at NNTP in action through the <emphasis role="bold">nntpd</emphasis> server.</para></sect2></sect1><sect1 id="x-087-2-nntp.nntpd"><title>Installing the NNTP Server</title><para><indexterm significance="normal"><primary>nntpd</primary><secondary>installing the server</secondary></indexterm>
The NNTP server (<emphasis role="bold">nntpd</emphasis>) may be compiled in
two ways, depending on the expected load on the news system.  There are no
compiled versions available, because of some site-specific defaults that are
hardcoded into the executable.  All configuration is done through
macros defined in <filename moreinfo="none">common/conf.h</filename>.</para><para><emphasis role="bold">nntpd</emphasis> may be configured as either a standalone server that
is started at system boot time from an <command moreinfo="none">rc</command> file, or a daemon
managed by <command moreinfo="none">inetd</command>. In the latter case, you have to have the
following entry in <filename moreinfo="none">/etc/inetd.conf</filename>:

<screen format="linespecific">nntp    stream  tcp nowait      news    /usr/etc/in.nntpd    nntpd</screen></para><para>The <filename moreinfo="none">inetd.conf</filename> syntax is described in detail in <xref linkend="x-087-2-appl"></xref>. If you configure <command moreinfo="none">nntpd</command> as standalone, 
make sure that any such line in <command moreinfo="none">inetd.conf</command> is commented 
out. In either case, you have to make sure the following line appears in
<filename moreinfo="none">/etc/services</filename>:

<screen format="linespecific">nntp    119/tcp   readnews untp    # Network News Transfer Protocol</screen></para><para>To temporarily store any incoming articles, <command moreinfo="none">nntpd</command> also needs
a <filename moreinfo="none">.tmp</filename> directory in your news spool. You should create it
using the following commands:

<screen format="linespecific"># <userinput moreinfo="none">mkdir /var/spool/news/.tmp</userinput>
# <userinput moreinfo="none">chown news.news /var/spool/news/.tmp</userinput></screen></para></sect1><sect1 id="x-087-2-nntp.access"><title>Restricting NNTP Access</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>restricting access in</secondary></indexterm>
<indexterm significance="normal"><primary>nntp_access file</primary></indexterm>
<indexterm significance="normal"><primary>access</primary><secondary>NNTP</secondary></indexterm>
Access to NNTP resources is governed by the file
<filename moreinfo="none">nntp_access</filename> in <filename moreinfo="none">/etc/news</filename>. Lines
in this file describe the access rights granted to foreign hosts. Each line
has the following format:

<screen width="110" format="linespecific"><replaceable>site</replaceable>   read|xfer|both|no    post|no      [!<replaceable>exceptgroups</replaceable>]</screen></para><para>If a client connects to the NNTP port, <emphasis role="bold">nntpd</emphasis> attempts to
obtain the host's fully qualified domain name from its IP address using reverse
lookup. The client's hostname and IP address are checked against the
<replaceable>site</replaceable> field of each entry in the order in which they
appear in the file. Matches may be either partial or exact. If an entry
matches exactly, it applies; if the match is partial, it applies only if there
is no other match following it that is at least as good.
<replaceable>site</replaceable> may be specified in one of the following ways:

<variablelist><varlistentry><term>Hostname</term><listitem><para>This is a fully qualified domain name of a host. If this matches the client's
canonical hostname literally, the entry applies, and all following entries are
ignored.</para></listitem></varlistentry><varlistentry><term>IP address</term><listitem><para>This is an IP address in dotted quad notation.  If the client's IP address
matches this, the entry applies, and all following entries are ignored.</para></listitem></varlistentry><varlistentry><term>Domain name</term><listitem><para>This is a domain name, specified as
<systemitem moreinfo="none" role="sitename">*.</systemitem><replaceable>domain</replaceable>.
If the client's hostname matches the domain name, the entry matches.</para></listitem></varlistentry><varlistentry><term>Network name</term><listitem><para>This is the name of a network as specified in
<filename moreinfo="none">/etc/networks</filename>. If the network number of the client's
IP address matches the network number associated with the network name, the
entry matches.</para></listitem></varlistentry><varlistentry><term>Default</term><listitem><para>The string <literal moreinfo="none">default</literal> matches any client.</para></listitem></varlistentry></variablelist></para><para>Entries with a more general site specification should be specified earlier,
because any matches will be overridden by later, more exact matches.</para><para>The second and third fields describe the access rights granted to the
client. The second field details the permissions to retrieve news by pulling
(<systemitem moreinfo="none" role="keyword">read</systemitem>), and transmit news by pushing
(<systemitem moreinfo="none" role="keyword">xfer</systemitem>). A value of
<systemitem moreinfo="none" role="keyword">both</systemitem> enables both;
<systemitem moreinfo="none" role="keyword">no</systemitem> denies access
altogether. The third field grants the client the right to post
articles, i.e., deliver articles with incomplete header information,
which is completed by the news software.  If the second field contains
<systemitem moreinfo="none" role="keyword">no</systemitem>, the third field is ignored.</para><para>The fourth field is optional and contains a comma-separated list of groups to 
which the client is denied access.</para><para>This is a sample <filename moreinfo="none">nntp_access</filename> file:

<screen format="linespecific">#
# by default, anyone may transfer news, but not read or post
default                 xfer            no
#
# public.vbrew.com offers public access via modem. We allow
# them to read and post to any but the local.* groups
public.vbrew.com        read            post    !local
#
# all other hosts at the brewery may read and post
*.vbrew.com             read            post</screen></para></sect1><sect1 id="x-087-2-nntp.authorize"><title>NNTP Authorization</title><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>authorization</secondary></indexterm>
<indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>restricting access in</secondary></indexterm>
<indexterm significance="normal"><primary>access</primary><secondary>NNTP</secondary></indexterm>
<indexterm significance="normal"><primary>authorization</primary><secondary>with NNTP</secondary></indexterm>
The <command moreinfo="none">nntpd</command> daemon provides a simple authorization scheme.
If you capitalize any of the access tokens in the
<filename moreinfo="none">nntp_access</filename> file, <command moreinfo="none">nntpd</command> requires
authorization from the client for the respective operation. For instance,
when specifying a permission of <systemitem moreinfo="none" role="keyword">Xfer</systemitem> or
<systemitem moreinfo="none" role="keyword">XFER</systemitem>, (as opposed to
<systemitem moreinfo="none" role="keyword">xfer</systemitem>), <command moreinfo="none">nntpd</command> will not
let the client transfer articles to your site unless it passes authorization.</para><para>The authorization procedure is implemented by means of a new NNTP command
named <command moreinfo="none">AUTHINFO</command>. Using this command, the
client transmits a username and a password to the NNTP server.
<command moreinfo="none">nntpd</command> validates them by checking them against the
<filename moreinfo="none">/etc/passwd</filename> database and verifies that the user belongs to
the <systemitem moreinfo="none" role="userid">nntp</systemitem> group.</para><para>The current implementation of NNTP authorization is only experimental
and has therefore not been implemented very portably.  The result of
this is that it works only with plain-style password databases; shadow
passwords are not recognized. If you are compiling from source and
have the PAM package installed, the password check is fairly simple to 
change.</para></sect1><sect1 id="x-087-2-nntp.interact"><title>nntpd Interaction with C News</title><para><indexterm significance="normal"><primary>C News</primary><secondary>NNTP support</secondary></indexterm>
<indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>C News and</secondary></indexterm>
When <command moreinfo="none">nntpd</command> receives an article, it has to deliver
it to the news subsystem. Depending on whether it was received as a
result of an <command moreinfo="none">IHAVE</command> or <command moreinfo="none" role="keyword">POST</command> command, the article is handed to
<command moreinfo="none">rnews</command> or <command moreinfo="none">inews</command>,
respectively. Instead of invoking <command moreinfo="none">rnews</command>, you may
also configure it (at compile time), to batch the incoming articles
and move the resulting batches to
<filename moreinfo="none">/var/spool/news/in.coming</filename>, where they are left
for <command moreinfo="none">relaynews</command> to pick them up at the next queue
run.</para><para><indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>ihave command</secondary></indexterm>
<indexterm significance="normal"><primary>ihave command (NNTP)</primary></indexterm>
<command moreinfo="none">nntpd</command> has to have access to the
<filename moreinfo="none">history</filename> file to be able to properly perform the 
ihave/sendme protocol. At compile time, you have to
make sure the path to that file is set correctly.  If you use C News, make 
sure that C News and <command moreinfo="none">nntpd</command> agree on the format of your 
history file. C News uses <filename moreinfo="none">dbm</filename> hashing functions to 
access it; however, there are quite a number of different and slightly 
incompatible implementations of the <filename moreinfo="none">dbm</filename> library.  If 
C News has been linked with a different <filename moreinfo="none">dbm</filename> library 
than you have in your standard <filename moreinfo="none">libc</filename>, you have to 
link <command moreinfo="none">nntpd</command> with this library, too.</para><para><indexterm significance="normal"><primary>checking</primary><secondary>NNTP</secondary></indexterm>
<command moreinfo="none">nntpd</command> and C news disagreement sometimes produces error 
messages in the system log that <command moreinfo="none">nntpd</command> can not open it 
properly, or you might see duplicate articles being received via NNTP.  A 
good test of a malfunctioning news transfer is to pick an article from your
spool area, telnet to the <emphasis role="bold">nntp</emphasis> port, 
and offer it to <command moreinfo="none">nntpd</command> as shown in the next example. Of 
course, you have to replace <replaceable>msg@id</replaceable> with the
message ID of the article you want to feed to <command moreinfo="none">nntpd</command>:</para><screen format="linespecific">$ <userinput moreinfo="none">telnet localhost nntp</userinput>
Trying 127.0.0.1...
Connected to localhost
Escape characters is '^ ]'.
201 vstout NNTP[auth] server version 1.5.11t (16 November 1991) ready at
Sun Feb 6 16:02:32 1194 (no posting)
<userinput moreinfo="none">IHAVE</userinput> <replaceable>msg@id</replaceable>
435 Got it.
<userinput moreinfo="none">QUIT</userinput></screen><para>This conversation shows <command moreinfo="none">nntpd</command>'s proper reaction;
the message <literal moreinfo="none">Got it</literal> tells you that it already
has this article. If you get a message of
<command moreinfo="none">335 Ok</command> instead, the lookup in the history
file failed for some reason. Terminate the conversation by typing Ctrl-D.
You can check what has gone wrong by checking the system log;
<command moreinfo="none">nntpd</command> logs all kinds of messages to the
<systemitem moreinfo="none" role="keyword">daemon</systemitem> facility of
<command moreinfo="none">syslog</command>. An incompatible <filename moreinfo="none">dbm</filename> library
usually manifests itself in a message complaining that
<function moreinfo="none">dbminit</function> failed.</para><indexterm significance="normal" class="endofrange" startref="ch18.nntp.desc"></indexterm><indexterm significance="normal" class="endofrange" startref="idx-configuringnntp-1"></indexterm><indexterm significance="normal" class="endofrange" startref="protocols.nntp"></indexterm></sect1></chapter><chapter id="x-087-2-inn"><title>Internet News</title><para>The Internet News daemon (INN) is arguably the most popular Netnews
server in use today. INN is extremely flexible and is suitable for all
but the smallest news sites.<footnote id="x-087-2-fnin01"><para> Very
small news sites should consider a caching NNTP server program like
<command moreinfo="none">leafnode</command>, which is available at <systemitem moreinfo="none" role="url">http://wpxx02.toxi.uni-wuerzburg.de/~krasel/leafnode.html.</systemitem></para></footnote> INN scales well and is suited to large news server
configurations.</para><para>The INN server comprises a number of components, each with their own
configuration files that we will discuss in turn. Configuration of INN
can be a little involved, but we'll describe each of the stages in this
chapter and arm you with enough information to make
sense of the INN manual pages and documentation and build configurations for
just about any application.</para><sect1><title>Some INN Internals</title><para><indexterm significance="normal" class="startofrange" id="innd.command"><primary>innd command (INN)</primary></indexterm>
INN's core program is the <command moreinfo="none">innd</command> daemon.
<command moreinfo="none">innd</command>'s task is to handle all incoming articles,
storing them locally, and to pass them on to any outgoing newsfeeds if
required.  It is started at boot time and runs continually as a background
process. Running as a daemon improves performance because it has to read 
its status files only once when starting. Depending
on the volume of your news feed, certain files such as
<filename moreinfo="none">history</filename> (which contain a list of all recently
processed articles) may range from a few megabytes to tens of megabytes.</para><para>Another important feature of INN is that there is always only one
instance of <command moreinfo="none">innd</command> running at any time. This is also very 
beneficial to performance, because the daemon can process all articles
without having to worry about synchronizing its internal states with
other copies of <command moreinfo="none">innd</command> rummaging around the news spool at
the same time. However, this choice affects the overall design
of the news system. Because it is so important that incoming news is
processed as quickly as possible, it is unacceptable that the server be
tied up with such mundane tasks as serving newsreaders accessing the news
spool via NNTP, or decompressing newsbatches arriving via UUCP. Therefore,
these tasks have been broken out of the main server and implemented in separate support programs.
<xref linkend="x-087-2-inn.inn.architecture"></xref> attempts to illustrate the
relationships between <command moreinfo="none">innd</command>, the other local tasks, and
remote news servers and newsreaders.</para><para><indexterm significance="normal"><primary>INN (Internet News)</primary><secondary>ihave protocol</secondary></indexterm>
<indexterm significance="normal"><primary>INN (Internet News)</primary><secondary>rnews</secondary></indexterm>
<indexterm significance="normal"><primary>INN (Internet News)</primary><secondary>NNTP and</secondary></indexterm>
<indexterm significance="normal"><primary>NNTP (Network News Transfer Protocol)</primary><secondary>INN (Internet News) and</secondary></indexterm>
Today, NNTP is the most common means of transporting news articles around,
and <command moreinfo="none">innd</command> doesn't directly support anything else.
This means that <command moreinfo="none">innd</command> listens on a TCP socket (port 119)
for connections and accepts news articles using the ihave
protocol.</para><para>Articles arriving by transports other than NNTP are supported indirectly
by having another process accept the articles and forward them to
<command moreinfo="none">innd</command> via NNTP. Newsbatches coming in over a UUCP link,
for instance, are traditionally handled by the <command moreinfo="none">rnews</command>
program. INN's <command moreinfo="none">rnews</command> decompresses the batch if necessary,
and breaks it up into individual articles; it then offers them to
<command moreinfo="none">innd</command> one by one.</para><para>Newsreaders can deliver news when a user
posts an article. Since the handling of newsreaders deserves special 
attention, we will come back to this a little later.</para><figure float="0" id="x-087-2-inn.inn.architecture"><title>INN architecture (simplified for clarity)</title><graphic fileref="lag2_2301.jpg"></graphic></figure><para>When receiving an article, <command moreinfo="none">innd</command> first looks up its
message ID in the <filename moreinfo="none">history</filename> file. Duplicate
articles are dropped and the occurrences are optionally logged. The
same goes for articles that are too old or lack some required header
field, such as <literal moreinfo="none">Subject:</literal>.<footnote><para> This is
indicated by the <replaceable>Date:</replaceable> header field; the limit is
usually two weeks.</para></footnote> If <command moreinfo="none">innd</command> finds
that the article is acceptable, it looks at the
<literal moreinfo="none">Newsgroups:</literal> header line to find out what groups it
has been posted to. If one or more of these groups are found in the
<filename moreinfo="none">active</filename> file, the article is filed to
disk. Otherwise, it is filed to the special group <systemitem moreinfo="none" role="newsgroup">junk</systemitem>.</para><para>Individual articles are kept below <filename moreinfo="none">/var/spool/news</filename>, also
called the <emphasis>news spool</emphasis>. Each newsgroup has a
separate directory, in which each article is stored in a separate file. The
file names are consecutive numbers, so that an article in
<systemitem moreinfo="none" role="newsgroup">comp.risks</systemitem> may be filed
as <filename moreinfo="none">comp/risks/217</filename>, for instance. When
<command moreinfo="none">innd</command> finds that the directory it wants to store the
article in does not exist, it creates it automatically.</para><para><indexterm significance="normal"><primary>newsfeeds file (INN)</primary></indexterm>
Apart from storing articles locally, you may also want to pass them on to
outgoing feeds. This is governed by the <filename moreinfo="none">newsfeeds</filename> file
that lists all downstream sites along with the newsgroups that should be fed
to them.</para><para>Just like <command moreinfo="none">innd</command>'s receiving end, the
processing of outgoing news is handled by a single interface, too.
Instead of doing all the transport-specific handling itself,
<command moreinfo="none">innd</command> relies on various backends to manage the
transmission of articles to other news servers.  Outgoing facilities
are collectively dubbed <emphasis>channels</emphasis>.  Depending on
its purpose, a channel can have different attributes that determine
exactly what information <command moreinfo="none">innd</command> passes on to it.</para><para><indexterm significance="normal"><primary>innxmit command (INN)</primary></indexterm>
For an outgoing NNTP feed, for instance, <command moreinfo="none">innd</command> might
fork the <command moreinfo="none">innxmit</command> program at startup, and, for each
article that should be sent across that feed, pass its message ID,
size, and filename to <command moreinfo="none">innxmit</command>'s standard input. For
an outgoing UUCP feed, on the other hand, it might write the article's
size and file name to a special logfile, which is head by a different
process at regular intervals in order to create batches and queue them
to the UUCP subsystem.</para><para>Besides these two examples, there are other types of channels that are
not strictly outgoing feeds. These are used, for instance, when
archiving certain newsgroups, or when generating overview
information. Overview information is intended to help newsreaders
thread articles more efficiently.  Old-style newsreaders had to scan
all articles separately in order to obtain the header information
required for threading. This would put an immense strain on the server
machine, especially when using NNTP; furthermore, it was very
slow.<footnote><para>Threading 1,000 articles when talking to a loaded
server could easily take around five minutes, which only the most
dedicated Usenet addict would find acceptable.</para></footnote> The
overview mechanism alleviates this problem by prerecording all
relevant headers in a separate file (called
<filename moreinfo="none">.overview</filename>) for each newsgroup. This information
can then be picked up by newsreaders either by reading it directly
from the spool directory, or by using the <command moreinfo="none">XOVER</command>
command when connected via NNTP. INN has the <command moreinfo="none">innd</command>
daemon feed all articles to the <command moreinfo="none">overchan</command> command,
which is attached to the daemon through a channel. We'll see how this
is done when we discuss configuring news feeds later.
</para><indexterm significance="normal" class="endofrange" startref="innd.command"></indexterm></sect1><sect1><title>Newsreaders and INN</title><para><indexterm significance="normal"><primary>newsreaders</primary><secondary>INN (Internet News) and</secondary></indexterm>
<indexterm significance="normal"><primary>INN (Internet News)</primary><secondary>newsreaders</secondary></indexterm>
Newsreaders running on the same machine as the server (or having mounted 
the server's news spool via NFS) can read articles from the
spool directly. To post an article composed by the user, they invoke the
<command moreinfo="none">inews</command> program, which adds any header fields that are
missing and forwards them to the daemon via NNTP.</para><para><indexterm significance="normal"><primary>nnrpd command (INN)</primary></indexterm>
Alternatively, newsreaders can access the server remotely via
NNTP. This type of connection is handled differently from NNTP-based
news feeds, to avoid tying up the daemon. Whenever a newsreader
connects to the NNTP server, <command moreinfo="none">innd</command> forks a
separate program called <command moreinfo="none">nnrpd</command>, which handles
the session while <command moreinfo="none">innd</command> returns to the more
important things (receiving incoming news, for
example).<footnote><para> The name apparently stands for NetNews Read
 Post Daemon.  </para></footnote> You may be wondering how the
<command moreinfo="none">innd</command> process can distinguish between an incoming
news feed and a connecting newsreader. The answer is quite simple: the
NNTP protocol requires that an NNTP-based newsreader issue a
<command moreinfo="none">mode reader</command> command after connecting to the server;
when this command is received, the server starts the
<command moreinfo="none">nnrpd</command> process, hands the connection to it, and
returns to listening for connections from another news server. There
used to be at least one DOS-based newsreader which was not configured
to do this, and hence failed miserably when talking to INN, because
<command moreinfo="none">innd</command> itself does not recognize any of the commands
used to read news if it doesn't know the connection is from a news
reader.</para><para>We'll talk a little more about newsreader access to INN under
"Controlling Newsreader Access," later in the chapter.</para></sect1><sect1><title>Installing INN</title><para><indexterm significance="normal"><primary>INN (Internet News)</primary><secondary>installing</secondary></indexterm>
<indexterm significance="normal"><primary>installing</primary><secondary>INN (Internet News)</secondary></indexterm>
Before diving into INN's configuration, let's talk about its installation. 
Read this section, even if you've installed INN from one of the various
Linux distributions; it contains some hints about security and compatibility.</para><para>Linux distributions included Verson INN-1.4sec for quite some time.
Unfortunately, this version had two subtle security problems. Modern
versions don't have these problems and most distributions include
a precompiled Linux binary of INN Version 2 or later.</para><para>If you choose, you can build INN yourself. You can obtain the
source from <systemitem moreinfo="none" role="sitename">ftp.isc.org</systemitem> in the
<filename moreinfo="none">/isc/inn/</filename> directory. Building INN requires that
you edit a configuration file that tells INN some detail about your
operating system, and some features may require minor modifications to
the source itself.</para><para>Compiling the package itself is pretty simple; there's a script called
<command moreinfo="none">BUILD</command> that will guide you through the process. The
source also contains extensive documentation on how to install and
configure INN.</para><para>After installing all binaries, some manual fixups may be required to
reconcile INN with any other applications that may want to access its
<command moreinfo="none">rnews</command> or <command moreinfo="none">inews</command> programs. UUCP,
for instance, expects to find the <command moreinfo="none">rnews</command> program in
<filename moreinfo="none">/usr/bin</filename> or <filename moreinfo="none">/bin</filename>, while INN
installs it in <filename moreinfo="none">/usr/lib/bin</filename> by default. Make sure
<filename moreinfo="none">/usr/lib/bin/</filename> is in the default search path, or
that there are symbolic links pointing to the actual location of the
<command moreinfo="none">rnews</command> and <command moreinfo="none">inews</command> commands.</para></sect1><sect1><title>Configuring INN: the Basic Setup</title><para>One of the greatest obstacles beginners may face is that INN requires a
working network setup to function properly, even when running on a standalone
host. Therefore, it is essential that your kernel supports TCP/IP networking 
when running INN, and that you have set up the loopback interface as
explained in <xref linkend="x-087-2-iface"></xref>.</para><para>Next, you have to make sure that <command moreinfo="none">innd</command> is started at
boot time. The default INN installation provides a script file called
<filename moreinfo="none">boot</filename> in the <filename moreinfo="none">/etc/news/</filename>
directory.  If your distribution uses the SystemV-style
<command moreinfo="none">init</command> package, all you have to do is create a
symbolic link from your <filename moreinfo="none">/etc/init.d/inn</filename> file
pointing to <filename moreinfo="none">/etc/news/boot</filename>. For other flavors of
<command moreinfo="none">init</command>, you have to make sure
<filename moreinfo="none">/etc/news/boot</filename> is executed from one of your
<filename moreinfo="none">rc</filename> scripts. Since INN requires networking
support, the startup script should be run <emphasis>after</emphasis>
the network interfaces are configured.</para></sect1><sect1><title>INN Configuration Files</title><para><indexterm significance="normal" class="startofrange" id="config.files.inn"><primary>configuration files</primary><secondary>INN (Internet News)</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="inn.config.files"><primary>INN (Internet News)</primary><secondary>configuration files</secondary></indexterm>
Having completed these general tasks, you can now turn to the really
interesting part of INN: its configuration files. All these files reside in
<filename moreinfo="none">/etc/news</filename>. Some changes to configurations files were
introduced in Version 2, and it is Version 2 that we describe here. If you're
running an older version, you should find this chapter useful to guide you in
upgrading your configuration. During the next few sections, we will discuss
them one by one, building the Virtual Brewery's configuration as an example.</para><para>If you want to find out more about the features of individual configuration
files, you can also consult the manual pages; the INN distribution contains
individual manual pages for each of them.</para><sect2><title>Global Parameters</title><para><indexterm significance="normal" class="startofrange" id="inn.global.params"><primary>INN (Internet News)</primary><secondary>global parameters</secondary></indexterm>
There are a number of INN parameters that are global in nature; they
are relevant to all newsgroups carried.</para><sect3><title>The inn.conf file</title><para><indexterm significance="normal"><primary>inn.conf file (INN)</primary></indexterm>
INN's main configuration file is <filename moreinfo="none">inn.conf</filename>. Among other
things, it determines the name by which your machine is known on Usenet.
Version 2 of INN allows a baffling number of parameters to be configured in 
this file. Fortunately, most parameters have default values that are 
reasonable for most sites. The <filename moreinfo="none">inn.conf(5)</filename> file details 
all of the parameters, and you should read it carefully if you experience any 
problems.</para><para>A simple example <filename moreinfo="none">inn.conf</filename> might look like:

<screen width="49" format="linespecific"># Sample inn.conf for the Virtual Brewery
server:          vlager.vbrew.com
domain:          vbrew.com
fromhost:        vbrew.com
pathhost:        news.vbrew.com
organization:    The Virtual Brewery
mta:             /usr/sbin/sendmail -oi %s
moderatormailer: %s@uunet.uu.net
#
# Paths to INN components and files.
#
pathnews:               /usr/lib/news
pathbin:                /usr/lib/news/bin
pathfilter:             /usr/lib/news/bin/filter
pathcontrol:            /usr/lib/news/bin/control
pathdb:                 /var/lib/news
pathetc:                /etc/news
pathrun:                /var/run/news
pathlog:                /var/log/news
pathhttp:               /var/log/news
pathtmp:                /var/tmp
pathspool:              /var/spool/news
patharticles:           /var/spool/news/articles
pathoverview:           /var/spool/news/overview
pathoutgoing:           /var/spool/news/outgoing
pathincoming:           /var/spool/news/incoming
patharchive:            /var/spool/news/archive
pathuniover:            /var/spool/news/uniover
overviewname:           .overview</screen></para><para>The first line tells the programs <command moreinfo="none">rnews</command> and
<command moreinfo="none">inews</command> which host to contact when delivering articles.
This entry is absolutely crucial; to pass articles to
<command moreinfo="none">innd</command>, they have to establish an NNTP connection with
the server.</para><para>The <systemitem moreinfo="none" role="keyword">domain</systemitem> keyword should specify
the domain portion of the host's fully qualified domain name. A couple of
programs must look up your host's fully qualified domain name; if your
resolver library returns the unqualified hostname only, the name given in the
<systemitem moreinfo="none" role="keyword">domain</systemitem> attribute is tacked onto it. It's not a problem to configure it either way, so it's best
to define <systemitem moreinfo="none" role="keyword">domain</systemitem>.</para><para>The next line defines what hostname <command moreinfo="none">inews</command> is going to use
when adding a <replaceable>From:</replaceable> line to articles posted by local users.
Most newsreaders use the <replaceable>From:</replaceable> field when composing a
reply mail message to the author of an article. If you omit this field, it
will default to your news host's fully qualifed domain name. This is ot
always the best choice. You might, for example, have news and mail handled
by two different hosts. In this case, you would supply the fully qualified
domain name of your mail host after the
<systemitem moreinfo="none" role="keyword">fromhost</systemitem> statement.</para><para>The <systemitem moreinfo="none" role="keyword">pathhost</systemitem> line defines the hostname
INN is to add to the <literal moreinfo="none">Path:</literal> header field whenever it
receives an article. In most cases, you will want to use the fully
qualified domain name of your news server; you can then omit this field since
that is the default. Occasionally you may want to use a generic name, such as
<emphasis role="bold">news.vbrew.com</emphasis>, when serving a large
domain. Doing this allows you to move the news system easily to a different
host, should you choose to at some time.</para><para>The next line contains the <systemitem moreinfo="none" role="keyword">organization</systemitem>
keyword.  This statement allows you to configure what text
<command moreinfo="none">inews</command> will put into the <literal moreinfo="none">Organization:</literal>
line of articles posted by your local users. Formally, you would place a
description of your organization or your organization's name in full here.
Should you not wish to be so formal, it is fashionable for organizations with
a sense of humor to exhibit it here.</para><para>The <systemitem moreinfo="none" role="keyword">organization</systemitem> keyword is mandatory
and specifies the pathname of the mail transport agent that will be used
for posting moderator messages. <literal moreinfo="none">%s</literal> is replaced by the 
moderator email address.</para><para><?troff .hw feminism?>The <systemitem moreinfo="none" role="keyword">moderatormailer</systemitem> entry defines a
default address used when a user tries to post to a moderated newsgroup. The
list of moderator addresses for each newsgroup is usually kept in a separate
file, but you will have a hard time keeping track of all of them. The
<systemitem moreinfo="none" role="keyword">moderatormailer</systemitem> entry is therefore
consulted as a last resort; if it is defined, <command moreinfo="none">inews</command> will
replace the <literal moreinfo="none">%s</literal> string with the (slightly transformed)
newsgroup name and send the entire article to this address. For instance, 
when posting to <systemitem moreinfo="none" role="newsgroup">soc.feminism</systemitem>, the 
article is mailed to 
<systemitem moreinfo="none" role="email">soc-feminism@uunet.uu.net</systemitem>, given
the above configuration. At UUNET, there should be a mail alias installed for
each of these submissions addresses that automatically forwards all messages
to the appropriate moderator.</para><para>Finally, each of the remaining entries specifies the location of some component
file or executable belonging to INN. If you've installed INN from a package,
these paths should have been configured for you. If you're installing from
source, you'll need to ensure that they reflect where you've installed INN.</para></sect3><indexterm significance="normal" class="endofrange" startref="inn.global.params"></indexterm></sect2><sect2><title>Configuring Newsgroups</title><para><indexterm significance="normal" class="startofrange" id="config.newsgroups"><primary>configuring</primary><secondary>newsgroups</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="newsgroups.config"><primary>newsgroups</primary><secondary>configuring</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="inn.config.newsgroups"><primary>INN (Internet News)</primary><secondary>configuring</secondary><tertiary>newsgroups</tertiary></indexterm>
The news administrator on a system is able to control which newsgroups
users have access to. INN provides two configuration files that
allow the administrator to decide which newsgroups to support and provide
descriptions for them.</para><sect3><title>The active and newsgroups files</title><para><indexterm significance="normal"><primary>active file (INN)</primary></indexterm>
<indexterm significance="normal"><primary>newsgroups file (INN)</primary></indexterm>
The <filename moreinfo="none">active</filename> and <filename moreinfo="none">newsgroups</filename> files
are used to store and describe the newsgroups hosted by this news server.
They list which newsgroups we are interested in receiving and serving
articles for, and administrative information about them. These files are 
found in the <filename moreinfo="none">/var/lib/news/</filename> directory.</para><para>The <filename moreinfo="none">active</filename> file determines which newsgroups this
server supports. Its syntax is straightforward. Each line in the
<filename moreinfo="none">active</filename> file has four fields delimited by whitespace:

<screen format="linespecific">name himark lomark flags</screen></para><para>The <replaceable>name</replaceable> field is the name of the
newsgroup.  The <replaceable>himark</replaceable> field is the highest
number that has been used for an article in that newsgroup. The
<replaceable>lomark</replaceable> field is the lowest active number in
use in the newsgroup. To illustrate how this works, consider the
follow scenario.  Imagine that we have a newly created newsgroup:
<replaceable>himark</replaceable> and
<replaceable>lowmark</replaceable> are both 0 because there are no
articles. If we post 5 articles, they will be numbered 1 through
5. <replaceable>himark</replaceable> will now equal 5, the highest
numbered article, and <replaceable>lowmark</replaceable> will equal 1,
the lowest active article. If article 5 is cancelled there will be no
change; <replaceable>himark</replaceable> will remain at 5 to ensure
that that article number is not reallocated and
<replaceable>lowmark</replaceable> will remain at 1, the lowest active
article. If we now cancel article 1, <replaceable>himark</replaceable>
will remain unchanged, but <replaceable>lowmark</replaceable> will now
equal 2, because 1 is no longer active. If we now post a new article,
it will be assigned article number 6, so
<replaceable>himark</replaceable> will now equal 6. Article 5 has been
in use, so we won't reassign it. <replaceable>lowmark</replaceable>
remains at 2. This mechanism allows us to easily allocate unique
article numbers for new articles and to calculate approximately how
many active articles there are in the group:
<replaceable>himark</replaceable><replaceable>lowmark</replaceable>.</para><para>The field may contain one of the following:

<variablelist><varlistentry><term>y</term><listitem><para>Posting directly to this news server is allowed. </para></listitem></varlistentry><varlistentry><term>n</term><listitem><para>Posting directly to this news server is not allowed. This prevents newsreaders
from posting directly to this news server. New articles may only be received
from other news servers.</para></listitem></varlistentry><varlistentry><term>m</term><listitem><para>The group is moderated. Any articles posted to this newsgroup are forwarded 
to the newsgroup moderator for approval before they enter the newsgroup. Most 
newsgroups are unmoderated.</para></listitem></varlistentry><varlistentry><term>j</term><listitem><para>Articles in this group are not kept, but only passed on. This causes the
news server to accept the article, but all it will do with it is pass it to
the up-stream news servers. It will not make the articles
available to newsreaders reading from this server.</para></listitem></varlistentry><varlistentry><term>x</term><listitem><para>Articles cannot be posted to this newsgroup. The only way that news articles
are delivered to this server is by feeding them from another news server.
Newsreaders may not directly write articles to this server.</para></listitem></varlistentry><varlistentry><term>=<replaceable>foo.bar</replaceable></term><listitem><para>Articles are locally filed into the ``foo.bar'' group.</para></listitem></varlistentry></variablelist>

In our simple server configuration we'll carry a small number of
newsgroups, so our <filename moreinfo="none">/var/lib/news/active</filename> file will
look like:

<screen width="52" format="linespecific">control 0000000000 0000000001 y
junk 0000000000 0000000001 y
rec.crafts.brewing 0000000000 0000000001 y
rec.crafts.brewing.ales 0000000000 0000000001 y
rec.crafts.brewing.badtaste 0000000000 0000000001 y
rec.crafts.brewing.brandy 0000000000 0000000001 y
rec.crafts.brewing.champagne 0000000000 0000000001 y
rec.crafts.brewing.private 0000000000 0000000001 y</screen>

The <replaceable>himark</replaceable> and <replaceable>lomark</replaceable> 
numbers in this example are those you would use when creating new newsgroups. 
The <replaceable>himark</replaceable> and <replaceable>lomark</replaceable> 
numbers will look quite different for a newsgroup that has been active for 
some time.</para><para>The <filename moreinfo="none">newsgroups</filename> file is even simpler. It provides 
one-line descriptions of newsgroups. Some newsreaders are
able to read and present this information to a user to help them decide 
whether they want to subscribe.</para><para>The format of the <filename moreinfo="none">newsgroups</filename> file is simply:

<screen format="linespecific">name description</screen>

The <replaceable>name</replaceable> field is the name of a newsgroup, and the <replaceable>description</replaceable> is a single line description of that newsgroup.</para><para>We want to describe the newsgroups that our server supports, so we'll build
our <filename moreinfo="none">newsgroups</filename> file as follows:

<screen width="70" format="linespecific">rec.crafts.brewing.ales         Home brewing Ales and Lagers
rec.crafts.brewing.badtaste     Home brewing foul tasting brews
rec.crafts.brewing.brandy       Home brewing your own Brandy
rec.crafts.brewing.champagne    Home brew your own Champagne
rec.crafts.brewing.private      The Virtual Brewery home brewers group</screen></para></sect3><indexterm significance="normal" class="endofrange" startref="config.newsgroups"></indexterm><indexterm significance="normal" class="endofrange" startref="newsgroups.config"></indexterm><indexterm significance="normal" class="endofrange" startref="inn.config.newsgroups"></indexterm></sect2><sect2><title>Configuring Newsfeeds</title><para><indexterm significance="normal" class="startofrange" id="config.newsfeeds"><primary>configuring</primary><secondary>newsfeeds</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="newsfeeds.config"><primary>newsfeeds, configuring</primary></indexterm>
<indexterm significance="normal" class="startofrange" id="inn.config.newsfeeds"><primary>INN (Internet News)</primary><secondary>configuring</secondary><tertiary>newsfeeds</tertiary></indexterm>
INN provides the news administrator the ability to control which
newsgroups are forwarded on to other news servers and how they will be
forwarded. The most common method uses the NNTP protocol described
earlier, but INN also allows newsfeeds via other protocols, such as UUCP.</para><sect3><title>The newsfeeds file</title><para><indexterm significance="normal" class="startofrange" id="newsfeeds.file"><primary>newsfeeds file (INN)</primary></indexterm>
The <filename moreinfo="none">newsfeeds</filename> file determines where news articles
will be sent. It normally resides in the <filename moreinfo="none">/etc/news/</filename>
directory.</para><para>The format of the <filename moreinfo="none">newsfeeds</filename> is a little complicated at
first. We'll describe the general layout here, and the
<filename moreinfo="none">newsfeeds(5)</filename> manual page describes
what we leave out. The format is as follows:

<screen format="linespecific"># newsfeeds file format
site:pattern:flags:param
site2:pattern2\
	:flags2:param2</screen>

Each news feed to a site is described by a single line, or may be
spread across multiple lines using the \ continuation character. The
: characters delimit the fields in each line. The # character at the
start of a line marks that line as a comment.</para><para>The <replaceable>site</replaceable> field names the site to which this feed
description relates. The sitename can be coded any way you like and
doesn't have to be the domain name of the site. The site name will be
used later and will refer to an entry in a table that supplies the
hostname to the <command moreinfo="none">innxmit</command> program that transmits the
news articles by NNTP to the remote server. You may have multiple
entries for each site; each entry will be treated individually.</para><para>The <replaceable>pattern</replaceable> field specifies which news groups are
to be sent to this site. The default is to send all groups, so if that
is what you want, just make this field empty. This field is usually a
comma-delimited list of pattern-matching expressions. The * character
matches zero or more of any character, the . character has no special
significance, the ! character (if used at the start of an expression)
performs a logical NOT, and the  character at the start of a
newsgroup name means Do not forward any articles that are
posted or crossposted to this group. The list is read and
parsed from left to right, so you should ensure that you place the
more specific rules first.  The pattern:</para><screen format="linespecific">rec.crafts.brewing*,!rec.crafts.brewing.poison,@rec.crafts.brewing.private</screen><para>would send all of the <emphasis>rec.crafts.brewing</emphasis> news heirarchy
<emphasis>except</emphasis> the <emphasis>rec.crafts.brewing.poison</emphasis>. 
It would not feed any articles that were either posted or crossposted to the
<emphasis>rec.crafts.brewing.private</emphasis> newsgroup; these articles will
be trapped and available only to those people who use this server.
If you reversed the first two patterns, the first pattern would be overridden
by the second and you would end up feeding articles for the
<emphasis>rec.crafts.brewing.poison</emphasis> newsgroup. The same is true of
the first and last patterns; you must always place the more specific
patterns before any less specific patterns for them to take effect.</para><para><replaceable>flags</replaceable> controls and places constraints on the feed
of news articles to this site. The <replaceable>flags</replaceable> field is a
comma delimited list can contain any of the items from the following list, delimited by commands:</para><variablelist><varlistentry><term><replaceable>size</replaceable></term><listitem><para>Article must be less then size bytes.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">A</literal><replaceable>items</replaceable></term><listitem><para>Article checks. <replaceable>items</replaceable> can be one or more of
<literal moreinfo="none">d</literal> (must have Distribution header) or
<literal moreinfo="none">p</literal> (don't check for site in Path header).</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">B</literal><replaceable>high</replaceable>/<replaceable>low</replaceable></term><listitem><para>Internal buffer size before writing to output.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">H</literal>[<replaceable>count</replaceable>]</term><listitem><para>Article must have less then <replaceable>count</replaceable> hops; the default is 1.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">I</literal><replaceable>size</replaceable></term><listitem><para>Internal buffer size (for a file feed).</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">M</literal><replaceable>pattern</replaceable></term><listitem><para>Only moderated groups that match the pattern.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">N</literal><replaceable>pattern</replaceable></term><listitem><para>Only unmoderated groups that match the pattern.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">S</literal><replaceable>size</replaceable></term><listitem><para>Start spooling if more than size bytes get queued.</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">T</literal><replaceable>type</replaceable></term><listitem><para>Feed types: <literal moreinfo="none">f</literal> (file), <literal moreinfo="none">m</literal> (funnel; the
<replaceable>param</replaceable> field names the entry that articles will be
funneled to), <literal moreinfo="none">p</literal> (pipe to program), <literal moreinfo="none">c</literal>
(send to stdin channel of the <replaceable>param</replaceable> field's
subprocess), and <literal moreinfo="none">x</literal> (like c, but handles commands on stdin).</para></listitem></varlistentry><varlistentry><term><literal moreinfo="none">W</literal><replaceable>items</replaceable></term><listitem><para>What to write: <literal moreinfo="none">b</literal> (article bytesize), <literal moreinfo="none">f</literal>
(full path), <literal moreinfo="none">g</literal> (first newsgroup), <literal moreinfo="none">m</literal>
(Message ID), <literal moreinfo="none">n</literal> (relative path), <literal moreinfo="none">s</literal> (site
that fed article), <literal moreinfo="none">t</literal> (time received), <literal moreinfo="none">*</literal>
(names of funnel feed-ins or all sites that get the article),
<literal moreinfo="none">N</literal> (newsgroups header), <literal moreinfo="none">D</literal> (distribution
header), <literal moreinfo="none">H</literal> (all headers), <literal moreinfo="none">O</literal> (overview
data), and <literal moreinfo="none">R</literal> (replication data).</para></listitem></varlistentry></variablelist><para>The <literal moreinfo="none">param</literal> field has special coding that is dependent on
the type of feed. In the most common configuration it is where you specify
the name of the output file to which you will write the outgoing feed.
In other configurations you can leave it out. In yet other configurations
it takes on different meanings. If you want to do something unusual, the
<filename moreinfo="none">newsfeeds(5)</filename> manual page will explain the use of the
<literal moreinfo="none">param</literal> field in some detail.</para><para>There is a special site name that should be coded as <literal moreinfo="none">ME</literal>
and should be the first entry in the file. This entry is used to control
the default settings for your news feeds. If the <literal moreinfo="none">ME</literal>
entry has a distribution list associated with it, this list will
be prepended to each of the other site entries before they are sent.
This allows you to, for example, declare some
newsgroups to be automatically fed, or automatically blocked from
feeding, without having to repeat the pattern in each site entry.</para><para>We mentioned earlier that it was possible to use some special feeds to
generate thread data that makes the newsreader's job easier. We'll do this
by exploiting the <command moreinfo="none">overchan</command> command that is part of the
INN distribution. To do this, we've created a special local feed called
<literal moreinfo="none">overview</literal> that will pass the news articles to the
<command moreinfo="none">overchan</command> command for processing into overview data.</para><para>Our news server will provide only one external news feed, which goes to 
the Groucho Marx University, and they receive articles for
all newsgroups except the <emphasis>control</emphasis> and
<emphasis>junk</emphasis> newsgroups, the
<emphasis>rec.crafts.brewing.private</emphasis> newsgroup, which will be 
kept locally, and the <emphasis>rec.crafts.brewing.poison</emphasis>
newsgroup, which we don't want people from our brewery seen posting to.</para><para>We'll use the <command moreinfo="none">nntpsend</command> command to transport the news via
NNTP to the <systemitem moreinfo="none" role="sitename">news.groucho.edu</systemitem> server. <command moreinfo="none">nntpsend</command> requires us to use the file
delivery method and to write the article's pathname and article ID. Note
that we've set the <replaceable>param</replaceable> field to the name of the output 
file. We'll talk a little more about the <command moreinfo="none">nntpsend</command> 
command in a moment. Our resulting newsfeed's configuration is:

<screen width="74" format="linespecific"># /etc/news/newsfeeds file for the Virtual Brewery
#
# Send all newsgroups except the control and junk ones by default
ME:!control,!junk::
#
# Generate overview data for any newsreaders to use.
overview::Tc,WO:/usr/lib/news/bin/overchan
#
# Feed the Groucho Marx University everything except our private newsgroup
# and any articles posted to the rec.crafts.brewing.poison newsgroup.
gmarxu:!rec.crafts.brewing.poison,@rec.crafts.brewing.private:\
	Tf,Wnm:news.groucho.edu
#</screen>
</para><indexterm significance="normal" class="endofrange" startref="newsfeeds.file"></indexterm></sect3><sect3><title>The nntpsend.ctl file</title><para><indexterm significance="normal"><primary>nntpsend.ctl file (INN)</primary></indexterm>
<indexterm significance="normal"><primary>innxmit command (INN)</primary></indexterm>
The <command moreinfo="none">nntpsend</command> program manages the transmission of
news articles using the NNTP protocol by calling the
<command moreinfo="none">innxmit</command> command. We saw a simple use of the
<command moreinfo="none">nntpsend</command> command earlier, but it too has a
configuration file that provides us with some flexibility in how we
configure our news feeds.</para><para>The <command moreinfo="none">nntpsend</command> command expects to find batch files
for the sites it will feed. It expects those batch files to be named
<filename moreinfo="none">/var/spool/news/out.going/<replaceable>sitename</replaceable></filename>. <command moreinfo="none">innd</command>
creates these batch files when acting on an entry in the
<filename moreinfo="none">newsfeeds</filename>, which we saw in the previous
sections. We specified the sitename as the filename in the
<replaceable>param</replaceable> field, and that satisfies the
<command moreinfo="none">nntpsend</command> command's input requirements.</para><para>The <command moreinfo="none">nntpsend</command> command has a configuration file called
<filename moreinfo="none">nntpsend.ctl</filename> that is usually stored in the
<filename moreinfo="none">/etc/news/</filename> directory.</para><para>The <filename moreinfo="none">nntpsend.ctl</filename> file allows us to associate a fully
qualified domain name, some news feed size constraints, and a number of
transmission parameters with a news feed site name. The sitename is a means
of uniquely identifying a logical feed of articles.
The general format of the file is:

<screen format="linespecific">sitename:fqdn:max_size:[args]</screen></para><para>The following list describes the elements of this format:</para><variablelist><varlistentry><term><replaceable>sitename</replaceable></term><listitem><para>The sitename as supplied in the <filename moreinfo="none">newsfeeds</filename> file</para></listitem></varlistentry><varlistentry><term><replaceable>fqdn</replaceable></term><listitem><para>The fully qualified domain name of the news server to which we will be feeding
the news articles</para></listitem></varlistentry><varlistentry><term><replaceable>max_size</replaceable></term><listitem><para>The maximum volume of news to feed in any single transfer</para></listitem></varlistentry><varlistentry><term><replaceable>args</replaceable></term><listitem><para>Additional arguments to pass to the <command moreinfo="none">innxmit</command> command</para></listitem></varlistentry></variablelist><para>Our sample configuration requires a very simple
<filename moreinfo="none">nntpsend.ctl</filename> file. We have only one news feed. We'll
restrict the feed to a maximum of 2 MB of traffic and we'll pass an
argument to the <command moreinfo="none">innxmit</command> that sets a 3-minute
(180 second) timeout. If we were a larger site and had many news feeds,
we'd simply create new entries for each new feed site that looked much
the same as this one:

<screen format="linespecific"># /etc/news/nntpsend.ctl
#
gmarxu:news.groucho.edu:2m:-t 180
#</screen>
</para></sect3><indexterm significance="normal" class="endofrange" startref="config.newsfeeds"></indexterm><indexterm significance="normal" class="endofrange" startref="newsfeeds.config"></indexterm><indexterm significance="normal" class="endofrange" startref="inn.config.newsfeeds"></indexterm></sect2><sect2><title>Controlling Newsreader Access</title><para><indexterm significance="normal" class="startofrange" id="newsreaders.control.access"><primary>newsreaders</primary><secondary>controlling access</secondary></indexterm>
<indexterm significance="normal" class="startofrange" id="inn.control.nwsrder.access"><primary>INN (Internet News)</primary><secondary>newsreaders</secondary><tertiary>controlling access</tertiary></indexterm>
Not so many years ago, it was common for organizations to provide public
access to their news servers. Today it is difficult to locate public news
servers; most organizations carefully control who has access to their
servers, typically restricting access to users supported on their network.
INN provides configuration files to control this access.</para><sect3><title>The incoming.conf file</title><para><indexterm significance="normal" class="startofrange" id="incoming.conf.file"><primary>incoming.conf file (INN)</primary></indexterm>
<indexterm significance="normal" class="startofrange" id="etc.news.incoming.conf"><primary sortas="etc/news/incoming.conf file">/etc/news/incoming.conf file (INN)</primary></indexterm>
We mentioned in our introduction to INN that it achieves some of its
efficiency and size by separating the news feed mechanism from the
newsreading mechanism.  The
<filename moreinfo="none">/etc/news/incoming.conf</filename> file is where you specify
which hosts will be feeding you news using the NNTP protocol, as well
as where you define some parameters that control the way articles are
fed to you from these hosts.  Any host not listed in this file that
connects to the news socket will not be handled by the
<command moreinfo="none">innd</command> daemon; instead, it will be handled by the
<command moreinfo="none">nnrpd</command> daemon.</para><para>The <filename moreinfo="none">/etc/news/incoming.conf</filename> file syntax is
very simple, but it takes a moment to come to terms with. Three types of
valid entries are allowed: key/value pairs, which are how you specify
attributes and their values; peers, which is how you specify the name
of a host allowed to send articles to us using NNTP; and groups, a means 
of applying key/value pairs to groups of peers.  Key/value
pairs can have three different types of scope. Global pairs apply to
every peer defined in the file. Group pairs apply to all peers defined
within that group. Peer pairs apply only to that one peer. Specific
definitions override less specific ones: therefore, peer definitions
override group definitions, which in turn override global pairs.</para><para>Curly brace characters (<literal moreinfo="none">{}</literal>) are used to delimit the
start and end of the <literal moreinfo="none">group</literal> and <literal moreinfo="none">peer</literal>
specifications. The # character marks the rest of the
line it appears on as a comment. Key/value pairs are separated by the
colon character and appear one to a line.</para><para>A number of different keys may be specified. The more common
and useful are:

<variablelist><varlistentry><term>hostname</term><listitem><para>This key specifies a comma-separated list of fully qualifed names or IP
addresses of the peers that we'll allow to send us articles. If this key is
not supplied, the hostname defaults to the label of the peer.</para></listitem></varlistentry><varlistentry><term>streaming</term><listitem><para>This key determines whether streaming commands are allowed from this host.
It is a Boolean value that defaults to <literal moreinfo="none">true</literal>.</para></listitem></varlistentry><varlistentry><term>max-connections</term><listitem><para>This key specifies the maximum number of connections allowed from this group
or peer. A value of zero means unlimited (which can also be specified using
<literal moreinfo="none">none</literal>).</para></listitem></varlistentry><varlistentry><term>password</term><listitem><para>This key allows you to specify the password that must be used by a peer if it
is to be allowed to transfer news. The default is to not require a password.</para></listitem></varlistentry><varlistentry><term>patterns</term><listitem><para>This key specifies the newsgroups that we accept from the associated peer.
This field is coded according to precisely the same rules as we used in our
<filename moreinfo="none">newsfeeds</filename> file.</para></listitem></varlistentry></variablelist>
</para><para>In our example we have only one host that we are expecting to feed us
news: our upstream news provider at Groucho Marx
University. We'll have no password, but we will ensure that we don't
accept any articles for our private newsgroup from outside. Our
<filename moreinfo="none">hosts.nntp</filename> looks like:

<screen width="45" format="linespecific"># Virtual Brewery incoming.conf file.

# Global settings
streaming:       true
max-connections: 5

# Allow NNTP posting from our local host.
peer ME {
    hostname: "localhost, 127.0.0.1"
}

# Allow groucho to send us all newsgroup except our local ones.
peer groucho {
    hostname: news.groucho.edu
    patterns: !rec.crafts.brewing.private
}</screen>
</para><indexterm significance="normal" class="endofrange" startref="incoming.conf.file"></indexterm><indexterm significance="normal" class="endofrange" startref="etc.news.incoming.conf"></indexterm></sect3><sect3><title>The nnrp.access file</title><para><indexterm significance="normal"><primary>nnrp.access file (INN)</primary></indexterm>
<indexterm significance="normal"><primary>nnrpd command (INN)</primary></indexterm>
We mentioned earlier that newsreaders, and in fact any host not listed
in the <filename moreinfo="none">hosts.nntp</filename>, that connect to the INN news
server are handled by the <command moreinfo="none">nnrpd</command> program. <command moreinfo="none">nnrpd</command> uses the
<filename moreinfo="none">/etc/news/nnrp.access</filename> file to determine who is
allowed to make use of the news server, and what permissions they
should have.</para><para>The <filename moreinfo="none">nnrp.access</filename> file has a similar structure to the other
configuration files we've looked at. It comprises a set of patterns used to
match against the connecting host's domain name or IP address, and fields
that determine what access and permission it should be given. Each entry
should appear on a line by itself, and fields are separated by colons. The
last entry in this file that matches the connecting host will be the one
used, so again, you should put general patterns first and follow them with
more specific ones later in the file. The five fields of each entry in
the order they should appear are:

<variablelist><varlistentry><term>Hostname or IP address</term><listitem><para>This field conforms to <filename moreinfo="none">wildmat(3)</filename> pattern-matching rules. It is a pattern that describes the connecting host's name or IP address.</para></listitem></varlistentry><varlistentry><term>Permissions</term><listitem><para>This field determines what permissions the matching host should be granted.
There are two permissons you may configure: <literal moreinfo="none">R</literal> gives
read permissions, and <literal moreinfo="none">P</literal> gives posting permissions.</para></listitem></varlistentry><varlistentry><term>Username</term><listitem><para>This field is optional and allows you to specify a username that an NNTP
client must log into the server before being allowed to post news
articles. This field may be left blank. No user authentication is required
to read articles.</para></listitem></varlistentry><varlistentry><term>Password</term><listitem><para>This field is optional and is the password accompanying the
<replaceable>username</replaceable> field. Leaving this field blank means that no
password is required to post articles.</para></listitem></varlistentry><varlistentry><term>Newsgroups</term><listitem><para>This field is a pattern specifying which newsgroups the client is allowed to
access. The pattern follows the same rules as those used in the
<filename moreinfo="none">newsfeeds</filename> file. The default for this field is no
newsgroups, so you would normally have a pattern configured here.</para></listitem></varlistentry></variablelist>
</para><para>In the virtual brewery example, we will allow any NNTP client in the Virtual 
Brewery domain to both read and post to all newsgroups. We will allow any NNTP
client read-only access to all newsgroups except our private internal
newsgroup. Our <filename moreinfo="none">nnrp.access</filename> file will look like this:

<screen width="78" format="linespecific"># Virtual Brewery - nnrp.access
# We will allow public reading of all newsgroups except our private one.
*:R:::*,!rec.crafts.brewing.private

# Any host with the Virtual Brewery domain may Read and Post to all 
# newsgroups
*.vbrew.com:RP::*</screen></para></sect3><indexterm significance="normal" class="endofrange" startref="newsreaders.control.access"></indexterm><indexterm significance="normal" class="endofrange" startref="inn.control.nwsrder.access"></indexterm></sect2><sect2><title>Expiring News Articles</title><para><indexterm significance="normal"><primary>news (network)</primary><secondary>articles</secondary><tertiary>expiring</tertiary></indexterm>
<indexterm significance="normal"><primary>articles (news)</primary><secondary>expiring</secondary></indexterm>
<indexterm significance="normal"><primary>INN (Internet News)</primary><secondary>expiring news articles</secondary></indexterm>
When news articles are received by a news server, they are stored to
disk. News articles need to be available to users for some period of
time to be useful, so a large operating news server can consume lots
of disk space. To ensure that the disk space is used effectively, you
can opt to delete news articles automatically after a period of
time. This is called <command moreinfo="none">article expiration</command>. Naturally,
INN provides a means of automatically expiring news articles.</para><sect3><title>The expire.ctl file</title><para><indexterm significance="normal"><primary>expire.ctl file (INN)</primary></indexterm>
The INN server uses a program called <command moreinfo="none">expire</command> to delete
expired news articles. The <command moreinfo="none">expire</command> program in turn uses a
file called <filename moreinfo="none">/etc/news/expire.ctl</filename> to configure
the rules that govern article expiration.</para><para>The syntax of <filename moreinfo="none">/etc/news/expire.ctl</filename> is fairly simple.
As with most configuration files, empty lines or lines beginning with the # 
character are ignored. The general idea is that you specify
one rule per line. Each rule defines how article expiration will be performed
on newsgroups matching a supplied pattern. The rule syntax looks like this:

<screen width="34" format="linespecific"><replaceable>pattern</replaceable>:<replaceable>modflag</replaceable>:<replaceable>keep</replaceable>:<replaceable>default</replaceable>:<replaceable>purge</replaceable></screen></para><para>The following list describes the fields:

<variablelist><varlistentry><term>pattern</term><listitem><para>This field is a comma-delimited list of patterns matching names of
newsgroups.  The <filename moreinfo="none">wildmat</filename>(3) routine is used to
match these patterns. The last rule matching a newsgroup name is the
one that is applied, so if you want to specify wildcard (*) rules,
they should be listed first in this file.</para></listitem></varlistentry><varlistentry><term>modflag</term><listitem><para>This flag describes how this rule applies to moderated newsgroups. It can be
coded with an <literal moreinfo="none">M</literal> to mean that this rule applies only to
moderated newsgroups, a <literal moreinfo="none">U</literal> to mean that this rule applies 
only to unmoderated newsgroups, or an <literal moreinfo="none">A</literal> to mean that this 
rule ignores the moderated status and applies to all groups.</para></listitem></varlistentry><varlistentry><term>keep</term><listitem><para>This field allows you to specify the minimum time an article with an
Expires header will be kept before it is expired. The units
are days, and are a floating point, so you may specify values like
<literal moreinfo="none">7.5</literal> for seven-and-a-half days. You may also specify 
<literal moreinfo="none">never</literal> if you wish articles to stay in a newsgroup forever.</para></listitem></varlistentry><varlistentry><term>default</term><listitem><para>This field is the most important. This field allows you to specify the
time an article without an <literal moreinfo="none">Expires</literal> header will be
kept. Most articles won't have an <literal moreinfo="none">Expires</literal>
header. This field is coded in the same way as the
<replaceable>keep</replaceable> field, with <literal moreinfo="none">never</literal> meaning
that articles without <literal moreinfo="none">Expires</literal> headers will never be
expired.</para></listitem></varlistentry><varlistentry><term>purge</term><listitem><para>This field allows you to specify the maximum time an article with an 
<literal moreinfo="none">Expires</literal> header will be kept before it is expired. The coding
of this field is the same as for the <literal moreinfo="none">keep</literal> field.</para></listitem></varlistentry></variablelist></para><para>Our requirements are simple. We will keep all articles in all newsgroups
for 14 days by default, and between 7 and 21 days for articles that have
an <literal moreinfo="none">Expires</literal> header.
The <emphasis>rec.crafts.brewing.private</emphasis> newsgroup is our internal
newsgroup, so we'll make sure we don't expire any articles from it:

<screen width="69" format="linespecific"># expire.ctl file for the Virtual Brewery

# Expire all articles in 14 days by default, 7-21 days for those with
# Expires: headers
*:A:7:14:21

# This is a special internal newsgroup, which we will never expire.
rec.crafts.brewing.private:A:never:never:never</screen>
</para><para>We will mention one special type of entry you may have in your
<filename moreinfo="none">/etc/news/expires.ctl</filename> file.
You may have exactly one line that looks like this:

<screen format="linespecific">/remember/:<replaceable>days</replaceable></screen>

This entry allows you to specify the minimum number of days that an article
will be remembered in the history file, irrespective of whether the article
itself has been expired or not. This might be useful if one of the sites that
is feeding you articles is infrequent and has a habit of sending you old
articles every now and again. Setting the <replaceable>/remember/</replaceable>
field helps to prevent the upstream server from sending you the article again,
even if it has already been expired from your server. If your server remembers
it has already received the article, <?troff .ne 10?>it will reject attempts to resend it.
It is important to remember that this setting has no effect at all on article
expiration; it affects only the time that details of an article are kept in the history database.</para></sect3></sect2><sect2><title>Handling Control Messages</title><para><indexterm significance="normal" class="startofrange" id="inn.control.msgs"><primary>INN (Internet News)</primary><secondary>control messages, handling</secondary></indexterm>
Just as with C News, INN can automatically process control messages.
INN provides a powerful configuration mechanism to control what action will
occur for each of a variety of control messages, and an access control
mechanism to control who can initiate actions against which newsgroups.</para><sect3><title>The control.ctl file</title><para><indexterm significance="normal"><primary>control.ctl file (INN)</primary></indexterm>
The <filename moreinfo="none">control.ctl</filename> file is fairly simple in structure.
The syntax rules for this file are much the same as for the other INN
configuration files. Lines beginning with <literal moreinfo="none">#</literal>
are ignored, lines may be continued using <literal moreinfo="none">/</literal>, and
fields are delimited by <literal moreinfo="none">:</literal>.</para><para>When a control message is received, it is tested against each rule in turn.
The last rule in the file that matches the message is the rule that will be
used, so you should put any generic rules at the start of the file and
more specific rules at the end of the file. The general syntax of the file is:</para><para><screen width="30" format="linespecific"><replaceable>message</replaceable>:<replaceable>from</replaceable>:<replaceable>newsgroups</replaceable>:<replaceable>action</replaceable></screen></para><para>The meanings of each of the fields are:

<variablelist><varlistentry><term>message</term><listitem><para>This is the name of the control message. Typical control messages are
described later.</para></listitem></varlistentry><varlistentry><term>from</term><listitem><para>This is a shell-style pattern matching the email address of the person 
sending the message. The email address is converted to lowercase before comparison. </para></listitem></varlistentry><varlistentry><term>newsgroups</term><listitem><para>If the control message is <literal moreinfo="none">newgroup</literal> or
<literal moreinfo="none">rmgroup</literal>, this field is a shell-style pattern matching
the newsgroup created or removed.</para></listitem></varlistentry><varlistentry><term>action</term><listitem><para>This field specifies what action to take for any message matching the rule. 
There are quite a number of actions we can take; they are
described in the next list.</para></listitem></varlistentry></variablelist></para><para>The <replaceable>message</replaceable> field of each line can have one of the following values:</para><variablelist id="x-087-2-chin.contmess"><varlistentry><term>checkgroups</term><listitem><para>This message requests that news administrators resynchonrize their
active newsgroups database against the list of newsgroups supplied in
the control message.</para></listitem></varlistentry><varlistentry><term>newgroup</term><listitem><para>This message requests the creation of a new newsgroup. The body of the
control message should contain a short description of the purpose of
the newsgroup to be created.</para></listitem></varlistentry><varlistentry><term>rmgroup</term><listitem><para>requests that a newsgroup be removed.</para></listitem></varlistentry><varlistentry><term>sendsys</term><listitem><para><indexterm significance="normal"><primary>RFC-1036</primary></indexterm>
This message requests that the <filename moreinfo="none">sys</filename> file of this
news server be transmitted by mail to the originator of the control
message. RFC-1036 states that it is a requirement of Usenet membership
that this information be publicly available because it is used to
keep the map of Usenet up to date.</para></listitem></varlistentry><varlistentry><term>version</term><listitem><para>
This message requests that the hostname and version of news server
software be returned to the originator of the control message.
</para></listitem></varlistentry><varlistentry><term>all</term><listitem><para>This is a special coding that will match any control message.</para></listitem></varlistentry></variablelist><para>The <replaceable>message</replaceable> field may include the following actions:</para><variablelist id="x-087-2-chin.contacts"><varlistentry><term>doit</term><listitem><para>The requested command is performed. In many cases, a mail message will
be sent to the administrator to advise them that the action has taken place.</para></listitem></varlistentry><varlistentry><term>doit=<replaceable>file</replaceable></term><listitem><para>This is the same as the <literal moreinfo="none">doit</literal> action except
that a log message will be written to the <emphasis>file</emphasis>
log file. If the specified file is <emphasis>mail</emphasis>, the log
entry is sent by email. If the specified file is the null string, the
log message is written to <filename moreinfo="none">/dev/null</filename> and is equivalent
to using the unqualified <literal moreinfo="none">doit</literal> action. If the
<emphasis>file</emphasis> name begins with a / character, the name is 
taken to be an absolute filename for the logfile; otherwise, the specified 
name is translated to
<filename moreinfo="none">/var/log/news/file.log</filename>.</para></listitem></varlistentry><varlistentry><term>doifarg</term><listitem><para>The requested command is performed if the command has an argument.
If the command has no argument, the control message is ignored.</para></listitem></varlistentry><varlistentry><term>drop</term><listitem><para>The requested command is ignored.</para></listitem></varlistentry><varlistentry><term>log</term><listitem><para>A log message is sent to the <literal moreinfo="none">stderr</literal> output of the
<command moreinfo="none">innd</command> process. This is normally directed out to the
<filename moreinfo="none">/var/log/news/errlog</filename> file.</para></listitem></varlistentry><varlistentry><term>log=<replaceable>file</replaceable></term><listitem><para>This is the same as a <literal moreinfo="none">log</literal> action, except the
logfile is specified as per the rules given for the
<literal moreinfo="none">doit</literal>=<replaceable>file</replaceable> action.</para></listitem></varlistentry><varlistentry><term>mail</term><listitem><para>An email message is sent to the news administrator containing the
requested command details. No other action takes place.</para></listitem></varlistentry><varlistentry><term>verify-*</term><listitem><para><indexterm significance="normal"><primary>PGP (Pretty Good Privacy)</primary></indexterm>
<indexterm significance="normal"><primary>GPG (GNU Privacy Guard)</primary></indexterm>
If an action begins with the string <literal moreinfo="none">verify-</literal>, 
then the control message is authenticated using PGP (or
GPG).<footnote><para>PGP and GPG are tools designed to authenticate or encrypt messages using
public key techniques. GPG is the GNU free version of PGP. GPG may be found
at <systemitem moreinfo="none" role="url">http://www.gnupg.org/</systemitem>, and PGP may be
found at <systemitem moreinfo="none" role="url">http://www.pgp.com/</systemitem>.</para></footnote></para></listitem></varlistentry></variablelist><para>So that you can see what a <filename moreinfo="none">control.ctl</filename> file would look 
like in practice, here is a very short illustrative sample:</para><screen width="80" format="linespecific">## Sample /etc/news/control.ctl
##
## Warning: You should not use this file, it is illustrative only.

##	Control Message Handling
all:*:*:mail
checkgroups:*:*:mail
ihave:*:*:drop
sendme:*:*:drop
sendsys:*:*:log=sendsys
senduuname:*:*:log=senduuname
version:*:*:log=version
newgroup:*:*:mail
rmgroup:*:*:mail

##  Handle control messages for the eight most important news heirarchies
##  COMP, HUMANITIES, MISC, NEWS, REC, SCI, SOC, TALK
checkgroups:*:comp.*|humanities.*|misc.*|news.*|rec.*|sci.*|soc.*|talk.*:drop
newgroup:*:comp.*|humanities.*|misc.*|news.*|rec.*|sci.*|soc.*|talk.*:drop
rmgroup:*:comp.*|humanities.*|misc.*|news.*|rec.*|sci.*|soc.*|talk.*:drop
checkgroups:group-admin@isc.org:*:verify-news.announce.newgroups
newgroup:group-admin@isc.org:comp.*|misc.*|news.*:verify-news.announce.newgroups
newgroup:group-admin@isc.org:rec.*|sci.*|soc.*:verify-news.announce.newgroups
newgroup:group-admin@isc.org:talk.*|humanities.*:verify-news.announce.newgroups
rmgroup:group-admin@isc.org:comp.*|misc.*|news.*:verify-news.announce.newgroups
rmgroup:group-admin@isc.org:rec.*|sci.*|soc.*:verify-news.announce.newgroups
rmgroup:group-admin@isc.org:talk.*|humanities.*:verify-news.announce.newgroups

## GNU ( Free Software Foundation )
newgroup:gnu@prep.ai.mit.edu:gnu.*:doit
newgroup:news@*ai.mit.edu:gnu.*:doit
rmgroup:gnu@prep.ai.mit.edu:gnu.*:doit
rmgroup:news@*ai.mit.edu:gnu.*:doit

## LINUX (Newsfeed from news.lameter.com)
checkgroups:christoph@lameter.com:linux.*:doit
newgroup:christoph@lameter.com:linux.*:doit
rmgroup:christoph@lameter.com:linux.*:doit</screen></sect3><indexterm significance="normal" class="endofrange" startref="inn.control.msgs"></indexterm></sect2><indexterm significance="normal" class="endofrange" startref="config.files.inn"></indexterm><indexterm significance="normal" class="endofrange" startref="inn.config.files"></indexterm></sect1><sect1><title>Running INN</title><para><indexterm significance="normal"><primary>INN (Internet News)</primary><secondary>running</secondary></indexterm>
<indexterm significance="normal"><primary>inn source package</primary></indexterm>
The <command moreinfo="none">inn</command> source package provides a script suitable for
starting <command moreinfo="none">inn</command> at boot time. The script is usually called
<filename moreinfo="none">/usr/lib/news/bin/rc.news</filename>. The script reads arguments
from another script, usually called
<filename moreinfo="none">/usr/lib/news/innshellvars</filename>, which contains definitions
of the filenames and filepaths that <command moreinfo="none">inn</command> will use to locate
components it needs. It is generally considered a good idea to execute
<command moreinfo="none">inn</command> with the permissions of a non-root user, such as 
<literal moreinfo="none">news</literal>.</para><para>To ensure that <command moreinfo="none">inn</command> is started at boot time, you should
check that <filename moreinfo="none">/usr/lib/news/innshellvars</filename> is configured
correctly and then call the <filename moreinfo="none">/usr/lib/news/bin/rc.news</filename>
script from a script executed at boot time.</para><para>Additionally, there are administrative tasks that must be performed
periodically. These tasks are usually configured to be executed by the
<command moreinfo="none">cron</command> command. The best way to do this is to add the
appropriate commands to your <filename moreinfo="none">/etc/crontab</filename> file, or
even better, create a file suitable for the <filename moreinfo="none">/etc/cron.d</filename>
directory, if your distribution provides one. An example of such a file might
look like:

<screen width="67" format="linespecific"># Example /etc/cron.d/inn file, as used in the Debian distribution.
#
SHELL=/bin/sh
PATH=/usr/lib/news/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Expire old news and overview entries nightly, generate reports.

15 0 * * *      news    news.daily expireover lowmark delayrm

# Every hour, run an rnews -U. This is not only for UUCP sites, but
# also to process queued up articles put there by in.nnrpd in case
# innd wasn't accepting any articles.

10 * * * *      news    rnews -U</screen></para><para>These commands will ensure that old news is automatically expired each day,
and that any queued articles are processed each hour. Note also that they
are executed with the permissions of the <literal moreinfo="none">news</literal> user.</para></sect1><sect1><title>Managing INN: The ctlinnd Command</title><para><indexterm significance="normal" class="startofrange" id="ctlinnd.command"><primary>ctlinnd command (INN)</primary></indexterm>
<indexterm significance="normal" class="startofrange" id="inn.managing"><primary>INN (Internet News)</primary><secondary>managing</secondary></indexterm>
The INN news server comes with a command to manage its day-to-day operation.
The <command moreinfo="none">ctlinnd</command> command can be used to manipulate newsgroups
and newsgroup feeds, to obtain the status, of the server, and to reload, stop,
and start the server.</para><?troff .Nd 10?><para>You'd normally get a summary of the <command moreinfo="none">ctlinnd</command> command
syntax using:

<screen format="linespecific"><emphasis role="bold"># ctlinnd -h</emphasis></screen></para><para>We'll cover some of the more important uses of
<command moreinfo="none">ctlinnd</command> here; please consult the
<command moreinfo="none">ctlinnd</command> manual page for more detail.</para><sect2><title>Add a New Group</title><para>Use the following syntax to add a new group:</para><para><screen width="35" format="linespecific">ctlinnd newgroup <replaceable>group</replaceable> <replaceable>rest</replaceable> <replaceable>creator</replaceable></screen></para><para>The arguments are defined as follows:</para><variablelist><varlistentry><term><replaceable>group</replaceable></term><listitem><para>The name of the group to create.</para></listitem></varlistentry><varlistentry><term><replaceable>rest</replaceable></term><listitem><para>This argument should be coded in the same way as the
<replaceable>flags</replaceable> field of the <filename moreinfo="none">active</filename> file.
It defaults to <literal moreinfo="none">y</literal> if not supplied.</para></listitem></varlistentry><varlistentry><term><replaceable>creator</replaceable></term><listitem><para>The name of the person creating the group. Enclose it in quotes
if there are any spaces in the name.</para></listitem></varlistentry></variablelist></sect2><sect2><title>Change a Group</title><para>Use the following syntax to change a group:</para><para><screen width="30" format="linespecific">ctlinnd changegroup <replaceable>group</replaceable> <replaceable>rest</replaceable></screen></para><para>The arguments are defined as follows:</para><variablelist><varlistentry><term><replaceable>group</replaceable></term><listitem><para>The name of the group to change.</para></listitem></varlistentry><varlistentry><term><replaceable>rest</replaceable></term><listitem><para>This argument should be coded in the same way as the <replaceable>flags</replaceable> field of the <filename moreinfo="none">active</filename> file.</para></listitem></varlistentry></variablelist><para>This command is useful to change the moderation status of a group.</para></sect2><sect2><title>Remove a Group</title><para>Use the following syntax to remove a group:</para><para><screen format="linespecific">ctlinnd rmgroup <replaceable>group</replaceable></screen></para><?troff .Nd 10?><?troff .wcon_off?><para>The argument is defined as follows:</para><variablelist><varlistentry><term><replaceable>group</replaceable></term><listitem><para>The name of the group to remove.</para></listitem></varlistentry></variablelist><para>This command removes the specified newsgroup from the
<filename moreinfo="none">active</filename> file. It has no effect on the news spool. All
articles in the spool for the specified group will be expired in the usual
fashion, but no new articles will be accepted.</para></sect2><sect2><title>Renumber a Group</title><para>Use the following syntax to renumber a group:</para><para><screen format="linespecific">ctlinnd renumber <replaceable>group</replaceable></screen></para><?troff .Nd 10?><para>The argument is defined as follows:</para><variablelist><varlistentry><term><replaceable>group</replaceable></term><listitem><para>The name of the group to renumber. If a <command moreinfo="none">group</command> is an empty 
string, all groups are renumbered.</para></listitem></varlistentry></variablelist><para>This command updates the low-water mark for the specified group.</para></sect2><sect2><title>Allow/Disallow Newsreaders</title><para>Use the following syntax to allow or disallow newsreaders:</para><para><screen format="linespecific">ctlinnd readers <replaceable>flag</replaceable> <replaceable>text</replaceable></screen></para><para>The arguments are defined as follows:</para><variablelist><varlistentry><term><replaceable>flag</replaceable></term><listitem><para>Specifying <literal moreinfo="none">n</literal> causes all newsreader connections to be
disallowed. Specifying <literal moreinfo="none">y</literal> allows newsreader connections.</para></listitem></varlistentry><varlistentry><term><replaceable>text</replaceable></term><listitem><para>The text supplied will be given to newsreaders who attempt to connect, and 
usually describes the reason for disabling newsreader access. When
reenabling newsreader access, this field must be either an empty 
string or a copy of the text supplied when the newsreader was disabled.</para><para>This command does not affect incoming newsfeeds. It only controls connections
from newsreaders.</para></listitem></varlistentry></variablelist></sect2><sect2><title>Reject Newsfeed Connections</title><para>Use the following syntax to reject newsfeed connections:</para><screen format="linespecific">ctlinnd reject <replaceable>reason</replaceable></screen><?troff. Nd 10?><para>The argument is defined as follows:</para><variablelist><varlistentry><term><replaceable>reason</replaceable></term><listitem><para>The text supplied should explain why incoming connections to 
<command moreinfo="none">innd</command> are rejected.</para></listitem></varlistentry></variablelist><para>This command does not affect connections that are handed off to
<command moreinfo="none">nnrpd</command> (i.e., newsreaders); it only affects connections that
would be handled by <command moreinfo="none">innd</command> directly, such as remote newsfeeds.</para></sect2><sect2><title>Allow Newsfeed Connections</title><para>Use the following syntax to allow newsfeed connections:</para><para><screen format="linespecific">ctlinnd allow <replaceable>reason</replaceable></screen></para><para>The argument is defined as follows:</para><variablelist><varlistentry><term><replaceable>reason</replaceable></term><listitem><para>The supplied text must be the same as that supplied to the preceding
<command moreinfo="none">reject</command> command or an empty string.</para></listitem></varlistentry></variablelist><para>This command reverses the effect of a <command moreinfo="none">reject</command> command.</para></sect2><sect2><title>Disable News Server</title><para>Use the following syntax to disable the news server:</para><para><screen format="linespecific">ctlinnd throttle <replaceable>reason</replaceable></screen></para><para>The argument is defined as follows:</para><variablelist><varlistentry><term><replaceable>reason</replaceable></term><listitem><para>The reason for throttling the server.</para></listitem></varlistentry></variablelist><para>This command is simultaneously equivalent to a 
<literal moreinfo="none">newsreaders no</literal> and a <literal moreinfo="none">reject</literal>, 
and is useful when emergency work is performed on the news database. 
It ensures that nothing attempts to update it while you are working on it.</para></sect2><sect2><title>Restart News Server</title><para>Use the following syntax to restart the news server:</para><para><screen format="linespecific">ctlinnd go <replaceable>reason</replaceable></screen></para><para>The argument is defined as follows:</para><variablelist><varlistentry><term><replaceable>reason</replaceable></term><listitem><para>The reason given when stopping the server. If this field is an empty
string, the server will be reenabled unconditionally. If a reason is given, 
only those functions disabled with a reason matching the supplied text
will be restarted.</para></listitem></varlistentry></variablelist><para>This command is used to restart a server function after a
<command moreinfo="none">throttle</command>, <command moreinfo="none">pause</command>, or
<command moreinfo="none">reject</command> command.</para></sect2><sect2><title>Display Status of a Newsfeed</title><para>Use the following syntax to display the status of a newsfeed:</para><para><screen format="linespecific">ctlinnd feedinfo <replaceable>site</replaceable></screen></para><para>The argument is defined as follows:</para><variablelist><varlistentry><term><replaceable>site</replaceable></term><listitem><para>The site name (taken from the <filename moreinfo="none">newsfeeds</filename> file) for which 
you wish to display the newsfeed's status.</para></listitem></varlistentry></variablelist></sect2><sect2><title>Drop a Newsfeed</title><para>Use the following syntax to drop a newsfeed:</para><para><screen format="linespecific">ctlinnd drop <replaceable>site</replaceable></screen></para><para>The argument is defined as follows:</para><variablelist><varlistentry><term><replaceable>site</replaceable></term><listitem><para>The name of the site (taken from the <filename moreinfo="none">newsfeeds</filename> file) to
which feeds are dropped. If this field is an empty string, all active feeds 
will be dropped.</para></listitem></varlistentry></variablelist><para>Dropping a newsfeed to a site halts any active feeds to the site. It is not
a permanent change. This command would be useful if you've modified the feed
details for a site and a feed to that site is active.</para></sect2><sect2><title>Begin a Newsfeed</title><para>Use the following syntax to begin a newsfeed:</para><para><screen format="linespecific">ctlinnd begin <replaceable>site</replaceable></screen></para><para>The argument is defined as follows:</para><variablelist><varlistentry><term><replaceable>site</replaceable></term><listitem><para>The name of the site from the <filename moreinfo="none">newsfeeds</filename> file to
which feeds are started. If a feed to the site is already active, a 
<command moreinfo="none">drop</command> command is done first automatically.</para></listitem></varlistentry></variablelist><para>This command causes the server to reread the <filename moreinfo="none">newsfeeds</filename>
file, locate the matching entry, and commence a newsfeed to the named
site using the details found. You can use this command to test a new
news feed to a site after you've added or modified its entry in the
<filename moreinfo="none">newsfeeds</filename> file.</para></sect2><sect2><title>Cancel an Article</title><para>Use the following syntax to cancel an article:</para><para><screen format="linespecific">ctlinnd cancel <replaceable>Message-Id</replaceable></screen></para><para>The argument is defined as follows:</para><variablelist><varlistentry><term><replaceable>Message-ID</replaceable></term><listitem><para>The ID of the article to be cancelled.</para></listitem></varlistentry></variablelist><para>This command causes the specified article to be deleted from the server.
It does not generate a cancel message.</para></sect2><indexterm significance="normal" class="endofrange" startref="ctlinnd.command"></indexterm><indexterm significance="normal" class="endofrange" startref="inn.managing"></indexterm></sect1></chapter><chapter id="x-087-2-newsreaders"><title>Newsreader <?lb?>Configuration</title><indexterm significance="normal" class="startofrange" id="chnr.newsrdr.config"><primary>newsreaders</primary><secondary>configuring</secondary></indexterm><indexterm significance="normal" class="startofrange" id="chnr.config.newsrdr"><primary>configuring</primary><secondary>newsreader</secondary></indexterm><para>A <command moreinfo="none">newsreader</command> is a program that users invoke to view, 
store, and create news articles.  Several newsreaders have been ported to 
Linux. We will describe the basic setup for the three most popular 
newsreaders: <command moreinfo="none">tin</command>, <command moreinfo="none">trn</command>, and <command moreinfo="none">nn</command>.</para><para>One of the most effective newsreaders is:

<screen format="linespecific">$ <userinput moreinfo="none">find /var/spool/news -name '[0-9]*' -exec cat {} \; | more</userinput></screen></para><para>This is the way Unix die-hards read their news.</para><para>Most newsreaders, however, are much more sophisticated. They usually offer
a full-screen interface with separate levels for displaying all groups the
user has subscribed to, an overview of all articles in each group, and
individual articles. Many web browsers double as newsreaders, but if you want 
to use a standalone newsreader, this chapter explains how to configure two 
classic ones: <command moreinfo="none">trn</command> and <command moreinfo="none">nn</command>.</para><para>At the newsgroup level, most newsreaders display a list of articles,
showing their subject lines and authors. In big groups, it is difficult
for the user to keep track of articles relating to each other, although
it is possible to identify responses to earlier articles.</para><para><indexterm significance="normal"><primary>newsreaders</primary><secondary>threading</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>follow-up</secondary></indexterm>
A response usually repeats the original article's subject, prepending it
with <literal moreinfo="none">Re:</literal>. Additionally, the <literal moreinfo="none">References:</literal> 
header line should include the message ID of the article on which the 
response is directly following up. Sorting articles by these two criteria 
generates small clusters (in fact, trees) of articles, which are called 
<emphasis>threads</emphasis>. One of the tasks of writing a newsreader is 
devising an efficient scheme of threading, because the time required for this 
is proportional to the square of the number of articles.</para><para>We will not go into how the user interfaces are built here. All newsreaders
currently available for Linux have a good help function; please refer to it 
for more details.</para><para>In the following sections, we will deal only with administrative tasks. Most of
these relate to the creation of threads databases and accounting.</para><sect1 id="x-087-2-newsreaders.tin"><title>tin Configuration</title><indexterm significance="normal"><primary>newsreaders</primary><secondary>tass</secondary></indexterm><indexterm significance="normal"><primary>newsreaders</primary><secondary>tin</secondary></indexterm><indexterm significance="normal"><primary>tass newsreader</primary></indexterm><indexterm significance="normal"><primary>tin newsreader, configuration</primary></indexterm><para>The most versatile newsreader with respect to threading is
<command moreinfo="none">tin</command>. It was written by Iain Lea and is loosely modeled
on an older newsreader named <command moreinfo="none">tass</command> (written by Rich Skrenta).
It does its threading when the user enters the newsgroup, and it is
pretty fast unless you're getting posts via NNTP.</para><para>On a 486DX50, it takes roughly 30 seconds to thread 1,000 articles when
reading directly from disk.  It would take more than 5 minutes over NNTP 
to reach a loaded news server.<footnote id="x-087-2-fnnr01"><para>Things improve drastically if the NNTP server does the threading itself and
lets the client retrieve the threads databases; INN does this, for instance.</para></footnote>
You may improve this time by regularly updating your index file by invoking
<command moreinfo="none">tin</command> with the <option>u</option> option, so that when
you next start <command moreinfo="none">tin</command> to read news the threads already exist.
Alternatively, you can invoke <command moreinfo="none">tin</command> with the
<option>U</option> option to read news. When invoked this way,
<command moreinfo="none">tin</command> forks a background process to build the index files
while you are reading news.
</para><para>Usually, <command moreinfo="none">tin</command> dumps its threading databases in the user's
home directory below <filename moreinfo="none">.tin/index</filename>. This may be costly
in terms of resources, however, so you should keep a single copy of them in
a central location. This may be achieved by making <command moreinfo="none">tin</command>
setuid to <systemitem moreinfo="none" role="userid">news</systemitem>, for
example. <command moreinfo="none">tin</command> will then keep all thread databases below
<filename moreinfo="none">/var/spool/news/.index</filename>. For any file access or shell
escape, it will reset its effective uid to the real uid of the user who
invoked it.<footnote id="x-087-2-fnnr03"><para>This is the reason why you will get ugly error messages when invoking 
<command moreinfo="none">tin</command> as superuser. But you shouldn't do routine work as
<systemitem moreinfo="none" role="userid">root</systemitem>, anyway.</para></footnote></para><para>The version of <command moreinfo="none">tin</command> included in some Linux distributions
is compiled without NNTP support, but most do have it now.  When invoked as
<command moreinfo="none">rtin</command> or with the <option>r</option> option,
<command moreinfo="none">tin</command> tries to connect to the NNTP server specified in
the file <filename moreinfo="none">/etc/nntpserver</filename> or in the
<systemitem class="environvar" moreinfo="none">NNTPSERVER</systemitem> environment variable.
The <filename moreinfo="none">nntpserver</filename> file simply contains the server's name
on a single line.
<indexterm significance="normal"><primary sortas="etc/nntpserver file">/etc/nntpserver file</primary></indexterm> 
<indexterm significance="normal"><primary>NNTPSERVER environment variables</primary></indexterm> 
<indexterm significance="normal"><primary>environment variables</primary><secondary>NNTPSERVER</secondary></indexterm> </para></sect1><sect1 id="x-087-2-newsreaders.trn"><title>trn Configuration</title><indexterm significance="normal"><primary>newsreaders</primary><secondary>trn</secondary></indexterm><indexterm significance="normal"><primary>trn newsreader, configuration</primary></indexterm><para><?troff .hw Davidson?><command moreinfo="none">trn</command> is also the successor to an older newsreader, namely
<command moreinfo="none">rn</command> (which means <emphasis>read news</emphasis>). The
t in its name stands for threaded.  It was
written by Wayne Davidson.</para><para><indexterm significance="normal"><primary>newsreaders</primary><secondary>creating thread databases</secondary></indexterm>
Unlike <command moreinfo="none">tin</command>, <command moreinfo="none">trn</command> has no provision for
generating its threading database at runtime. Instead, it uses those prepared
by a program called <command moreinfo="none">mthreads</command> that has to be invoked
regularly from <command moreinfo="none">cron</command> to update the index files.</para><para><indexterm significance="normal"><primary>mthreads program</primary></indexterm>
You can still access new articles if you're not running
<command moreinfo="none">mthreads</command>, but you will have all those
A GENUINE INVESTMENT OPPORTUNITY articles scattered across your
article selection menu, instead of a single thread you may easily skip.</para><para>To turn on threading for particular newsgroups, invoke
<command moreinfo="none">mthreads</command> with the list of newsgroups on the command line.
The format of the list is the same as the one in the C News
<filename moreinfo="none">sys</filename> file:

<screen format="linespecific">$ <userinput moreinfo="none">mthreads comp,rec,!rec.games.go</userinput></screen></para><para>This command enables threading for all of
<systemitem moreinfo="none" role="newsgroup">comp</systemitem> and
<systemitem moreinfo="none" role="newsgroup">rec</systemitem>, except for
<systemitem moreinfo="none" role="newsgroup">rec.games.go</systemitem> (people who play Go don't
need fancy threads). After that, you simply invoke <command moreinfo="none">mthreads</command>
with no options at all to make it thread any newly arrived articles. Threading
of all groups found in your <filename moreinfo="none">active</filename> file can be turned on
by invoking <command moreinfo="none">mthreads</command> with a group list of
<systemitem moreinfo="none" role="newsgroup">all</systemitem>.</para><para>If you're receiving news during the night, you will customarily run
<command moreinfo="none">mthreads</command> once in the morning, but you can also to do so
more frequently if necessary. Sites that have very heavy traffic may want to
run <command moreinfo="none">mthreads</command> in daemon mode.  When it is started at boot
time using the <option>d</option> option, it puts itself in the
background, wakes up every ten minutes to check if there are any newly arrived
articles, and threads them. To run <command moreinfo="none">mthreads</command> in daemon
mode, put the following line in your <filename moreinfo="none">rc.news</filename> script:

<screen format="linespecific">/usr/local/bin/rn/mthreads -deav</screen></para><para>The <option>a</option> option makes <command moreinfo="none">mthreads</command>
automatically turn on threading for new groups as they are created;
<option>v</option> enables verbose log messages to the
<command moreinfo="none">mthreads</command> log file <filename moreinfo="none">mt.log</filename> in
the directory where you have <command moreinfo="none">trn</command> installed.</para><para><indexterm significance="normal"><primary>C News</primary><secondary>update low water mark</secondary></indexterm>
<indexterm significance="normal"><primary>news (network)</primary><secondary>expiration of</secondary></indexterm>
Old articles that are no longer available must be removed from the index files
regularly.  By default, only articles with a number below the low-water 
mark will be removed.<footnote id="x-087-2-fnnr04"><para>Note that C News (described in <xref linkend="x-087-2-cnews"></xref>) doesn't update
this low-water mark automatically; you have to run <command moreinfo="none">updatemin</command>
to do so. </para></footnote>
Articles above this number that have been expired (because the
oldest article has been assigned a long expiration date by an
<replaceable>Expires:</replaceable> header field) may nevertheless be removed by giving
<command moreinfo="none">mthreads</command> the <option>e</option> option to force an
enhanced expiry run. When <command moreinfo="none">mthreads</command> is running
in daemon mode, the <option>e</option> option makes 
<command moreinfo="none">mthreads</command> put in such an enhanced expiry run once a day, 
shortly after midnight.</para></sect1><sect1 id="x-087-2-newsreaders.nn"><title>nn Configuration</title><indexterm significance="normal"><primary>newsreaders</primary><secondary>nn</secondary></indexterm><indexterm significance="normal"><primary>nn newsreader, configuration</primary></indexterm><indexterm significance="normal"><primary>Storm, Kim F.</primary></indexterm><para><command moreinfo="none">nn</command>, written by Kim F. Storm, claims to be a newsreader
whose ultimate goal is not to read news. Its name stands for
No News, and its motto is
No news is good news. <command moreinfo="none">nn</command> is better.</para><para>To achieve this ambitious goal, <command moreinfo="none">nn</command> comes with a large
assortment of maintenance tools that not only allow thread generation,
but also extensive database consistency checks, accounting,
gathering of usage statistics, and access restrictions. There is also an
administration program called <command moreinfo="none">nnadmin</command>, which allows you
to perform these tasks interactively. It is very intuitive, so we will not
dwell on these aspects, but deal only with the generation of the index files.</para><para><indexterm significance="normal"><primary>newsreaders</primary><secondary>creating thread databases</secondary></indexterm>
The <command moreinfo="none">nn</command> threads database manager is called
<command moreinfo="none">nnmaster</command>. It is usually run as a daemon, started from an
<filename moreinfo="none">rc</filename> file at boot time. It is invoked as:

<screen format="linespecific">/usr/local/lib/nn/nnmaster -l -r -C</screen></para><para>This enables threading for all newsgroups present in your
<filename moreinfo="none">active</filename> file.</para><para><indexterm significance="normal"><primary>cron</primary><secondary>running</secondary><tertiary>nnmaster via</tertiary></indexterm> 
Equivalently, you may invoke <command moreinfo="none">nnmaster</command> periodically from
<command moreinfo="none">cron</command>, giving it a list of groups to act upon. This list is
very similar to the subscription list in the <filename moreinfo="none">sys</filename> file,
except that it uses blanks instead of commas. Instead of the fake group name
<emphasis role="bold">all</emphasis>, an empty argument of <literal moreinfo="none">""</literal> should be
used to denote all groups.  A sample invocation looks like this:

<screen format="linespecific"># <userinput moreinfo="none">/usr/local/lib/nn/nnmaster !rec.games.go rec comp</userinput></screen></para><para>Note that the order is significant. The leftmost group specification that
matches always wins. Thus, if we had put
<systemitem moreinfo="none" role="keyword">!rec.games.go</systemitem> after
<systemitem moreinfo="none" role="keyword">rec</systemitem>, all articles from this group
would have been threaded nevertheless.</para><para><indexterm significance="normal"><primary>news (network)</primary><secondary>expiration of</secondary></indexterm>
<command moreinfo="none">nn</command> offers several methods to remove expired articles from
its databases.  The first is to update the database by scanning the newsgroup 
directories and discarding the entries whose corresponding article
has exceeded its expiration date. This is the default operation obtained by
invoking <command moreinfo="none">nnmaster</command> with the <option>E</option> option.
It is reasonably quick, unless you're doing this via NNTP.  </para><para>The second method behaves exactly like a default expiration run of
<command moreinfo="none">mthreads</command>; it removes only those entries that refer
to articles with numbers below the low-water mark in the
<filename moreinfo="none">active</filename> file. It may be enabled using the
<option>e</option> option.</para><para>Finally, the third strategy discards the entire database and recollects all
articles. It may be enabled using the <option>E3</option> option.</para><para>The list of groups to be expired is given by the <option>F</option>
option in the same fashion as above.  However, if you have
<command moreinfo="none">nnmaster</command> running as daemon, you must kill it (using
<option>k</option>) before expiration can take place, and restart it 
with the original options afterward.  Thus the proper command to run 
expiration on all groups using the first method is:

<screen format="linespecific"># <userinput moreinfo="none">nnmaster -kF ""</userinput>
# <userinput moreinfo="none">nnmaster -lrC</userinput></screen></para><para>There are many more flags that fine-tune the <command moreinfo="none">nn</command>'s 
behavior. If you are concerned about removing bad articles or
assembling article digests, read the <command moreinfo="none">nnmaster</command> manual page.</para><para><command moreinfo="none">nnmaster</command> relies on a file named <filename moreinfo="none">GROUPS</filename>,
which is located in <filename moreinfo="none">/var/lib/nn</filename>. If it does not exist
when <command moreinfo="none">nnmaster</command> is first run, it is created. For each
newsgroup, it contains a line that begins with the group's name, optionally
followed by a time stamp and flags. You may edit these flags to enable certain
behavior for the group in question, but you may not change the order in which
the groups appear.<footnote id="x-087-2-fnnr05"><para>Their order has to agree with that of the entries in the
(binary) <filename moreinfo="none">MASTER</filename> file.</para></footnote> The flags allowed and
their effects are detailed in the <command moreinfo="none">nnmaster</command> manual page, too.

<indexterm significance="normal" class="endofrange" startref="chnr.newsrdr.config"></indexterm> 
<indexterm significance="normal" class="endofrange" startref="chnr.config.newsrdr"></indexterm> </para></sect1></chapter><appendix id="x-087-2-appendix.brewery"><title>Example Network:<?lb?>The Virtual Brewery</title><indexterm significance="normal"><primary>Virtual Brewery</primary></indexterm><indexterm significance="normal"><primary>Brewery, Virtual</primary></indexterm><para>Throughout this book we've used the following example that is a little less
complex than Groucho Marx University and may be closer to the tasks you will
actually encounter.</para><para>The Virtual Brewery is a small company that brews, as the name suggests,
virtual beer. To manage their business more efficiently, the virtual brewers
want to network their computers, which all happen to be PCs running the
brightest and shiniest production Linux kernel. <xref linkend="x-087-2-appendix.brewery.diagram"></xref> shows the network configuration.</para><para>On the same floor, just across the hall, there's the Virtual Winery, which
works closely with the brewery.  The vintners run an Ethernet of their own.
Quite naturally, the two companies want to link their networks once they are
operational.  As a first step, they want to set up a gateway host that
forwards datagrams between the two subnets. Later, they also want to have a
UUCP link to the outside world, through which they exchange mail and news. In
the long run, they also want to set up PPP connections to connect to offsite
locations and to the Internet.</para><para>The Virtual Brewery and the Virtual Winery each have a class C subnet of 
the Brewery's class B network, and gateway to each other via the host
<systemitem moreinfo="none" role="sitename">vlager</systemitem>, which also supports the
UUCP connection. <xref linkend="x-087-2-appendix.brewery.subsidiary"></xref> shows the configuration.</para><figure float="0" id="x-087-2-appendix.brewery.diagram"><title>The Virtual Brewery and Virtual Winery subnets</title><graphic fileref="lag2_aa01.jpg"></graphic></figure><figure float="0" id="x-087-2-appendix.brewery.subsidiary"><title>The Virtual Brewery Network</title><graphic fileref="lag2_aa02.jpg"></graphic></figure><sect1><title>Connecting the Virtual Subsidiary Network</title><para>The Virtual Brewery grows and opens a branch in another city. The
subsidiary runs an Ethernet of its own using the IP network number
<systemitem moreinfo="none" role="sitename">172.16.3.0</systemitem>, which is subnet 3 of the
Brewery's class B network. The host
<systemitem moreinfo="none" role="sitename">vlager</systemitem> acts as the gateway for the
Brewery network and will support the PPP link; its peer at the new branch is
called <systemitem moreinfo="none" role="sitename">vbourbon</systemitem> and has an IP address
of <systemitem moreinfo="none" role="sitename">172.16.3.1</systemitem>. This network is
illustrated in <xref linkend="x-087-2-appendix.brewery.subsidiary"></xref>.</para><para>                 
                 
                 
                 
                 
                 
                 </para><para>                 
                 
                 
                 
                 
                 
                 </para><para>                 
                 
                 
                 
                 
                 
                 </para></sect1></appendix><appendix id="x-087-2-appendix.cables"><title>Useful Cable Configurations</title><para>If you wish to connect two computers together and you don't have an Ethernet
network, you will need either a serial null modem cable, or a PLIP parallel
cable.</para><para>These cables can be bought off the shelf, but are much cheaper and fairly
simple to make yourself.</para><sect1 id="x-087-2-cable.plip"><title>A PLIP Parallel Cable</title><para><indexterm significance="normal"><primary>PLIP (Parallel Line IP) protocol</primary><secondary>null printer cable for</secondary></indexterm> 
To make a parallel cable to use for PLIP, you will need two 25-pin
connectors (called DB-25) and a cable with at least eleven conductors.
The cable must not be any longer than 15 meters (50 feet). The cable may or may
not have a shield, but if you are building a long cable, it is probably
a good idea to have one.</para><para>If you look at the connector, you should be able to read tiny numbers
at the base of each pinfrom 1 for the pin at the top left (if you hold 
the broader side up) to 25 for the pin at the bottom right. For the null 
printer cable, you have to connect the following pins of both connectors
with each other, as shown in <xref linkend="x-087-2-cable.plip.diagram"></xref>.</para><para>All remaining pins remain unconnected. If the cable is shielded, the
shield should be connected to the DB-25's metallic shell on just 
<emphasis>one</emphasis> end.</para></sect1><sect1 id="x-087-2-cable.serial"><title>A Serial NULL Modem Cable</title><para><indexterm significance="normal"><primary>SLIP (Serial Line IP) protocol</primary><secondary>null modem cable for</secondary></indexterm> 
<indexterm significance="normal"><primary>PPP (Point-to-Point Protocol)</primary><secondary>null modem cable for</secondary></indexterm> 
A serial null modem cable will work for both SLIP and PPP. Again, you
will need two DB-25 connectors. This time your cable requires only
eight conductors.</para><para>You may have seen other NULL modem cable designs, but this one allows you
to use hardware flow controlwhich is far superior to XON/XOFF
flow controlor none at all. The conductor configuration is
shown in <xref linkend="x-087-2-cable.nullmodem.diagram"></xref>:</para><para>Again, if you have a shield, you should connect it to the first pin at one 
end only.</para><figure float="0" id="x-087-2-cable.plip.diagram"><title>Parallel PLIP cable</title><graphic fileref="lag2_ab01.jpg"></graphic></figure><para>                 
                 
                 
                 
                 
                 </para><figure float="0" id="x-087-2-cable.nullmodem.diagram"><title>Serial NULL-Modem cable</title><graphic fileref="lag2_ab02.jpg"></graphic></figure><para>                 
                 
                 
                 
                 
                 </para></sect1></appendix><appendix id="x-087-2-appendix.gpl"><title>Linux Network Administrator's Guide, Second Edition <?lb?>Copyright Information</title><para>Copyright  1993 Olaf Kirch<?troff .br?>
Copyright  2000 Terry Dawson<?troff .br?>
Copyright on O'Reilly printed version  2000 O'Reilly  Associates<?troff .br?></para><para><?troff .hw linuxdoc?><indexterm significance="normal"><primary>copyright information</primary></indexterm>
The online version of this book, which at this time of printing
contains exactly the same text as the O'Reilly printed version, is
available under the GNU FDL. Rights to reprint the document under the
FDL include the right to print and distribute printed copies of the
online version.  Rights to copy the O'Reilly printed version are
reserved.  You can find the online copy of the license at <systemitem moreinfo="none" role="url">http://www.oreilly.com/catalog/linag/licenseinfo.html</systemitem>.
The book is available at <systemitem moreinfo="none" role="url">http://www.linuxdoc.org/LDP/nag/nag.html</systemitem> and
<systemitem moreinfo="none" role="url">http://www.oreilly.com/catalog/linag/</systemitem>, and may
be reposted by others at other locations.</para><para>Permission is granted to copy, print, distribute, and modify the
online document under the terms of the GNU Free Documentation License,
Version 1.1, or any later version published by the Free Software
Foundation; with the Invariant Sections being the Acknowledgments (in
the <emphasis>Preface</emphasis> and <xref linkend="x-087-2-appendix.gpl"></xref>." Further acknowledgments can be added outside
the Invariant Section. The Front-Cover Text must read:</para><literallayout format="linespecific" class="normal"><emphasis>Linux Network Administrator's Guide</emphasis>
by Olaf Kirch and Terry Dawson
Copyright   1993 Olaf Kirch
Copyright   2000 Terry Dawson
Copyright on O'Reilly printed version  2000 O'Reilly  Associates</literallayout><para><indexterm significance="normal" class="startofrange" id="gnu.fdl"><primary>GNU Free Documentation License (FDL)</primary></indexterm>
The following is a copy of the GNU Free Documentation License, which
is also at <systemitem moreinfo="none" role="url">http://www.gnu.org/copyleft/fdl.html</systemitem>.</para><literallayout format="linespecific" class="normal">Version 1.1, March 2000
Copyright  2000  Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.</literallayout><sect1><title>0. Preamble</title><para>The purpose of this License is to make a manual, textbook, or other
written document "free" in the sense of freedom: to assure everyone
the effective freedom to copy and redistribute it, with or without
modifying it, either commercially or noncommercially.  Secondarily,
this License preserves for the author and publisher a way to get
credit for their work, while not being considered responsible for
modifications made by others.</para><para>This License is a kind of "copyleft," which means that derivative
works of the document must themselves be free in the same sense.  It
complements the GNU General Public License, which is a copyleft
license designed for free software.</para><para>We have designed this License in order to use it for manuals for free
software, because free software needs free documentation: a free
program should come with manuals providing the same freedoms that the
software does.  But this License is not limited to software manuals;
it can be used for any textual work, regardless of subject matter or
whether it is published as a printed book.  We recommend this License
principally for works whose purpose is instruction or reference.</para></sect1><sect1><title>1. Applicability and Definitions</title><para>This License applies to any manual or other work that contains a
notice placed by the copyright holder saying it can be distributed
under the terms of this License.  The "Document," below, refers to any
such manual or work.  Any member of the public is a licensee, and is
addressed as "you."</para><para>A "Modified Version" of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.</para><para>A "Secondary Section" is a named appendix or a front-matter section of
the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall subject
(or to related matters) and contains nothing that could fall directly
within that overall subject.  (For example, if the Document is in part a
textbook of mathematics, a Secondary Section may not explain any
mathematics.)  The relationship could be a matter of historical
connection with the subject or with related matters, or of legal,
commercial, philosophical, ethical or political position regarding
them.</para><para>The "Invariant Sections" are certain Secondary Sections whose titles
are designated, as being those of Invariant Sections, in the notice
that says that the Document is released under this License.</para><para>The "Cover Texts" are certain short passages of text that are listed,
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
the Document is released under this License.</para><para>A "Transparent" copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, whose contents can be viewed and edited directly and
straightforwardly with generic text editors or (for images composed of
pixels) generic paint programs or (for drawings) some widely available
drawing editor, and that is suitable for input to text formatters or
for automatic translation to a variety of formats suitable for input
to text formatters.  A copy made in an otherwise Transparent file
format whose markup has been designed to thwart or discourage
subsequent modification by readers is not Transparent.  A copy that is
not "Transparent" is called "Opaque."</para><para><?troff .hw generated?>Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format, SGML
or XML using a publicly available DTD, and standard-conforming simple
HTML designed for human modification.  Opaque formats include
PostScript, PDF, proprietary formats that can be read and edited only
by proprietary word processors, SGML or XML for which the DTD and/or
processing tools are not generally available, and the
machine-generated HTML produced by some word processors for output
purposes only.</para><para>The "Title Page" means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the material
this License requires to appear in the title page.  For works in
formats that do not have any title page as such, "Title Page" means
the text near the most prominent appearance of the work's title,
preceding the beginning of the body of the text.</para></sect1><sect1><title>2. Verbatim Copying</title><para>You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License applies
to the Document are reproduced in all copies, and that you add no other
conditions whatsoever to those of this License.  You may not use
technical measures to obstruct or control the reading or further
copying of the copies you make or distribute.  However, you may accept
compensation in exchange for copies.  If you distribute a large enough
number of copies you must also follow the conditions in section 3.</para><para>You may also lend copies, under the same conditions stated above, and
you may publicly display copies.</para></sect1><sect1><title>3. Copying in Quantity</title><para>If you publish printed copies of the Document numbering more than 100,
and the Document's license notice requires Cover Texts, you must enclose
the copies in covers that carry, clearly and legibly, all these Cover
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
the back cover.  Both covers must also clearly and legibly identify
you as the publisher of these copies.  The front cover must present
the full title with all words of the title equally prominent and
visible.  You may add other material on the covers in addition.
Copying with changes limited to the covers, as long as they preserve
the title of the Document and satisfy these conditions, can be treated
as verbatim copying in other respects.</para><para>If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto adjacent
pages.</para><para>If you publish or distribute Opaque copies of the Document numbering
more than 100, you must either include a machine-readable Transparent
copy along with each Opaque copy, or state in or with each Opaque copy
a publicly-accessible computer-network location containing a complete
Transparent copy of the Document, free of added material, which the
general network-using public has access to download anonymously at no
charge using public-standard network protocols.  If you use the latter
option, you must take reasonably prudent steps, when you begin
distribution of Opaque copies in quantity, to ensure that this
Transparent copy will remain thus accessible at the stated location
until at least one year after the last time you distribute an Opaque
copy (directly or through your agents or retailers) of that edition to
the public.</para><para>It is requested, but not required, that you contact the authors of the
Document well before redistributing any large number of copies, to give
them a chance to provide you with an updated version of the Document.</para></sect1><sect1><title>4. Modifications</title><para>You may copy and distribute a Modified Version of the Document under
the conditions of sections 2 and 3 above, provided that you release
the Modified Version under precisely this License, with the Modified
Version filling the role of the Document, thus licensing distribution
and modification of the Modified Version to whoever possesses a copy
of it.  In addition, you must do these things in the Modified Version:</para><orderedlist numeration="upperalpha" inheritnum="ignore" continuation="restarts"><listitem><para>Use in the Title Page (and on the covers, if any) a title distinct
   from that of the Document, and from those of previous versions
   (which should, if there were any, be listed in the History section
   of the Document).  You may use the same title as a previous version
   if the original publisher of that version gives permission.</para></listitem><listitem><para>List on the Title Page, as authors, one or more persons or entities
   responsible for authorship of the modifications in the Modified
   Version, together with at least five of the principal authors of the
   Document (all of its principal authors, if it has less than five).</para></listitem><listitem><para>State on the Title page the name of the publisher of the
   Modified Version, as the publisher.</para></listitem><listitem><para>Preserve all the copyright notices of the Document.</para></listitem><listitem><para>Add an appropriate copyright notice for your modifications
   adjacent to the other copyright notices.</para></listitem><listitem><para>Include, immediately after the copyright notices, a license notice
   giving the public permission to use the Modified Version under the
   terms of this License, in the form shown in the Addendum below.</para></listitem><listitem><para>Preserve in that license notice the full lists of Invariant Sections
   and required Cover Texts given in the Document's license notice.</para></listitem><listitem><para>Include an unaltered copy of this License.</para></listitem><listitem><para>Preserve the section entitled "History," and its title, and add to
   it an item stating at least the title, year, new authors, and
   publisher of the Modified Version as given on the Title Page.  If
   there is no section entitled "History" in the Document, create one
   stating the title, year, authors, and publisher of the Document as
   given on its Title Page, then add an item describing the Modified
   Version as stated in the previous sentence.</para></listitem><listitem><para>Preserve the network location, if any, given in the Document for
   public access to a Transparent copy of the Document, and likewise
   the network locations given in the Document for previous versions
   it was based on.  These may be placed in the "History" section.
   You may omit a network location for a work that was published at
   least four years before the Document itself, or if the original
   publisher of the version it refers to gives permission.</para></listitem><listitem><para>In any section entitled "Acknowledgements" or "Dedications,"
   preserve the section's title, and preserve in the section all the
   substance and tone of each of the contributor acknowledgements
   and/or dedications given therein.</para></listitem><listitem><para>Preserve all the Invariant Sections of the Document,
   unaltered in their text and in their titles.  Section numbers
   or the equivalent are not considered part of the section titles.</para></listitem><listitem><para>Delete any section entitled "Endorsements."  Such a section
   may not be included in the Modified Version.</para></listitem><listitem><para>Do not retitle any existing section as "Endorsements"
   or to conflict in title with any Invariant Section.</para></listitem></orderedlist><para>If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no material
copied from the Document, you may at your option designate some or all
of these sections as invariant.  To do this, add their titles to the
list of Invariant Sections in the Modified Version's license notice.
These titles must be distinct from any other section titles.</para><para>You may add a section entitled "Endorsements," provided it contains
nothing but endorsements of your Modified Version by various
partiesfor example, statements of peer review or that the text has
been approved by an organization as the authoritative definition of a
standard.</para><para>You may add a passage of up to five words as a Front-Cover Text, and a
passage of up to 25 words as a Back-Cover Text, to the end of the list
of Cover Texts in the Modified Version.  Only one passage of
Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity.  If the Document already
includes a cover text for the same cover, previously added by you or
by arrangement made by the same entity you are acting on behalf of,
you may not add another; but you may replace the old one, on explicit
permission from the previous publisher that added the old one.</para><para>The author(s) and publisher(s) of the Document do not by this License
give permission to use their names for publicity for or to assert or
imply endorsement of any Modified Version.</para></sect1><sect1><title>5. Combining Documents</title><para>You may combine the Document with other documents released under this
License, under the terms defined in section 4 above for modified
versions, provided that you include in the combination all of the
Invariant Sections of all of the original documents, unmodified, and
list them all as Invariant Sections of your combined work in its
license notice.</para><para>The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single
copy.  If there are multiple Invariant Sections with the same name but
different contents, make the title of each such section unique by
adding at the end of it, in parentheses, the name of the original
author or publisher of that section if known, or else a unique number.
Make the same adjustment to the section titles in the list of
Invariant Sections in the license notice of the combined work.</para><para>In the combination, you must combine any sections entitled "History"
in the various original documents, forming one section entitled
"History"; likewise combine any sections entitled "Acknowledgements,"
and any sections entitled "Dedications."  You must delete all sections
entitled "Endorsements."</para></sect1><sect1><title>6. Collections of Documents</title><para>You may make a collection consisting of the Document and other documents
released under this License, and replace the individual copies of this
License in the various documents with a single copy that is included in
the collection, provided that you follow the rules of this License for
verbatim copying of each of the documents in all other respects.</para><para>You may extract a single document from such a collection, and distribute
it individually under this License, provided you insert a copy of this
License into the extracted document, and follow this License in all
other respects regarding verbatim copying of that document.</para></sect1><sect1><title>7. Aggregation with Independent Works</title><para>A compilation of the Document or its derivatives with other separate
and independent documents or works, in or on a volume of a storage or
distribution medium, does not as a whole count as a Modified Version
of the Document, provided no compilation copyright is claimed for the
compilation.  Such a compilation is called an "aggregate," and this
License does not apply to the other self-contained works thus compiled
with the Document, on account of their being thus compiled, if they
are not themselves derivative works of the Document.</para><para>If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one quarter
of the entire aggregate, the Document's Cover Texts may be placed on
covers that surround only the Document within the aggregate.
Otherwise they must appear on covers around the whole aggregate.</para></sect1><sect1><title>8. Translation</title><para>Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section 4.
Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include
translations of some or all Invariant Sections in addition to the
original versions of these Invariant Sections.  You may include a
translation of this License provided that you also include the
original English version of this License.  In case of a disagreement
between the translation and the original English version of this
License, the original English version will prevail.</para></sect1><sect1><title>9. Termination</title><para>You may not copy, modify, sublicense, or distribute the Document except
as expressly provided for under this License.  Any other attempt to
copy, modify, sublicense or distribute the Document is void, and will
automatically terminate your rights under this License.  However,
parties who have received copies, or rights, from you under this
License will not have their licenses terminated so long as such
parties remain in full compliance.</para></sect1><sect1><title>10. Future Revisions of this License</title><para>The Free Software Foundation may publish new, revised versions
of the GNU Free Documentation License from time to time.  Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.  See
<systemitem moreinfo="none" role="url">http://www.gnu.org/copyleft/</systemitem>.</para><para>Each version of the License is given a distinguishing version number.
If the Document specifies that a particular numbered version of this
License "or any later version" applies to it, you have the option of
following the terms and conditions either of that specified version or
of any later version that has been published (not as a draft) by the
Free Software Foundation.  If the Document does not specify a version
number of this License, you may choose any version ever published (not
as a draft) by the Free Software Foundation.</para></sect1><indexterm significance="normal" class="endofrange" startref="gnu.fdl"></indexterm></appendix><appendix id="x-087-2-sage.app"><title>SAGE: The System<?lb?>Administrators Guild</title><indexterm significance="normal"><primary>SAGE (System Administrator's Guild)</primary></indexterm><indexterm significance="normal"><primary>USENIX Association, SAGE</primary></indexterm><para>If you are not getting everything you need from posting to
<systemitem moreinfo="none" role="newsgroup">comp.os.linux.*</systemitem> groups and reading documentation, maybe it's time to
consider joining SAGE, the System Administrators Guild, sponsored by
USENIX.  The main goal of SAGE is to advance system administration as
a profession.  SAGE brings together system and network administrators
to foster professional and technical development, share problems and
solutions, and communicate with users, management, and vendors on
system administration topics.</para><para>Current SAGE initiatives include:

<itemizedlist><listitem><para>Co-sponsoring the highly successful annual System
Administration Conferences (LISA) with USENIX.</para></listitem><listitem><para>Publishing <command moreinfo="none">Job Descriptions for System Administrators</command>, edited by Tina
Darmohray, the first in a series of very practical booklets and resource
guides covering system administration issues and techniques.</para></listitem><listitem><para>Creating an archive site, <systemitem moreinfo="none" role="sitename">ftp.sage.usenix.org</systemitem>, for papers from the System
Administration Conferences and sysadmin-related documentation.</para></listitem><listitem><para>Establishing working groups in areas important to system administrators,
such as jobs, publications, policies, electronic information distribution,
education, vendors, and standards.</para></listitem></itemizedlist></para><para>To learn more about the USENIX Association and its Special Technical
Group, SAGE, contact the USENIX Association office at (510) 528-8649 in
the U.S., or by email to
<systemitem moreinfo="none" role="emailaddr">office@usenix.org</systemitem>.
To receive information electronically, contact 
<systemitem moreinfo="none" role="emailaddr">info@usenix.org</systemitem>.
Annual SAGE membership is $25 (you must also be a member of USENIX).
Members enjoy free subscriptions to <emphasis>login:</emphasis> and
<command moreinfo="none">Computing Systems</command>, a quarterly refereed technical journal;
discounts on conference and symposia registration; and
savings on SAGE publication purchases and other services.</para><?troff .BLANK?></appendix></book>

