ubuntu 连校园网 via l2tp
因为在树莓派上写脚本会有点卡,
就先在台式机上写写看, 还能边写边用浏览器查...
连校园网, 这次是用脚本实现的, 上次是用一个下载的软件, 但是那个被我重新装之后, 就不能用了,因为在以前没有记录下怎么配置的过程,
那现在, 用现在的方法,可以做到开机就连上网络,
首先 先说一下, 这个拨号的过程,
- 学校的局域网内有个 192.168.254.1 的服务器是作为l2tp的server.
学生作为client, 可以和他建立vpn, 也就是l2tp隧道. - 在隧道建立完成之后, 会使用ppp协议作为载体, 把隧道内传输的数据按照ppp来打包, 然后这些ppp包就从这个隧道中发到server. 从而实现上网.
有个链接: 解释了为啥还是在使用l2tp作为上网的认证手段,而不是用ppop啥的:
https://www.zhihu.com/question/26810403
简单的说, 就是认证用户是用ppp协议的, 但是宿舍到server不是一条线的, 中间要经过好多个路由啥的, 就不是peer to peer的了, 那么ppp的包就过不去了, 最后要借助l2tp这个在ip层的协议来帮助发送ppp包.
然后再来看怎么配置:
要下的软件:
要建立l2tp连接, 那么就要用xl2tpd这个软件.
要用ppp协议发送包, 那么就要用pppd这个软件.
( 如果l2tp是要加密的话, 好像还要下载其他的东西, 但是我发现, 联通的这个东西, 是不加密的, 密码都是明文发送的......)
你可以用apt-get 来下载这两个包.
给软件的配置文件:
xl2tpd 的配置文件:
/etc/xl2tpd/xl2tpd.conf
内容:
[lac testvpn]
name = test
lns = 192.168.254.1
pppoptfile = /etc/ppp/peers/testvpn.l2tpd
ppp debug = yes
第一个name,这个选项不晓得干啥的,但是例子上有..
第二个就是远端服务器的ip.
第三个是ppp协议的配置文件, 因为xl2tpd在建立完成隧道之后, 就会自己启动pppd, 所以他就需要知道pppd的配置文件在哪里.
第4个是 是否要输出ppp的详细运行信息.
更多的有关配置的信息可以在这里找到:https://linux.die.net/man/5/xl2tpd.conf
配置是分lac 和lns和global的, global和lns的配置不用去管, lns是服务器的配置信息.
因为xl2tpd还是可以用作服务端的, 我们就只用到了作为客户的功能.
然后就是要设置 pppd 的配置文件:
/etc/ppp/peers/testvpn.l2tpd
内容:
remotename testvpn
user "账号"
passwrod 密码
unit 0
nodeflate
noauth
persist
noaccomp
maxfail 5
usepeerdns
debug
这些参数可以用 man pppd来查询,
这个option文件是我抄网上的教程后修修改改出来的,
有些东西也不知道为啥....
我发现, 我们的机器的ip和dns都是需要server告诉我们的, 所以加了 usepeerdns.
然后ppp 有两种认证的方式PAP和CHAP, 我选的是PAP, 因为感觉chap比较高级, chap比较耗费运算??
这些认证过程可以/var/log/syslog文件中找到.
有个中文的翻译:http://blog.csdn.net/chenliang0224/article/details/8572699
然后两个文件设置完成之后, 就要启动这个连接了.
首先启动xl2tp:
xl2tpd -c /etc/xl2tpd/xl2tpd.conf -D
-c 是指定配置文件
你不加这个也可以, 因为xl2tpd的默认的配置文件就是这个目录上的文件.
-D 是debug模式, 不加的话, xl2tpd就会变成后台进程, 但可以用ps aux | grep xl2tpd 和 kill 杀死...
然后你就可以在当前的terminal中看到他的执行情况了.
然后再发送连接指令给xl2tpd
echo 'c testvpn' > /var/run/xl2tpd/l2tp-control
这里的testvpn这个名字, 就是上面设置的remotename, 我不清楚这两个名字是不是有关系的, 其实改一下就好知道, 但是太懒....
echo 'd testvpn' > /var/run/xl2tpd/l2tp-control 是断开连接.
成功的话, 就可以在ifconfig中看到ppp0接口了.
如果不成功, 就需要查看日志来找出错误.
我碰到的大部分的错误是可以在 xl2tpd -D的那个terminal中可以看出来的,
我经常就是 ppp 的参数设置错误, 然后xl2tpd检测到错误后就杀死了pppd啥的, 反正就改改配置文件后再来一边试试看.
还有一个可以看到日志的地方就是 /var/log/message 或者 /var/log/syslog 文件.
你可以再开个窗口, 然后用 tail -f 看.
反正目标就是 看不到 fail的字样. 要看到: 隧道成功建立和ppp认证成功.
这里是我的成功后的两个日志的情况:
syslog.png
上图是 syslog 的. 可以看到, 在l2tp连接建立之后, 就会有
Mar 8 18:08:11 dogegg-HP pppd[3618]: sent [LCP EchoReq id=0x2 magic=0x2a789e01]
Mar 8 18:08:11 dogegg-HP pppd[3618]: rcvd [LCP EchoRep id=0x2 magic=0x4dd4d216]
这样子的收发信息, 这个是代表这个隧道是存在的,30s一次( 这个东西很重要, 和路由有关)
然后我们可以看到服务器发给我们, 我们的ip地址, 我们的主/次dns服务器地址, 还有他的地址.
上图是xl2tpd进程的日志, 可以看到他一步步的把配置文件中的内容给解析出来, 如果有解析错的, 那么肯定会打印出来的.
设置路由
这样弄完之后, 网上的教程都说, 你就可以上网了, 但是我不行.....
因为是路由的问题.....
我们要让电脑的所有流量都经过ppp0端口出去, 而不是原来的eth0啥的.
现在我们的情况是 我们和服务器连上了, 但是我们包还是从默认的路由默认的网关发送出去的.
用route -n看到的情况大概是这样子的.
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.64.70.1 255.255.255.255 ?????????
10.64.70.0 0.0.0.0 255.255.255.0 U 100 0 0 enx000ec6d2bc57
101.68.75.84 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 enx000ec6d2bc57
第一条的??参数是我忘记了... 就乱打上去.
destination是 0.0.0.0的那条是叫做default路由. 数据包不知道往哪里发的话, 就发那边去.
我的路由表在 没有连上ppp0之前就只有3个路由, 就是现在的去掉第三条的样子.
最后一条169.254.0.0的是local-link, 查了百度, 也没怎么弄清楚这是干啥的, 反正不影响.
如果想把流量都改了的话, 那么就应该把default给删除再加上一条去ppp0的default,
但是, 并不是把所有的流量都给导过去, 我们和server的通讯是要走网卡的不能走ppp0.
所以, 就需要3条route命令来改:
echo 'add route to 192..'
route add -host 192.168.254.1 gw $getway dev enx000ec6d2bc57
echo 'del default'
route del default
echo 'add default to ppp0'
route add default gw $remote dev ppp0
这是脚本里面写着的, 这样子改完之后, 应该就好上网了.如果还不行...
可以试试看ping remote通不通. 然后ping那个dns服务器.
我本来以为加上 ping 的-I 参数 就可以跳过路由, 但是如果路由不对, 就算加上-I ppp0, ping的包好像也是不会顺利的发送出去的.
下面是脚本:
#!/bin/bash
dir=/home/dogegg/Desktop/log.txt
#因为xl2tpd进程是自动随着系统开机而运行的, 就不用写入脚本了.
echo 'c testvpn' > /var/run/xl2tpd/l2tp-control
#在发送完连接命令之后, 就每隔2s检查下有没有ppp0的接口在ifconfig中出现. 次数超过10次就exit.
count=0
while [ $count -lt 10 ]; do
haveppp0=`ifconfig | grep ppp0`
if [[ $haveppp0 != "" ]];then
break
fi
echo 'check ppp0 is exist, time:'$count > $dir
let count=count+1
sleep 2s
done
if [[ $count == 10 ]];then
echo 'time out!' >> $dir
exit 0
fi
echo 'ppp0 is exist!' >> $dir
#匹配出 网关的地址.
getway=`ifconfig enx000ec6d2bc57 | grep 'inet addr'`
reg='.*inet addr\:([0-9]+\.[0-9]+\.[0-9]+\.)([0-9]+).*'
if [[ "$getway" =~ $reg ]];then
pre=${BASH_REMATCH[1]}
last=${BASH_REMATCH[2]}
else
exit 222
fi
getway=$pre'1'
# 匹配出 远程server的地址
remote=`ifconfig ppp0 | grep 'P-t-P'`
reg='.*P-t-P:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*'
if [[ "$remote" =~ $reg ]];then
remote=${BASH_REMATCH[1]}
else
exit 223
fi
### debug!!
echo 'the getway is '$getway >> $dir
echo 'the remote is '$remote >> $dir
###
#改改路由:
echo 'add route to 192..' >> $dir
route add -host 192.168.254.1 gw $getway dev enx000ec6d2bc57
echo 'del default' >> $dir
route del default
echo 'add default to ppp0' >> $dir
route add default gw $remote dev ppp0
exit 0
最后就是配置开机了
在/etc/rc.local
文件中加入运行脚本的语句
如果 想知道一些出错的信息, 我用的是笨办法, 就是让我的脚本里面的echo把字符串输出到一个桌面的文件中($dir), 但是好像网上有比较优雅的办法, 看上去是改输出流啥的:
exec 2> /tmp/rc.local.log
exec 1>&2
set -x
不懂.... 用不来, 但是在 /tmp/rc.local.log里面可以看到:
+ ./home/dogegg/Desktop/checkppp0.sh
+ exit 0
下一步就是把这个东西转到树梅pi上.