Files
socks-manager/health.py
T
Your Name aa8af6c2e0 feat: SOCKS5 代理管理系统 v1.0
Flask + SQLite + Bootstrap5 暗色主题
- 仪表盘: 在线/离线统计 + 最近代理 + 操作日志
- 代理 CRUD: 增删改 + 启用/禁用 + 单/批量健康检测(SOCKS5)
- 分组管理: 创建/删除/筛选
- 操作日志: 分页查询
- RESTful API + Web 界面
- 管理员登录认证 (SM_ADMIN_PASSWORD 环境变量)
2026-07-16 16:40:20 +08:00

87 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import time
import logging
from datetime import datetime, timezone
from models import Proxy, db
from extensions import db as _db_ext
log = logging.getLogger("socks.health")
TEST_URL = "http://httpbin.org/get"
def check_proxy(proxy):
"""检查单个 SOCKS5 代理是否可用。返回 {status, latency_ms, error}"""
import socks
import socket
host, port = proxy.host, proxy.port
timeout = 10
status = "unknown"
latency = None
error = None
orig_getaddrinfo = socket.getaddrinfo
orig_socket = socket.socket
try:
# 使用 PySocks 创建 SOCKS5 隧道
s = socks.socksocket()
s.settimeout(timeout)
s.set_proxy(socks.SOCKS5, host, port,
username=proxy.username or None,
password=proxy.password or None)
t0 = time.time()
# 尝试连接到测试 URLhttpbin.org
s.connect(("httpbin.org", 80))
elapsed = time.time() - t0
latency = round(elapsed * 1000, 1)
# 发送一个简单 HTTP HEAD 请求验证隧道通畅
s.sendall(b"HEAD /get HTTP/1.1\r\nHost: httpbin.org\r\nConnection: close\r\n\r\n")
resp = s.recv(1024)
s.close()
if resp and (b"200" in resp[:4] or b"301" in resp[:4] or b"302" in resp[:4]):
status = "online"
else:
status = "online" # 连接成功即算在线(某些代理只允许特定目标)
except Exception as e:
status = "offline"
error = str(e)[:200]
log.warning("Proxy %s:%d check failed: %s", host, port, e)
finally:
socket.getaddrinfo = orig_getaddrinfo
socket.socket = orig_socket
return {"status": status, "latency_ms": latency, "error": error}
def run_health_checks():
"""对所有 enabled 的代理运行健康检测,更新数据库,返回结果摘要。"""
proxies = Proxy.query.filter_by(enabled=True).all()
results = []
online_count = 0
for p in proxies:
r = check_proxy(p)
p.status = r["status"]
p.latency_ms = r["latency_ms"]
p.last_check = datetime.now(timezone.utc)
if r["status"] == "online":
online_count += 1
results.append({
"id": p.id, "name": p.name, "host": p.host, "port": p.port,
**r,
})
_db_ext.session.commit()
return {
"checked": len(results),
"online": online_count,
"offline": len(results) - online_count,
"details": results,
}