Automated Tor Bridge Fleet Management with Ansible
Running 10 or more Tor bridges manually is unsustainable. Configuration drift between instances, manual rotation processes, and inconsistent monitoring setups compound into reliability problems that degrade service for users. Infrastructure automation with Ansible transforms bridge fleet management from an ongoing manual effort into a repeatable, auditable process where adding a new bridge instance, rotating an IP, or updating configurations across the fleet takes minutes instead of hours. This guide covers a practical Ansible-based bridge fleet architecture suitable for organizations running 5 to 50 bridge instances.
Need this done for your project?
We implement, you ship. Async, documented, done in days.
Repository Structure for Bridge Fleet
Organize the bridge fleet Ansible repository with clear separation between inventory, roles, and playbooks:
bridge-fleet/
inventory/
production.yml # Active bridge hosts
staging.yml # Test instances
roles/
tor-bridge/
tasks/main.yml
templates/torrc.j2
handlers/main.yml
monitoring/
tasks/main.yml
security-hardening/
tasks/main.yml
playbooks/
provision-bridge.yml
rotate-bridge.yml
update-all.yml
emergency-shutdown.yml
vars/
vault.yml # Encrypted credentials
common.yml # Shared configuration
Store the repository in a private git repository with encrypted secrets managed through Ansible Vault. This structure allows any operator with the vault password to provision, update, or rotate bridges from any machine with Ansible installed, without requiring direct SSH access to individual bridge servers during normal operations.
The tor-bridge Role
The core role handles all Tor relay configuration. The torrc.j2 template uses Ansible variables to customize each bridge instance:
BridgeRelay 1
ORPort {{ orport }}
ExtORPort auto
ServerTransportPlugin obfs4 exec /usr/bin/obfs4proxy
ServerTransportListenAddr obfs4 0.0.0.0:{{ obfs4_port }}
PublishServerDescriptor {{ publish_descriptor }}
ContactInfo {{ contactinfo }}
Nickname {{ nickname }}
RelayBandwidthRate {{ bandwidth_rate }} MB
RelayBandwidthBurst {{ bandwidth_burst }} MB
AccountingMax {{ accounting_max }} GB
AccountingStart month 1 00:00
The tasks/main.yml installs packages, deploys the torrc template, manages the firewall, and starts the service. A handler restarts tor when the configuration changes. After provisioning, a separate task waits for the bridge line file to appear and registers its content as a variable for downstream use in notifications or distribution automation.
Rotation Playbook
The rotation playbook coordinates the complete IP rotation workflow:
# rotate-bridge.yml
- name: Rotate bridge IP
hosts: "{{ old_bridge }}"
tasks:
- name: Disable bridge from distribution
delegate_to: localhost
command: ./scripts/remove-from-distribution.sh "{{ inventory_hostname }}"
- name: Stop tor service
service: name=tor state=stopped
- name: Provision replacement bridge
hosts: "{{ new_bridge }}"
roles:
- tor-bridge
- monitoring
- name: Fetch new bridge line
hosts: "{{ new_bridge }}"
tasks:
- name: Read bridge line
slurp: src=/var/lib/tor/pt_state/obfs4_bridgeline.txt
register: new_bridge_line
- name: Add to distribution
delegate_to: localhost
command: ./scripts/add-to-distribution.sh "{{ new_bridge_line.content | b64decode }}"
- name: Terminate old bridge
hosts: "{{ old_bridge }}"
tasks:
- name: Final cleanup
shell: "echo 'Bridge {{ inventory_hostname }} decommissioned'"
Run the rotation playbook with: ansible-playbook rotate-bridge.yml -e "old_bridge=bridge01 new_bridge=bridge06" --vault-password-file .vault-pass. The entire rotation including notification to distribution channels completes in under 10 minutes.
Related Services
Why Anubiz Host
Ready to get started?
Skip the research. Tell us what you need, and we'll scope it, implement it, and hand it back — fully documented and production-ready.