There's not much use for a 100 MHz Pentium computer in the Microsoft world. Modern applications require faster processors (to run animated paperclips), and while the 32 mb of RAM the computer has is certainly sufficient, it comes with an ATI-32 video card built into the motherboard which isn't powerful enough to run the latest, greatest 3D gorefests.
I've loved Linux since the 0.95 days. I actually bought hardware around the Linux/X-Free86 compatibility lists (until my wife got toys like low-end scanners, digital cameras, and color printers). When the Pentium-100 wasn't able to run her Windows apps anymore, I had an opportunity to upgrade to that machine. Since then, she's gone through two upgrade cycles, and I've received the cast-offs. :-)
The main Linux box is still that Pentium-100, loaded with all our old 72-pin
SIMMs to bring it up to 32 mb of RAM. It's got 1.5 gb of disk space (spread
across two drives, with 128 mb of swap) and works well with RedHat 5.2. I
recently dumped the old configuration to upgrade to RedHat 5.2 and applied
my new administration standards to it (namely, keep every change in a
separate /usr/local/
and symlink those files back to their place in the
root filesystem).
I've been promising to share the modem with my wife for over a year. I had successfully set this up at a small company I worked with for six months, and figured it would be no problem to do at home. What I didn't count on was being laid off and changing jobs, moving, and not having a decent place to put the PCs for months. When I finally got everything together, I forgot about my plans to network the PCs and share the modem--I was too busy at work to want to do more than boot up a computer to play Quake II for a few hours a night.
The first difficulty, of course, was to make every computer see the network
and be visible. The NeXT box was tricky to configure, but only because it
was designed to work through the admin applets and I'm used to editing rc
files and the /etc
directory. The Intel
Ether Express card was also a problem because its hardware is permanently
set to the same IRQ as the
second serial port. Ouch! This meant that I wouldn't be able to use a mouse
with the Linux box (I don't have a PS/2-style mouse port on the box). No X
Windows based configuration although, thankfully, Linuxconf works with
Curses.
A big business is likely to choose a class A address because it affords them a huge base of IPs and great flexibility in subnetting. I've never personally seen anyone use the reserved class B network. The reserved class A is appropriate for a small office or home network--it's unlikely that these networks will use more than 254 devices, and if that situation did occur, the network could be segmented with gateways between class C subnets.
I chose the reserved class C subnet 192.168.1.0 (netmask 255.255.255.0) because my traffic will not be routed beyond my network, I don't want to use any real Internet addresses which could potentially cause a conflict with a real Internet assigned address, and it's a conveniently small size to manage.
I planned ahead, as well, choosing my default DNS, server, and gateway addresses at this point. I decided to use DNS and my default server on the 192.168.1.1 address, with my gateway occupying the extreme end at 192.168.1.254. Companies I have worked for in the past have used gateways at .1 in a class C network, with DNS being served on a different network, or the absurd assignment gateways at an arbitrary address range of .181 to .183.
I added the Linux box, next. Linuxconf made configuring the Ether Express card a breeze. Initially, I added the aliased IP address to the Linux box wrong, but Linuxconf caught the error and figured out what I wanted it to do. The Linux box now had two IPs and all the computers could ping each other successfully across the network.
Network: Mischief (192.168.1.0, netmask 255.255.255.0) | ||
Computer | Aliases | IP address |
menagery | becky | 192.168.1.30 |
chris | win95 | 192.168.1.130 |
next | 192.168.1.9 | |
linux | 192.168.1.1 | |
gw | 192.168.1.254 | |
(sl0) | 192.168.1.253 |
All computers in the network are connected to a single five port, 10-base-T Linksys hub via category 3 and category 5 RJ-45 twisted pair cable of distances ranging from two meters to 30 meters.
All computers, except for linux have these minimal network characteristics defined:
linux acts as a caching nameserver and has its default route
set by diald. I use a common hostfile instead of local DNS to make my life
easier. I only have four real hosts, so it's not a big deal. My
/etc/hosts
file looks like this:
127.0.0.1 localhost localhost.localdomain localhost.mischief 192.168.1.1 linux linux.mischief 192.168.1.9 next next.mischief 192.168.1.30 menagery becky becky.mischief menagery.mischief 192.168.1.130 chris chris.mischief win95 win95.mischief 192.168.1.254 gw gw.mischief
To allow the linux box to act as a caching nameserver, I used the default
configuration that came with RedHat 5.2, turned on the named, and edited my
/etc/resolv.conf
file to include my ISP's nameservers. This
means that nameserver requests require a PPP connection, but that is fine
for my setup. I want to be online as much as possible while using the PCs.
My /etc/resolv.conf
file is below:
nameserver 192.168.1.1 nameserver 206.112.192.104 nameserver 206.112.192.110
linux has a network, mischief, defined in
/etc/networks
.
# network-name network mischief 192.168.1.0 internet 0.0.0.0
I never see the internet alias in my routing table. I do see the mischief network.
The routing table of linux looks like this when not connected to the Internet (you won't see this if diald is running because it will assume the default route):
Destination Gateway Genmask Flags Metric Ref Use Iface gw * 255.255.255.255 UH 0 0 0 eth0:0 mischief * 255.255.255.0 U 0 0 13 eth0 127.0.0.0 * 255.0.0.0 U 0 0 2 lo
And just in case you're curious, this is the routing table when diald is running and connected:
Destination Gateway Genmask Flags Metric Ref Use Iface gw * 255.255.255.255 UH 0 0 0 eth0:0 192.168.1.253 * 255.255.255.255 UH 1 0 0 sl0 sv25.access.one * 255.255.255.255 UH 0 0 0 ppp0 mischief * 255.255.255.0 U 0 0 13 eth0 127.0.0.0 * 255.0.0.0 U 0 0 2 lo default * 0.0.0.0 U 0 0 205 ppp0 default * 0.0.0.0 U 1 0 8 sl0
Next, get Eric Schenk's diald and the diald patch.
diald-1.16 won't compile without the
patch to
diald-1.16.5 on glibc systems. Check freshmeat.net's software finder for
more recent updates.
diald is also available from sunsite/metalab, but the patch is only available
from the diald homepage. Make diald, but make sure that you edit the
config.h
file first! Some file locations differ under RedHat 5.1 and 5.2
from the diald defaults.
When you have made diald, configure a /etc/diald.conf
file.
Mine is below (warts and all):
# General options mode ppp #pppd-options 192.168.1.254: debug 20 # Device configuration connect "chat -v -t 30 -f /etc/sysconfig/network-scripts/chat-ppp0" device /dev/cua0 speed 115200 modem lock crtscts # Network Configuration local 192.168.1.254 remote 192.168.1.253 #netmask 255.255.255.0 #mtu 576 #mru 576 #window 2048 dynamic defaultroute # include filtering rules include /usr/lib/diald/standard.filter
You'll note that with my RedHat installation I can use the chat script
built by the configuration utilities (Linuxconf, in my case), that is
/etc/sysconfig/network-scripts/chat-ppp0
.
Now, you should have a working diald. If you execute diald and then try to ping an outside, host, you modem should dial and your Linux box should attempt to connect to your ISP.
/etc/rc.d/rc.local
file. Ideally, these would be
executed in a runlevel with a proper start/stop script, but I'm lazy.
# Turn on IP firewalling/masquerading. This is a dangerous command # because anyone capable of spoofing their IP address can appear to # be part of your network. A better configuration should be used # once this setup has been shown to work. /sbin/ipfwadm -F -i m # Start the diald daemon. /usr/local/bin/diald
The first line (ipfwadm
) is dangerous. It essentially lets the
firewall masquerade all input. A better firewall configuration is highly
recommended. Not many
people know how to spoof meaningful packets, but it would be possible for
someone who knows how to spoof into your 192.168.1.x network. Potentially,
they could access your insecure Win95/98 shares. See Setting up a secure firewall system for more
information on fixing this hole.
The second line starts the diald binary in your chosen location. The default
was /usr/sbin/diald
, but I'm a stickler for seperate
/usr/local
and /
partitions.
eth0:0
), but
it still worked. Don't repeat my mistake. (Hint: it should
be under
Networking -> Client Tasks -> Host name search path)
Oh, and while you're
in Linuxconf, don't forget to turn on IPV4 packet forwarding, but don't
export any routes and don't specify a default gateway. Diald does that for
you. If you're a hands-on administrator, edit your
/etc/sysconfig/network
file and make sure that it has a line
that says FORWARD_IPV4="yes"
.
Finally, you can reboot and if you were lucky and I didn't leave anything out, you can ping your ISP automagically.
It's worth noting that my mail is delivered in a POP-only mailbox. This is becoming more common as ISPs begin to use NT systems and avoid UNIX shells. Although my ISP offers a UNIX shell account and web hosting, I have a POP-only mail address through a special offer (my wife's e-mail address is the primary for the account, so she has the dial in, the default e-mail address, and the web space). This situation absolutely required the use of some way to use the POP server to retrieve my mail. I considered the very nice tool Eudora, but I realized that I wouldn't be able to access my mail from work via telnet if I used Eudora on my PC. Additionally, it would mean that my mail is removed from my native Linux environment and placed into Windows.
I've used Fetchmail in the past and was impressed with its ease of use and
stability. I grabbed the latest build from http://www.tuxedo.org/~esr/fetchmail/.
As root, I read the appropriate README files, configured it and ran make.
It installed without a hitch. Note that I installed it to
/usr/local/bin/fetchmail
, and renamed my old version of Fetchmail to
/usr/bin/__fetchmail
. I then symlinked
/usr/local/bin/fetchmail
to
/usr/bin/fetchmail
.
Configuration was tricky. The best option is to use a working example, which
is what I did. I'm including the interesting parts of my
/home/cjones/.fetchmailrc
file
(I copied esr's example and modified it for my needs).
set daemon 300 # Poll at 5-minute intervals defaults user cjones is cjones here fetchall poll mail.one.net with protocol POP3 port 110: password pop_password;
You'll note that I included a line that isn't really necessary: user
cjones is cjones here
. Additionally, I specified the POP3 port just
to reduce the possibility of errors. You can test your
.fetchmailrc
without them--I am happy to have one that works.
Before your start Fetchmail, you have four more tasks. First, make sure than sendmail (or some other MTA) is running:
[cjones@linux cjones]$ ps ax | grep sendmail | grep -v grep 353 ? S 0:00 sendmail: accepting connections on port 25
If it's not running, you should use Linuxconf to turn the service on. Fetchmail relies on a mail transfer agent (MTA) to deliver mail to local users.
Because my ISP requires that all connections to the Internet be live, with real activity, I have to limit the polling of Fetchmail to a reasonable time--otherwise, I'll be on-line all night long! To do this, I created a simple shell script to start Fetchmail. This script has the added bonus of allowing the user to perform more extensive work around or with Fetchmail in the future. Note that all actions beyond this point should be performed as the normal user who will use fetchmail (in my case, I was logged in as cjones).
First, I created a script called
/home/cjones/runfetchmail
and made it executable (chmod u+x).
The script, at this point, contains two lines:
#!/bin/sh /usr/local/bin/fetchmail
Fetchmail uses the name of the user running it to retrieve the
.fetchmailrc
from his home directory when
starting. You can test this shell script by entering
~/runfetchmail
Next, I created a simple shell script to stop fetchmail automatically,
/home/cjones/stopfetchmail
. Its two lines look like:
#!/bin/sh kill `cat ~/.fetchmail.pid`
Fetchmail is kind enough to record
its process id in my home directory and shuts down gracefully when given a
SIGTERM. Again, this script can be tested with the command
~/stopfetchmail
.
Finally, I created cron jobs to automatically start Fetchmail in the morning
and stop it when I should be going to bed. I created a crontab file in my
home directory (/home/cjones/.crontab
) and entered the
following lines:
# personal crontab SHELL=/bin/sh MAILTO=cjones # run at 8am weekdays 0 8 * * 1-5 /home/cjones/runfetchmail # run at 6am weekends 0 6 * * 0,7 /home/cjones/runfetchmail # run everyday at 11pm 0 23 * * * /home/cjones/stopfetchmail
I then registered the crontab with the cron process via the command
crontab ~/.crontab
. To verify that the crontab was entered
correctly, I entered the command crontab -l
and saw my
cron schedule.
I was now set to start fetchmail (manually, since it wasn't 8 am anymore). I'm pleased to report that my mail is delivered without a hitch.
I chose the MUTT mail user agent (MUA)
because it is very customizable, works well in terminal mode, and has the
right ethic. (I had been pointed to it by a review in 32-Bits Online.) It works without
any special .muttrc
files and a version without a serious
security hole comes with RedHat 5.2. The best of all worlds!
I'm including a copy of my /home/cjones/.muttrc
file here so
you can avoid some pitfalls I ran into. Note that one majordomo listserv I
have attempted to use queries my server for my servername and ignores the
name I specify, so all the wrinkles haven't been ironed out yet. Note that I
have two additional include files for my .muttrc that I'm not putting
on-line. Read the MUTT Manual
to get an idea of what is going on inside these files.
# mail aliases source ~/.mail_aliases set alias_file=~/.mail_aliases # set user name set realname='Chris Jones' # set hostname set hostname=one.net # edit headers as part of message set edit_hdrs # editor--if I get sick of vi #set editor=/usr/bin/joe # default mailbox (for compatibility with elm) set mbox=received # copy all messages to sent mbox set record=~/Mail/sent # unless a mailbox is defined for that recipient, then save there set save_name # not using fcc-hook yet... # mailing lists source ~/.mailing_lists
You can find better, more customized examples from the MUTT homepage.
To fix the problem with your mail address not being recognized as what you
specify, you need to tell sendmail
to masquerade your hostname.
I did that this way:
/etc/sendmail.cf
to /usr/local/etc
and
setting a symbolic link back to /etc/sendmail.cf
less
to search for the string DM
(enter
/DM when paging with less
)vi
editor when you find a line that has
DM
by itself, and a line above mentioning masqueradingDM
line and then hit
a
(append) to add your mail domain name (mine is
one.net
to
that line. No spaces. Hit
followed by :wq
to
save your changes.q
uit less
and restart sendmail with
/etc/rc.d/init.d/sendmail restart
As noted above, the default firewall design listed above includes IP masquerading, but in an insecure way. The challenge is to provide good security, while allowing my home network of Windows boxes to access the Internet as transparently as the insecure method.
A great resource for Linux Kernels of the 2.0 vintage is XOS paper of Linux firewalls. These instructions are exceptionally clear and great for a permanent, small office connection to the Internet. They're not quite what I need, though. Another good source is the IP Masquerading HOWTO.
My ISP doesn't like keep-alive programs. Fetchmail, by itself, won't keep my connection up. The best option I have is to have my wife browse the web while I'm at work.
Out of the box, however, diald has some really short timeouts for
connections to your ISP. I increased the timeouts so that idle times will be
just short of those used by my ISP. I changed a few key lines in my
/usr/lib/diald/standard.filter
file. I'm including the
surrounding comment block so that it's easier to find my changes, which
consist of commenting out the original line, and replacing it with my
version.
# make sure http transfers hold the link for 2 minutes, even after they end. # NOTE: Your /etc/services may not define the tcp service www, in which # case you should comment out the following two lines or get a more # up to date /etc/services file. See the FAQ for information on obtaining # a new /etc/services file. #accept tcp 120 tcp.dest=tcp.www #accept tcp 120 tcp.source=tcp.www accept tcp 1200 tcp.dest=tcp.www accept tcp 1200 tcp.source=tcp.www ... # an ftp-data or ftp connection can be expected to show reasonably frequent # traffic. #accept tcp 120 tcp.dest=tcp.ftp #accept tcp 120 tcp.source=tcp.ftp accept tcp 300 tcp.dest=tcp.ftp accept tcp 300 tcp.source=tcp.ftp ... # If we don't catch it above, give the link 10 minutes up time. #accept tcp 600 any accept tcp 1200 any
/etc/rc.d/init.d/xntpd
, which can be used to start and stop the
daemon. To make this run during hours you expect the server to be on-line,
add these lines to your /etc/crontab
, then re-read your
crontab
file with crontab /etc/crontab
:
# run xntpd when expected to be on-line 05 8 * * * '/etc/rc.d/init.d/xntpd start' 55 21 * * * '/etc/rc.d/init.d/xntpd stop'
By default, NTP won't cause diald to bring up a link (see
/usr/lib/diald/standard.filter
). These crontab entries are more
a courtesy than anything else.
I read the man page for pppd
and learned how to execute scripts
after it has finished running. First, I created an
/etc/ppp/ipup.local
file, called by
/etc/ppp/ipup
, which is called by pppd
immediately
after a successful login and negotiation of IP addresses. On my RedHat 5.2
system, /etc/ppp/ipup
sets the default route and expects local
changes to be found in ipup.local
. The
ipup.local
file is very simple:
# local ipup file # params: interface-name tty-device speed local-IP-address remote-IP-address ipparam # LOCALIP=$4 # pass the PPP IP to a file echo $LOCALIP > /usr/local/etc/ppp/ip.data # upload the IP data file to a webserver /usr/local/etc/ppp/registerip.sh
I added two additional files, recordip
which is an expect
script that connects to my ISP's ftp server, and registerip.sh
which sets up the environment for recordip
and captures
STDIO
and STDERR
to an ftp.log
file.
/usr/local/etc/ppp/recordip
connects to the ftp server and
uploads the ip.data
file for the web. It looks like:
#!/usr/bin/expect -f # -d > /usr/local/etc/ppp/ftp.log 2>&1 spawn /usr/bin/ftp ftp.one.net expect "ame" send "ftp-user\n" expect "Password:" send "ftp-password\n" expect ">" send "cd directory\n" expect "250" send "put ip.data\n" expect "226" send "quit\n" expect "221"
/usr/local/etc/ppp/registerip.sh
waits for five seconds to
ensure the link is up, then captures debugging information and execute the
expect script. This shell script looks like:
#!/bin/sh /bin/sleep 5 echo 'cd' >> ftp.log cd /usr/local/etc/ppp echo 'exec ./recordip' >> ftp.log ./recordip >> ftp.log 2>> ftp.log echo 'done ./recordip' >> ftp.log
There are other ways to do this, some of which I considered and tried. I discounted using a Perl script to POST to a CGI script on the webserver because ftp provides better security (imagine doing a simple, unathenticated POST to your ISP--and someone malicious doing that as well). I also toyed with building .netrc files for FTP, but the only one I found that worked well was to use expect scripts. While .netrc with a special user seemed to be the simplest, cleanest implementation, it didn't end up working.
The final step is to create a redirector on the web site. There isn't any
programming involved on my ISP--I was able to build it using a server-side
include (SSI), index.shtml
:
<HTML> <HEAD> <TITLE>Redirector</TITLE> <META HTTP-EQUIV="Refresh" CONTENT="0; URL=http://<!--#include file="ip.data"-->/"> </HEAD> <BODY> Redirecting to <A HREF="http://<!--#include file="ip.data"-->/">http://<!--#include file="ip.data"-->/</A> </BODY>