- Published on
自动更新服务端口
- Authors
- Name
- Zhao Tao
- github
- @taoz27
该日志中很多表述不够严谨准确,待更新。
需求
在服务器上搭建了科学上网工具后,发现用一段时间,端口就会被封,无法继续使用。
现在需要写一个自动化脚本,封禁后自动切换端口。
思路
- 检测当前端口是否被封。
- 在配置文件中切换端口。
- 重新启动 nginx 服务,并将链接复制到 ftp 上。
步骤
1. 获取当前公网 ip
通过ifconfig无法正常获取本机公网 ip,ip.sb提供相关接口。
使用curl ip.sb以纯文本形式获取公网 ip。
2. 获取当前使用的端口
一种方案思路是在本地保存一个using_port文件,文件内容是当前正在使用的端口,每次修改端口后更新该文件。
另一种方案思路是直接在配置文件中寻找端口号。
最简单的方法,按行列搜索。例如端口号在$conf文件的第9行第2列,可用如下命令获取:
cat $conf | sed -n '9p' | awk '{print $2}'
cat $conf命令读取$conf文件并将内容通过管道输送给sed命令,sed -n '9p'命令抽取第9行输出给awk命令,awk '{print $2}'输出第2列数据。
sed命令和awk命令都是强大的文本分析工具,后面替换端口号时还会用到sed命令。在搜索数据时,sed通常以行为单位,awk通常以列为单位。
上面这个方法的缺点是,如果$conf文件中增删了行,可能导致执行结果错误。可以选择使用正则匹配进行更严谨的搜索。
cat $conf | sed -n '1,//{/listen.*ssl http2/p}' | awk '{print $2}'
该命令按listen.*ssl http2正则匹配搜索行,1,表明从第一行开始搜索,输出找到的第一个匹配项。
3. 查看当前端口是否开放
使用nc命令,全称netcat,网络工具中的瑞士军刀。
最简单的用法:nc -z -w 3 $Domain $port,其中-z是指扫描端口时不发送其他数据,-w设定超时时长,大部分开放的端口扫描在 2 秒内就会出结果,这里设置超时时长为 3 秒。
这条命令执行后,如果结果为 0,表明端口开放,如果为 1,表明端口未开放。
4. 获取新的端口
在防火墙配置中开放了一批连续的端口号,一个端口被封禁后,直接使用下一个端口。
shell 中变量加一的方法有以下几种:
a=$(($a+1))
a=$[$a+1]
a=`expr $a + 1`
let a++
let a+=1
((a++))
5. 替换端口号
使用sed命令进行替换
sed -i "s/$port/$next_port/g" $conf,该命令将$conf中所有的$port替换为$next_port。
6. 保存订阅链接
将链接结果输出到 ftp 文件中,以供订阅。ftp 搭建及 vmess 订阅参考该链接。
7. 定时启动
可以在/etc/crontab文件中注册定时任务,这些任务同时也会开机自动启动(满足设定条件的情况下)。
Crontab 表达式规则:
* * * * *
- - - - -
| | | | |
| | | | +----- 星期中星期几 (0 - 6) (星期天 为0)
| | | +---------- 月份 (1 - 12)
| | +--------------- 一个月中的第几天 (1 - 31)
| +-------------------- 小时 (0 - 23)
+------------------------- 分钟 (0 - 59)
设置脚本每 10 分钟自动执行一次:
/10 * * * * root bin/sh /home/user/auto_run.sh
最终代码
#!/bin/sh
# 设置你自己的域名或IP
Domain="Your Domain or IP"
# nginx对应的配置文件路径
conf="/etc/nginx/conf.d/"$Domain".conf"
# 根据自己实际情况设定端口提取规则
port=$(cat $conf | sed -n '1,//{/listen.*ssl http2/p}' | awk '{print $2}')
# 检测端口是否可以访问
nc -z $Domain $port -w 3
if [ $? -eq 0 ]; then
# 正常访问,直接退出
exit
fi
# 不能访问,准备更新端口号
echo $(date): $Domain:$port NOT reachable.
# 下一端口号
next_port=`expr $port + 1`
# 替换配置文件中的端口号
sed -i "s/$port/$next_port/g" $conf
echo $(date): replace $conf, $port -\> $next_port.
# 重新启动nginx和v2ray服务
systemctl restart nginx
systemctl restart v2ray
systemctl status nginx
systemctl status v2ray
# 生成链接,并写入ftp文件
./v2ray_info.sh
echo ============================================================