Create branch 'RELENG_2_1_0'.

This commit is contained in:
Doc Manager 1995-10-14 21:49:55 +00:00
parent 4c0228d53f
commit 31383071dd
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/branches/RELENG_2_1_0/; revision=122
8 changed files with 6795 additions and 0 deletions

80
handbook/crypt.sgml Normal file
View file

@ -0,0 +1,80 @@
<!-- $Id: crypt.sgml,v 1.1 1995-09-25 04:53:28 jfieber Exp $ -->
<!-- The FreeBSD Documentation Project -->
<sect><heading>DES, MD5, and Crypt<label id="crypt"></heading>
<p><em>Contributed by &a.wollman;<newline>24 September 1995.</em>
<p><bf>History</bf>
<p>In order to protect the security of passwords on UN*X systems from
being easily exposed, passwords have traditionally been scrambled in
some way. Starting with Bell Labs' Seventh Edition Unix, passwords
were encrypted using what the security people call a ``one-way hash
function''. That is to say, the password is transformed in such a way
that the original password cannot be regained except by brute-force
searching the space of possible passwords. Unfortunately, the only
secure method that was available to the AT&amp;T researchers at the
time was based on DES, the Data Encryption Standard. This causes only
minimal difficulty for commercial vendors, but is a serious problem
for an operating system like FreeBSD where all the source code is
freely available, because national governments in many places like to
place restrictions on cross-border transport of DES and other
encryption software.
<p>So, the FreeBSD team was faced with a dilemma: how could we provide
compatibility with all those UNIX systems out there while still not
running afoul of the law? We decided to take a dual-track approach:
we would make distributions which contained only a non-regulated
password scrambler, and then provide as a separate add-on library the
DES-based password hash. The password-scrambling function was moved
out of the C library to a separate library, called `<tt>libcrypt</tt>'
because the name of the C function to implement it is
`<tt>crypt</tt>'. In FreeBSD 1.x and some pre-release 2.0 snapshots,
the non-regulated scrambler uses an insecure function written by Nate
Williams; in subsequent releases this was replaced by a mechanism
using the RSA Data Security, Inc., MD5 one-way hash function. Because
neither of these functions involve encryption, they are believed to be
exportable from the US and importable into many other countries.
<p>Meanwhile, work was also underway on the DES-based password hash
function. First, a version of the `<tt>crypt</tt>' function which was
written outside the US was imported, thus synchronizing the US and
non-US code. Then, the library was modified and split into two; the
DES `<tt>libcrypt</tt>' contains only the code involved in performing
the one-way password hash, and a separate `<tt>libcipher</tt>' was
created with the entry points to actually perform encryption. The
code was partitioned in this way to make it easier to get an export
license for the compiled library.
<p><bf>Recognizing your `<tt>crypt</tt>' mechanism</bf>
<p>It is fairly easy to recognize whether a particular password
string was created using the DES- or MD5-based hash function.
MD5 password strings always begin with the characters
`<tt>&dollar;1&dollar;</tt>'. DES password strings do not have
any particular identifying characteristics, but they are shorter
than MD5 passwords, and are coded in a 64-character alphabet
which does not include the `<tt>&dollar;</tt>' character, so a
relatively short string which doesn't begin with a dollar sign is
very likely a DES password.
<p>Determining which library is being used on your system is fairly
easy for most programs, except for those like `<tt>init</tt>' which
are statically linked. (For those programs, the only way is to try
them on a known password and see if it works.) Programs which use
`<tt>crypt</tt>' are linked against `<tt>libcrypt</tt>', which for
each type of library is a symbolic link to the appropriate
implementation. For example, on a system using the DES versions:
<tscreen><verb>
$ cd /usr/lib
$ ls -l /usr/lib/libcrypt*
lrwxr-xr-x 1 bin bin 13 Sep 5 12:50 libcrypt.a -> libdescrypt.a
lrwxr-xr-x 1 bin bin 18 Sep 5 12:50 libcrypt.so.2.0 -> libdescrypt.so.2.0
lrwxr-xr-x 1 bin bin 15 Sep 5 12:50 libcrypt_p.a -> libdescrypt_p.a
</verb></tscreen>
On a system using the MD5-based libraries, the same links will be
present, but the target will be `<tt>libscrypt</tt>' rather than
`<tt>libdescrypt</tt>'.

105
handbook/dma.sgml Normal file
View file

@ -0,0 +1,105 @@
<!-- $Id: dma.sgml,v 1.1 1995-09-25 04:53:29 jfieber Exp $ -->
<!-- The FreeBSD Documentation Project -->
<sect><heading>PC DMA<label id="dma"></heading>
<p><em>Contributed by &a.uhclem;.<newline>
31 August 1995.</em>
Posted to <htmlurl url="mailto:hackers@freebsd.org"
name="freebsd-hackers@freebsd.org">:
<quote>
<p><em>Yes, as long as `single mode' is appropriate for you, there's no need
to worry about TC. TC is intented for continuous mode. Well, i've
just noticed that the PC DMAC cannot even generate an interrupt when
ready... hmm, go figure, the Z80 DMAC did it.</em>
<p><em>And yes, for `single mode', the masking trick will do it. The
peripheral device will issue a DRQ signal for each transfered
byte/word, and masking would prevent the DMAC from accepting new DRQs
for this channel. Aborting a continuous mode transfer would not be so
easy (or even impossible at all).</em>
</quote>
Actually, masking is the correct procedure for all transfer modes on the
8237, even autoinit mode, which is frequently used for audio operations
since it allows seamless DMA transfers with no under/overruns.
You are generally correct about TC. All the TC signal does is
when the counter on any channel in the DMA controller goes from
one to zero, TC is asserted. What the peripherals are supposed
to if they want to generate an interrupt when the transfer is
through, is that peripheral device is supposed to look at
<tt>(-DACK%d &amp;&amp; TC &amp;&amp; DEVICE_DMA_ACTIVE)</tt> and then
latch an <tt>IRQ%d</tt> for the 8259 interrupt controller. Since there is
only one TC signal, it is important that only the peripheral who
is transferring data at that moment honor the TC signal.
The host CPU will eventually investigate the interrupt by having some driver
poll the hardware associated with the peripheral, NOT the DMA controller.
If a peripheral doesn't want an interrupt associated with the DMA counter
reaching zero, it doesn't implement the circuitry to monitor TC.
Some sound cards realize that when the TC hits zero it means the DMA
is now idle and that is really too late, so they don't use TC and
instead allow the driver to program in a local counter value, which
is usually set lower than the value programmed into the DMA. This means
the peripheral can interrupt the CPU in advance of the DMA "running dry",
allowing the CPU to be ready to reprogram the DMA the instant it finishes
what it is doing, rather than incurring the latency later.
This also means that two or more different devices could share a
DMA channel, by tristating <tt>DRQ%d</tt> when idle and only
honoring <tt>-DACK%d</tt> when the device knows it is expecting
the DMA to go active. (Iomega PC2B boards forgot this minor
point and will transfer data even if they are not supposed to.)
So, if you want to abort a 8237 DMA transfer of any kind, simply mask the
bit for that DMA channel in the 8237. Note: You can't interrupt an individual
transfer (byte or burst) in progress. Think about it... if the DMA is
running, how is your OUT instruction going to be performed?
The CPU has to be bus master for the OUT to be performed.
Since the 8237 DMA re-evaluates DMA channel priorities constantly, even if
the DMA had already asserted HOLD (to request the bus from the CPU) when
the OUT actually took place, the processor would still grant the bus to the
DMA controller. The DMA controller would look for the highest-priority
DMA source remaining (your interrupt is masked now) at that instant,
and if none remained, the DMA will release HOLD and the processor will
get the bus back after a few clocks.
There is a deadly race condition in this area, but if I remember right,
you can't get into it via mis-programming the DMA, UNLESS you cause the DMA
controller to be RESET. You should not do this. Effectively the CPU
can give up the bus and the DMA doesn't do anything, including giving the
bus back. Very annoying and after 16msec or so, all is over since
refresh on main memory has started failing.
So, mask the DMA controller, then go do what you have to do to get the
transfer aborted in the peripheral hardware. In some extremely stupid
hardware (I could mention a few), you may have to program the DMA to
transfer one more byte to a garbage target to get the peripheral hardware
to go back to an idle state. Most hardware these days isn't that
stupid.
Technically, you are supposed to mask the DMA channel, program the other
settings (direction, address, length, etc), issue commands to the
peripheral and then unmask the DMA channel once the peripheral commands have
been accepted. The last two steps can be done out of order without
harm, but you must always program the DMA channel while it is masked to
avoid spraying data all over the place in the event the peripheral
unexpected asserts <tt>DRQ%d</tt>.
If you need to pad-out an aborted buffer, once you have masked the
DMA, you can ask it how many bytes it still had to go and what
address it was to write to next. Your driver can then fill in the
remaining area or do what needs to be done.
Don't forget that the 8237 was designed for use with the 8085 and
really isn't suited to the job that IBM gave it in the original PC.
That's why the upper eight bits of DMA addressing appear to be lashed-on.
They are. Look at the schematics of the original PC and you will
the upper bits are kept in external latches that are enabled whenever
the DMA is too. Very kludgy.

421
handbook/esdi.sgml Normal file
View file

@ -0,0 +1,421 @@
<!-- $Id: esdi.sgml,v 1.2 1995-10-07 04:31:20 jfieber Exp $ -->
<!-- The FreeBSD Documentation Project -->
<!--
<title>An introduction to ESDI hard disks and their use with FreeBSD</title>
<author>(c) 1995, Wilko Bulte, <tt/wilko@yedi.iaf.nl/
<date>Tue Sep 12 20:48:44 MET DST 1995</date>
Copyright 1995, Wilko C. Bulte, Arnhem, The Netherlands
<abstract>
This document describes the use of ESDI disks in combination
with the FreeBSD operating system. Contrary to popular
belief, this is possible and people are using ESDI based
systems succesfully! This document tries to explain you
how to do this.
If you find something missing, plain wrong or have useful
comments on how to improve
the document please send mail to <tt/wilko@yedi.iaf.nl/
</abstract>
-->
<sect><heading>ESDI hard disks and FreeBSD<label id="esdi"></heading>
<p><em>Copyright &copy; 1995, &a.wilko;.<newline>24 September 1995.</em>
ESDI is an acronym that means Enhanced Small Device Interface.
It is loosely based on the good old ST506/412 interface originally
devised by Seagate Technology, the makers of the first affordable
5.25" winchester disk.
The acronym says Enhanced, and rightly so. In the first place
the speed of the interface is higher, 10 or 15 Mbits/second
instead of the 5 Mbits/second of ST412 interfaced drives.
Secondly some higher level commands are added, making the ESDI
interface somewhat 'smarter' to the operating system driver
writers. It is by no means as smart as SCSI by the way. ESDI
is standardised by ANSI.
Capacities of the drives are boosted by putting more sectors
on each track. Typical is 35 sectors per track, high capacity
drives I've seen were up to 54 sectors/track.
Although ESDI has been largely obsoleted by IDE and SCSI interfaces,
the availability of free or cheap surplus drives makes them
ideal for low (or now) budget systems.
<sect1><heading>Concepts of ESDI</heading>
<p>
<sect2><heading>Physical connections</heading>
<p>
The ESDI interface uses two cables connected to each drive.
One cable is a 34 pin flatcable edge connector that carries
the command and status signals from the controller to the
drive and viceversa. The command cable is daisy chained
between all the drives. So, it forms a bus onto which all
drives are connected.
The second cable is a a 20 pin flatcable edge connector that
carries the data to and from the drive. This cable is radially
connected, so each drive has it's own direct connection to the
controller.
To the best of my knowledge PC ESDI controllers are limited
to using a maximum of 2 drives per controller. This is
compatibility feature(?) left over from the WD1003 standard
that reserves only a single bit for device addressing.
<sect2><heading>Device addressing</heading>
<p>
On each command cable a maximum of 7 devices and 1 controller
can be present. To enable the controller to uniquely
identify which drive it addresses, each ESDI device is equipped
with jumpers or switches to select the devices address.
On PC type controllers the first drive is set to address 0,
the second disk to address 1. <it>Always make sure</it> you
set each disk to an unique address! So, on a PC with it's
two drives/controller maximum the first drive is drive 0, the
second is drive 1.
<sect2><heading>Termination</heading>
<p>
The daisy chained command cable (the 34 pin cable remember?)
needs to be terminated at the last drive on the chain.
For this purpose ESDI drives come with a termination resistor
network that can be removed or disabled by a jumper when it
is not used.
So, one and <it>only</it> one drive, the one at
the fartest end of the command
cable has it's terminator installed/enabled. The controller
automatically terminates the other end of the cable.
Please note that this implies that the controller must be
at one end of the cable and <it>not</it> in the middle.
<sect1><heading>Using ESDI disks with FreeBSD</heading>
<p>
Why is ESDI such a pain to get working in the first place?
People who tried ESDI disks with FreeBSD are known to have
developed a profound sense of frustration. A combination of
factors works against you to produce effects that are
hard to understand when you have never seen them before.
This has also led to the popular legend ESDI and FreeBSD
is a plain NO-GO.
The following sections try to list all the pitfalls and
solutions.
<sect2><heading>ESDI speed variants</heading>
<p>
As briefly mentioned before, ESDI comes in two speed flavours.
The older drives and controllers use a 10 Mbits/second
data transfer rate. Newer stuff uses 15 Mbits/second.
It is not hard to imagine that 15 Mbits/second drive cause
problems on controllers laid out for 10 Mbits/second.
As always, consult your controller <it>and</it> drive
documentation to see if things match.
<sect2><heading>Stay on track</heading>
<p>
Mainstream ESDI drives use 34 to 36 sectors per track.
Most (older) controllers cannot handle more than this
number of sectors.
Newer, higher capacity, drives use higher numbers of sectors
per track. For instance, I own a 670 Mb drive that has
54 sectors per track.
In my case, the controller could not handle this number
of sectors. It proved to work well except that it only
used 35 sectors on each track. This meant losing a
lot of diskspace.
Once again, check the documentation of your hardware for
more info. Going out-of-spec like in the example might
or might not work. Give it a try or get another more
capable controller.
<sect2><heading>Hard or soft sectoring</heading>
<p>
Most ESDI drives allow hard or soft sectoring to be
selected using a jumper. Hard sectoring means that the
drive will produce a sector pulse on the start of each
new sector. The controller uses this pulse to tell when
it should start to write or read.
Hard sectoring allows a selection of sector size (normally
256, 512 or 1024 bytes per formatted sector). FreeBSD uses
512 byte sectors. The number of sectors per track also varies
while still using the same number of bytes per formatted sector.
The number of <em>unformatted</em> bytes per sector varies,
dependent on your controller it needs more or less overhead
bytes to work correctly. Pushing more sectors on a track
of course gives you more usable space, but might give
problems if your controller needs more bytes than the
drive offers.
In case of soft sectoring, the controller itself determines
where to start/stop reading or writing. For ESDI
hard sectoring is the default (at least on everything
I came across). I never felt the urge to try soft sectoring.
In general, experiment with sector settings before you install
FreeBSD because you need to re-run the low-level format
after each change.
<sect2><heading>Low level formatting</heading>
<p>
ESDI drives need to be low level formatted before they
are usable. A reformat is needed whenever you figgle
with the number of sectors/track jumpers or the
physical orientation of the drive (horizontal, vertical).
So, first think, then format.
The format time must not be underestimated, for big
disks it can take hours.
After a low level format, a surface scan is done to
find and flag bad sectors. Most disks have a
manufacturer bad block list listed on a piece of paper
or adhesive sticker. In addition, on most disks the
list is also written onto the disk.
Please use the manufacturer's list. It is much easier
to remap a defect now than after FreeBSD is installed.
Stay away from low-level formatters that mark all
sectors of a track as bad as soon as they find one
bad sector. Not only does this waste space, it also
and more importantly causes you grief with bad144
(see the section on bad144).
<sect2><heading>Translations</heading>
<p>
Translations, although not exclusively a ESDI-only problem,
might give you real trouble.
Translations come in multiple flavours. Most of them
have in common that they attempt to work around the
limitations posed upon disk geometries by the original
IBM PC/AT design (thanks IBM!).
First of all there is the (in)famous 1024 cylinder limit.
For a system to be able to boot, the stuff (whatever
operating system) must be in the first 1024 cylinders
of a disk. Only 10 bits are available to encode the
cylinder number. For the number of sectors the limit
is 64 (0-63).
When you combine the 1024 cylinder limit with the 16 head
limit (also a design feature) you max out at fairly limited
disk sizes.
To work around this problem, the manufacturers of ESDI
PC controllers added a BIOS prom extension on their boards.
This BIOS extension handles disk I/O for booting (and for
some operating systems <it>all</it> disk I/O) by using
translation. For instance, a big drive might be presented
to the system as having 32 heads and 64 sectors/track.
The result is that the number of cylinders is reduced to
something below 1024 and is therefore usable by the system
without problems.
It is noteworthy to know that FreeBSD after it's kernel has
started no longer uses the BIOS. More on this later.
A second reason for translations is the fact that most
older system BIOSes could only handle drives with 17 sectors
per track (the old ST412 standard). Newer system BIOSes
usually have a user-defined drive type (in most cases this is
drive type 47).
<em>Whatever you do to translations after reading this document,
keep in mind that if you have multiple operating systems on the
same disk, all must use the same translation</em>
While on the subject of translations, I've seen one controller
type (but there are probably more like this) offer the option
to logically split a drive in multiple partitions as a BIOS
option. I had select 1 drive == 1 partition because this
controller wrote this info onto the disk. On powerup it
read the info and presented itself to the system based on
the info from the disk.
<sect2><heading>Spare sectoring</heading>
<p>
Most ESDI controllers offer the possibility to remap bad sectors.
During/after the low-level format of the disk bad sectors are
marked as such, and a replacement sector is put in place
(logically of course) of the bad one.
In most cases the remapping is done by using N-1 sectors on
each track for actual datastorage, and sector N itself is
the spare sector. N is the total number of sectors physically
available on the track.
The idea behind this is that the operating system sees
a 'perfect' disk without bad sectors. In the case of
FreeBSD this concept is not usable.
The problem is that the translation from <it>bad</it> to <it>good</it>
is performed by the BIOS of the ESDI controller. FreeBSD,
being a true 32 bit operating system, does not use the BIOS
after it has been booted. Instead, it has device drivers that
talk directly to the hardware.
<em>So: don't use spare sectoring, bad block remapping or
whatever it may be called by the controller manufacturer when you
want to use the disk for FreeBSD.</em>
<sect2><heading>Bad block handling</heading>
<p>
The preceding section leaves us with a problem. The controller's
bad block handling is not usable and still FreeBSD's filesystems
assume perfect media without any flaws.
To solve this problem, FreeBSD use the <it>bad144</it> tool.
Bad144 (named after a Digital Equipment standard for bad block
handling) scans a FreeBSD slice for bad blocks. Having found
these bad blocks, it writes a table with the offending block
numbers to the end of the FreeBSD slice.
When the disk is in operation, the diskaccesses are checked
against the table read from the disk. Whenever a blocknumber
is requested that is in the bad144 list, a replacement block
(also from the end of the FreeBSD slice) is used.
In this way, the bad144 replacement scheme presents 'perfect'
media to the FreeBSD filesystems.
There are a number of potential pitfalls associated with
the use of bad144.
First of all, the slice cannot have more than 126 bad sectors.
If your drive has a high number of bad sectors, you might need
to divide it into multiple FreeBSD slices each containing less
than 126 bad sectors. Stay away from low-level format programs
that mark <em>every</em> sector of a track as bad when
they find a flaw on the track. As you can imagine, the
126 limit is quickly reached when the low-level format is done
this way.
Second, if the slice contains the root filesystem, the slice
should be within the 1024 cylinder BIOS limit. During the
boot process the bad144 list is read using the BIOS and this
only succeeds when the list is within the 1024 cylinder limit.
<em>Note</em> that the restriction is not that only the root
<em>filesystem</em> must be within the 1024 cylinder limit, but
rather the entire <em>slice</em> that contains the root filesystem.
<sect2><heading>Kernel configuration</heading>
<p>
ESDI disks are handled by the same <it>wd</it>driver as
IDE and ST412 MFM disks. The <it>wd</it> driver should work
for all WD1003 compatible interfaces.
Most hardware is jumperable for one of two different I/O
address ranges and IRQ lines. This allows you to have
two wd type controllers in one system.
When your hardware allows non-standard strappings, you
can use these with FreeBSD as long as you enter the
correct info into the kernel config file.
An example from the kernel config file (they live in
<tt>/sys/i386/conf</tt> BTW).
<tscreen><verb>
# First WD compatible controller
controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
disk wd0 at wdc0 drive 0
disk wd1 at wdc0 drive 1
# Second WD compatible controller
controller wdc1 at isa? port "IO_WD2" bio irq 15 vector wdintr
disk wd2 at wdc1 drive 0
disk wd3 at wdc1 drive 1
</verb></tscreen>
<!--
<sect2><heading>Tuning your ESDI kernel setup</heading>
<p>
-->
<sect1><heading>Particulars on ESDI hardware</heading>
<p>
<sect2><heading>Adaptec 2320 controllers</heading>
<p>
I succesfully installed FreeBSD onto a ESDI disk controlled by a
ACB-2320. No other operating system was present on the disk.
To do so I low level formatted the disk using NEFMT.EXE
(<it>ftp</it>able from <it>www.adaptec.com</it>) and answered NO
to the question whether the disk should be formatted with a
spare sector on each track. The BIOS on the ACD-2320 was
disabled. I used the 'free configurable' option in the system
BIOS to allow the BIOS to boot it.
Before using NEFMT.EXE I tried to format the disk using the
ACB-2320 BIOS builtin formatter. This proved to be a showstopper,
because it didn't give me an option to disable spare sectoring.
With spare sectoring enabled the FreeBSD installation
process broke down on the bad144 run.
Please check carefully which ACB-232xy variant you have. The
x is either 0 or 2, indicating a controller without or with
a floppy controller on board.
The y is more interesting. It can either be a blank,
a "A-8" or a "D". A blank indicates a plain 10 Mbits/second
controller. An "A-8" indicates a 15 Mbits/second controller
capable of handling 52 sectors/track.
A "D" means a 15 Mbits/second controller that can also
handle drives with > 36 sectors/track (also 52 ?).
All variations should be capable of using 1:1 interleaving. Use 1:1,
FreeBSD is fast enough to handle it.
<sect2><heading>Western Digital WD1007 controllers</heading>
<p>
I succesfully installed FreeBSD onto a ESDI disk controlled by a
WD1007 controller. To be precise, it was a WD1007-WA2. Other
variations of the WD1007 do exist.
To get it to work, I had to disable the sector translation and
the WD1007's onboard BIOS. This implied I could not use
the low-level formatter built into this BIOS. Instead, I grabbed
WDFMT.EXE from www.wdc.com Running this formatted my drive
just fine.
<sect2><heading>Ultrastor U14F controllers</heading>
<p>
According to multiple reports from the net, Ultrastor ESDI
boards work OK with FreeBSD. I lack any further info on
particular settings.
<!--
<sect1><heading>Tracking down problems</heading>
<p>
-->
<sect1><heading>Further reading<label id="esdi:further-reading"></>
<p>
If you intend to do some serious ESDI hacking, you might want to
have the official standard at hand:
The latest ANSI X3T10 committee document is:
<itemize>
<item>Enhanced Small Device Interface (ESDI) &lsqb;X3.170-1990/X3.170a-1991&rsqb;
&lsqb;X3T10/792D Rev 11&rsqb;
</itemize>
On Usenet the newsgroup <htmlurl url="news:comp.periphs"
name="comp.periphs"> is a noteworthy place to look
for more info.
The World Wide Web (WWW) also proves to be a very handy info source:
For info on Adaptec ESDI controllers see <htmlurl
url="http://www.adaptec.com/">.
For info on Western Digital controllers see <htmlurl
url="http://www.wdc.com/">.
<sect1>Thanks to...
<p>
Andrew Gordon for sending me an Adaptec 2320 controller and ESDI disk
for testing.

525
handbook/firewalls.sgml Normal file
View file

@ -0,0 +1,525 @@
<!-- $Id: firewalls.sgml,v 1.1 1995-10-14 21:49:45 jfieber Exp $ -->
<!-- The FreeBSD Documentation Project -->
<sect><heading>Firewalls<label id="firewalls"></heading>
<p><em>Contributed by &a.gpalmer;.<newline>4th of October 1995</em>
Firewalls are an area of increasing interest for people who are
connected to the Internet, and are even finding applications on
private networks to provide enhanced security. This section will
hopefully explain what firewalls are, how to use them, and how to use
the facilities provided in the FreeBSD kernel to impliment them.
<quote><bf>Note</bf>: People often think that having a firewall between
your companies internal network and the ``Big Bad Internet'' will
solve all your security problems. It may help, but a poorly setup
firewall system is more of a security risk than not having one at all.
A firewall can only add another layer of security to your systems, but
they will not be able to stop a really determined hacker from
penetrating your internal network. If you let internal security lapse
because you believe your firewall to be impenetrable, you have just
made the hackers job that bit easier.</quote>
<sect1><heading>What is a firewall?</heading>
<p>There are currently two distinct types of firewalls in common
use on the Internet today. The first type is more properly called
a <bf>packet filtering router</bf>, where the kernel on a
multi-homed machine chooses whether to forward or block packets
based on a set of rules. The second type, known as <bf>proxy
servers</bf>, rely on daemons to provide authentication and to
forward packets, possibly on a multi-homed machine which has
kernel packet forwarding disabled.
<p>Sometimes sites combine the two types of firewalls, so that only a
certain machine (known as a <bf>bastion host</bf>) is allowed to send
packets through a packet filtering router onto an internal
network. Proxy services are run on the bastion host, which are
generally more secure than normal authentication mechanisms.
<p>FreeBSD comes with a kernel packet filter (known as <tt>IPFW</tt>),
which is what the rest of this section will concentrate on. Proxy
servers can be built on FreeBSD from third party software, but there
is such a vareity of proxy servers available that it would be
impossible to cover them in this document.
<sect2><heading>Packet filtering routers<label id="firewalls:packet_filters"></heading>
<p>A router is a machine which forwards packets between two or more
networks. A packet filtering router has an extra piece of code in it's
kernel, which compares each packet to a list of rules before deciding
if it should be forwarded or not. Most modern IP routing software has
packet filtering code in it, which defaults to forwarding all
packets. To enable the filters, you need to define a set of rules for
the filtering code, so that it can decide if the packet should be
allowed to pass or not.
<p>To decide if a packet should be passed on or not, the code looks
through it's set of rules for a rule which matches the contents of
this packets headers. Once a match is found, the rule action is
obeyed. The rule action could be to drop the packet, to forward the
packet, or even to send an ICMP message back to the originator. Only
the first match counts, as the rules are searched in order. Hence, the
list of rules can be referred to as a ``rule chain''.
<p>The packet matching criteria varies depending on the software used,
but typically you can specify rules which depend on the source IP
address of the packet, the destination IP address, the source port
number, the destination port number (for protocols which support
ports), or even the packet type (UDP, TCP, ICMP, etc).
<sect2><heading>Proxy servers<label id="firewalls:proxy_servers"></heading>
<p>Proxy servers are machines which have had the normal system daemons
(telnetd, ftpd, etc) replaced with special servers. These servers are
called <bf>proxy servers</bf> as they normally only allow onward
connections to be made. This enables you to run (for example) a proxy
telnet server on your firewall host, and people can telnet in to your
firewall from the outside, go through some authentication mechanism,
and then gain access to the internal network (alternatively, proxy
servers can be used for signals coming from the internal network and
heading out).
<p>Proxy servers are normally more secure than normal servers, and
often have a wider variety of authentication mechanisms available,
including ``one-shot'' password systems so that even if someone
manages to discover what password you used, they will not be able to use
it to gain access to your systems as the password instantly
expires. As they do not actually give users access to the host machine,
it becomes a lot more difficult for someone to install backdoors
around your security system.
<p>Proxy servers often have ways of restricting access further, so
that only certain hosts can gain access to the servers, and often they
can be set up so that you can limit which users can talk to which
destination machine. Again, what facilities are available depends
largely on what proxy software you choose.
<sect1><heading>What does <tt>IPFW</tt> allow me to do?</heading>
<p><tt>IPFW</tt>, the software supplied with FreeBSD, is a packet
filtering and accounting system which resides in the kernel, and has a
user-land control utility, <tt>ipfw(8)</tt>. Together, they
allow you to define and query the rules currently used by the kernel
in its routing decisions.
<p>There are two related parts to <tt>IPFW</tt>. The firewall section
allows you to perform packet filtering. There is also an IP accounting
section which allows you to track usage of your router, based on
similar rules to the firewall section. This allows you to see (for
example) how much traffic your router is getting from a certain
machine, or how much WWW (World Wide Web) traffic it is forwarding.
<p>As a result of the way that <tt>IPFW</tt> is designed, you can use
<tt>IPFW</tt> on non-router machines to perform packet filtering on
incoming and outgoing connections. This is a special case of the more
general use of <tt>IPFW</tt>, and the same commands and techniques
should be used in this situation.
<sect1><heading>Enabling <tt>IPFW</tt> on FreeBSD</heading>
<p>As the main part of the <tt>IPFW</tt> system lives in the kernel, you will
need to add one or more options to your kernel configuration
file, depending on what facilities you want, and recompile your kernel. See
<ref id="kernelconfig" name="reconfiguring the kernel"> for more
details on how to recompile your kernel.
<p>There are currently three kernel configuration options
relevant to IPFW:
<descrip>
<tag/options IPFIREWALL/ Compiles into the kernel the code for packet
filtering.
<tag/options IPFIREWALL_VERBOSE/ Enables code to allow logging of
packets through <tt>syslogd</tt>. Without this option, even if you
specify that packets should be logged in the filter rules, nothing
will happen.
<tag/options IPACCT/ Turns on the IP accounting facilities.
</descrip>
<sect1><heading>Configuring <tt>IPFW</tt></heading>
<p>The configuration of the <tt>IPFW</tt> software is done through the
<tt>ipfw(8)</tt> utility. The syntax for this command looks
quite complicated, but it is relatively simple once you understand
it's structure.
<p>There are currently two different command line formats for the
utility, depending on what you are doing. The first form is used when
adding/deleting entries from the firewall or accounting chains, or
when clearing the counters for an entry on the accounting chain. The
second form is used for more general actions, such as flushing the
rule chains, listing the rule chains or setting the default policy.
<sect2><heading>Altering the <tt>IPFW</tt> rules</heading>
<p>The syntax for this form of the command is:
<tscreen>
ipfw [-n] <em>command</em> <em>action</em> <em>protocol</em> <em>addresses</em>
</tscreen>
<p>There is one valid flag when using this form of the command:
<descrip>
<tag/-n/Do not attempt to resolve given addresses.
</descrip>
The <em>command</em> given can be shortened to the shortest unique
form. The valid <em>commands</em> are:
<descrip>
<tag/addfirewall/Add an entry to the firewall rule list
<tag/delfirewall/Delete an entry from the firewall rule list
<tag/addaccounting/Add an entry to the accounting rule list
<tag/delaccounting/Delete an entry from the accounting rule list
<tag/clraccounting/Clear the counters for an accounting rule entry.
</descrip>
If no command is given, it will default <bf>addfirewall</bf> or
<bf>addaccounting</bf> depending on the arguments given.
<p>Currently, the firewall support in the kernel applies a set of
weights to the rule being added. This means that the rules will
<em>not</em> be evaluated in the order that they are given to the
system. The weighting system is designed so that rules which are very
specific are evaluated first, and rules which cover very large ranges
are evaluated last. In other words, a rule which applies to a specific
port on a specific host will have a higher priority than a rule which
applies to that same port, but on a range of hosts, or that host on a
range of ports.
<p>The weighting system is not perfect, however, and can lead to
problems. The best way to see what order it has put your rules in is
to use the <bf>list</bf> command, as that command lists the rules in
the order that they are evaluated, not the order that they were fed to
the system.
<p>The <em>actions</em> available depend on which rule chain the
entry is destined for. For the firewall chain, valid
<em>actions</em> are:
<descrip>
<tag/reject/Drop the packet, and send an ICMP HOST_UNREACHABLE packet
to the source.
<tag/lreject/As <bf>reject</bf>, but also log the packet details.
<tag/deny/Drop the packet.
<tag/ldeny/As <bf>deny</bf>, but also log the packet details.
<tag/log/Log the packets details and pass it on as normal.
<tag/accept/Pass the packet on as normal.
<tag/pass/Synonym for <bf>accept</bf>.
</descrip>
For the accounting chain, valid <em>actions</em> are:
<descrip>
<tag/single/Count packets matching the address specifier.
<tag/bidirectional/Count packets matching the address specifier, and
also packets travelling in the opposite direction (i.e. those going
from ``destination'' to ``source'').
</descrip>
<p>Each <em>action</em> will be recognized by the shortest unambigious
prefix.
The <em>protocols</em> which can be specified are:
<descrip>
<tag/all/Matches any IP packet
<tag/icmp/Matches ICMP packets
<tag/tcp/Matches TCP packets
<tag/udp/Matches UDP packets
<tag/syn/Matches the TCP SYN (synchronization) packet used during TCP
connection negotiation. You can use this to block ``incoming'' TCP
connections, but allow ``outgoing'' TCP connections.
</descrip>
<p>The <em>address</em> specification is:
<tscreen>
&lsqb;<bf>from</bf> &lt;<em>address/mask</em>&gt;&lsqb;<em>port</em>&rsqb;&rsqb; &lsqb;<bf>to</bf>
&lt;<em>address/mask</em>&gt;&lsqb;<em>port</em>&rsqb;&rsqb; &lsqb;<bf>via</bf> &lt;<em>interface</em>&gt;&rsqb;
</tscreen>
<p>You can only specify <em>port</em> in conjunction with
<em>protocols</em> which support ports (UDP, TCP and SYN).
<p>The order of the <bf>from</bf>, <bf>to</bf>, and
<bf>via</bf> keywords is unimportant. Any of them can be omitted,
in which case a default entry for that keyword will be supplied which
matches everything.
<p>The <bf>via</bf> is optional and may specify the IP address or
domain name of a local IP interface, or an interface name (e.g.
<tt>ed0</tt>) to match only packets coming through this interface. The
keyword <bf>via</bf> can be substituted by <bf>on</bf>, for
readability reasons.
<p>The syntax used to specify an <tt>&lt;address/mask&gt;</tt> is:
<tscreen>
&lt;address&gt;
</tscreen>
or
<tscreen>
&lt;address&gt;/mask-bits
</tscreen>
or
<tscreen>
&lt;address&gt;:mask-pattern
</tscreen>
<p>A valid hostname may be specified in place of the IP
address. <tt>mask-bits</tt> is a decimal number representing how many
bits in the address mask should be set. e.g. specifying
<tscreen>
192.216.222.1/24
</tscreen>
will create a mask which will allow any address in a class C subnet
(in this case, 192.216.222) to be matched. <tt>mask-pattern</tt> is an IP
address which will be logically AND'ed with the address given. The
keyword <tt>any</tt> may be used to specify ``any IP address''.
<p>The port numbers to be blocked are specified as:
<tscreen>
port&lsqb;,port&lsqb;,port&lsqb;...&rsqb;&rsqb;&rsqb;
</tscreen>
to specify either a single port or a list of ports, or
<tscreen><verb>
port:port
</verb></tscreen>
to specify a range of ports. The name of a service (from
<em>/etc/services</em>) can be used instead of a numeric port value.
<sect2><heading>Listing/flushing the <tt>IPFW</tt> rules</heading>
<p>The syntax for this form of the command is:
<tscreen>
ipfw &lsqb;-ans&rsqb; <em>command</em> &lsqb;<em>argument</em>&rsqb;
</tscreen>
<p>There are three valid flags when using this form of the command:
<descrip>
<tag/-a/While listing, show counter values. This option is the only
way to see accounting counters. Works only with <bf>-s</bf>.
<tag/-n/Do not attempt to resolve given addresses.
<tag/-s/Use short listing form. This should be used with <bf>-a</bf>
to see accounting counters. The short form listing is incompatible
with the input syntax used by the <tt>ipfw(8)</tt> utility.
</descrip>
The <em>command</em> given can be shortened to the shortest unique
form. The valid <em>commands</em> are:
<descrip>
<tag/list/List the chain rule entries. Unless the <bf>-s</bf> flag is
given, the format is compatable with the command line syntax.
<tag/flush/Flush the chain rule entries.
<tag/zero/Clear counters for the entire accounting chain.
<tag/policy/Set or display the default policy for the firewall
code. Without an argument, the current policy will be displayed.
</descrip>
The <bf>list</bf> and <bf>flush</bf> commands may optionally be passed
an <em>argument</em> to specify which chain to flush. Valid arguments are:
<descrip>
<tag/firewall/The packet filter chain.
<tag/accounting/The accounting chain.
</descrip>
<p>The <bf>policy</bf> command can be given one of two arguments:
<descrip>
<tag/accept/If a packet is not matched by any rule, pass it on.
<tag/deny/If a packet is not matched by any rule, do not pass it on.
</descrip>
As usual, the arguments can be shortened to the shortest unique form
(in this case, the first letter).
<sect1><heading>Example commands for ipfw</heading>
<p>This command will deny all packets from the host
<bf>evil.hacker.org</bf> to the telnet port of the host
<bf>nice.people.org</bf> by being forwarded by the router:
<tscreen><verb>
ipfw addf deny tcp from evil.hacker.org to nice.people.org telnet
</verb></tscreen>
<p>The next example denies and logs any TCP traffic from the entire
<bf>hacker.org</bf> network (a class C) to the <bf>nice.people.org</bf>
machine (any port).
<tscreen><verb>
ipfw addf ldeny tcp from evil.hacker.org/24 to nice.people.org
</verb></tscreen>
If you do not want people sending X sessions to your internal network
(a subnet of a class C), the following command will do the necessary
filtering:
<tscreen><verb>
ipfw addf deny syn to my.org/28 6000
</verb></tscreen>
To allow access to the SUP server on <bf>sup.FreeBSD.ORG</bf>, use the
following command:
<tscreen><verb>
ipfw addf accept syn to sup.FreeBSD.ORG supfilesrv
</verb></tscreen>
To see the accounting records:
<tscreen><verb>
ipfw -sa list accounting
</verb></tscreen>
or in the short form
<tscreen><verb>
ipfw -sa l a
</verb></tscreen>
<sect1><heading>Building a packet filtering firewall</heading>
<p><quote><bf>Note:</bf> The following suggestions are just that:
suggestions. The requirements of each firewall are different and I
cannot tell you how to build a firewall to meet your particular
requirements.</quote>
<p>When initially setting up your firewall, unless you have a test
bench setup where you can configure your firewall host in a controlled
environment, I strongly recommend you use the logging version of the
commands and enable logging in the kernel. This will allow you to
quickly identify problem areas and cure them without too much
disruption. Even after the initial setup phase is complete, I
recommend using the logging for of `deny' as it allows tracing of
possible attacks and also modification of the firewall rules if your
requirements alter.
<quote><bf>Note:</BF> If you use the logging versions of the
<bf>accept</bf> command, it can generate <em>large</em> ammounts
of log data as one log line will be generated for every packet
that passes through the firewall, so large ftp/http transfers,
etc, will really slow the system down. It also increases the
latencies on those packets as it requires more work to be done by
the kernel before the packet can be passed on. syslogd with also
start using up a lot more processor time as it logs all the extra
data to disk, and it could quite easily fill the partition
<tt>/var/log</tt> is located on.</quote>
<p>As currently supplied, FreeBSD does not have the ability to
load firewall rules at boot time. My suggestion is to put a call
to a shell script in the <tt>/etc/netstart</tt> script. Put the
call early enough in the netstart file so that the firewall is
configured before any of the IP interfaces are configured. This
means that there is no window during which time your network is
open.
<p>The actual script used to load the rules is entirely up to
you. There is currently no support in the <tt>ipfw</tt> utility for
loading multiple rules in the one command. The system I use is to use
the command:
<tscreen><verb>
# ipfw list
</verb></tscreen>
to write a list of the current rules out to a file, and then use a
text editor to prepend ``<tt>ipfw </tt>'' before all the lines. This
will allow the script to be fed into /bin/sh and reload the rules into
the kernel. Perhaps not the most efficient way, but it works.
<p>The next problem is what your firewall should actually <bf>DO</bf>!
This is largely dependant on what access to your network you want to
allow from the outside, and how much access to the outside world you
want to allow from the inside. Some general rules are:
<itemize>
<item>Block all incoming access to ports below 1000 for TCP. This is
where most of the security sensitive services are, like finger, smtp
(mail) and telnet.
<item>Block incoming SYN connections to ports between 1001 and 1024
(this will allow internal users to rsh/rlogin to the outside). If you
do not want to allow rsh/rlogin connections from the inside to the
outside, then extend the above suggestion to cover ports 1-1024.
<item>Block <bf>all</bf> incoming UDP traffic. There are very few
useful services that travel over UDP, and what useful traffic there is
is normally a security threat (e.g. Suns RPC and NFS protocols). This
has its disadvantages also, since UDP is a connectionless protocol,
denying incoming UDP traffic also blocks the replies to outoing UDP
traffic. This can cause a problem for people (on the inside)
using external archie (prospero) servers. If you want to allow access
to archie, you'll have to allow packets coming from ports 191 and 1525
to any internal UDP port through the firewall. ntp is another service
you may consider allowing through, which comes from port 123.
<item>Block traffic to port 6000 from the outside. Port 6000 is the
port used for access to X11 servers, and can be a security threat
(especially if people are in the habbit of doing <tt>xhost +</tt> on
their workstations). X11 can actually use a range of ports starting at
6000, the upper limit being how many X displays you can run on the
machine. The upper limit as defined by RFC 1700 (Assigned Numbers) is
6063.
<item>Check what ports any internal servers use (e.g. SQL servers,
etc). It's probably a good idea to block those as well, as they
normally fall outside the 1-1024 range specified above.
</itemize>
<p>Of course, if you want to make sure that no un-authorised traffic
gets through the firewall, change the default policy to ``deny''. This
will mean that any traffic which is allowed through has to be
specified explicitly in an ``accept'' or ``allow'' filter rule. Which
ports you allow through is again something that you will have to
decide for yourself. If you do set the default policy to be deny, you
will probably want to install proxy servers, as no traffic will be
able to get OUT either unless you allow TCP SYN connections going form
the inside out.
<p>As I said above, these are only <em>guidelines</em>. You will have
to decide what filter rules you want to use on your firewall
yourself. I cannot accept ANY responsibility if someone breaks into
your network, even if you follow the advice given above.

1206
handbook/kernelconfig.sgml Normal file

File diff suppressed because it is too large Load diff

3877
handbook/printing.sgml Normal file

File diff suppressed because it is too large Load diff

279
handbook/routing.sgml Normal file
View file

@ -0,0 +1,279 @@
<!-- $Id: routing.sgml,v 1.1 1995-10-07 04:31:41 jfieber Exp $ -->
<!-- The FreeBSD Documentation Project -->
<!-- <!DOCTYPE linuxdoc PUBLIC '-//FreeBSD//DTD linuxdoc//EN'> -->
<sect><heading>Gateways and routes<label id="routing"></heading>
<p><em>Contributed by &a.gryphon;.<newline>6 October 1995.</em>
For one machine to be able to find another, there must be a
mechanism in place to describe how to get from one to the
other. This is called Routing. A ``route'' is a defined
pair of addresses: a <bf>destination</bf> and a
<bf>gateway</bf>. The pair indicates that if you are
trying to get to this <em>destination</em>, send along
through this <em>gateway</em>. There are three types of
destinations: individual hosts, subnets, and ``default''. The
``default route'' is used if none of the other routes
apply. We will talk a little bit more about default routes
later on. There are also three types of gateways:
individual hosts, interfaces (also called ``links''), and
ethernet hardware addresses.
<sect1><heading>An example</heading>
<p>To illustrate different aspects of routing, we will use
the following example which is the output of the command
<tt>netstat -r</tt>:
<tscreen><verb>
Destination Gateway Flags Refs Use Netif Expire
default outside-gw UGSc 37 418 ppp0
localhost localhost UH 0 181 lo0
test0 0:e0:b5:36:cf:4f UHLW 5 63288 ed0 77
10.20.30.255 link#1 UHLW 1 2421
foobar.com link#1 UC 0 0
host1 0:e0:a8:37:8:1e UHLW 3 4601 lo0
host2 0:e0:a8:37:8:1e UHLW 0 5 lo0 =>
host2.foobar.com link#1 UC 0 0
224 link#1 UC 0 0
</verb></tscreen>
The first two lines specify the default route (which we
will cover in the next section) and the <tt>localhost</tt> route.
The interface (<tt>Netif</tt> column) that it specifies to use
for <tt>localhost</tt> is <tt>lo0</tt>, also known as the
loopback device. This says to keep all traffic for this
destination internal, rather than sending it out over the
LAN, since it will only end up back where it started
anyway.
The next thing that stands out are the
``<tt>0:e0:...</tt>'' addresses. These are ethernet
hardware addresses. FreeBSD will automatically identify any
hosts (<tt>test0</tt> in the example) on the local ethernet and
add a route for that host, directly to it over the ethernet
interface, <tt>ed0</tt>. There is also a timeout
(<tt>Expire</tt> column) associated with this type of route,
which is used if we fail to hear from the host in a
specific amount of time. In this case the route will be
automatically deleted. These hosts are identified using a
mechanism known as RIP (Routing Information Protocol),
which figures out routes to local hosts based upon a
shortest path determination.
FreeBSD will also add subnet routes for the local subnet
(<tt>10.20.30.255</tt> is the broadcast address for the subnet
<tt>10.20.30</tt>, and <tt>foobar.com</tt> is the domain name
associated with that subnet). The designation <tt>link&num;1</tt>
refers to the first ethernet card in the machine. You'll
notice no additional interface is specified for those.
Both of these groups (local network hosts and local
subnets) have their routes automatically configured by a
daemon called <tt>routed</tt>. If this is not run, then only
routes which are statically defined (ie. entered
explicitly) will exist.
The <tt>host1</tt> line refers to our host, which it knows by
ethernet address. Since we are the sending host, FreeBSD
knows to use the loopback interface (<tt>lo0</tt>) rather than
sending it out over the ethernet interface.
The two <tt>host2</tt> lines are an example of what happens
when we use an ifconfig alias (see the section of ethernet
for reasons why we would do this). The <tt>=&gt</tt>
symbol after the <tt>lo0</tt> interface says that not only are
we using the loopback (since this is address also refers to
the local host), but specifically it is an alias. Such
routes only show up on the host that supports the alias;
all other hosts on the local network will simply have a
<tt>link&num;1</tt> line for such.
The final line (destination subnet <tt>224</tt>) deals with
MultiCasting, which will be covered in a another section.
The other column that we should talk about are the
<tt>Flags</tt>. Each route has different attributes that are
described in the column. Below is a short table of some of
these flags and their meanings:
<descrip>
<tag/U/ <bf/Up:/ The route is active.
<tag/H/ <bf/Host:/ The route destination is a single host.
<tag/G/ <bf/Gateway:/ Send anything for this destination
on to this remote system, which will figure out from
there where to send it.
<tag/S/ <bf/Static:/ This route was configured manually,
not automatically generated by the system.
<tag/C/ <bf/Clone:/ Generates a new route based upon this
route for machines we connect to. This type of route is
normally used for local networks.
<tag/W/ <bf/WasCloned/ Indicated a route that was
auto-configured based upon a local area network (Clone)
route.
<tag/L/ <bf/Link:/ Route involves references to ethernet
hardware.
</descrip>
<sect1><heading>Default routes</heading>
<p>When the local system needs to make a connection to
remote host, it checks the routing table to determine if
a known path exists. If the remote host falls into a
subnet that we know how to reach (Cloned routes), then
the system checks to see if it can connect along that
interface.
If all known paths fail, the system has one last option:
the <bf>default</bf> route. This route is a special type
of gateway route (usually the only one present in the
system), and is always marked with a ``<tt>c</tt>'' in
the flags field. For hosts on a local area network, this
gateway is set to whatever machine has a direct
connection to the outside world (whether via PPP link, or
your hardware device attached to a dedicated data line).
If you are configuring the default route for a machine
which itself is functioning as the gateway to the outside
world, then the default route will be the gateway machine
at your Internet Service Provider's (ISP) site.
Let's look at an example of default routes. This is a
common configuration:
<tscreen><verb>
[Local2] <--ether--> [Local1] <--PPP--> [ISP-Serv] <--ether--> [T1-GW]
</verb></tscreen>
The hosts <tt>Local1</tt> and <tt>Local2</tt> are at your
site, with the formed being your PPP connection to your
ISP's Terminal Server. Your ISP has a local network at
their site, which has, among other things, the server
where you connect and a hardware device (T1-GW) attached
to the ISP's internet feed.
The default routes for each of your machines will be:
<tscreen><verb>
host default gateway interface
---- --------------- ---------
Local2 Local1 ethernet
Local1 T1-GW PPP
</verb></tscreen>
A common question is ``Why (or how) would we set the
T1-GW to be the default gateway for Local1, rather than
the ISP server it is connected to?''.
Remember, since the PPP interface is using an address on
the ISP's local network for your side of the connection,
routes for any other machines on the ISP's local network
will be automatically generated. Hence, you will already
know how to reach the T1-GW machine, so there is no need
for the intermediate step of sending traffic to the ISP
server.
As a final note, it is common to use the address ``<tt>...1</tt>''
as the gateway address for your local network. So (using
the same example), if your local class-C address space
was <tt>10.20.30</tt> and your ISP was using <tt>10.9.9</tt> then the
default routes would be:
<tscreen><verb>
Local2 (10.20.30.2) --> Local1 (10.20.30.1)
Local1 (10.20.30.1, 10.9.9.30) --> T1-GW (10.9.9.1)
</verb></tscreen>
<sect1><heading>Dual homed hosts</heading>
<p>There is one other type of configuration that we should
cover, and that is a host that sits on two different
networks. Technically, any machine functioning as a
gateway (in the example above, using a PPP connection)
counts as a dual-homed host. But the term is really only
used to refer to a machine that sits on two local-area
networks.
In one case, the machine as two ethernet cards, each
having an address on the seperate subnets. Alternately,
the machine may only have one ethernet card, and be using
ifconfig aliasing. The former is used if two physically
separate ethernet networks are in use, the latter if
there is one physical network segment, but two logically
seperate subnets.
Either way, routing tables are set up so that each subnet
knows that this machine is the defined gateway (inbound
route) to the other subnet. This configuration, with the
machine acting as a Bridge between the two subnets, is
often used when we need to implement packet filtering or
firewall security in either or both directions.
<sect1><heading>Routing propogation</heading>
<p>We have already talked about how we define our routes to
the outside world, but not about how the outside world
finds us.
We already know that routing tables can be set up so that
all traffic for a particular address space (in our
examples, a class-C subnet) can be sent to a particular
host on that network, which will forward the packets
inbound.
When you get an address space assigned to your site, your
service provider will set up their routing tables so that
all traffic for your subnet will be sent down your PPP
link to your site. But how do sites across the country
know to send to your ISP?
There is a system (much like the distributed DNS
information) that keeps track of all assigned
address-spaces, and defines their point of connection to
the Internet Backbone. The ``Backbone'' are the main
trunk lines that carry internet traffic across the
country, and around the world. Each backbone machine has
a copy of a master set of tables, which direct traffic
for a particular network to a specific backbone carrier,
and from there down the chain of service providers until
it reaches your network.
It is the task of your service provider to advertise to
the backbone sites that they are the point of connection
(and thus the path inward) for your site. This is known
as route propogation.
<!--
<sect1><heading>Multicast Routing</heading>
-->
<sect1><heading>Troubleshooting</heading>
<p>Sometimes, there is a problem with routing propogation,
and some sites are unable to connect to you. Perhaps the
most useful command for trying to figure out where a
routing is breaking down is the <tt>traceroute(8)</tt>
command. It is equally useful if you cannot seem to make
a connection to a remote machine (ie. <tt>ping(8)</tt>
fails).
The <tt>traceroute(8)</tt> command is run with the name
of the remote host you are trying to connect to. It will
show the gateway hosts along the path of the attempt,
eventually either reaching the target host, or
terminating because of a lack of connection.
For more information, see the manual page for
<tt>traceroute(8)</tt>.

302
handbook/skey.sgml Normal file
View file

@ -0,0 +1,302 @@
<!-- $Id: skey.sgml,v 1.3 1995-10-07 04:31:56 jfieber Exp $ -->
<!-- The FreeBSD Documentation Project -->
<!--
Copyright 1995 Massachusetts Institute of Technology
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that both the above copyright notice and this
permission notice appear in all copies, that both the above
copyright notice and this permission notice appear in all
supporting documentation, and that the name of M.I.T. not be used
in advertising or publicity pertaining to distribution of the
software without specific, written prior permission. M.I.T. makes
no representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied
warranty.
THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-->
<sect><heading>S/Key<label id="skey"></heading>
<p><em>Contributed by &a.wollman;<newline>25 September 1995.</em>
<p>S/Key is a one-time password scheme based on a one-way hash function
(in our version, this is MD4 for compatibility; other versions have
used MD5 and DES-MAC). S/Key has been a standard part of all FreeBSD
distributions since version 1.1.5, and is also implemented on a large
and growing number of other systems. S/Key is a registered trademark
of Bell Communications Research, Inc.
<!-- XXX - is there a better word to use than UNIX? -->
<p>There are three different sorts of passwords which we will talk about
in the discussion below. The first is your usual UNIX-style or Kerberos
password; we'll call this a ``UNIX password''. The second sort is the
one-time password which is generated by the S/Key `<tt/key/' program and
accepted by the `<tt/keyinit/' program and the login prompt; we'll call
this a ``one-time password''. The final sort of password is the
secret password which you give to the `<tt/key/' program (and sometimes the
`<tt/keyinit/' program) which it uses to generate one-time passwords; we'll
call it a ``secret password'' or just unqualified ``password''.
<p>The secret password does not necessarily have anything to do with your
UNIX password (while they can be the same, this is not recommended).
While UNIX passwords are limited to eight characters in length, your
S/Key secret password can be as long as you like; I use seven-word
phrases. In general, the S/Key system operates completely
independently of the UNIX password system.
<p>There are in addition two other sorts of data involved in the S/Key
system; one is called the ``seed'' or (confusingly) ``key'', and
consists of two letters and five digits, and the other is the
``iteration count'' and is a number between 100 and 1. S/Key
constructs a one-time password from these components by concatenating
the seed and the secret password, then applying a one-way hash (the
RSA Data Security, Inc., MD4 secure hash function) iteration-count
times, and turning the result into six short English words. The
`<tt/login/' and `<tt/su/' programs keep track of the last one-time
password used, and the user is authenticated if the hash of the
user-provided password is equal to the previous password. Because a
one-way hash function is used, it is not possible to generate future
one-time passwords having overheard one which was successfully used;
the iteration count is decremented after each successful login to keep
the user and login program in sync. (When you get the iteration count
down to 1, it's time to reinitialize S/Key.)
<p>There are four programs involved in the S/Key system which we will
discuss below. The `<tt/key/' program accepts an iteration count, a
seed, and a secret password, and generates a one-time password. The
`<tt/keyinit/' program is used to initialized S/Key, and to change
passwords, iteration counts, or seeds; it takes either a secret
password, or an iteration count, seed, and one-time password. The
`<tt/keyinfo/' program examines the <tt>/etc/skeykeys</tt> file and
prints out the invoking user's current iteration count and seed.
Finally, the `<tt/login/' and `<tt/su/' programs contain the necessary
logic to accept S/Key one-time passwords for authentication. The
`<tt/login/' program is also capable of disallowing the use of UNIX
passwords on connections coming from specified addresses.
<p>There are four different sorts of operations we will cover. The first
is using the `<tt/keyinit/' program over a secure connection to set up
S/Key for the first time, or to change your password or seed. The
second operation is using the `<tt/keyinit/' program over an insecure
connection, in conjunction with the `<tt/key/' program over a secure
connection, to do the same. The third is using the `<tt/key/' program to
log in over an insecure connection. The fourth is using the `<tt/key/'
program to generate a number of keys which can be written down or
printed out to carry with you when going to some location without
secure connections to anywhere (like at a conference).
<sect1><heading>Secure connection initialization</heading>
<p>To initialize S/Key, change your password, or change your seed while
logged in over a secure connection (e.g., on the console of a machine),
use the `<tt/keyinit/' command without any parameters while logged in as
yourself:
<tscreen><verb>
$ keyinit
Updating wollman: ) these will not appear if you
Old key: ha73895 ) have not used S/Key before
Reminder - Only use this method if you are directly connected.
If you are using telnet or rlogin exit with no password and use keyinit -s.
Enter secret password: ) I typed my pass phrase here
Again secret password: ) I typed it again
ID wollman s/key is 99 ha73896 ) discussed below
SAG HAS FONT GOUT FATE BOOM )
</verb></tscreen>
<p>There is a lot of information here. At the `Enter secret password:'
prompt, you should enter some password or phrase (I use phrases of
minimum seven words) which will be needed to generate login keys. The
line starting `ID' gives the parameters of your particular S/Key
instance: your login name, the iteration count, and seed. When
logging in with S/Key, the system will remember these parameters and
present them back to you so you don't have to remember them. The last
line gives the particular one-time password which corresponds to those
parameters and your secret password; if you were to re-login
immediately, this one-time password is the one you would use.
<sect1><heading>Insecure connection initialization</heading>
<p>To initialize S/Key or change your password or seed over an insecure
connection, you will need to already have a secure connection to some
place where you can run the `<tt/key/' program; this might be in the form
of a desk accessory on a Macintosh, or a shell prompt on a machine you
trust (we'll show the latter). You will also need to make up an
iteration count (100 is probably a good value), and you may make up
your own seed or use a randomly-generated one. Over on the insecure
connection (to the machine you are initializing), use the `<tt/keyinit -s/'
command:
<tscreen><verb>
$ keyinit -s
Updating wollman:
Old key: kh94741
Reminder you need the 6 english words from the skey command.
Enter sequence count from 1 to 9999: 100 ) I typed this
Enter new key [default kh94742]:
s/key 100 kh94742
</verb></tscreen>
To accept the default seed (which the `keyinit' program confusingly
calls a `key'), press return. Then move over to your secure
connection or S/Key desk accessory, and give it the same parameters:
<tscreen><verb>
$ key 100 kh94742
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password: ) I typed my secret password
HULL NAY YANG TREE TOUT VETO
</verb></tscreen>
Now switch back over to the insecure connection, and copy the one-time
password generated by `<tt/key/' over to the `<tt/keyinit/' program:
<tscreen><verb>
s/key access password: HULL NAY YANG TREE TOUT VETO
ID wollman s/key is 100 kh94742
HULL NAY YANG TREE TOUT VETO
</verb></tscreen>
The rest of the description from the previous section applies here as
well.
<sect1><heading>Diversion: a login prompt</heading>
<p>Before explaining how to generate one-time passwords, we should go
over an S/Key login prompt:
<tscreen><verb>
$ telnet himalia
Trying 18.26.0.186...
Connected to himalia.lcs.mit.edu.
Escape character is '^]'.
s/key 92 hi52030
Password:
</verb></tscreen>
Note that, before prompting for a password, the login program
prints out the iteration number and seed which you will need in order
to generate the appropriate key. You will also find a useful feature
(not shown here): if you press return at the password prompt, the
login program will turn echo on, so you can see what you are typing.
This can be extremely useful if you are attempting to type in an S/Key
by hand, such as from a printout.
<p>If this machine were configured to disallow UNIX passwords over a
connection from my machine, the prompt would have also included the
annotation `<tt>(s/key required)</tt>', indicating that only S/Key one-time
passwords will be accepted.
<sect1><heading>Generating a single one-time password</heading>
<p>Now, to generate the one-time password needed to answer this login
prompt, we use a trusted machine and the `<tt/key/' program. (There are
versions of the `<tt/key/' program from DOS and Windows machines, and there
is an S/Key desk accessory for Macintosh computers as well.) The
command-line `<tt/key/' program takes as its parameters the iteration count
and seed; you can cut-and-paste right from the login prompt starting
at ``<tt/key/'' to the end of the line. Thus:
<tscreen><verb>
$ key 92 hi52030 ) pasted from previous section
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password: ) I typed my secret password
ADEN BED WOLF HAW HOT STUN
</verb></tscreen>
And in the other window:
<tscreen><verb>
s/key 92 hi52030 ) from previous section
Password:
(turning echo on)
Password:ADEN BED WOLF HAW HOT STUN
Last login: Wed Jun 28 15:31:00 from halloran-eldar.l
[etc.]
</verb></tscreen>
This is the easiest mechanism <em/if/ you have a trusted machine.
<sect1><heading>Generating multiple one-time passwords</heading>
<p>Sometimes we have to go places where no trusted machines or
connections are available. In this case, it is possible to use the
`<tt/key/' command to generate a number of one-time passwords in the same
command; these can then be printed out. For example:
<tscreen><verb>
$ key -n 25 57 zz99999
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password:
33: WALT THY MALI DARN NIT HEAD
34: ASK RICE BEAU GINA DOUR STAG
[...]
56: AMOS BOWL LUG FAT CAIN INCH
57: GROW HAYS TUN DISH CAR BALM
</verb></tscreen>
The `<tt/-n 25/' requests twenty-five keys in sequence; the `<tt/57/' indicates
the <em/ending/ iteration number; and the rest is as before. Note that
these are printed out in <em/reverse/ order of eventual use. If you're
really paranoid, you might want to write the results down by hand;
otherwise you can cut-and-paste into `<tt/lpr/'. Note that each line shows
both the iteration count and the one-time password; you may still find
it handy to scratch off passwords as you use them.
<sect1><heading>Restricting use of UNIX passwords</heading>
<p>The configuration file <tt>/etc/skey.access</tt> can be used to
configure restrictions on the use of UNIX passwords based on the host
name, user name, terminal port, or IP address of a login session. The
complete format of the file is documented in the <em/skey.access/(5)
manual page; there are also some security cautions there which should
be read before depending on this file for security.
<p>If there is no <tt>/etc/skey.access</tt> file (which is the default
state as FreeBSD is shipped), then all users will be allowed to use
UNIX passwords. If the file exists, however, then all users will be
required to use S/Key unless explicitly permitted to do otherwise by
configuration statements in the <tt/skey.access/ file. In all cases,
UNIX passwords are permitted on the console.
<p>Here is a sample configuration file which illustrates the three most
common sorts of configuration statements:
<tscreen><verb>
permit internet 18.26.0.0 255.255.0.0
permit user jrl
permit port ttyd0
</verb></tscreen>
The first line (`<tt/permit internet/') allows users whose IP source
address (which is vulnerable to spoofing) matches the specified value
and mask, to use UNIX passwords. This should not be considered a
security mechanism, but rather, a means to remind authorized users
that they are using an insecure network and need to use S/Key for
authentication.
<p>The second line (`<tt/permit user/') allows the specified user to
use UNIX passwords at any time. Generally speaking, this should only
be used for people who are either unable to use the `<tt/key/'
program, like those with dumb terminls, or those who are uneducable.
<p>The third line (`<tt/permit port/') allows all users logging in on
the specified terminal line to use UNIX passwords; this would be used
for dial-ups.