# anygo **Repository Path**: kylinpan/anygo ## Basic Information - **Project Name**: anygo - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-24 - **Last Updated**: 2026-09-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # anygo 基于 Go 语言的命令行 VPN 客户端,兼容 Cisco AnyConnect 协议,并支持 WireGuard 隧道。 ## 功能特性 - Cisco AnyConnect SSL VPN 连接 - WireGuard 隧道协议支持(基于 wireguard-go) - WireGuard 密钥对生成(`keygen` 命令) - 密码认证、证书认证、动态码(OTP/TOTP)认证 - CSTP(Cisco Secure Tunnel Protocol)数据通道 - DTLS(Datagram TLS)数据通道,支持自动回退 - 跨平台 TUN 设备支持(macOS utun、Linux tun、Windows Wintun) - Split-tunnel 路由(重叠路由自动跳过,支持多实例共存) - 多实例连接支持:多个 `anygo connect` 进程可同时连接不同 VPN 服务器 - 虚拟 IP 占用检测与残留地址自动释放 - 主机休眠/唤醒后自动检测半开隧道并重连 - 机器可读 JSON 输出(`--json`、`--session-file`) - WireGuard 私钥经 stdin 注入,避免 argv 暴露 - 优雅信号处理(SIGINT/SIGTERM) ## 环境要求 ### macOS - 无需额外驱动(使用系统内置 utun 接口) - 使用 `sudo` 运行以创建 TUN 设备 ### Linux - TUN/TAP 内核模块:`sudo modprobe tun` - 使用 `sudo` 运行,或赋予 `CAP_NET_ADMIN` 权限 ### Windows - 安装 [Wintun](https://www.wintun.net/) 驱动(`make build` 会自动复制 DLL 到 bin/) - 以管理员身份运行 ## 安装 ```bash git clone https://github.com/kylin/anygo cd anygo make build ``` ## 使用方法 ### AnyConnect 连接 ```bash # 密码认证连接(互动式密码输入) sudo ./bin/anygo connect vpn.company.com -u alice # 密码 + 动态码认证(直接发送验证码) sudo ./bin/anygo connect vpn.company.com -u alice --password="pass" --dynamic-secret="123456" # 密码 + TOTP 认证(自动生成 6 位验证码,RFC 6238) sudo ./bin/anygo connect vpn.company.com -u alice --password="pass" --totp-secret="JBSWY3DPEHPK3PXP" # 指定隧道组 sudo ./bin/anygo connect vpn.company.com -u alice -g Corporate # 客户端证书认证 sudo ./bin/anygo connect vpn.company.com --client-cert=cert.pem --client-key=key.pem # 跳过服务器证书验证(测试用) sudo ./bin/anygo connect vpn.company.com -u alice --no-cert-check # 详细日志输出 sudo ./bin/anygo connect vpn.company.com -u alice -v ``` ### WireGuard 连接 ```bash # 1. 生成 WireGuard 密钥对 anygo keygen # 2. 连接(私钥经 stdin 注入,第一行私钥、第二行预共享密钥可选) printf 'CLIENT_PRIVATE_KEY\n' | sudo ./bin/anygo connect vpn.wg.example.com --proto wg \ --wg-server-public-key=SERVER_PUBLIC_KEY \ --wg-allowed-ips=10.0.0.0/8,172.16.0.0/12 \ --wg-dns=10.0.0.1 \ --wg-persistent-keepalive=25 \ --wg-keys-stdin # 或直接通过参数传入(注意:私钥会暴露于进程列表) sudo ./bin/anygo connect vpn.wg.example.com --proto wg \ --wg-private-key=CLIENT_PRIVATE_KEY \ --wg-server-public-key=SERVER_PUBLIC_KEY \ --wg-allowed-ips=10.0.0.0/8 # WireGuard 模式默认 MTU 1420,可用 --mtu 覆盖 sudo ./bin/anygo connect vpn.wg.example.com --proto wg --mtu 1400 \ --wg-private-key=CLIENT_PRIVATE_KEY --wg-server-public-key=SERVER_PUBLIC_KEY ``` ### 多实例连接 多个实例可同时连接不同的 VPN 服务器,互不干扰: ```bash # 终端 1:连接公司 A 内网 sudo ./bin/anygo connect vpn-a.company.com -u alice # 终端 2:连接公司 B 内网 sudo ./bin/anygo connect vpn-b.company.com -u bob ``` - Linux 上 TUN 设备名由内核自动分配(`tun0`、`tun1`…),macOS 自动分配 utun 单元 - 重叠子网路由会被后连接的实例自动跳过并警告,不影响连接 - 虚拟 IP 被占用时会尝试自动释放残留地址,失败则报错回滚 ### 进程管理与机器输出 `connect` 启动时就把自己写进**会话文件**(默认 `/tmp/anygo-session.json`),`status` 与 `disconnect` 读同一个文件,因此三个命令都可以零参数使用: ```bash # 终端 1:连接(启动即写会话文件) sudo ./bin/anygo connect vpn.company.com -u alice # 终端 2:查看状态 / 断开,无需任何路径参数 anygo status anygo disconnect # 机器可读 JSON 输出(供脚本/面板消费) sudo ./bin/anygo connect vpn.company.com -u alice --json anygo status --json # Windows wintun 适配器自定义名称(默认 AnyGo,按名复用网卡) sudo ./bin/anygo connect vpn.company.com -u alice --tun-name=WorkVPN ``` ### status 输出 `status` 按“能否判定”分情况输出,不靠猜测: | 情况 | 输出 | exit | |---|---|---| | 会话文件不存在(从未连接,或断开后已清理) | `disconnected` | 0 | | 文件存在但不是会话文件(如误传 PID 文件) | 报错 + 正确用法 | 1 | | `connected=false` 且 pid 存活 | `connecting (session pid N is running)` | 0 | | `connected=true` 且 pid 存活 | 原样回显会话文件 | 0 | | `connected=true` 但 pid 已消失(如被 `kill -9`) | `disconnected` 并清理陈旧文件 | 0 | 认证期间也会如实报告 `connecting`,而不是谎报“已断开”。 ### disconnect 行为 `disconnect` 从会话文件取出 pid,发送 SIGTERM,然后等待会话真正结束(最多 10s): - 进程已退出 → `session pid N exited; VPN disconnected.` - 会话已收尾但进程尚未退出 → `VPN disconnected; session pid N has not exited yet.` - 10s 内会话仍未结束 → 报错(exit 1) - 没有活动会话 / 进程早已不在 → 说明情况并 exit 0(幂等,可重复执行) Windows 无法向其他进程投递 SIGTERM,此时会明确报错并提示在 connect 窗口按 Ctrl+C, 不会假装断开成功。 ### 多实例 默认路径服务单会话场景;同时连接多个 VPN 时用 `--session-file` 区分,否则后启动的 connect 会覆盖前一个的会话文件(它会打印 warning 提示): ```bash sudo ./bin/anygo connect vpn-a.company.com -u alice --session-file=/tmp/anygo-a.json anygo status --session-file=/tmp/anygo-a.json anygo disconnect --session-file=/tmp/anygo-a.json ``` ### 旧参数兼容 - `--status-file` 仍是 `--session-file` 的别名,取值语义不变,既有脚本无需改动。 - `--pid-file` 已弃用但保留:`connect` 仍会写入纯数字 PID 文件,`disconnect` 仍接受它。 ## 项目结构 ``` anygo/ ├── cmd/anygo/ # CLI 入口(connect、disconnect、status、keygen) ├── internal/ │ ├── auth/ # 认证模块(密码、证书、动态码) │ ├── config/ # 配置结构体 │ ├── cstp/ # CSTP 协议(Cisco 安全隧道协议) │ ├── dtls/ # DTLS 数据通道 │ ├── session/ # 会话生命周期管理 │ ├── tun/ # TUN 设备抽象(macOS、Linux、Windows) │ ├── wg/ # WireGuard 配置、密钥与握手监控 │ └── xmlutil/ # AnyConnect XML 响应解析 ├── third_party/wintun/ # Wintun 驱动 DLL 与头文件 ├── docs/superpowers/ # 设计与规划文档 ├── Makefile └── README.md ``` ## 架构说明 详细架构文档请参阅: - [docs/superpowers/specs/2026-08-24-go-connect-design.md](docs/superpowers/specs/2026-08-24-go-connect-design.md) - [docs/superpowers/specs/2026-08-24-multi-instance-design.md](docs/superpowers/specs/2026-08-24-multi-instance-design.md) ## 开发命令 ```bash make build # 编译当前平台二进制(Windows 下自动复制 wintun.dll) make build-all # 交叉编译 darwin/linux/windows 全平台 make test # 运行所有测试 make test-race # 带竞态检测运行测试 make lint # 执行 go vet 代码检查 make clean # 清除构建产物 ``` ## 许可证 MIT