21.2. 使用用户级PPP

Updated and enhanced by Tom Rhodes. Originally contributed by Brian Somers. With input from Nik Clayton, Dirk Frömberg, and Peter Childs.

21.2.1. 用户级PPP

21.2.1.1. 前提条件

本章假定您具备如下条件:

  • 您有一个ISP提供的用于连接使用PPP的帐号.

  • 您需要一个连接到您的系统并做了正确配置的modem或其它设备,使您能连接到ISP.

  • ISP的拨号号码.

  • 您的登录名称和密码(可能是一般的UNIX风格的登录名和密码对, 也可能是PAP或CHAP登录名和密码对.)

  • 一个或多个域名服务器IP地址. 通常,您会从ISP处得到两个这样的IP地址. 如果您至少得到了一个, 就可以 在文件ppp.conf中加入enable dns命令 使ppp设置域名服务.这个功能取决于ISP对支持DNS协商的具体实现.

下面的信息由您的ISP提供,但不是必需的:

  • ISP的网关IP地址. 网关是您要连接的且要被设为默认路由的主机. 如果您没有这个信息,您可以虚构一个,在连接时ISP的PPP服务器会自动告诉您正确的值.

    这个虚构的IP号被ppp称为 HISADDR.

  • 需要使用的子网掩码.如果ISP没有提供,您可以安全地使用 255.255.255.255.

  • 如果ISP提供了一个静态的IP地址和主机名,可以输入它们.否则,让对方主机指定它 认为合适的IP地址.

如果您不知道这些信息,请与您的ISP联系.

Note: 在这节中,所有作为样例显示的配置文件信息都对行进行了编号. 这些行号只是为了使解释和讨论变得方便,在真实当地用tab键和sp文件中并不存在. 缩进是必需的.

21.2.1.2. 创建PPP设备节点

一般情况下,大多数用户只需要一个tun设备 (/dev/tun0),提及tun0时, 即指tunN,N是您系统中具体的号码.

若的FreeBSD(FreeBSD 4.X 及早前版本)没有启用devfs(5),应当先检查 是否存在tun0设备,如果已经启用了devfs(5),这一步就没必要了 (因为devfs(5)会根据需要创建设备).

为了确保tun0配置正确,最古老的方式是重新创建它. 按照以下步骤可以重新创建设备:

# cd /dev
# sh MAKEDEV tun0

如果您的内核要有16个tunnel设备,您必须创建它们.可以通过执行以下命令完成:

# cd /dev
# sh MAKEDEV tun15

21.2.1.3. PPP自动化配置

ppppppd(PPP的内核级实现) 都使用/etc/ppp目录中的配置文件.用户级PPP的例子能 在/usr/share/examples/ppp/中找到.

配置ppp要求根据您的需要编辑几个文件.编辑哪几个文件取决于您的 IP是静态分配还是动态分配的.

21.2.1.3.1. PPP和静态IP地址

您需要编辑配置文件/etc/ppp/ppp.conf.如下所示.

Note: 以冒号:结尾的行从第一列 (行首)开始, 其它所有的行都要缩进一个空格或制表区间.

1     default:
2       set log Phase Chat LCP IPCP CCP tun command
3       ident user-ppp VERSION (built COMPILATIONDATE)
4       set device /dev/cuaa0
5       set speed 115200
6       set dial "ABORT BUSY ABORT NO\\sCARRIER TIMEOUT 5 \
7                 \"\" AT OK-AT-OK ATE1Q0 OK \\dATDT\\T TIMEOUT 40 CONNECT"
8       set timeout 180
9       enable dns
10
11    provider:
12      set phone "(123) 456 7890"
13      set authname foo
14      set authkey bar
15      set login "TIMEOUT 10 \"\" \"\" gin:--gin: \\U word: \\P col: ppp"
16      set timeout 300
17      set ifaddr x.x.x.x y.y.y.y 255.255.255.255 0.0.0.0
18      add default HISADDR
行1 :

指定默认的项.当PPP运行时这个项中的命令将自动执行.

行2:

启用登录参数.工作正常后,为避免产生过多的日志文件,这行应该简化为:

set log phase tun
.

行 3:

告诉PPP怎样向对方自我标识. 如果在建立或使用连接时遇到任何麻烦,PPP就会向对方主机自我标识.对方主机管理员 在处理这个问题时,这些信息会有用.

行 4:

标明modem要连接的端口号.COM1/dev/cuaa0, COM2/dev/cuaa1.

行 5:

设置连接的速度.如果115200 不能工作,试试 38400.

行6 和7:

拨号字符串. 用户级PPP使用一种与chat(8)程序相似的语法. 请参考联机手册了解这种语言的相关信息.

注意,为了便于阅读此命令进行了换行.任何ppp.conf里的 命令都可以这样做,前提是行的最后一个字符必须是“\”.

行 8:

设置连接的时间间隔.默认是180秒,所以这一行是多余的.

行 9:

告诉PPP向对方主机确认本地域名解析设置.如果您运行了本地的域名服务器,要注释或删除掉这一行.

行 10:

为了可读性的需要设置一个空行.空行会被PPP忽略.

行 11:

为“provider”指定一个项.可以改成 ISP的名字.这样您以后就可以使用load ISP 开启连接.

行 12:

设置提供商的电话号码. 多个电话号码可以使用冒号(:) 或管道符号(|)隔开.这两个字符的区别在ppp(8)的联机手册中有介绍. 总的来讲,如果您要循环使用这些号码,可以使用冒号.如果您想使用第一个号码, 当第一个号码失败了再用第二个号码,就使用管道符号.正如显示的那样,要用括号将号码集括起来.

如果电话号码里有空格,必须用引号(")将其括起来. 否则会造成简单却难以察觉的错误.

行13和14:

指定用户名和密码.当使用一个UNIX®风格的命令提示符登录时,这些值可以用带有\U \P参数 的set login命令进行修改.当使用PAP或CHAP进行连接时, 这些值在验证使用.

行 15:

如果您使用的是PAP或者CHAP,在这里就不会有登录.要注释或删除掉这一行. 请参考 PAP和CHAP认证 以获取更多细节.

登录命令是的语法是chat类型的.在这个例子中,是这样的:

J. Random Provider
login: foo
password: bar
protocol: ppp

您需要改变这个脚本以适合您自己的需要.当您第一次写这个脚本时, 应当确保已经启用“chat”并处于登录状态,这样您才能确认通信是否 正在按计划进行.

行16:

设置默认的超时时间.这里,连接若在300秒内无响应将被断开.如果您不想设置成超时, 将这个值设置成0,或在命令行使用-ddial选项.

行 17:

设置接口地址. 字符串 x.x.x.x需要用ISP提供给您的IP地址替换. 字符串 y.y.y.y要用ISP的网关IP地址替换(即您要连接的主机). 如果ISP没有给您网关地址,可以使用10.0.0.2/0. 如果您需要使用一个“猜到”的地址,请确保在/etc/ppp/ppp.linkup 中为每个PPP和动态IP地址指令创建了项. 如果没有这一行,ppp 将无法运行-auto模式.

第18行:

添加一个到ISP网关的默认路由。 HISADDR这个关键字会被第17行所指定的网关地址替换。 这行必须出现在第17行之后,以免在 HISADDR 初始化之前使用它的值。

如果您不想使用 -auto 的 PPP,则这行应挪到, ppp.linkup 文件中。

若您有一个静态IP地址,且使用-auto 模式运行ppp(因为在连接之前已经正确设置了路由表项),那就不需要再向ppp.linkup 添加项.您可能希望在连接以后创建一个项来调用程序.这在以后的sendmail的例子中会解释. .

示例配置文件可以在目录/usr/share/examples/ppp/中找到.

21.2.1.3.2. PPP和动态IP地址

如果ISP没给您指定静态的IP地址,ppp要被配置成能够与对方协商确定本地和远程地址. 要完成这项工作,先要“猜”一个IP地址,然后允许 ppp在连接后使用IP配置协议(IPCP)进行正确配置. ppp.conf的配置是与 PPP和静态IP地址一样的,除了以下的改变:

17      set ifaddr 10.0.0.1/0 10.0.0.2/0 255.255.255.255

再次强调,不要包括行号,它只是一个引用标记.缩排一个空格是必须的.

行17:

/字符以后是PPP所要求的地址位码. 您可以根据需要使用不同IP号码,但以上的例子永远是可行的.

最后的参数(0.0.0.0)告诉 PPP从0.0.0.0 而不是 10.0.0.1 开始协商地址,对于有些ISP, 这是必需的.不要将 0.0.0.0 作为 set ifaddr的第一个参数,因为这使得PPP在 -auto 模式时不能设置初始路由.

如果您不运行-auto模式, 就需要在/etc/ppp/ppp.linkup中创建一个项. 连接建立之后,ppp.linkup被启用. 这时候, ppp将指派接口地址,接着再添加路由表项:

1     provider:
2        add default HISADDR
Line 1:

为了建立连接, ppp 会按按照如下规则在 ppp.linkup寻找项:首先,试图寻找相同的标签 (如同在ppp.conf一样).如果失败了,寻找作为网关 IP地址的项,此项是四个八位字节的风格.如果依旧没有找到,就寻找MYADDR

行 2:

这行告诉 ppp添加指向 HISADDR的默认路由. HISADDR由通过IPCP协商得到的IP号替换.

参考/usr/share/examples/ppp/ppp.conf.sample/usr/share/examples/ppp/ppp.linkup.sample 中的pmdemand项以获取细节化的例子.

21.2.1.3.3. 接收拨入

当要配置 ppp接受来自LAN上的 拨入时,您需要决定是否将包转给LAN.如果是的话,您就必须从LAN子网中 给对方分配一个IP, 需要在文件/etc/ppp/ppp.conf 中使用命令enable proxy .您还应该确定文件 /etc/rc.conf中包含以下内容:

gateway_enable="YES"

21.2.1.3.4. 使用哪个ggtty?

配置FreeBSD的拨号服务描述了怎么使用命令 getty(8)启动拨号服务.

除了getty 还有 mgetty, 它是getty的智能版本,是按照拨号线的思想设计的.

使用mgetty的好处是它能积极地与modems进行 talks , 这就意味着如果在/etc/ttys中的端口被关闭, 您的moderm就不会回应拨入.

最新版本的mgetty (from 0.99beta onwards)也支持自动侦测PPP数据流,允许客户端不使用脚本就可以访问服务器 .

参考Mgetty 和 AutoPPP的联机手册了解更多信息.

21.2.1.3.5. PPP 权限

ppp命令通常必须作为root用户运行. 但如果想让一个普通用户将ppp运行于服务器模式(就像下面描述的那样) ,您必须要把此用户加入network组以使其获得运行 ppp 的权限.

您还需要使用allow命令使用户能访问配置文 件的一个或多个部分:

allow users fred mary

如果这个命令被用在 default 部分中,您可以让指定的用户访问任何东西.

21.2.1.3.6. 动态IP用户的PPP Shell

创建一个名为/etc/ppp/ppp-shell文件,加入以下内容:

#!/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

这个脚本要有可执行属性. 然后通过如下命令创建一个指向此脚本且名为 ppp-dialup的符号链接:

# ln -s ppp-shell /etc/ppp/ppp-dialup

您应该将这个脚本作为所有拨入用户的shell. 以下是在文件/etc/password中关于一个PPP用户的例子,用户名为 pchilds (切记不要直接修改这个密码文件, 而是使用vipw命令).

pchilds:*:1011:300:Peter Childs PPP:/home/ppp:/etc/ppp/ppp-dialup

创建一个名为 /home/ppp的目录作为拨入用户的主目录, 包含以下这些空文件:

-r--r--r--   1 root     wheel           0 May 27 02:23 .hushlogin
-r--r--r--   1 root     wheel           0 May 27 02:22 .rhosts

这样就可以防止/etc/motd被显示出来.

21.2.1.3.7. 静态IP用户的Shell

像上面那样创建ppp-shell文件, 为每个静态分配IP用户创建一个到 ppp-shell的 符号链接.

例如,如果您有三个拨号用户, fred,sam,和 mary,您为他们路由C类网络,您需要键入以下内容:

# ln -s /etc/ppp/ppp-shell /etc/ppp/ppp-fred
# ln -s /etc/ppp/ppp-shell /etc/ppp/ppp-sam
# ln -s /etc/ppp/ppp-shell /etc/ppp/ppp-mary

每个用户的Shell必须被设成一个符号链接(例如用户 mary的Shell应该是/etc/ppp/ppp-mary).

21.2.1.3.8. 为动态IP用户设置ppp.conf

/etc/ppp/ppp.conf文件应该包含下面 这些行:

default:
  set debug phase lcp chat
  set timeout 0

ttyd0:
  set ifaddr 203.14.100.1 203.14.100.20 255.255.255.255
  enable proxy

ttyd1:
  set ifaddr 203.14.100.1 203.14.100.21 255.255.255.255
  enable proxy

Note: 缩进得必须的.

default:项在每次会话时都会加载.每个在 /etc/ttys中启用的行都必须为其创建一个相似于 ttyd0: 的项.每一行应该从动态IP 地址池中取得 唯一的IP地址.

21.2.1.3.9. 为静态IP用户配置ppp.conf

根据上面/usr/share/examples/ppp/ppp.conf文件的内容, 您必须为每个静态拨号用户添加一个项.我们继续以fred, sam, 和mary为例.

fred:
  set ifaddr 203.14.100.1 203.14.101.1 255.255.255.255

sam:
  set ifaddr 203.14.100.1 203.14.102.1 255.255.255.255

mary:
  set ifaddr 203.14.100.1 203.14.103.1 255.255.255.255

如果需要,/etc/ppp/ppp.linkup 也应该包括每个静态IP用户的的路由信息.下面这一行为客户连接添加了 203.14.101.0C类路由.

fred:
  add 203.14.101.0 netmask 255.255.255.0 HISADDR

sam:
  add 203.14.102.0 netmask 255.255.255.0 HISADDR

mary:
  add 203.14.103.0 netmask 255.255.255.0 HISADDR

21.2.1.3.10. mgetty和AutoPPP

在配置和编译mgetty 时启用 AUTO_PPP选项 使mgetty能够探测PPP连接的的LCP状态 并自动产生PPP Shell. 但如果默认的login/password队列没有出现, 那就必须使用PAP或CHAP来验证用户.

这节假定您已经为用户成功地配置,编译了带有AUTO_PPP选项的 mgetty.

确认钅件/usr/local/etc/mgetty+sendfax/login.config 包含以下内容:

/AutoPPP/ -     -            /etc/ppp/ppp-pap-dialup

这行告诉mgetty运行 ppp-pap-dialup脚本来侦听PPP连接.

创建/etc/ppp/ppp-pap-dialup文件写入以下内容 (此文件应该是可执行的):

#!/bin/sh
exec /usr/sbin/ppp -direct pap$IDENT

对应于每个在/etc/ttys的启用行,都要在/etc/ppp/ppp.conf 中创建相应的项. 这和上面的定义是相同的.

pap:
  enable pap
  set ifaddr 203.14.100.1 203.14.100.20-203.14.100.40
  enable proxy

每个通过这种方式登录的用户必须在 /etc/ppp/ppp.secret文件中有一个username/password项,或者加入 以下选项以使服务器通过PAP方式用/etc/password文件验证用户.

enable passwdauth

如果您想为某些用户分配静态IP, 可以在/etc/ppp/ppp.secret中将IP号作为第三个参数指定. 参看 /usr/share/examples/ppp/ppp.secret.sample 中的例子.

21.2.1.3.11. MS Extensions

可以配置PPP以提供DNS和NetBIOS域名服务器地址.

要在PPP版本 1.x中启用这些扩展,必须向 /etc/ppp/ppp.conf的相关项加入以下行:

enable msext
set ns 203.14.100.1 203.14.100.2
set nbns 203.14.100.5

PPP版本2及以上 :

accept dns
set dns 203.14.100.1 203.14.100.2
set nbns 203.14.100.5

这将告诉客户端首选域名服务器和备用域名服务器.

在版本2及以上版本中, 如果省略了 set dns, PPP会使用 /etc/resolv.conf中的值.

21.2.1.3.12. PAP 和CHAP验证

一些ISP将系统设置成使用PAP或CHAP机制来完成连接的验证部分. . 如果是这样,在您连接时ISP就不会给出login:提示符而是立即开始PPP对话.

PAP安全性要比CHAP差一些,但在这里安全性并不是问题,因为密码(即使用明文传送)只是通过串行线传送. 黑客没有太多机会“窃听”.

参考PPP 和静态IP地址PPP 和动态IP地址 节,必须做以下修改:

13      set authname MyUserName
14      set authkey MyPassword
15      set login
第 13 行:

这一行指明您的PAP/CHAP用户名. 您需要为MyUserName输入正确的值.

第 14 行:

这一行指明您的 PAP/CHAP password密码。 您需要为 MyPassword 输入正确的值。 另外,您可能希望加入一些额外的选项,例如:

16      accept PAP

16      accept CHAP

以明确您的意图,但PAP和CHAP都是被默认接受的.

Line 15:

Your ISP will not normally require that you log into the server if you are using PAP or CHAP. You must therefore disable your “set login” string.

21.2.1.3.13. 即时改变您的ppp 配置

与后台运行的ppp程序进行对话是可能的, 前提是设置了一个合适的诊断端口. 做到这一点,需要把下面的行加入到您的配置中:

set server /var/run/ppp-tun%d DiagnosticPassword 0177

这行告诉 PPP在指定的UNIX域socket中侦听,当用户连接时需要给出指定的密码. %dtun设备号替换.

一旦启用了socket, 就可以在脚本中调用程序pppctl(8)来处理正在运行的 的PPP.

21.2.1.4. 使用PPP网络地址翻译

PPP可以使用内建的NAT,而不需内核支持. 这个功能可以通过在/etc/ppp/ppp.conf中的 以下行启用:

nat enable yes

PPP NAT也可以使用命令行选项 -nat启动. 在文件 /etc/rc.conf中也有 ppp_nat项,且是默认启用的.

如果您使用了这个特性, 您还会发现在 /etc/ppp/ppp.conf中以下 选项对于启用incoming connections forwarding是有用的:

nat port tcp 10.0.0.2:ftp ftp
nat port tcp 10.0.0.2:http http

or do not trust the outside at all

nat deny_incoming yes

21.2.1.5. 最后的系统配置

现在您已配置了ppp,但在真正工作之前还有一些事情要做.它们都与编辑 /etc/rc.conf有关.

从上依次往下看,确认设置了 hostname= 行, e.g.:

hostname="foo.example.com"

如果您的ISP提供给您一个静态的IP和名字,将这个名字设为hostname是最合适的.

寻找 network_interfaces 变量. 如果要配置系统通过拨号连入ISP, 一定要将tun0设备加入这个列表,否则就删除它.

network_interfaces="lo0 tun0"
ifconfig_tun0=

Note: ifconfig_tun0变量应该是空的,且要创建一个名为 /etc/start_if.tun0的文件. 这个文件应该包含这一行:

ppp -auto mysystem

此脚本在网络配置时被执行,开启PPP守护进程进入自动模式.如果这台机子充当一个LAN的网关, 您可能希望使用-alias.参考相关联机手册了解更多细节.

/etc/rc.conf用下面这一行把路由程序设为NO:

router_enable="NO"

这很重要,如果您没有启动 routed 服务的话(这是默认情况), 因为 routed 总是会删掉 ppp 所建立的默认路由。

此外,可能还应该确认一下 sendmail_flags 中不包括 -q 这个选项,否则 sendmail 会不断地尝试做网络连接,这可能会导致您的机器不停地进行拨号。 可以试试看:

sendmail_flags="-bd"

替代的作法是当每次PPP连接建立时您必须通过键入以下命令强制 sendmail重新检查邮件队列:

# /usr/sbin/sendmail -q

您也可以在ppp.linkup使用!bg命令自动完成这些工作:

1     provider:
2       delete ALL
3       add 0 0 HISADDR
4       !bg sendmail -bd -q30m

如果您不喜欢这样做, 可以设立一个 “dfilter” 以阻止 SMTP传输.参考相关文件了解更多细节 .

现在您唯一要做的事是重新启动计算机。 重起之后,可以输入:

# ppp

然后是dial provider以开启 PPP会话. 或者如果您想让ppp自动建立会话 ,因为您有一个广域连接(且没有创建 start_if.tun0 脚本),键入:

# ppp -auto provider

21.2.1.6. 总结

当第一次设置PPP时,下面几步是必须的:

客户端:

  1. 确保 tun编译进了进核.

  2. 确保tunN 设备文件在 /dev 目录中是可用的.

  3. /etc/ppp/ppp.conf中创建一个项. pmdemand示例应该适合于绝大多数ISP.

  4. 如果您使用动态IP地址,在/etc/ppp/ppp.linkup创建一个项.

  5. 更新/etc/rc.conf 文件.

  6. 如果您要求按需拨号,创建一个start_if.tun0脚本.

服务器端:

  1. 确保tun设备已编译入内核.

  2. 确保tunN设备文件在 /dev目录中是可用的.

  3. /etc/passwd中创建一个项 (使用vipw(8)程序).

  4. 在用户的home目录创建一个运行 ppp -direct direct-server或相似命令的profile.

  5. /etc/ppp/ppp.conf中创建一个项. direct-server示例应该能满足要求.

  6. /etc/ppp/ppp.linkup中创建一个项.

  7. 更新 /etc/rc.conf 文件.