第二四章 PPP服务器

因为我们已经讲过如何用 linux 做 ppp 客户,所以这一节我们用 Windows 做客户来配合讲述 linux 的服务器,因为毕竟 Windows 做客户还是多数嘛。

24.1 设置基本的拨号服务器

24.2 回拨( callback )

24.3 小结

24.1 设置基本的拨号服务器

  在这一节里,我们一步一步的建立拨号服务器,力求做到条理清楚。做拨号服务器的方法很多,这里讲的只是其中一种方法而已。

  我们首先要确保 linux 的内核支持 ppp ,并且支持 IP 转发( IP forwording ),这个功能让你通过 linux 拨号服务器访问局域网上其他的机器,进而访问 Internet ,而不只是拨号服务器本身。幸好现在的 linux 发布版本所带的内核都支持这些功能,如果你使用自己编译的内核,你就要注意这个问题了。

  在内核支持 IP 转发之后,还要激活 IP 转发这个功能。使用如下命令:
echo "1">/proc/sys/net/ipv4/ip_forward

  如果使用 RedHat ,可以将 /etc/sysconfig/network 文件里的 FORWARD_IPV4=false 改成 true 就行了。之后需要重启动以激活 IP 转发。

  使 linux 能够接受电话拨入

  要实现这个功能,要用到一个叫 getty 的程序,它的功能就是向用户显示 login: 和 password: 这样的登录提示,并调用 login 程序实现登录。我们平时在局域网里用 telnet 登录某台 unix 主机时,也是这个过程。只不过现在我们走的物理线路不同,我们走的是电话线,telnet 程序走的是网线和网卡。

  目前 linux 上有三种 getty : getty_ps , agetty , mgetty 。 getty_ps 就是所说的 getty ,另外两种也都实现了 getty 的功能。其中 mgetty 的功能比较强大,我们决定就用 mgetty 了。 RedHat6 包含了 mgetty 的四个软件包, mgetty-1.1.14-8.i386.rpm 是必须安装的,如果你要用回拨功能,就要安装 mgetty-sendfax-1.1.14-8.i386.rpm , callback 程序包含在这个包里(不明白为什么在这个包里)。我反正不管那么多, rpm -Uvh mgetty* ,全安装上算了。

  我们现在要做的就是使 modem 所接的那个串口可以接受外来连接。打开 /etc/inittab, 你会看到这样的几行:

# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6

  在这几行之后,加上如下一行:
7:2345:respawn:/sbin/mgetty ttyS1

  它的意思就是让 mgetty 在串口 ttyS1 上监听,等待连接,如果有连接请求, mgetty 就向用户提示用户名和密码。 Mgetty 也有好多参数,预知详情,请看 mgetty 的手册页。注意:程序的名字是 megtty 而不是上面几行写的 mingetty 。 Mingetty 是 RedHat 自己的终端程序,它不支持 modem 连接。改好之后,要使修改有效,运行: init q

  为了从远端登录,我们要有一个账号,用 useradd 命令加一个叫 ppp 的用户,并用 passwd 命令为它设置口令。

  下面我们就用 Windows 的客户来试一试,我们在 Windows 下新建一个连接,电话号码当然要填对,然后右键单击这个连接,依次选择属性 - 〉常规 - 〉设置 - 〉选项,再按两次确定关闭对话框。现在双击这个连接,用户名和密码不用填,直接按拨号,你会听到拨号声和一阵乱叫,接着会弹出一个黑底白字的窗口,这就是登录的终端窗口了!你会看到这与你登录 linux 时是一样的,输入用户名 ppp 和密码,你看到的是 shell 提示符,你通过 modem 登录到 linux 主机上了!但这种终端的形式上网,并不是 ppp 连接,相信你一定不会满意,你需要的是有 WWW , FTP 等丰富功能的网络。我们下面就来看看怎么实现 ppp 连接,现在在 shell 提示符下输入 exit 退出。

  启动 pppd 与客户建立 ppp 连接

  上面一小节已经实现跟 telnet 差不多的终端联网,但还很不够,现在我们要用 pppd 实现端对端的连接,实现真正的联网。

  为了给客户分配 IP 地址,我们要编辑一个新文件: /etc/ppp/options.ttyXX 。文件名中的 ttyXX 就是你所用到的串口设备文件,我的就是 /etc/ppp/options.ttyS1 。在这个文件中给出一个 IP 地址对,就像这样:
10.39.1.1:10.39.1.123

  冒号前面的的拨号服务器的 IP 地址,后面的是要分配给客户的 IP 地址。

  在前面讲述 ppp 客户时我们已经清楚, pppd 程序要在服务器和客户机分别启动,并进行握手,实现连接。客户的 pppd 程序现在是用 Windows 的拨号网络,我们就不管了,服务器端的 pppd 怎么启动呢?诚然,你可以登录后手工输入下面命令来启动 pppd :
pppd debug proxyarp asyncmap 0 lock modem crtscts

  但这似乎太过麻烦,我们需要 pppd 能自动启动,下面就来看看怎么搞!

  打开 /etc/passwd 文件,找到用户 ppp 的哪一行,差不多是这样的:
ppp:x:500:500::/home/ppp: /bin/bash

  你可以看出用户 ppp 使用的 shell 程序是 bash ,我们现在要做的就是用 pppd 换掉这个 bash ,这样当用 ppp 登录时,就不会执行 bash ,而是执行 pppd ,如此, pppd 就在服务器端启动了。

  具体我们可以这样做:在 /etc/ppp 建立一个 ppplogin 文件,内容如下:
#!/bin/sh exec /usr/sbin/pppd debug passive asyncmap 0 proxyarp lock modem crtscts
   pppd 的参数大多都见过,其中 proxyarp 的意思就是让 ppp 客户通过 ppp 服务器访问网上其他机器,而不只是 ppp 服务器一台。将 ppplogin 设成可执行的:
chmod +x ppplogin

  用 ppplogin 替换用户 ppp 的登录 shell ,就像这样: ppp:x:500:500::/home/ppp:/etc/ppp/ppplogin

  由于 pppd 执行必须要 root 权限,还要将 pppd 设成以 root 权限执行:
chmod u+s /usr/sbin/pppd

  替换了登录 shell 和修改 pppd 属性之后,我们来试一试。与上一小节一样的进行拨号,在输入了用户名和密码之后,你是否看到 pppd 所特有垃圾字符?并且一行一行的没完?如果看到的话,恭喜你!服务器端 pppd 已经启动了!你接着点继续按钮,也就是启动客户的 pppd ,与服务器的 pppd 进行握手,一会儿,你就会看到登录网络成功,那个熟悉的绿色小电脑又出现了!你是不是意识到什么?对了!你可以上网了!如果你使用 linux 做客户的话,工作就完成了。但是由于 Windows 的一些特殊要求,我们还要针对 Windows 做一些特殊设置。

  针对 Windows 客户的特殊设置

  前面谈到了 Windows 与 linux 做客户,对域名服务器的要求是不一样的。 Windows 要求域名服务器在连接的时候传给它,这在 linux 拨号服务器上怎么做呢?

  如果你看过 pppd 的手册页,你可能已经看到 pppd 有个参数 ms-dns ,它就是用来传 dns 给客户的。在你的 ppplogin 里加上这个参数就可以了,比如:
#!/bin/sh exec /usr/sbin/pppd debug passive asyncmap 0 proxyarp lock \
modem crtscts ms-dns 10.39.0.133 ms-dns 10.39.1.133

  两个 dns 第一个是主,第二个是辅。

  Mgetty 有几个配置文件在 /etc/mgetty+sendfax ,其中 login.config 是比较重要的。在 login.config 中有下面这样一行:
#/AutoPPP/ - a_ppp /usr/sbin/pppd auth -chap +pap login debug modem crtscts proxyarp lock

  我们把行首的注释 # 去掉就行了。由于拨号连接可以是 ppp 也可以是 slip , Windows 客户与拨号服务器对话的时候,要求自动使用 ppp , Windows 客户向拨号服务器发出某种信号,让拨号服务器自动启动 ppp 。我们这里所做的就是让 mgetty 响应这个信号并启动 pppd 实现 AutoPPP 。我们看到这里的 pppd 程序的参数多了几个: auth -chap +pap login ,我们只要知道这些跟 Windows 的安全认证有关系就行了,具体含义请看 pppd 的手册页。为了支持这几个参数,需要编辑 /etc/ppp/pap-secrets 文件。这个文件是 pap 认证用的,我们不做研究,在里面填上一行最通用的就行了,如果你要对用户进行安全认证,请参阅 pppd 所带的例子和相关的文档。这个文件的内容就像这样:
# Secrets for authentication using PAP
# client server secret IP addresses
* * "" *

现在我们用 Windows 建立一个新的拨号连接,就像连接别的 ISP 一样输入用户名和口令.

24.2 回拨( callback )

Callback 就是当用户拨号连到拨号服务器时,服务器先断掉连接,然后再拨回给用户,用户的 modem 接收这个呼叫,从而建立拨号连接。如此,电话费就是拨号服务器来付了,这样就给所谓摷彝グ旃珨创造了有利条件,你可以在家里用回拨的方式连到公司进行办公,而不必担心电话费了。

  服务器端设置

  在设置之前,你应该确保 mgetty 的 callback 程序安装好了。

  将下面这行内容加到 /etc/mgetty+sendfax/login.config 中:
call_hxf - - /usr/sbin/callback -d -l ttyS1 -s 115200 -S 62345678

  前面的 call_hxf 是指为 mgetty 增加一个叫 call_hxf 的用户入口。这个用户只是 mgetty 用来启动 callback 程序的,不是 linux 系统中的用户,不要真的用 useradd 添加一个 call_hxf 用户,这个 call_hxf 用户名只是 mgetty 用的,不是系统的。当用户通过 modem 连到 linux 上, mgetty 向用户提示输入用户名时,如果输入的是 call_hxf , mgetty 就调用 /usr/sbin/callback 程序来处理回拨。参数 -d 是指在 /var/log/mgetty.ttyS1 留下调试信息, -l ttyS1 是指使用 ttyS1 为拨出设备, -s 115200 是串口速率, -S 62345678 是指定的回拨电话号码,如果没有 -S 参数, mgetty 就会提示你输入回拨的目的电话号码。基于安全的考虑,建议在这里指定回拨的目的号码,不然的话,别人用 call_hxf 登录同样也可以使用回拨了。关于 Callback 的详细信息请察看手册页。

  现在我们来试一试,在 Windows ,还是使用那个拨号连接,当出现终端窗口并提示 login 时,输入 call_hxf ,如果你在 login.config 中没有指定回拨号码,现在就有提示问你回拨的电话号码了,输入现在你使用的号码,此时服务器断开电话准备回拨,但是 Windows 会认为服务器断了,弹出一个对话框告诉你服务器断开连接,请稍候在试。一会儿,你就会惊喜的听到你的电话在震铃,服务器正在回拨,但是 Windows 已经不理会了,看来 Windows 上还要搞一搞才能协调起来。现在你还是把 linux 服务器上的那个 callback 进程 kill 了吧,要不然它会一直播下去的,呵呵。

  客户端设置

  服务器准备回拨的时候要把电话先断掉,我们现在的目的是让 Windows 检测不到这个变化,这样 Windows 就不会退出拨号程序了。我们打开所使用的拨号连接的属性 - 〉常规 - 〉设置 - 〉连接 - 〉高级 - 〉附加设置,将 AT&C 这个命令写在附加设置里。这个命令的意思就是让串口的载波检测( Carrier Detect )那根线保持有效,这样 Windows 就会认为电话一直是通的,服务器回拨时断掉电话 Windows 就检测不出来了,这样 Windows 的拨号客户程序就可以继续与服务器对话并建立连接了。

  下面的工作就是使 Windows 能接听服务器回拨的电话,并通过服务器的用户认证。我们建立一个脚本文件 callback.scp 如下:
proc main
waitfor "ogin: "
transmit "call_hxf^M"
waitfor "number for callback: "
transmit "62345678^M"
waitfor "RING"
transmit "ATA^M"
waitfor "ogin: "
transmit $USERID
transmit "^M"
waitfor "assword: "
transmit $PASSWORD
transmit "^M"
endproc

  我们在所使用的拨号连接的属性 - 〉制作脚本里填上这个文件的全路径和文件名。你需要根据你的情况修改蓝色的地方。

  这个脚本很简单,它由一个一个的 waitfor--transmit 对组成,收到登录提示符 login: ,就发送 callback 的用户名 call_hxf 。(这里 login 没有第一个字母 l ,这是因为字母 l 有可能是大写的 L ,就像这样: Login: ,为了不出错,干脆就不要字母 l 了。同样,下面的 password 也没有字母 p 。)如果在服务器没有指定回拨的电话号码,现在就要问你了,在收到 number for callback: 这样的字符串后,发送自己的电话号码。如果服务器指定了号码,这两行就不要了。当你给了回拨号码后(或服务器已经指定),服务器就挂断电话,进行回拨。客户端的 modem 检测到一个震铃,就向串口发送一个 RING 字符串, Windows 从串口读到这个字符串,就会向 modem 发出 ATA 命令,让 modem 接听这个电话。这样连接就建立了。之后, mgetty 向客户提示输入用户名和密码,这里的 $USERID 和 $PASSWORD ,就是引用你在拨号的那个对话框里填入的用户名和密码。

  现在我们来试一试,这个 ppp 用户的登录 shell 是我们曾经改成 ppplogin 的。连接后你首先听到你的 modem 在拨出,并与服务器对话,一会儿,你就听到你的电话响了起来,这是服务器在回拨,你的 modem 立刻接起这个电话,并与服务器对话,安全认证通过之后,你熟悉的那个绿色小电脑又出现了!你的回拨成功了!在这个过程中, Windows 的拨号程序一直告诉你正在验证用户名和口令,因为它不知道我们在做回拨,所以只好认为是在验证口令了。这个 callback 程序的反应速度不是很快,在服务器断掉电话到你听到回拨的电话铃声,可能要等 20 秒到 30 秒的样子,需要耐心等待。在回拨过程中,你会发现有一个被最小化的终端窗口,它就是你的 callback.scp 脚本文件执行时的窗口,modem 收到一个震铃。

  我们只讲述了 Windows 的客户怎么配置回拨, linux 下不准备说了,但是 linux 的 pppd 软件包还带了几个脚本文件是用来支持回拨的。我们在搞清楚回拨的工作过程之后,参考这些脚本程序,就不难配置 linux 客户的来支持回拨了。

24.3 小结

  至此, linux 拨号服务器以及回拨服务器的配置就讲完了。大概你可能觉得做服务器不如做客户条理清楚,头绪比较繁杂。的确, linux 配置拨号服务器细碎的地方比较多,下面就把服务器的配置过程整理一下:

1.使IP转发有效 echo "1">/proc/sys/net/ipv4/ip_forward,

2. RedHat 可以修改 /etc/sysconfig/network

3.安装 mgetty 。编辑 /etc/inittab 文件,

4. 加入 7:2345:respawn:/sbin/mgetty ttyS1 这一行。 init q 使修改有效。

5.编辑拨号登录文件 ppplogin ,

6. 内容就是执行 pppd 程序。将 ppplogin 设置成可执行 chmod +x ppplogin 。将 pppd 程序设置成以 root 权限执行 chmod u+s /usr/sbin/pppd 。

7.用 useradd 加一个拨号用户,

8. 比如 ppp 。用 passwd 为这个用户设置密码。编辑 /etc/passwd 文件,

9. 修改此用户的登录 shell 为 ppplogin 。

10.为客户分配 IP 地址,

11. 编辑文件: /etc/ppp/options.ttyXX ,

12. 填入 IP 地址对。

13.为支持 AutoPPP ,

14. 修改 /etc/mgetty+sendfax/login.config 文件,

15. 把 AutoPPP 前的 # 去掉。再编辑 /etc/ppp/pap-secrets 文件,

16. 加入一行 * * "" * ,

17. 以支持 AutoPPP 。