前言
访问学院服务器需要在校网环境下连接vpn访问,而且是用的docker容器分开用户,而在家里访问用teamviewer又蠢又难受,所以用的是ssh内网穿透(用自己的阿里云服务器穿透我的容器)。
然而,别的服务器穿透连接都很稳定正常,就这个倒是半天一天一断,不知道为什么。
过程
确保能连
用的阿里云的5000端口去连容器的22端口
确保了阿里云的控制台开启了该端口,并且俩服务器防火墙都开了这俩端口。
然后/etc/ssh/sshd_config的Listen Address设成0.0.0.0,GatewayPorts设成yes,service ssh restart确保能公网访问,在容器上用ssh -f -g -N -R 5000:localhost:22 root@47.101.151.73建立穿透,就可以用ssh root@47.101.151.73 -p 5000在所有环境下访问内网服务器。
同样,把需要的服务如jupyterlab的8889端口映射出来。
ssh -f -g -N -R 8889:localhost:8889 root@47.101.151.73
断连状况
半天一天5000及8889端口lsof就会没有进程,当然也就没法ssh root@47.101.151.73 -p 5000访问服务器,但内网服务器运作正常,重新配置一下穿透就行,而我的别的内网服务器的穿透就没断过。
解决
crontab蹲点
先试着用crontab蹲点看lsof的运行情况
crontab -e:
#/bin/bash
* * * * * lsof -i:5000 2>&1 | xargs bash $HOME/datecrontalog.sh /tmp/cron.log
* * * * * lsof -i:8889 2>&1 | xargs bash $HOME/datecrontalog.sh /tmp/cron.log
启动crontab服务日志每分钟写到/tmp/cron.log
/tmp/cron.log文件大致如下
2021-02-04@13:54:01:COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEsshd525root8uIPv4711132310t0TCP*:5000(LISTEN)sshd525root9uIPv4711135200t0TCPiZuf678rk4gl43eoeyfaexZ:5000->116.230.176.176:14456(ESTABLISHED)sshd525root10uIPv4711135310t0TCPiZuf678rk4gl43eoeyfaexZ:5000->116.230.176.176:57024(ESTABLISHED)
2021-02-04@13:54:01:COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEsshd4660root8uIPv4715183730t0TCP*:8889(LISTEN)sshd4660root9uIPv4715186950t0TCPiZuf678rk4gl43eoeyfaexZ:8889->116.230.176.176:64328(ESTABLISHED)sshd4660root10uIPv4715186960t0TCPiZuf678rk4gl43eoeyfaexZ:8889->116.230.176.176:55217(ESTABLISHED)sshd4660root11uIPv4715187490t0TCPiZuf678rk4gl43eoeyfaexZ:8889-
2021-02-04@13:55:01:COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEsshd525root8uIPv4711132310t0TCP*:5000(LISTEN)sshd525root9uIPv4711135200t0TCPiZuf678rk4gl43eoeyfaexZ:5000->116.230.176.176:14456(ESTABLISHED)sshd525root10uIPv4711135310t0TCPiZuf678rk4gl43eoeyfaexZ:5000->116.230.176.176:57024(ESTABLISHED)
2021-02-04@13:55:01:COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEsshd4660root8uIPv4715183730t0TCP*:8889(LISTEN)sshd4660root9uIPv4715186950t0TCPiZuf678rk4gl43eoeyfaexZ:8889->116.230.176.176:64328(ESTABLISHED)sshd4660root10uIPv4715186960t0TCPiZuf678rk4gl43eoeyfaexZ:8889->116.230.176.176:55217(ESTABLISHED)sshd4660root11uIPv4715187490t0TCPiZuf678rk4gl43eoeyfaexZ:8889-
但自己懒得一直去看文件,因为其实只要知道啥时候突然没有返回内容了,或者返回内容突然没有"(LISTEN)"了,就说明断连。那就想到用server酱监督该文件,如果内容不符合逾期就给微信报警
server酱python内容
import os
import time
import requests
def __get_last_line( filename):
"""
get last line of a file
:param filename: file name
:return: last line or None for empty file
"""
try:
filesize = os.path.getsize(filename)
if filesize == 0:
return None
else:
with open(filename, 'rb') as fp: # to use seek from end, must use mode 'rb'
offset = -8 # initialize offset
while -offset < filesize: # offset cannot exceed file size
fp.seek(offset, 2) # read # offset chars from eof(represent by number '2')
lines = fp.readlines() # read from fp to eof
if len(lines) >= 2: # if contains at least 2 lines
return lines[-1].decode() # then last line is totally included
else:
offset *= 2 # enlarge offset
fp.seek(0)
lines = fp.readlines()
return lines[-1].decode()
except FileNotFoundError:
print(filename + ' not found!')
return None
sckey = '########################'
while True:
lastline=__get_last_line('/tmp/cron.log')
print(lastline.find('(LISTEN)'),lastline[:16],time.strftime("%Y-%m-%d@%H:%M", time.localtime()))
if lastline.find('(LISTEN)')==-1 or lastline[:16]!=time.strftime("%Y-%m-%d@%H:%M", time.localtime()):
desp=lastline[:16]+'\n\n'+lastline
url = 'https://sc.ftqq.com/%s.send?text=penetration_failed&desp=%s'%(sckey,desp)
requests.get(url)
break
time.sleep(60)
逻辑就是获取文件最后一行,如果最后一条日志时间和当前时间不一样或者日志里没"(listen)"了就报警。
报警如下:
然后就在2.4 1:24的时候蹲到了方糖的设备通知报警。
本来想先去看看/var/log/message(/var/root/mail)结果发现内网下服务器都连不上,
我的容器被关了,而在1:24这个时间点只有一个容器刚刚开开来,那我直接把该容器的主人找到就解决问题了。
解决1
13服务器上被写入了个木马,刚才排查了下,现在解决了
问题又出现
这次问题出现时内网服务器仍然正常登录,所以
网络拓扑:校外PC--------------阿里云服务器(47.101.151.73)----------------学校的一个内网服务器(公网IP) 校外PC ssh连接阿里云服务器5000端口,阿里云服务器做端口映射去连接学校服务器。接着在客户端,阿里云服务器,学校服务器上同时抓包,注意一定要包含断开连接的时间点。
linux: tcpdump
tcpdusmp -s 0 -i any port 5000 -w /tmp/test.cap
windows: wireshark
规则:
ip.addr == 47.101.151.73 && tcp.port == 5000
经检测,怀疑是类似白名单配置问题,也就是校网出口的地方的网络限制,比如访问校网需要外网web认证。
所以编写python脚本定时运行
# coding=utf-8
import requests,time
while True:
s = requests.session()
data = [('action','login'),('username',''),('password',''),('ac_id','1'),('user_ip',''),('nas_ip',''),('user_mac',''),('save_me','0'),('ajax','1')]
res = s.post('https://login.ecnu.edu.cn/include/auth_action.php', data)
print(res)
# 每隔半个小时进行一次登录
time.sleep(1800)
至此,暂未出现过任何问题。