-- Status: Done; please make comments; added rc.conf step (stupid me forgot)
--Don't expect the getty related portions of this HOWTO to work perfectly. Use mgetty. --
I recently succeeded in creating a FreeBSD dialin server, which allows remote users to establish a ppp connection through a phone line, aquire an IP address on my LAN, and browse the internet or whatever with my cable connection.
The final result I arrived at after much trial and error is really no different than the setup shown in various other HowTos and the Handbook (see links below), and once I actually did it, it seemed very simple. However, throughout the process, I really had no idea what was going on. I hope this guide is useful to people like me who were born into the world of cable, with no idea how modems work, or how ppp works.
This howto will show you how to configure your FreeBSD server to provide PPP access to remote FreeBSD terminals and Windows terminals using PPP only; I haven't successfully gotten getty to do authentication. Hopefully I will be able to add more methods after I have gotten then to work.
STEP 1 -- Getting and Testing a Modem
Your best bet is a serial hardware modem. I have seen these as cheap as $70, and you shouldn't have to spend more than $160 to get a nice 56Kbps. I have a USR V.Everything Courier (about $120) which is loaded with features and works perfectly with FreeBSD. You may be able to get a WinModem (generally PCI) to work using the ltmdm port (/usr/ports/comms/ltmdm) but I wouldn't put too much stock in them. Kindly post which modems you use with FreeBSD along with an estimated retail price - this will help others.
A little info on modems: WinModems are generally PCI, and come packaged with drivers which work only with Windows. Modems do a lot of work, and it is cheaper to build a modem where the OS does most of the work (e.g. a Windows machine with a 333mHz or greater processor) rather than one that does all the work itself. Most modems cheaper than $40 are PCI WinModems.
If your modem has DIP switches (like mine) you might as well set them for server mode now. Settings with a * you should do. Settings with a - are optional:
- DTR (data terminal ready) always on
* Verbal code results
- Display code results
* No echo offline commands
- Suppress auto answer
- Normal carrier detect
* Enable AT command set
I didn't include some settings which I felt were less important. These settings probably aren't critical since getty/mgetty can set them with their chat features.
Make sure everything is plugged in and powered on and begin testing.
See the handbook on setting up you kernel for FreeBSD. It is straightforward, and chances are you won't need to change anything.
Enter the ppp(8) program as root (or as a regular user added to the network group), set which device you will be using, and go into terminal (chat) mode by typing term.
code:%ppp
Working in interactive mode
Using interface: tun0
ppp ON englanderm> set device /dev/cuaaN
ppp ON englanderm> term
deflink: Entering terminal mode on /dev/cuaaN
Type '~?' for help
AT
OK
If nothing happens, there are a few possible causes:
1. You have (I did suggest one of these) set your modems DIP switches to prevent command echo and modem response.
2. You are using the wrong device. Use set device /dev/cuaaN in ppp(8) to change.
3. Your modem isn't set up properly.
If you think #1 is the cause, this is easy to fix. Back in terminal mode, issue the following (an OK is the modem's response to a successful offline command). You won't see what you are typing appear on the screen at first if you have command echo set to off.
code:ATE1 you probably won't see this
ATQ0
OK
ATZ
Issuing ATZ will reset your modem to its original configuration, plus whatever DIP switch settings you have.
STEP 2 -- Choosing and using a getty
A getty's job is to listen on a terminal (tty) for connections (serial, console, X, etc.) and figure out what to do with them. Mgetty (available in /usr/ports/comms/mgetty+sendfax) is specially designed to handle serial and ppp connections, with more intelligent modem handling than regular getty.
Getty -
According to some sources, all you should have to do to use this is edit /etc/tty (see below for more details) and turn on one of the dialup entries. This would allow remote users to get a pure serial connection (no ppp) and access FreeBSD in a telnet like fashion, getting a login(1) type prompt. I have not successfully done this yet, and ppp is more fun anyway :P.
To get getty to pass authentication to ppp(8), you'll have to create a custom entry in /etc/gettytab. Gettytab(5) defines terminal entries getty can use and how getty should handle connections to them, a-la termcap(5).
ppp.57600 is simply the entry name we will use in the /etc/ttys file. You can name it whatever you want, but it might as well reflect its characteristics. The ppp part shows that it is going to pass authentication to PPP, while 57600 represents the speed of the modem.A couple notes on some of the settings:
code::pl
Forces getty to pass authentication to the PPP program, regardless of whether the remote user is using PPP.
code::pp=
The name of the PPP program getty should use. Normally it would authenticate with login(1). The program we will use is simply a shell script from the FreeBSD handbook.
Mgetty -
There are only two things you need to do to install Mgetty. The first is simply to install it :P from ports and enter the settings it asks of you. The default settings are fine, really, and you shouldn't mess with anything you don't understand. You can always change these later in /usr/local/etc/mgetty+sendfax/mgetty.config. Just make sure to set your modem's maximum speed. The other thing you need to do is configure what login program mgetty should use. The ppp-dialup script from the handbook is fine for this. Make sure the following is the only thing uncommented in /usr/local/etc/mgetty+sendfax/login.config .
code:/AutoPPP/ - - /etc/ppp/ppp-dialup
STEP 3 -- The ppp-dialup script
code:#!/bin/sh
IDENT=`echo $0 | sed -e 's/^.*-\(.*\)$/\1/'`
CALLEDAS="$IDENT"
TTY=`tty`
if [ x$IDENT = xdialup ]; then
IDENT=`basename $TTY`
fi
echo "PPP for $CALLEDAS on $TTY"
echo "Starting PPP for $IDENT"
exec /usr/sbin/ppp -direct $IDENT
This is available in the links below, and the handbook, so I won't bother going over it in detail. Basically it finds what tty the remote user is connected to, and runs PPP for that user. The -direct $IDENT part simply tells PPP to use the settings/commands under the label in ppp.conf which matches $IDENT. This script is pretty much fail-proof, so just make sure it is in the right location ( /etc/ppp/ ) and chmod 0755 it.
STEP 4 -- Setting up ppp.conf
When ppp-dialup runs, it tells ppp(8) to run the commands under the $IDENT label. The label names in this HowTo are either ttydN or cuaaN. Getty(8) listens for connections on the former, while mgetty listens for them on the latter. You can begin to see the overall plan:
Mgetty gets a connection on /dev/cuaa0 and passes it on to the ppp-dialup script.
Ppp-dialup finds what tty (cuaa0) the remote user is connected to and starts ppp with the settings listed under the cuaa0: label in/etc/ppp/ppp.conf.
Ppp.conf should already have some default settings. The only thing you may need to change (under the default label)is the set device command, but probably not.
Here is my setup for a ppp(8) connection through getty. Note: indentation is important:
code:ttyd0:
set log phase chat connect lcp ipcp command
enable chap80 chap81 chap pap passwdauth
disable ipv6cp
enable proxy
set ifaddr 192.168.1.201 192.168.1.203 255.255.255.0
allow users englanderm neon-taegu
accept dns
set dns 192.168.1.1
ttyd0: is the label for the server entry. Everthing after must be indented.
set log ... will make /var/log/ppp.log pretty verbose. See the ppp(8) man for specifics on each.
enable ... tells ppp(8) what type authentication protocols to expectand allow. Chap80/81 are Microsoft's versions of the Challenge Handshake Authentication Protocol. Chap is regular. Pap is the clear-text Password Authentication Protocol. Passwdauth allows ppp(8) to match passwords against /etc/passwd. This will only work with PAP, however.
disable ipv6cp keeps ppp(8) from trying to establish an IPv6 connection. I would like to try this at some point, and there is no need to set this. I just do it to keep my log file clean.
enable proxy tells ppp(8) to proxy ARP for the remote user.
set ifaddr ... is the routing scheme for ppp(8) to follow. This needs to conform to your LAN (you will need a router, be it your FreeBSD box, Linksys hub, whatever). The first IP is the number to be assigned to the remote user. The second is the number to tell the user to set as his default gateway. You should set this to the IP address of the box your modem is connected to. The third is simply the netmask.
allow users ... specifies which users are allowed access to the section the command appears in. Make sure these users are also part of the network group.
accept dns enables DNS negotiation. Probably superfluous in this case.
set dns sets the IP of the machine that will handle DNS. In my case, I set it to the IP of my Linksys router, since it is capable of that.
My setup for mgetty(8) is EXACTLY the same except that I have the label as cuaa0: instead of ttyd0:. I only have either mgetty or getty handling incoming calls, but never both at once, so I don't have to worry about conflicting IP addresses. I also only have one remote dialin user, so I don't have to worry about dynamic IP addresses and the like.
STEP 5 -- Setting up ppp.secret
This file, located in /etc/ppp/ is used to check the user name and password given by incoming ppp connections. Here is the format with examples:
The first two users are set up for pap and chap. The format for the different authentication protocols are the same and can go in the same file. The third user, however, has a * for his password, indicating that ppp(8) should authenticate him against the /etc/passwd database. This will only work with pap, and passwdauth must be enabled in the server section of ppp.conf.
STEP 6 -- Setting up ttys
/etc/ttys Sets what ttys to make available for connection. For getty(8), the entry can be as simple as follows:
code:ttyd0 "/usr/libexec/getty ppp.57600" dialup on insecure
mgetty(8) will create it's own entry at the bottom of the file upon installation. Just make sure
the name (cuaaN is correct.
code:cuaa0 "/usr/local/sbin/mgetty" dialup on insecure
I would recommend having only the mgetty(8) one on. It is most likely to work. I happen to like getty, that is why I included it in here.
STEP 7 -- Final steps and overview
Restart init(8) (renewing which terminals it listens to) with
code:
kill -HUP 1
Don't forget the -HUP!. Do this everytime you make a change to gettytab or ttys.
If the PPP(8) server is going to be relaying packets between the remote end and a router machine, you need to let FreeBSD know that you are going to be acting as a gateway - add the following to /etc/rc.conf
code:gateway_enable="YES"
If you don't want to have this as a permanent setting or don't want to reboot before trying out your server, enable the following:
code:sysctl net.inet.ip.forwarding=1
Here is an overview of what needs to be done
Configure and set up your modem; find out what COM number it is.
Choose a getty, set it up to pass authentication to ppp(8).
Create a ppp script which will find the user's tty and run ppp using the settings in ppp.conf under the label matching that tty.
Set up ppp.conf to proxy for the user, and assign the user and IP address. Create labels like ttydN and cuaaN, depending on which getty you chose.
Set up the password file ppp will use (/etc/ppp/ppp.secret).
Set up the terminals' info (name, command, on or off) in the ttys file (/etc/ttys).
Edit rc.conf and kill -HUP 1
RESOURCES --
The Handbook. Read the sections on serial communications and PPP (user).