当前位置:Linux教程 - Linux - 用不同的isp访问internet

用不同的isp访问internet

摘要:
本文介绍如何在linux上配置多个不同的isp,如何容易地在它们之间切换。我们使用的概念不但适合配置一台pc和一个internet联接,也可用来使整个家庭同时上网,为了达到这个目的,我们在linux上配置了一个域名代理和ip欺骗。


介绍
internet访问变得越来越容易,大多数isp除了长期合约和月费外,不会问任何其它的事情。如果一个isp有技术问题,或者提供服务不好,你只需要切换到下一个isp,在德国,我们称之为“internet by call”.并且会更进一步,你不需要注册或者签署任何文件,只需通过你的日常电话费单付账。注意:这跟免费internet访问
不一样。免费internet通常处于堵塞崩溃的边缘,并且数据包错包较多,而使用“internet by call”时,有时你会花费相当高的费用,但能得到好的带宽服务。不管你所在国家具体情况怎样,这篇文章会告诉你如何快速地切换isp,在不同时候使用不同的拨号internet连接.
本文提及的internet访问类型是从你的pc拨号ppp联机到你的isp.在linux上有个叫作pppd的程序用来设置这种连接.pppd是一个非常棒的软件,有很好的适应性,但是不幸的是pppd所带的文档只有相当旧的例子并且用特定的认证方式登陆进你的isp.使用这些例子来设置大多数现代的isp的联接将会导致失败,现在的isp多采用:
.动态ip地址分配
.自动域名配置
.chap或pap认证
.有时自动http请求重定向到代理服务器
这篇文章解释了如何在linux下使用这些现代的功能.你仅仅需要从你的isp了解:电话号码,登陆名和口令.
用linux和ip地址欺骗,可以很容易地把整个地址池,整个网络的计算机而不仅是一台计算机通过一个ppp链路联接上你的isp.为了实现这些,你需要至少一台linux机器和任意数量的其它计算机.这看起来象下图:

如果你使用这样的ip欺骗linux网关,并且使用不同的isp,那么你会通常遇到两个问题:
1、每次当你切换isp时,dns服务器需要更换,你有不想每次重新配置你所有的计算机,特别是如果某些计算机在运行windows和Mac os时.
2、你想有一个任何人可以选择预配置好的isp列表,这个列表可能不适用你网中所有的操作系统.
我们可以用一个叫作dnrd的域名代理来解决问题1,并且可用一个CGI脚本产生一个你可以从哪里拨出的web页面.

配置pppd
所有的pppd配置文件通常位于/etc/ppp,通常你需要以root身份启动pppd.在安装和最早的测试你需要以root用户登陆.等会我将会告诉你如何让任何人启动和停止pppd,经常用root登陆不太好.root用户限制非常小,能够在不小心中轻易地破坏你的配置文件.
pppd的重要文件:
/etc/ppp/options:对所有isp有效的通用配置文件
/etc/ppp/pap-secrets:ppp认证的口令
/etc/ppp/ip-up:当ppp连接激活时,自动执行的脚本(当ip连接刚联结上就执行)
/etc/ppp/ip-down:当ppp连接被中止时,自动执行的脚本
/etc/ppp/peers/:放置一个isp的特定配置文件的目录
你可以下载这些文件的压缩包ppp.tar.gz,把它在/etc/下解压。子目录ppp和其它子目录将会在/etc下被创建.如果你已有/etc/ppp目录,那么你应该在解压前将它该名备份.
cd /etc
mv ppp ppp_old
tar zxvf ppp.tar.gz
解压后,你会发现ppp.tar.gz中包含许多文件,它们都是用来简化安装,配置的交换脚本.(注意,按照示例中的配置文件中来做会付出一些代价,它们可能是错误的,查找isp的网页,得到准确的信息.)
让我们来看一下一个叫做arcor的isp的配置文件.
# This is /etc/ppp/peers/arcor
# Home page of the ISP arcor: http://www.arcor-online.de/
#----------
# serial device and modem speed (normally 38400 or 57600):
/dev/modem 57600
# modem dial-out script with phone number:
connect ''/etc/ppp/scripts/ppp-on-dialer-pap 0192070''
# specific options, common options are
# read from /etc/ppp/options
noipdefault
# tell pppd to use this users name for PAP authentication:
user arcor
# try dynamic dns:
usepeerdns
#
以#开头的行是注解行,
第一个变量(/dev/modem)是使用的串口设备,/dev/modem是你的modem使用的设备的软联接.(/dev/ttyS0或/dev/ttyS1):
cd /dev
ln -s ttyS0 modem
57600是modem速度,这取决于你的modem硬件.以connect开始的那行指定了一个脚本(/etc/ppp/scripts/ppp-on-dialer-pap)通过AT指令集来处理与modem之间的通讯.这些AT指令是关于modem的ASCII命令语言.传给脚本的变量参数是要拨的电话号码(0192070).
noipdefaults是分配动态IP地址所需要的选项;usepeerdns是自动DNS配置所需要的选项.自动DNS配置工作原理就是:
如果你的ISP在握手期提供给你一或者两个DNS服务器的IP地址,那么它们将会在/etc/ppp/ip-up脚本中作为变量DNS1或DNS2被引用.
所有的解析器库函数都需要读一个叫作/etc/resolv.conf的文件来找出如何解析名称的方法.这个文件被netscape,sendmail等应用程序使用来查找DNS服务器.我们将会在ip-up脚本中来改变/etc/resolv.conf
尽管我们定义了电话号码,modem速度,使用的串口,一些pppd的配置选项.在这里我不想讨论/etc/ppp/options中的通用配置选项.你可以看一看例子文件和pppd的man手册.这样我们现在就可以来拨号到我们的ISP.要拨号,我们还需要做多两件事.
登陆名:arcor
口令:internet
这些信息需要输入到文件 /etc/ppp/pap-secrets中,登陆名同时要输入到文件/etc/ppp/peers/arcor中.
象下面例子一样在文件/etc/ppp/pap-secrets中加上一行:
# This is /etc/ppp/pap-secrets
# client server secret IP-addr
arcor * internet 0.0.0.0
就是这样了,现在我们可以来测试一下,键入下面一行来拨号:
pppd call arcor
在这会arcor是指在目录/etc/ppp/peers/ 中的配置文件的名字.
modem将会拨号,几秒钟之后,你就在线了.当你在线的时候,用命令/sbin/ifconfig将会显示一个叫作ppp0的接口.多试几次直到你能看到它,现在你可以使用你的web浏览器到linuxfocus.org冲浪了.
要终止INTERNET连接你可以用命令
kil lall pppd
我希望这个例子你能用的上,在德国的读者这会肯定能象这样工作了,其它国家的人当然要改写他们ISP的电话号码,登陆名和口令.如果不能正常工作,请看本文结尾部分的疑难解决篇.
现在,你有一个工作的ISP了,要增加其它的ISP可以如下操作:
1,拷贝文件 /etc/ppp/peers/arcor给新的名字
2,改变该文件的电话号码和用户信息
3,在文件/etc/ppp/pap-secrets中加多一行
拷贝这个文件和使用一个文本编辑器修改要比用图形化配置工具要快得多和容易得多.
出于这个目的,你应该大略了解下面的机制如何工作,下面,我们将要使用一些脚本来让它更容易使用,我们特别要介绍两个Set-UID perl脚本,来让你以普通用户身份(非root用户)登陆系统时可以启动和停止internet拨号联接.
Set-UID是一个让普通用户行使特殊的命令,并被当作这个命令的拥有者在执行的机制.显而易见地,这需要小心设计,防止产生安全问题,这些Set-UID perl脚本已经被包含进你刚解包的ppp.tar.gz中.它们得文件许可中含有"s",并且属于root用户.

> cd /etc/ppp/scripts
> ls -al ppp-on ppp-off
-rwsr-sr-x 1 root root 1258 Jan 7 13:24 ppp-off
-rwsr-sr-x 1 root root 2619 Jan 9 20:30 ppp-on

如果它们没有这样的权限可以用下面的命令来改变它们:
chmod 6755 ppp-off ppp-on.
ppp-off 和ppp-on脚本仅仅是包装脚本,它们做的仅仅是运行pppd call some-config-file 或者killall pppd.
这样的好处是所有的用户现在可以执行它.ppp-on脚本被作为一些特别的调用被那些不使用自动DNS配置的isp使用.
如果你碰巧有一个这样的isp,那么编辑这个文件,搜索"static",这里面有一些例子可用来修改,你象下面一样使用ppp-on/ppp-off 脚本.

拨号上网:
/etc/ppp/scripts/ppp-on arcor
中止联接:
/etc/ppp/scripts/ppp-off
现在你机器上的所有用户都可以使用它们了.arcor 对应/etc/ppp/peers/下的一个文件名.你或许想更欢一个不同的名字.
最后,我们将使用一个图形化界面来启动和停止internet联接,一个cgi程序是一个生成交互式页面的程序.一个设计良好的cgi程序在任何操作系统和任何浏览器上都工作正常.这就是为什么我们使用cgi程序.它看起来象这样.
几乎所有现在发行的linux版本都会带有一个配置好的apache WEB服务器,你所需要作的仅仅是解压pppcontrol.gz
并且拷贝到你WEB服务器的cgi目录下(大概是/home/httpd/cgi-bin/),为了让它可执行,键入:
chmod 755 pppcontrol
接着编辑改文件,修改这个perl 脚本中的$url变量。当然你要先用gunzip把pppcontrol.gz解压为pppcontrol。
$url一定要是这个脚本自己的url地址,比如你的pc是一台独立的linux机器,并且使用自返ip地址的话,
$url="http://127.0.0.1/cgi-bin/pppcontrol"
这个pppcontrol cgi脚本要读一个叫作/etc/ppp/gpppwrap.conf的配置文件。下面是它的使用语法:
ppponarg: <agument_to_pass_to_ppp_on> - some additional comment string
减号符开始是将会在pppcontrol页面上显示但不会传递到/etc/ppp/scripts/ppp-on程序的注解。下面有个例子,假设你的/etc/ppp/peers下有isp配置文件"arcor"和"talknet":

# This is /etc/ppp/gpppwrap.conf
ppponarg: arcor -- arcor.net 3pf/min
ppponarg: talknet -- internet by call 3.5pf/min

注意:上网费价格3pf/min和3.5pf/min可能会变化,或许到你看本文的时候已经是错误的。
这里对你来说可能有一些新的内容,但是暂时只需要了解这么多就可以设置好并运行起来。
现在你可以方便地在页面上的ISP表单中选择一个ISP,并只需按一下页面上的一个按钮就拨号出去。

域名代理
在上面的部分中,你已经了解如何配置一台linux机器拨号上网,当我们建立一个新的ppp联接时,我们都要修改文件/etc/resolv.conf
如果你使用ip欺骗来给整个网络提供internet访问的话,那么给在网络中的每一台主机都修改/etc/resolv.conf就相当困难.
如果你有一些运行windows的机器,那么任务变得近乎不可能.因为这些机器每次改变网络设置中的域名服务器时都需要重启动.
解决方案就是域名代理.这个小小的域名服务器看起来象你自己网络中自己的域名服务器,它仅仅是传递访问请求给你isp的域名服务器去处理.使用bind域名服务器来作传递域名服务器以实现这个目的也是可能的,尽管bind并不是为次而设计的.
dnrd是一个相当好的域名代理,它是专为这个目的来设计的.
假设你在一台linux机器上运行dnrd,并且你把这台linux机器的内部ip地址192.168.0.1作为你网络上其他机器的域名服务器.这是一个静态的设置,你不需要再更改它,非常容易.
要同过源代码来安装dnrd,你需要这样做:
解压
tar zxvf dnrd-2.10.tar.gz
cd dnrd-2.10/src/
编译
make
strip dnrd
安装
cp dnrd /usr/local/sbin/
创建空目录/etc/dnrd/
mkdir /etc/dnrd/
域名服务器设置(195.50.149.33和195.50.140.6是你isp的域名服务器)
当ppp联接激活时
dnrd -s 195.50.149.33 -s 195.50.140.6
当ppp联接被终止时
dnrd
dnrd在脚本/etc/ppp/ip-up和/etc/ppp/ip-down自动被调用.这些脚本你前面已经下载了,预计dnrd安装在目录/usr/local/sbin/中.
dnrd能够做更多的事情,它自己甚至可作一个真正的小域名服务器.在unix上你通常要这样设置/etc/host.conf
order hosts, bind
在/etc/hosts中提供你的小网络中所有机器的名字.不幸地是你网络中那些傻傻的windows机器就没可能了.
如果dnrd在你的linux机器上找到一个/etc/hosts文件,它会自动为文件中提及的选项作域名服务器.这样就解决了问题.
/etc/hosts文件的语法如下:
# syntax:
# ip-addr hostname alias1 alias2 ...
# example:
192.168.0.1 linuxpc.mynet linuxpc
192.168.0.2 peppermint.mynet pepper mint

当dnrd运行时,你可在网络上任何地方使用http://linuxpc.mynet/或http://linuxpc/来代替http://192.168.0.1/
用dnrd来做域名代理,同时做域名服务器,你需要增加这行:
daemon /usr/local/sbin/dnrd
这行增加到启动脚本/etc/rc.d/init.d中.
这样就可以了,现在你网络中任何人都可同时和其他人一同上网了,很容易地打开和停止ppp联接,或者在不同的isp之间进行转换.只需要把书签指向我们的cgi脚本pppcontrol

改进之处
如果你不想再修改/etc/resolv.conf文件,你可以好好编辑/etc/ppp/ip-up和/etc/ppp/ip-down脚本.
echo .....> /etc/resolv.conf
或者
cat > /etc/resolv.conf << ENDOFCAT
...
ENDOFCAT
做完这些后,你只需要自返地址作为域名服务器地址.
# This is /etc/resolv.conf when dnrd is running
nameserver 127.0.0.1
这样的好处是你访问外部时在所有的机器上也可以使用dnrd的缓存.
你可以用nslookup来测试域名代理:

>nslookup
Default Server: localhost
Address: 127.0.0.1

>pepper
Server: localhost
Address: 127.0.0.1

Non-authoritative answer:
Name: peppermint.mynet
Address: 192.168.0.2

用crtl-d可以中断nslookup

下面我介绍一下如何激活pppd的debug输出.这样可以帮助你找出不能正常工作的原因,不幸地是,当它不能正常工作时,通常并不是我这端的配置错误.
第一件事是pppd为了运行/etc/ppp/scripts/ppp-on-dialer-pap脚本时打开的端口上(/dev/modem, 一个/dev/ttyS0的连接).这个脚本传递AT命令给调制解调器,这些命令让调制解调器拨号到你的isp.如果其中出现任何错误,你都可以在文件 /etc/ppp/connect-errors中找到它们.大多数时候,这个connect-errors文件能给你足够的信息让你找出哪里出错.如果还不行的话,你可以手动输入AT命令.
要这样做你需要一个串行通讯程序,象minicom(大多linux发行版本都带有的),或者是cu(uucp包的一部分),或者是kermit(在网址http://www.columbia.edu/kermit/ck70.html上可下载).使用这个个串行
通讯程序和你的调制解调器来"交谈".当你键入AT,那么调制解调器就会说"好",如果不是这样,检查速度设置,电源线等.如果正常的话,接者试试命令ATDT1234,调制解调器就会拨号1234,如果不是的话,查查你的调制解调器手册.这个命令可能是ATD1234(没有T)或者有其他错误.
你的调制解调器拨号到你的isp后的下一步是ppp-negotiation变量.要观察这是如何进行的,你必须要在/etc/syslog.conf文件中使能daemon.debug选项.
编辑文件/etc/syslog.conf并且在/var/log/messages加入";daemon.debug"这行.例如:
*.info;mail.none;authpriv.none;daemon.debug /var/log/messages
接着用下面的命令重启 syslog
/etc/rc.d/init.d/syslog restart
现在你可以在 /etc/ppp/options中使能debug选项了,接着键入
tail -f /var/log/messages
当连接到你的isp时观察pppd的debug输出.

一个成功的ppp连接可能看起来象:
Jan 14 17:18:11 bearix pppd[721]: pppd 2.3.10 started by root, uid 0
Jan 14 17:18:34 bearix pppd[721]: Serial connection established.
Jan 14 17:18:34 bearix pppd[721]: Using interface ppp0
Jan 14 17:18:34 bearix pppd[721]: Connect: ppp0 <--> /dev/modem
Jan 14 17:18:35 bearix pppd[721]: sent [LCP ConfReq id=0x1 ]
Jan 14 17:18:37 bearix pppd[721]: rcvd [LCP ConfReq id=0x46 ]
Jan 14 17:18:37 bearix pppd[721]: sent [LCP ConfNak id=0x46 ]
Jan 14 17:18:38 bearix pppd[721]: rcvd [LCP ConfReq id=0x47 ]
Jan 14 17:18:38 bearix pppd[721]: sent [LCP ConfAck id=0x47 ]
Jan 14 17:18:38 bearix pppd[721]: sent [LCP ConfReq id=0x1 ]
Jan 14 17:18:38 bearix pppd[721]: rcvd [LCP ConfAck id=0x1 ]
Jan 14 17:18:38 bearix pppd[721]: sent [PAP AuthReq id=0x1 user="arcor" password="internet"]
Jan 14 17:18:40 bearix pppd[721]: rcvd [LCP ConfReq id=0x49 ]
Jan 14 17:18:40 bearix pppd[721]: sent [LCP ConfReq id=0x2 ]
Jan 14 17:18:40 bearix pppd[721]: sent [LCP ConfAck id=0x49 ]
Jan 14 17:18:41 bearix pppd[721]: rcvd [LCP ConfAck id=0x2 ]
Jan 14 17:18:41 bearix pppd[721]: rcvd [CHAP Challenge id=0x5 <0c7672840494152025f937ac4f5e135e>, name = "klndiinternet"]
Jan 14 17:18:41 bearix pppd[721]: sent [CHAP Response id=0x5 , name = "arcor"]
Jan 14 17:18:41 bearix pppd[721]: rcvd [CHAP Success id=0x5 ""]
Jan 14 17:18:41 bearix pppd[721]: sent [IPCP ConfReq id=0x1 ]
Jan 14 17:18:41 bearix pppd[721]: sent [CCP ConfReq id=0x1 ]
Jan 14 17:18:41 bearix pppd[721]: rcvd [IPCP ConfReq id=0x8e ]
Jan 14 17:18:41 bearix pppd[721]: sent [IPCP ConfAck id=0x8e ]
Jan 14 17:18:41 bearix pppd[721]: rcvd [IPCP ConfRej id=0x1 ]
Jan 14 17:18:41 bearix pppd[721]: sent [IPCP ConfReq id=0x2 ]
Jan 14 17:18:41 bearix pppd[721]: rcvd [LCP ProtRej id=0xfb 80 fd 01 01 00 0f 1a 04 78 00 18 04 78 00 15 03 2f]
Jan 14 17:18:41 bearix pppd[721]: rcvd [IPCP ConfNak id=0x2 ]
Jan 14 17:18:41 bearix pppd[721]: sent [IPCP ConfReq id=0x3 ]
Jan 14 17:18:41 bearix pppd[721]: rcvd [IPCP ConfAck id=0x3 ]
Jan 14 17:18:41 bearix pppd[721]: local IP address 145.253.88.6
Jan 14 17:18:41 bearix pppd[721]: remote IP address 145.253.1.150
Jan 14 17:18:41 bearix pppd[721]: primary DNS address 145.253.2.11
Jan 14 17:18:41 bearix pppd[721]: secondary DNS address 145.253.2.75
Jan 14 17:18:41 bearix pppd[721]: Script /etc/ppp/ip-up started (pid 723)
Jan 14 17:18:42 bearix pppd[721]: Script /etc/ppp/ip-up finished (pid 723), status = 0x0

要完全明白这些输出,你可能要了解ppp 协议的细节了.我不知道ppp 协议到底如 何工作,但是我可以猜懂一点点事情,
仅仅明白大致如何进行就通常够了.

"sent ... ConfReq"意味着为了谈判一些事情传递一个配置请求,回答就是在"rcvd ... ConfAck"或"rcvd ... ConfRej"中.
如果都成功了,你就会看到分配的动态ip地址和你isp的网关地址.
在这里讨论每一个错误是不可能的,因为首先我不知道你的设置,其次,这有太多地方可能导致错误.
通过这篇文章你可以找到通常的错误就有点创造性了,如果你实在不能搞定它,而且看起来不是你这边的错的话,换一个isp吧,这可能是isp的错.