Project: SOCKS5 proxy and VPN tunnel using SSH transport (Rust + Python integration tests)
Key Principle: Split testing - Rust unit tests (fast) + Python integration tests (Docker-based)
Current Phase: Phase 1 in progress (VPN foundation - workspace restructured, agent crate created)
Note: The x2ssh-agent binary is automatically built with musl for fully static binaries (portable to any Linux server). The main x2ssh binary builds with the host target for cross-platform support (Linux/Windows).
# Install musl target (one-time setup for agent)
rustup target add x86_64-unknown-linux-musl
# Install musl-tools (Ubuntu/Debian)
sudo apt-get install musl-tools
cargo build
cargo run -- -D 127.0.0.1:1080 user@server.com# Unit tests (fast, no Docker)
cargo test
# Integration tests (requires Docker, run from repo root)
./scripts/build-test-image.sh # One-time setup
uv run pytest # Run all integration tests
uv run ty check # Type check with ty (Rust-based, fast)./scripts/check.sh # Run all checks (build, Rust + Python tests, lint, format)
./scripts/check.sh -v # Verbose mode with full outputRust:
cargo fmt
cargo clippyPython (integration tests):
uv run ruff format # Format code
uv run ruff check # Lint
uv run ty check # Type check- NO testcontainers in Rust - Integration testing moved to Python
- Integration tests use
cargo run- Test actual binary, not internals - Keep fixtures in
tests/fixtures/- SSH keys, Dockerfile - Run
./scripts/build-test-image.shbefore first integration test - After making changes, run
./scripts/check.sh- Verifies all quality checks pass - Module structure: Use
module.rsinstead ofmodule/mod.rs- For cleaner file organization
x2ssh/
├── proto/ # Shared protocol code (framing, version negotiation)
│ └── src/
│ └── framing.rs # Length-prefixed packet framing
├── x2ssh/ # Main binary (SOCKS5 proxy + VPN client)
│ └── src/ # main.rs, lib.rs, retry.rs, socks.rs, transport.rs
├── x2ssh-agent/ # Server-side VPN agent (deployed over SSH)
│ └── src/main.rs
├── tests/ # Python integration tests (uv workspace member)
│ ├── tests/ # Test files
│ └── fixtures/ # SSH keys, Dockerfiles, docker-compose.vpn.yaml
├── scripts/ # check.sh, build-test-image.sh, generate-test-keys.sh
└── pyproject.toml # uv workspace root
- Rust: Pure logic, no network needed
- Python: Full workflows, network behavior, binary testing
- SOCKS5: Uses testcontainers for dynamic port allocation (single SSH container)
- VPN: Uses docker-compose for static IP network (client + server containers)
- Tests fail? Check:
docker ps,./scripts/build-test-image.sh,tests/fixtures/keys/ - VPN tests fail? Check: containers are privileged, docker network created
-
./scripts/check.shpasses (runs all checks below automatically) - AGENTS.md, README.md and DESIGN.md updated
- DESIGN.md - Architecture, testing strategy, implementation details
- VPN.md - VPN tunnel design and implementation plan
- README.md - User documentation
- todo/UDP_ASSOCIATE.md - UDP Associate design analysis (deferred)