Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
*.retry
.idea/
configs/*
~config.cfg
config.cfg.*
inventory_users
*.kate-swp
.env/
.venv/
.DS_Store
.vagrant
.ansible/
algo.egg-info/
.context/

# Python
.env/
.venv/
bin/
lib/
__pycache__/
*.pyc
algo.egg-info/
38 changes: 35 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Algo is an Ansible-based tool that sets up a personal VPN in the cloud. It's des
- **Privacy-preserving**: No logging, minimal data retention

### Core Technologies
- **VPN Protocols**: WireGuard (preferred) and IPsec/IKEv2
- **VPN Protocols**: WireGuard (preferred), IPsec/IKEv2, VLESS+Reality (stealth/anti-censorship)
- **Configuration Management**: Ansible (v12+)
- **Languages**: Python, YAML, Shell, Jinja2 templates
- **Supported Providers**: AWS, Azure, DigitalOcean, GCP, Vultr, Hetzner, local deployment
Expand Down Expand Up @@ -40,6 +40,7 @@ algo/
│ ├── common/ # Base system configuration, firewall, hardening
│ ├── wireguard/ # WireGuard VPN setup
│ ├── strongswan/ # IPsec/IKEv2 setup
│ ├── xray/ # VLESS+Reality stealth VPN (xray-core)
│ ├── dns/ # DNS configuration (dnscrypt-proxy)
│ └── cloud-*/ # Cloud provider specific roles
├── library/ # Custom Ansible modules
Expand Down Expand Up @@ -369,7 +370,38 @@ ansible-playbook main.yml -vvv

## Platform Support

- **Primary OS**: Ubuntu 22.04/24.04 LTS
- **Secondary**: Debian 11/12
- **Primary OS**: Ubuntu 24.04 LTS
- **Secondary**: Ubuntu 22.04, Debian 11/12
- **Architectures**: x86_64 and ARM64
- **Testing tip**: DigitalOcean droplets have both public and private IPs on eth0, making them good test cases for multi-IP NAT scenarios

## VLESS+Reality (Stealth VPN)

The `xray` role provides censorship-resistant VPN using VLESS protocol with XTLS-Reality transport:

### Why Reality?
- Traffic is indistinguishable from regular HTTPS to a legitimate website
- No TLS certificate needed (uses target site's real certificate)
- Cannot be detected by active probing
- Proven effective in China, Russia, Iran

### Configuration
```yaml
# config.cfg
xray_enabled: true
xray_port: 443
xray_reality_dest: "www.microsoft.com:443" # Site to mimic
xray_reality_sni: "www.microsoft.com"
```

### Client Configuration
Generated files in `configs/<server_ip>/xray/`:
- `<user>.json` - Full xray client config
- `<user>.txt` - VLESS share link
- `<user>.png` - QR code for mobile apps

### Recommended Clients
- **iOS/macOS**: Shadowrocket, Streisand
- **Android**: v2rayNG, NekoBox
- **Windows**: v2rayN, Nekoray
- **Linux**: v2rayA, Nekoray
23 changes: 20 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,39 @@ See our [release announcement](https://blog.trailofbits.com/2016/12/12/meet-algo

* Supports only IKEv2 with strong crypto (AES-GCM, SHA2, and P-256) for iOS, MacOS, and Linux
* Supports [WireGuard](https://www.wireguard.com/) for all of the above, in addition to Android and Windows 11
* Supports **VLESS+Reality** (xray-core) for censorship-resistant VPN that is undetectable by DPI
* Generates .conf files and QR codes for iOS, macOS, Android, and Windows WireGuard clients
* Generates VLESS share links and QR codes for stealth VPN clients
* Generates Apple profiles to auto-configure iOS and macOS devices for IPsec - no client software required
* Includes helper scripts to add, remove, and manage users
* Blocks ads with a local DNS resolver (optional)
* Sets up limited SSH users for tunneling traffic (optional)
* Privacy-focused with minimal logging, automatic log rotation, and configurable privacy enhancements
* Based on Ubuntu 22.04 LTS with automatic security updates
* Based on Ubuntu 24.04 LTS with automatic security updates
* Installs to DigitalOcean, Amazon Lightsail, Amazon EC2, Vultr, Microsoft Azure, Google Compute Engine, Scaleway, OpenStack, CloudStack, Hetzner Cloud, Linode, or [your own Ubuntu server (for advanced users)](docs/deploy-to-ubuntu.md)

## Anti-features

* Does not support legacy cipher suites or protocols like L2TP, IKEv1, or RSA
* Does not install Tor, OpenVPN, or other risky servers
* Does not depend on the security of [TLS](https://tools.ietf.org/html/rfc7457)
* Does not claim to provide anonymity or censorship avoidance
* Does not depend on the security of [TLS](https://tools.ietf.org/html/rfc7457) for WireGuard/IPsec (VLESS+Reality uses TLS for stealth)
* Does not claim to provide anonymity
* Does not claim to protect you from the [FSB](https://en.wikipedia.org/wiki/Federal_Security_Service), [MSS](https://en.wikipedia.org/wiki/Ministry_of_State_Security_(China)), [DGSE](https://en.wikipedia.org/wiki/Directorate-General_for_External_Security), or [FSM](https://en.wikipedia.org/wiki/Flying_Spaghetti_Monster)

## Stealth VPN (VLESS+Reality)

For networks where WireGuard is blocked, Algo now supports VLESS+Reality protocol:

```yaml
# In config.cfg, enable stealth VPN:
xray_enabled: true
xray_port: 443
xray_reality_dest: "www.microsoft.com:443"
xray_reality_sni: "www.microsoft.com"
```

Traffic appears as regular HTTPS to the configured destination. Works in China, Russia, Iran and other censored networks. Client apps: Shadowrocket (iOS), v2rayNG (Android), v2rayN (Windows), Nekoray (Linux/macOS).

## Deploy the Algo Server

The easiest way to get an Algo server running is to run it on your local system or from [Google Cloud Shell](docs/deploy-from-cloudshell.md) and let it set up a _new_ virtual machine in the cloud for you.
Expand Down Expand Up @@ -224,6 +240,7 @@ For the highest level of privacy, treat your Algo servers as disposable. Spin up
* Deploy from a [Docker container](docs/deploy-from-docker.md)

### Setup VPN Clients to Connect to the Server
* Setup [VLESS+Reality](docs/client-xray.md) stealth VPN clients (Shadowrocket, v2rayNG, etc.)
* Setup [Windows](docs/client-windows.md) clients
* Setup [Android](docs/client-android.md) clients
* Setup [Linux](docs/client-linux.md) clients with Ansible
Expand Down
1 change: 1 addition & 0 deletions algo-ubuntu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cd ~ && git clone https://github.com/trailofbits/algo.git && apt update && cd ./algo && apt install -y --no-install-recommends python3-virtualenv && python3 -m virtualenv --python="$(command -v python3)" .env && source .env/bin/activate && python3 -m pip install -U pip virtualenv && python3 -m pip install -r requirements.txt && ./algo
15 changes: 12 additions & 3 deletions config.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,25 @@ users:
- laptop
- desktop


### Review these options BEFORE you run Algo, as they are very difficult/impossible to change after the server is deployed.

# SSH port for cloud deployments (doesn't apply to existing Ubuntu servers)
ssh_port: 4160

# VPN protocols to deploy
ipsec_enabled: true
wireguard_enabled: true
# VPN protocols to deploy (defaults, can be overridden in interactive mode)
ipsec_enabled_default: true
wireguard_enabled_default: true
xray_enabled_default: true

wireguard_port: 51820 # Change if blocked by your network (avoid 53/UDP)

# Stealth VPN (VLESS + XTLS-Reality)
xray_port: 443
xray_reality_dest: "www.microsoft.com:443" # Target site to mimic
xray_reality_sni: "www.microsoft.com" # SNI for TLS handshake
xray_flow: "xtls-rprx-vision" # XTLS flow control

# Use different IP for outbound traffic (DigitalOcean only)
alternative_ingress_ip: false

Expand Down
136 changes: 136 additions & 0 deletions docs/client-xray.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# VLESS+Reality Client Setup Guide

VLESS with XTLS-Reality is a stealth VPN protocol that makes your traffic indistinguishable from regular HTTPS traffic. It's effective in networks where WireGuard and other VPN protocols are blocked.

## Generated Configuration Files

After deployment, client configuration files are located in:

```
configs/<server_ip>/xray/
├── <username>.json # Full xray client config
├── <username>.txt # VLESS share link
└── <username>.png # QR code for mobile apps
```

## Client Applications

### iOS/macOS

**Shadowrocket** (Recommended)
1. Open Shadowrocket
2. Tap the QR code icon in the top-left corner
3. Scan the QR code from `<username>.png`
4. Or copy the VLESS link from `<username>.txt` and paste it

**Streisand**
1. Open Streisand
2. Tap "+" to add a new server
3. Select "Scan QR Code" or "Import from Clipboard"
4. Use the provided QR code or VLESS link

### Android

**v2rayNG** (Recommended)
1. Install from [Google Play](https://play.google.com/store/apps/details?id=com.v2ray.ang) or [GitHub](https://github.com/2dust/v2rayNG)
2. Tap "+" button → "Import config from Clipboard"
3. Paste the VLESS link from `<username>.txt`
4. Or use the QR code scanner

**NekoBox**
1. Install from [GitHub](https://github.com/MatsuriDayo/NekoBoxForAndroid)
2. Tap "+" → "Import from Clipboard"
3. Paste the VLESS link

### Windows

**v2rayN** (Recommended)
1. Download from [GitHub](https://github.com/2dust/v2rayN)
2. Extract and run `v2rayN.exe`
3. Right-click tray icon → "Import from clipboard"
4. Paste the VLESS link

**Nekoray**
1. Download from [GitHub](https://github.com/MatsuriDayo/nekoray)
2. Server → Add Profile from Clipboard
3. Paste the VLESS link

### Linux

**v2rayA** (Web UI)
1. Install v2rayA following [official docs](https://v2raya.org/)
2. Open web interface (default: http://localhost:2017)
3. Import → Paste VLESS link

**Nekoray**
1. Download from [GitHub](https://github.com/MatsuriDayo/nekoray)
2. Extract and run
3. Server → Add Profile from Clipboard

**Command Line (xray-core)**
1. Install xray-core
2. Copy `<username>.json` to `/etc/xray/config.json`
3. Start service: `sudo systemctl start xray`

## Manual Configuration

If you need to configure manually, use these parameters from your `<username>.txt` file:

| Parameter | Description |
|-----------|-------------|
| Protocol | VLESS |
| Address | Server IP |
| Port | 443 |
| UUID | Your unique user ID |
| Flow | xtls-rprx-vision |
| Security | reality |
| SNI | Configured destination domain |
| Fingerprint | chrome |
| Public Key | Reality public key |
| Short ID | Reality short ID |

## VLESS Link Format

```
vless://UUID@SERVER:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=DOMAIN&fp=chrome&pbk=PUBLIC_KEY&sid=SHORT_ID&type=tcp#NAME
```

## Troubleshooting

### Connection fails immediately
- Verify server IP and port are correct
- Check if port 443 is open on the server
- Ensure the VLESS link was copied completely

### Connection drops after a few seconds
- Try a different Reality destination domain in `config.cfg`
- Some domains work better in certain regions

### Slow speeds
- VLESS+Reality has minimal overhead, similar to WireGuard
- Check your network connection quality
- Try different client applications

### QR code not scanning
- Ensure good lighting and camera focus
- Try copying the text link from `.txt` file instead

## Security Notes

- Keep your UUID and configuration private
- Each user has a unique UUID
- Sharing configurations allows others to use your server quota
- Reality protocol does not require you to own the destination domain

## Comparison with WireGuard

| Feature | WireGuard | VLESS+Reality |
|---------|-----------|---------------|
| Speed | Excellent | Excellent |
| Stealth | Poor (easily detected) | Excellent |
| Setup | Very simple | Simple |
| Blocked by DPI | Yes, commonly | No |
| Battery usage | Low | Low |
| Protocol | UDP | TCP |

Use WireGuard when it works, VLESS+Reality when WireGuard is blocked.
35 changes: 33 additions & 2 deletions input.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,37 @@
- server_name is undefined
- algo_provider != "local"

- name: VPN protocols prompt
pause:
prompt: |
Which VPN protocols do you want to enable?
1. XRAY (VLESS+Reality) - stealth, undetectable by DPI [recommended]
2. WireGuard - fast, but easily blocked
3. IPsec/IKEv2 - native on Apple devices
4. All protocols
5. XRAY + WireGuard
6. XRAY + IPsec
7. WireGuard + IPsec

Enter the number of your choice
[1]
register: _vpn_protocols
when: vpn_protocols is undefined

- name: Set VPN protocol facts
set_fact:
_vpn_choice: "{{ vpn_protocols | default(_vpn_protocols.user_input | default('1') | trim) | string | trim }}"

- name: Set protocol flags based on choice
set_fact:
xray_enabled: "{{ _vpn_choice in ['1', '4', '5', '6'] }}"
wireguard_enabled: "{{ _vpn_choice in ['2', '4', '5', '7'] }}"
ipsec_enabled: "{{ _vpn_choice in ['3', '4', '6', '7'] }}"

- name: Debug protocol selection
debug:
msg: "Choice={{ _vpn_choice }} -> xray={{ xray_enabled }}, wg={{ wireguard_enabled }}, ipsec={{ ipsec_enabled }}"

- name: Cellular On Demand prompt
pause:
prompt: |
Expand Down Expand Up @@ -88,7 +119,7 @@
register: _store_pki
when:
- store_pki is undefined
- ipsec_enabled
- ipsec_enabled | bool

- name: DNS adblocking prompt
pause:
Expand Down Expand Up @@ -125,6 +156,6 @@
algo_ssh_tunneling: >-
{% if ssh_tunneling is defined %}{{ ssh_tunneling | bool }}{%- elif _ssh_tunneling.user_input is defined %}{{ booleans_map[_ssh_tunneling.user_input] | default(defaults['ssh_tunneling']) }}{%- else %}{{ false }}{% endif %}
algo_store_pki: >-
{% if ipsec_enabled %}{%- if store_pki is defined %}{{ store_pki | bool }}{%- elif _store_pki.user_input is defined %}{{ booleans_map[_store_pki.user_input] | default(defaults['store_pki']) }}{%- else %}{{ false }}{% endif %}{% endif %}
{% if ipsec_enabled %}{%- if store_pki is defined %}{{ store_pki | bool }}{%- elif _store_pki.user_input is defined %}{{ booleans_map[_store_pki.user_input] | default(defaults['store_pki']) }}{%- else %}{{ false }}{% endif %}{% else %}{{ false }}{% endif %}
rescue:
- include_tasks: playbooks/rescue.yml
3 changes: 3 additions & 0 deletions playbooks/cloud-post.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
IP_subject_alt_name: "{{ IP_subject_alt_name }}"
alternative_ingress_ip: "{{ alternative_ingress_ip | default(omit) }}"
cloudinit: "{{ cloudinit | default(false) }}"
xray_enabled: "{{ xray_enabled }}"
wireguard_enabled: "{{ wireguard_enabled }}"
ipsec_enabled: "{{ ipsec_enabled }}"

- name: Additional variables for the server
add_host:
Expand Down
5 changes: 5 additions & 0 deletions pyvenv.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
home = /opt/homebrew/opt/python@3.13/bin
include-system-site-packages = false
version = 3.13.1
executable = /opt/homebrew/Cellar/python@3.13/3.13.1/Frameworks/Python.framework/Versions/3.13/bin/python3.13
command = /opt/homebrew/opt/python@3.13/bin/python3.13 -m venv /Users/andrey/Developer/libraries/algo
Loading