首先,这篇文章是一篇WHY-TO,面向所有Linux操作系统(或者说偏向gentoo、arch之类习惯自己折腾的系统),而不是HOW-TO。小白或者懒人想要快速解决问题的,请看cc98 Linux天地置顶贴:【HOWTO】ubuntu下如何上网(需要浙大内网访问)。

前言:

紫金港宿舍区上网主要有两种方式:一、连接内网后使用学校VPN访问外网(通过设置路由表可以实现内外网同时访问),而连接内网的方式又分为闪讯和201卡两种;二、使用闪讯或201卡直接连接外网(可以使用RVPN来实现内外网同时访问)。

闪讯这东西短期内在Linux下是没有能够正常使用的可能了。而201卡连接外网的资费又是一小时一元,实在承受不起。所以唯一可行的方案只剩下使用201连接内网后用VPN连接外网。其实VPN上外网性价比也是很高的,如果不追求网速的话,10元一月的教育网出口就够用了;就算有网速需求,50元一月的电信出口也并不算贵(闪讯4M包月也是48元)。

接下来我们就按照201卡、VPN、路由的顺序来详细介绍上网设置。

201卡:

201卡可以到白沙宿舍服务中心买到,只要跟他说你是Linux用户就可以了,30元一张,含外网30小时、内网6个月。

201卡有一个网页登陆界面,在宿舍连上网线(使用DHCP),随便打开一个网页都会跳转到登陆界面,需要安装一个控件(Windows Only),在成功登陆它会通过控件给你设置一个新的IP/网关。不要看到Windows Only就灰心了,办法总是有的——用curl之类的东西发个登陆请求,然后获取返回的结果,parse出新的IP/网关,然后设置上即可。已经有前辈用perl实现了这个东西——就是我们所说的“portal”软件(见置顶贴)。

但是我们也有更简单的办法。201卡除了网页端以外还支持普通的PPPOE拨号(不像是闪讯做了各种手脚)。如此一来就简单了:使用NetworkManager的同学直接打开nm-connection-editor,在DSL标签页里添加一个连接,填上用户名密码即可;命令行控们可以直接使用pppd,在/etc/ppp/pears/中建立适当的配置文件即可(相信常用CLI的同学自己看看man什么的肯定能搞定,还可以参考Archlinux Wiki上的PPPOE设置,此处从略)。

P.S.连内网的话用户名就是:卡号@zheda,连外网的话用户名就是卡号

VPN:

浙大使用的VPN是普通的L2TP VPN。NetworkManager目前没有L2TP的插件,所以只能手动配置xl2tpd(可能需要先安装,一般发行版并不附带)。

首先,编辑/etc/xl2tpd/xl2tpd.conf文件,加入一个VPN配置段,例如:

1
2
3
4
5
6
7
8
9
10
[lac zju-vpn]
lns=lns.zju.edu.cn
redial=yes
redial timeout=5
max redials=10      #重拨相关配置
refuse pap=yes
require chap=yes    #强制使用chap验证而非pap
require authentication=yes
name=学号@账户类型    #账户类型即a、c或d等
pppoptfile = /etc/ppp/peers/zju-vpn       #文件名可自便,请记住该文件

并且确保原有的[global]配置段中有类似的配置(若没有则添加):

1
auth file = /etc/ppp/chap-secrets

其次,编辑上面指定的pppoptfile,加入如下配置:

1
2
3
noauth         #不需要pear端先验证自己
proxyarp
defaultroute   #添加默认路由,使用拨号产生的ppp设备

最后,编辑auth file,添加一行记录,例如:

1
学号@账户类型   *   "密码"    *

至此,VPN配置完毕。在启动xl2tpd服务后,使用xl2tpd-control connect zju-vpn即可拨号。如无意外应该能够拨号成功(可以查看syslog),但肯定无法上网,原因请看下文。

路由设置:

L2TP VPN最后的拨号也是基于ppp的,在ppp拨号成功后,会修改路由表默认路由为新建立的ppp虚拟网卡。然而浙大的VPN是只能访问外网的,而VPN服务器是内网IP(10.5.1.7),如此一来会导致无法连接VPN服务器,VPN连接在一分钟内就会被迫中断。

为此,我们必须手动修改路由表,以区分内外网不同线路。这里假设使用PPPOE拨号方式连接201卡,则会首先产生一个ppp0设备,VPN拨号后会产生ppp1设备,我们希望让所有内网流量都走ppp0,而其余则默认使用ppp1。

我的实现方法是,在VPN拨号前,先添加静态路由表,显式地指定内网走ppp0设备(内网网段信息是从Windows下的浙大L2TP-VPN客户端里找到的);在VPN拨号成功后,设置默认路由为ppp1(如果按照前文所述配置了defaultroute选项,则这将会由xl2tpd自动完成)。

这里给出一个脚本(参考了水寒大牛的vpn-connect,写得比较简陋,见谅~):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/bin/bash
#必须以root权限执行!

PPP_TIMEOUT=60          #l2tp ppp拨号超时
L2TPD_TIMEOUT=10        #l2tpd服务启动超时
L2TPD_CONTROL_FILE=/var/run/xl2tpd/l2tp-control
L2TPD_SERVICE_BIN=/etc/rc.d/xl2tpd    #xl2tpd服务路径,Debian系的请改为/etc/init.d/xl2tpd

function start_xl2tpd
{
  $L2TPD_SERVICE_BIN start
  for i in $(seq 0 $L2TPD_TIMEOUT)
  do
    if [ -e $L2TPD_CONTROL_FILE ]; then
      return 0
    fi
    sleep 1
  done
  return 1
}

if [ ! -e $L2TPD_CONTROL_FILE ]; then
  if ! start_xl2tpd; then
    echo "Failed starting xl2tpd"
    return 1
  fi
fi

GW=`ip route show 0/0 | cut -d " " -f 3`       #获取ppp0的默认网关

#添加静态路由表
ip route add 10.0.0.0/8 dev ppp0 via $GW
ip route add 58.196.192.0/19 dev ppp0 via $GW
ip route add 58.196.224.0/20 dev ppp0 via $GW
ip route add 210.32.0.0/20 dev ppp0 via $GW
ip route add 210.32.128.0/19 dev ppp0 via $GW
ip route add 210.32.160.0/21 dev ppp0 via $GW
ip route add 210.32.168.0/22 dev ppp0 via $GW
ip route add 210.32.172.0/23 dev ppp0 via $GW
ip route add 210.32.176.0/20 dev ppp0 via $GW
ip route add 222.205.0.0/17 dev ppp0 via $GW

xl2tpd-control connect zju-vpn                 #连接VPN

for i in $(seq 0 $PPP_TIMEOUT)
do
  if ip addr show | grep 'inet.*ppp1' > /dev/null; then
    echo "Connected"
    exit 0
  fi
  sleep 1
done

echo "Connect time out"
exit 1

要断开VPN连接的话只需要xl2tpd-control disconnect zju-vpn即可。

总结:

总结一下在配置好之后日常上网的流程:一、插上网线,IP设置什么的无所谓(= =);二、PPPOE拨号连接201卡;三、执行脚本连接VPN、设置路由。

最后说一下水寒大神做的xl2tpd包就将所需要的几个配置文件和一个脚本包括在内,不需要自己手动配置了。虽然傻瓜化,不过也有一些局限:一是与源中的xl2tpd冲突,给包管理带来麻烦;二是脚本默认用户使用portal连接201卡,故而还需要安装、配置portal(主要是有好几个依赖包,还得必须联网下,个人认为PPPOE要来得更方便快捷)。

Have Fun!