记一次反向代理教学管理服务平台

拥有一定的门槛,本文假设你了解 Linux 的基本操作,如创建并编辑文件、基本的进程管理等。

参考了 GitHub 项目 反向代理工大教务管理系统 及其一篇博客 反向代理教务系统,但由于学校不同,也遇到了一些上面没有提到的问题,故记录于此。

环境与准备

  1. 腾讯云服务器

    操作系统 CPU 内存 公网带宽
    Ubuntu Server 20.04 LTS 64位 1核 2GB 1Mbps
  2. Nginx

  3. MotionPro 客户端

一、安装 MotionPro 客户端

  1. 将下载好的 .sh 传至服务器(因为它官方需要验证码认证后才能下载,所以我选择下载到本地后通过 FTP 上传)。

  2. 授予可执行权限 chmod u+x MotionPro_Linux_Ubuntu_x64_v1.2.9.sh

  3. 执行安装脚本 sudo ./MotionPro_Linux_Ubuntu_x64_v1.2.9.sh

  4. 可以测试一下是否可用 MotionPro --host vpn.你的学校.edu.cn --user 你的账号 --passwd 你的密码,但是你将会和你的服务器失去连接。

    修改路由表,目的是你的linux机器可以同时访问工大vpn和公网,如果不修改路由表,你的虚拟机在连接到vpn后,会和你自己断开连接,这时候连ssh都连不上了,只能通过主机提供商的后台重启机器,切记切记

    回到腾讯云重启你的主机即可重新通过 SSH 连接你的云服务器。

    在这里可能会提醒没有启动 vpnd,直接在命令行输入 vpnd 后回车即可。后面会将怎么处理。

二、完成修改路由表脚本

第一步中如果可以使用 MotionPro 成功连接 VPN 会出现与 SSH 断开连接的情况,原因是连接 VPN 会改变服务器的路由,由于路由不对称,本地就会失去与服务器之间的连接。

修改路由表的作用就是让我们的服务器开启 VPN 后,在访问需要校园网才能访问的地址时通过 VPN 产生的路由,其他时候都使用默认路由。

在 Linux 里,修改路由表可以使用 route 进行修改,但是由于连接 VPN 后失去了链接,所以可以预先写个脚本来在连接 VPN 后修改路由表。

在我一开始提到的文章里,作者是使用 route_add.sh 来修改的,内容如下:

#!/bin/bash
echo "start"
for((i=1; i<172; i++))
do
v=$(/sbin/route add -net "$i".0.0.0 netmask 255.0.0.0 gw 182.92.123.247 dev eth1) #182.92.123.247 is the gateway address of your Virtual-Machine server.
echo "$v"
done

for((i=173; i<256; i++))
do
v=$(/sbin/route add -net "$i".0.0.0 netmask 255.0.0.0 gw 182.92.123.247 dev eth1)
echo "$v"
done

/sbin/route add -net 172.0.0.0 netmask 255.0.0.0 gw 1.1.1.1 dev tun0 #let 172.0.0.0 route to vpn channel.
/sbin/route del default #delete default route,we have add all route manually just before.
echo "finished"

v=$(/sbin/route)

echo "$v"

这里附带上 Issue 上作者的补充说明

对于route_add.sh,这个比较麻烦一点,脚本里面的内容要根据你自己的主机实际情况改一下,需要注意的有这么几个地方:

v=$(/sbin/route add -net "$i".0.0.0 netmask 255.0.0.0 gw 182.92.123.247 dev eth1)

/sbin/route add -net 172.0.0.0 netmask 255.0.0.0 gw 1.1.1.1 dev tun0
  1. 了解 route add 名行命令里面每一个参数什么意思

  2. 子网掩码应该就用 255.0.0.0

  3. 网关地址这个要用你主机默认路由表里的网关地址

  4. 接口名称eth1 也是来自于主机,不同主机不一样,你要改成你自己的

  5. 172.0.0.0这个地址段包含了咋们学校所有内网主机,所以需要针对这个使用vpn的代理通道,其中tun0网络名称应该是固定的,代理直至1.1.1.1你也要实际在你的主机上观察,这一步比较费事,因为你一旦连上vpn,你和主机就断开连接了,所以可能需要打印一些必要的日志信息来观察最简单的就是在连接vpn后加一句

    /sbin/route >> iplist.txt

也就是说,这个文件对于不同学校以及不同主机来说是有区别的。

我这里重新解释一下他文件中的一些字段为什么这样写:

  1. 他使用了两段循环执行 /sbin/route add -net "$i".0.0.0 netmask 255.0.0.0 gw 182.92.123.247 dev eth1 ,把 172 跳过了。是因为他学校的教务系统的 IP 都是172.*.*.*,所以通过这些命令,让除了访问172.*.*.*的 IP 地址,其他都通过原来的路由。

  2. 182.92.123.247 这个是他自己网卡的 IP 地址。这个可以通过 ifconfig 命令查看。

    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.17.0.8  netmask 255.255.240.0  broadcast 172.17.15.255
            inet6 fe80::5054:ff:fe4f:45b6  prefixlen 64  scopeid 0x20<link>
            ether 52:54:00:4f:45:b6  txqueuelen 1000  (Ethernet)
            RX packets 44385  bytes 12912991 (12.9 MB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 41628  bytes 8406493 (8.4 MB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    

    其中我的 172.17.0.8 即是他的 182.92.123.247

  3. eth1 这个是他的默认网卡名称,即是让访问除校园网以外的地址所采用的网卡,也是可以通过 ifconfig 查询你的默认网卡。如上一条所示,我的默认网卡名称为 eth0

  4. /sbin/route add -net 172.0.0.0 netmask 255.0.0.0 gw 1.1.1.1 dev tun0 这一条则是让访问校园网即172.*.*.*时走tun0(MotionPro产生的)。其中 255.0.0.01.1.1.1 不需要改变。

所以对于我个人来说,这个脚本应该修改为:

#!/bin/bash
echo "start"
for((i=1; i<202; i++))
do
v=$(/sbin/route add -net "$i".0.0.0 netmask 255.0.0.0 gw 172.17.0.8 dev eth0)
echo "$v"
done

for((i=203; i<256; i++))
do
v=$(/sbin/route add -net "$i".0.0.0 netmask 255.0.0.0 gw 172.17.0.8 dev eth0)
echo "$v"
done

/sbin/route add -net 202.0.0.0 netmask 255.0.0.0 gw 1.1.1.1 dev tun0
/sbin/route del default #delete default route,we have add all route manually just before.
echo "finished"

v=$(/sbin/route)

echo "$v"

再通过另一个脚本调用“启动MotionPro”和“修改路由表”:

MotionPro --host vpn.你的学校.edu.cn --user 你的账号 --passwd 你的密码
sleep 5s
sudo /home/ubuntu/vpn/script/route_add.sh >> /home/ubuntu/vpn/logs/route_add.log

通过 chmod 授予权限后启动。可以看到 VPN 连接成功,同时 SSH 也没有断开连接了。再 ping 一下学校的 ip 也可以访问了。

三、反向代理

这个需要修改 Nginx 的配置,我也没有很了解,这里借鉴原作者的内容,删除了关于 https 配置 ssl 的内容。具体位置请搜索 Nginx 配置文件位置。

upstream jxgl{ 
    # 你的大学的教学管理系统的网站
    server jxgl.你的大学.edu.cn:80;
}

server{
    listen 80;
    server_name 127.0.0.1;
	location =/{
	    proxy_set_header Host $host;
		proxy_pass http://jxgl;
	}
    location /{
	    proxy_set_header Host $host;
	    proxy_pass http://jxgl;
	}
}

之后重启 Nginx 即可。sudo systemctl restart nginx

四、完善脚本

完善内容:

  1. 日志输出添加时间
  2. 15 分钟检测一次,根据 MotionPro 提供的状态决定是否重连
  3. 由于我的学校有 3 个 VPN 连接入口,在其中一个不成功的情况下我可以连接其他的入口,所以添加多个连接命令

下面是我的两个文件。

home/ubuntu/vpn/script/check.sh

#!/bin/bash

idle="VPN Status: idle"
connected="VPN Status: connected"

stat=$(MotionPro -a)
if [ "$stat" == "$connected" ]
then
    time=$(date "+%Y-%m-%d %H:%M:%S")
    echo "$stat"
    echo "$time"
    exit 0
fi

if [ "$stat" == "$idle" ]
then
    echo "-try vpn1-"
	MotionPro --host vpn1.你的学校.edu.cn --user 你的账号 --passwd 你的密码
	sleep 5s
fi
stat=$(MotionPro -a)
if [ "$stat" == "$idle" ]
then
    echo "-try vpn2-"
    MotionPro --host vpn2.你的学校.edu.cn --user 你的账号 --passwd 你的密码
    sleep 5s
fi
stat=$(MotionPro -a)
if [ "$stat" == "$idle" ]
then
    echo "-try vpn3-"
    MotionPro --host vpn3.你的学校.edu.cn --user 你的账号 --passwd 你的密码
    sleep 5s
fi
stat=$(MotionPro -a)
if [ "$stat" == "$connected" ]
then
    sudo /home/ubuntu/vpn/script/route_add.sh 1>>/home/ubuntu/vpn/logs/route_add`date +'-%Y-%m-%d'`.log 2>>/home/ubuntu/vpn/logs/route_add_error`date +'-%Y-%m-%d'`.log
fi

time=$(date "+%Y-%m-%d %H:%M:%S")
echo "-$stat-"
echo "$time"

home/ubuntu/vpn/script/route_add.sh

#!/bin/bash
for((i=1; i<256; i++))
do

if [ $i -eq 202 ]
then
    continue
fi

/sbin/route add -net "$i".0.0.0 netmask 255.0.0.0 gw 172.17.0.8 dev eth0 #172.17.0.8 is the gateway address of your Virtual-Machine server.
done

/sbin/route add -net 202.0.0.0 netmask 255.0.0.0 gw 1.1.1.1 dev tun0 #let 202.0.0.0 route to vpn channel.
/sbin/route del default #delete default route,we have add all route manually just before.

time=$(date "+%Y-%m-%d %H:%M:%S")
echo "$time"

之后通过其他脚本或进程管理等方式 N 分钟执行一次即可。

五、其他问题

启动 MotionPro 需要提前启动 vpnd,本来打算找一下教程加入到开机自动启动里,即一种加入到 /etc/rc.local 的方法,但是打开后发现 vpnd 已经存在。之后通过 systemctl status rc-local service 检查了一下,报错如下:

Starting /etc/rc.local Compatibility...
rc-local.service: Failed to execute command: Exec format error
rc-local.service: Failed at step EXEC spawning /etc/rc.local: Exec formate error
rc-local.service: Control process exited, code=exited status=203
rc-local.service: Failed with result 'exit-code'.
Failed to start /etc/rc.local Compatibility.

看来是 rc.local 没有成功启动。

网上搜到两个解决方法,我都添加进去后生效了,并不知道哪一个是正确的,所以都贴出来了。

sudo vim /etc/systemd/system/rc-local.service

在结尾添加

[Install]
WantedBy=multi-user.target
sudo vim /etc/re.local

在开头添加

#!/bin/sh -e

有其他问题可以评论回复。

posted @ 2021-07-08 23:19  YL给力啊  阅读(497)  评论(0编辑  收藏  举报