Skip to content

Instantly share code, notes, and snippets.

@gledos
Created January 19, 2024 13:50
Show Gist options
  • Select an option

  • Save gledos/687aef235198cc479cdf913304a26701 to your computer and use it in GitHub Desktop.

Select an option

Save gledos/687aef235198cc479cdf913304a26701 to your computer and use it in GitHub Desktop.
SNI 阻断测试测试工具
import sys
import subprocess
import time
# 用法: python check_sni_blocking.py <target_url> [timeout]
def check_sni_blocking(target_url, timeout):
success_count = 0
failure_count = 0
results = []
start_time = time.time()
print(f"\n【提示】正在检测是否存在 SNI 被阻断的现象,请稍候 {timeout} 秒……(最多可能需要等待 {timeout + 15} 秒)\n")
try:
# 运行指定秒数
while time.time() - start_time < timeout:
# 尝试连接目标网站
command = f"curl --insecure -v --connect-to ::www.cloudflare.com: {target_url}"
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
output, _ = process.communicate()
# 将结果添加到列表
results.append(output)
# 检查是否遇到 TCP Reset
if "curl: (35) Recv failure: Connection was reset" in output:
print("\n".join(results))
print(f"\n【提示】SNI 可能被阻断,使用 {target_url} 作为 SNI 访问 www.cloudflare.com 失败,遭遇了 TCP Reset。")
failure_count += 1
break
# 检查是否成功连接
elif "HTTP/1.1 403 Forbidden" in output:
print("\n".join(results))
print(f"\n【提示】成功连接 {target_url}。")
success_count += 1
# results = [] # Reset results for the next test
# 检查是否遇到 SSL/TLS 连接失败
elif "schannel: failed to receive handshake, SSL/TLS connection failed" in output:
print("\n".join(results))
print(f"\n【提示】SNI 可能被阻断,使用 {target_url} 作为 SNI 访问 www.cloudflare.com 失败,无法接收握手,SSL/TLS 连接失败。可能遭到了某种「网络劣化」。")
failure_count += 1
# 未知情况
else:
print("\n".join(results))
print(f"\n【提示】发生了未知情况,请检查日志。")
failure_count += 1
# 整合结果并输出
# print("\n".join(results))
# 输出连接结果的统计信息
print(f"\n【统计】测试完成,一共测试了 {len(results)} 次。")
print(f"【统计】成功连接 {success_count} 次。")
print(f"【统计】连接失败 {failure_count} 次。")
# 判断 SNI 是否被阻断
if all("HTTP/1.1 403 Forbidden" in result for result in results):
print(f"\n【总结】{target_url} 可能未遭到 SNI 阻断。")
else:
print(f"\n【总结】{target_url} 可能遭到了 SNI 阻断,建议检查日志查看详情。")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
# 从命令行获取目标网站的URL和计时器时间
if len(sys.argv) not in [2, 3]:
print("用法: python check_sni_blocking.py <target_url> [timeout]")
sys.exit(1)
target_url = sys.argv[1]
# 运行 15 秒钟(可能因为无法握手,而延长 15 秒)
timeout = int(sys.argv[2]) if len(sys.argv) == 3 else 30
check_sni_blocking(target_url, timeout)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment