主要用于检测IP端口有没有被墙
import socket
socket.setdefaulttimeout(3)
def check_ip_port(host,port):
ip = socket.getaddrinfo(host, None)[0][4][0]
if ':' in ip:
inet = socket.AF_INET6
else:
inet = socket.AF_INET
sock = socket.socket(inet)
status = sock.connect_ex((ip,int(port)))
sock.close()
return status == 0
函数返回True,表示端口是能连接的;函数返回False,表示端口是不能连接的。
import threading
import MySQLdb
status_data = []
lock = threading.Lock()
threads = []
def check(ip,port):
status = check_ip_port(ip,port)
with lock:
status_data.append([ip,port,status])
con = MySQLdb.connect(host=host,user=user,passwd=passwd,db=db)
cur = con.cursor()
cur.execute('''SELECT ip,port FROM ss''')
for ip,port in cur.fetchall():
thread = threading.Thread(target=check, args=(ip,port))
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
cur.close()
con.close()
检测结果存入 status_data。 为了多线程稳定运行,需要增加文件描述符的最大数量。具体优化方法请参考 https://shadowsocks.org/en/config/advanced.html
以上检测方法并不能保证100%的准确,主要原因是: 由于国际网络线路的波动,可能会导致传输中的数据包丢失,即本来能连通的端口在网络波动的瞬间表现为不能连通。另外本站还观测到GFW有漏包的现象(持续时间非常短),即本来被封的端口在漏包的瞬间表现为能够连接。因此我们需要进行多节点和多时间上的统计来排除掉这些干扰。具体实现也很简单,只要在国内国外各部署几个检测点定期检测,通则记1分,不通没有分,通过打分就能100%准确检测出有没有被墙,甚至连被墙的准确时间都能检测出来。
主要用于检测SS账号是否存活
import os
import json
import time
import socket
import httplib2
def verify(host,port,passwd,method,local_port):
ip = socket.getaddrinfo(host, None)[0][4][0]
v6 = ':' in ip
config = {'server':host,'server_port':port,'password':passwd,'method':method,'local_address':'127.0.0.1','local_port':local_port,'timeout':60}
cfile = '/etc/shadowsocks-libev/%s.json' % local_port
with open(cfile, 'w') as f:
json.dump(config, f)
os.system('systemctl restart shadowsocks-libev-local@%s.service' % local_port)
time.sleep(1)
h = httplib2.Http(proxy_info=httplib2.ProxyInfo(2, '127.0.0.1', local_port), timeout=60)
status = False
try:
if v6:
r,c = h.request('http://v6.ipv6-test.com/api/myip.php')
else:
r,c = h.request('http://httpbin.org/ip')
status = r['status'] == '200':
except:
pass
os.system('systemctl stop shadowsocks-libev-local@%s.service' % local_port)
os.remove(cfile)
return status
函数返回True,表示账号正常;函数返回False,表示账号异常。
正常情况下,一个shadowsocks-libev进程占5M左右内存,需要根据机器的实际内存来控制并发数量。SSR 程序写得太烂,内存占用不忍直视,这也是本站不检测 SSR 账号的一个原因。