18.2. 使用用户级PPP

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

18.2.1. 用户级PPP

18.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文件中并不存在. 缩进是必需的.

18.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

18.2.1.3. PPP自动化配置

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

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

18.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这个特殊的词会被第9行指定的网关地址所替换. 这行出现在第9行之后是非常重要的,否则HISADDR将不能初始化.

如果你不想用-auto选项运行PPP, 这行要被移到ppp.linkup文件.

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

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

18.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项以获取细节化的例子.

18.2.1.3.3. 接收拨入

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

gateway_enable="YES"

18.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的联机手册了解更多信息.

18.2.1.3.5. PPP 权限

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

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

allow users fred mary

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

18.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被显示出来.

18.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).

18.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地址.

18.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

18.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 中的例子.

18.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中的值.

18.2.1.3.12. PAP 和CHAP验证

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

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

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

7       set login
...
12      set authname MyUserName
13      set authkey MyPassword
行 7:

如果使用PAP或CHAP,你的ISP一般不需要你登陆入服务器.因此你必须禁用 ``set login''字串.

行12:

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

行 13:

这一行指明你的PAP/CHAP密码. 你需要为 MyPassword输入正确的值.你也可以加入附加的行 ,比如:

15      accept PAP

15      accept CHAP

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

18.2.1.3.13. 即时改变你的ppp 配置

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

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

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

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

18.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

18.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每次都会对网络进行查询,可能使你的机器dial out. 可以这样试试:

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

18.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 文件.