- 服务器 lhins-3zqfts83 通过腾讯云TAT安装 strongSwan 5.9.13 + xl2tpd - 三种VPN协议已全部就绪: IKEv2(系统原生)/L2TP-IPSec(系统原生)/WireGuard - UDP 500/4500/1701 端口本地nc可达验证通过 - macOS 接入操作手册已生成 Co-Authored-By: Claude <noreply@anthropic.com>
171 lines
6.0 KiB
Python
171 lines
6.0 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""TAT 东京服务器: 状态检查 + 一键安装系统级 VPN(IKEv2 + L2TP)"""
|
||
import base64, json, os, re, sys, time
|
||
|
||
|
||
def _read_creds():
|
||
"""从真源私密总表读腾讯云 Lighthouse 凭证(AKID8Q...)"""
|
||
d = os.path.dirname(os.path.abspath(__file__))
|
||
for _ in range(6):
|
||
if os.path.basename(d) == "卡若AI":
|
||
break
|
||
d = os.path.dirname(d)
|
||
p = os.path.join(d, "运营中枢", "私密配置", "账号密码与API私密总表.md")
|
||
if not os.path.isfile(p):
|
||
return None, None
|
||
with open(p, "r", encoding="utf-8") as f:
|
||
t = f.read()
|
||
m = re.search(r"API SecretId\s*\|\s*`([^`]+)`", t)
|
||
n = re.search(r"API SecretKey\s*\|\s*`([^`]+)`", t)
|
||
if m and n:
|
||
return m.group(1).strip(), n.group(1).strip()
|
||
return None, None
|
||
|
||
|
||
def find_tokyo_instance(cli):
|
||
from tencentcloud.lighthouse.v20200324 import models
|
||
req = models.DescribeInstancesRequest()
|
||
r = cli.DescribeInstances(req)
|
||
for inst in (r.InstanceSet or []):
|
||
if "43.165.178.230" in (inst.PublicAddresses or []):
|
||
return inst.InstanceId, inst.InstanceName, inst.InstanceState
|
||
return None, None, None
|
||
|
||
|
||
def tat_run(client, instance_id, content_b64, name, timeout=180):
|
||
from tencentcloud.tat.v20201028 import models
|
||
req = models.RunCommandRequest()
|
||
req.Content = content_b64
|
||
req.InstanceIds = [instance_id]
|
||
req.CommandType = "SHELL"
|
||
req.Timeout = timeout
|
||
req.CommandName = name
|
||
resp = client.RunCommand(req)
|
||
return resp.InvocationId
|
||
|
||
|
||
def tat_get_result(client, inv_id, wait_sec=40):
|
||
from tencentcloud.tat.v20201028 import models
|
||
print(f" 等待 {wait_sec}s 取回结果...")
|
||
time.sleep(wait_sec)
|
||
req = models.DescribeInvocationTasksRequest()
|
||
f = models.Filter()
|
||
f.Name = "invocation-id"
|
||
f.Values = [inv_id]
|
||
req.Filters = [f]
|
||
r = client.DescribeInvocationTasks(req)
|
||
for t in (r.InvocationTaskSet or []):
|
||
tr = getattr(t, "TaskResult", None)
|
||
if not tr:
|
||
continue
|
||
try:
|
||
jj = json.loads(tr) if isinstance(tr, str) else tr
|
||
out = jj.get("Output", "")
|
||
if out:
|
||
out = base64.b64decode(out).decode("utf-8", errors="replace")
|
||
print("--- 服务器输出 ---\n" + out[:8000] + "\n---")
|
||
except Exception as e:
|
||
print(f" 解析结果失败: {e}\n 原始: {str(tr)[:600]}")
|
||
|
||
|
||
def main():
|
||
sid, skey = _read_creds()
|
||
if not sid or not skey:
|
||
print("❌ 未读到腾讯云凭证")
|
||
return 1
|
||
print(f" 凭证: {sid[:8]}...{skey[-6:]}")
|
||
|
||
from tencentcloud.common import credential
|
||
from tencentcloud.lighthouse.v20200324 import lighthouse_client as ls_cli
|
||
from tencentcloud.tat.v20201028 import tat_client as t_cli
|
||
|
||
REGION = "ap-tokyo"
|
||
cred = credential.Credential(sid, skey)
|
||
ls = ls_cli.LighthouseClient(cred, REGION)
|
||
iid, iname, istate = find_tokyo_instance(ls)
|
||
if not iid:
|
||
print("❌ 在 ap-tokyo 区域未找到 43.165.178.230 的实例")
|
||
return 1
|
||
print(f" 服务器: {iname} ID={iid} 状态={istate}")
|
||
|
||
# ===== 1. 状态检查 =====
|
||
cmd_status = r'''
|
||
echo "=== 1. 服务器基础信息 ==="
|
||
uname -a
|
||
cat /etc/os-release 2>/dev/null | head -3
|
||
echo ""
|
||
|
||
echo "=== 2. 资源 ==="
|
||
uptime
|
||
echo "磁盘:"; df -h / | tail -2
|
||
echo "内存:"; free -h | head -2
|
||
echo ""
|
||
|
||
echo "=== 3. 关键服务 ==="
|
||
for s in strongswan xl2tpd nginx bt; do
|
||
systemctl is-active $s 2>/dev/null || echo "$s: 未安装/未运行"
|
||
done
|
||
echo ""
|
||
|
||
echo "=== 4. 监听端口 ==="
|
||
ss -tulnp 2>/dev/null | awk '/LISTEN|UNCONN/ {print $1, $5}' | sort -u | head -30
|
||
echo ""
|
||
|
||
echo "=== 5. WireGuard / 进程 ==="
|
||
ls /etc/wireguard/ 2>/dev/null || echo "wireguard: 未安装"
|
||
wg show 2>/dev/null | head -10 || echo "wg: 未运行"
|
||
echo ""
|
||
|
||
echo "=== 6. iptables 状态 ==="
|
||
iptables -L INPUT -n 2>/dev/null | head -10
|
||
echo ""
|
||
|
||
echo "=== 7. 腾讯云外网自检 ==="
|
||
curl -s --max-time 5 https://api.ipify.org
|
||
echo ""
|
||
'''
|
||
print("\n[1/2] TAT 状态检查...")
|
||
tat = t_cli.TatClient(cred, REGION)
|
||
inv = tat_run(tat, iid, base64.b64encode(cmd_status.encode()).decode(), "TokyoStatusCheck", timeout=60)
|
||
print(f" 任务下发: {inv}")
|
||
tat_get_result(tat, inv, wait_sec=20)
|
||
|
||
# ===== 2. 推送并执行 VPN 安装 =====
|
||
script_path = os.path.join(os.path.dirname(__file__), "东京服务器_一键安装IKEv2_L2TP_VPN.sh")
|
||
if not os.path.isfile(script_path):
|
||
print(f"❌ 找不到脚本: {script_path}")
|
||
return 1
|
||
with open(script_path, "r", encoding="utf-8") as f:
|
||
script_content = f.read()
|
||
print(f"\n[2/2] 推送并执行 VPN 安装脚本 ({len(script_content)} bytes)...")
|
||
install_cmd = (
|
||
"cat > /tmp/vpn_install.sh << 'SCRIPT_EOF'\n"
|
||
+ script_content
|
||
+ "\nSCRIPT_EOF\n"
|
||
"chmod +x /tmp/vpn_install.sh\n"
|
||
"echo '脚本已写入 /tmp/vpn_install.sh,开始执行...'\n"
|
||
"bash /tmp/vpn_install.sh 2>&1\n"
|
||
)
|
||
inv2 = tat_run(tat, iid, base64.b64encode(install_cmd.encode()).decode(), "TokyoInstallVPN", timeout=300)
|
||
print(f" 安装任务下发: {inv2}")
|
||
tat_get_result(tat, inv2, wait_sec=90)
|
||
|
||
print("\n" + "="*60)
|
||
print(" ✅ TAT 流程结束")
|
||
print("="*60)
|
||
print("\n下一步用户在腾讯云控制台操作:")
|
||
print(" 轻量应用服务器 → 43.165.178.230 → 防火墙 → 添加规则:")
|
||
print(" 500/UDP 4500/UDP 1701/UDP (来源 0.0.0.0/0)")
|
||
print("\n然后 macOS 系统设置 → 网络 → 添加 VPN 配置:")
|
||
print(" • IKEv2(系统原生,零中间件): 服务器 43.165.178.230 · 远程ID 43.165.178.230")
|
||
print(" 账号 karuo · 密码 KaruoVPN@2026")
|
||
print(" • L2TP/IPSec(系统原生): 服务器 43.165.178.230 · 共享密钥 KaruoL2TP@2026")
|
||
print(" 账号 karuo · 密码 KaruoVPN@2026")
|
||
print(" • WireGuard(需装App,最快): 见 运营中枢/私密配置/房市通东京节点/wireguard-client.conf")
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|