Test scenario
Connect from Tor Browser Alpha on Windows to WebTunnel bridge on Ubuntu Linux.
Expected results
Tor Browser Alpha connects to Tor network through WebTunnel bridge.
Actual result
“General SOCKS server failure” in Tor Browser Alpha on Windows.
Procedure
Firewall
Open ports tcp/80
, tcp/443
, and tcp/10000
.
Install Tor
apt install apt-transport-https
lsb_release -c
Result:
Codename: jammy
cat <<EOF > /etc/apt/sources.list.d/tor.list
deb [signed-by=/usr/share/keyrings/tor-archive-keyring.gpg] https://deb.torproject.org/torproject.org jammy main
deb-src [signed-by=/usr/share/keyrings/tor-archive-keyring.gpg] https://deb.torproject.org/torproject.org jammy main
EOF
wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --dearmor | tee /usr/share/keyrings/tor-archive-keyring.gpg >/dev/null
apt update
apt install tor deb.torproject.org-keyring
Disable default instance
systemctl stop tor@default
systemctl mask tor@default
Install Go
wget https://go.dev/dl/go1.20.5.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.20.5.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
source /etc/profile
go version
Result:
go version go1.20.5 linux/amd64
Build webtunnel binary
git clone https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/webtunnel
cd webtunnel/main/server
go build
Copy server file to server
mkdir -p /var/lib/torwebtunnel
cp server /var/lib/torwebtunnel/webtunnel
cd ~
Set up new torrc
cat <<EOF > /var/lib/torwebtunnel/torrc
Log notice
BridgeRelay 1
Address xx.xx.xx.xx
AddressDisableIPv6 1
ORPort 10000 IPv4Only
ExtORPort auto
ServerTransportPlugin webtunnel exec /var/lib/torwebtunnel/webtunnel
ServerTransportListenAddr webtunnel 127.0.0.1:15000
ContactInfo xxx@xxx.xxx
Nickname computerscot4
PublishServerDescriptor 1
BridgeDistribution https
DataDirectory /var/lib/torwebtunnel/tor-data
CacheDirectory /tmp/tor-tmp-torwebtunnel
SocksPort 0
EOF
Create systemd service unit
cat <<EOF > /usr/lib/systemd/system/torwebtunnel.service
[Unit]
Description=Tor Web Tunnel
[Service]
Type=simple
DynamicUser=yes
PrivateUsers=true
PrivateMounts=true
ProtectSystem=strict
PrivateTmp=true
PrivateDevices=true
ProtectClock=true
NoNewPrivileges=true
ProtectHome=tmpfs
ProtectKernelModules=true
ProtectKernelLogs=true
StateDirectory=torwebtunnel
ExecStart=/usr/bin/tor -f /var/lib/torwebtunnel/torrc --RunAsDaemon 0
[Install]
WantedBy=default.target
EOF
Obtain SSL certificate
apt install socat
curl https://get.acme.sh | sh -s email=xxx@xxx.xxx
~/.acme.sh/acme.sh --issue --standalone --domain xxx.xxx.xxx
Results:
Your cert is in: /root/.acme.sh/xxx.xxx.xxx_ecc/xxx.xxx.xxx.cer
Your cert key is in: /root/.acme.sh/xxx.xxx.xxx_ecc/xxx.xxx.xxx.key
The intermediate CA cert is in: /root/.acme.sh/xxx.xxx.xxx_ecc/ca.cer
And the full chain certs is there: /root/.acme.sh/xxx.xxx.xxx_ecc/fullchain.cer
Install Nginx
apt install nginx
Configure HTTP upgrade forwarding
vi /etc/nginx/nginx.conf
Delete existing contents and insert:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
#WebSocket Support
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
}
Save file and check:
nginx -t
Results:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Generate random string
echo $(cat /dev/urandom | tr -cd "qwertyuiopasdfghjklzxcvbnmMNBVCXZLKJHGFDSAQWERTUIOP0987654321"|head -c 24)
Result:
zJvOFtjG8g3pTvi7xCsQP9ev
Define SSL virtual host
vi /etc/nginx/sites-available/bridge.conf
Insert contents:
server {
listen [::]:443 ssl http2;
listen 443 ssl http2;
server_name xxx.xxx.xxx;
ssl_certificate /root/.acme.sh/xxx.xxx.xxx_ecc/fullchain.cer;
ssl_certificate_key /root/.acme.sh/xxx.xxx.xxx_ecc/xxx.xxx.xxx.key;
ssl_session_timeout 15m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:MozSSL:50m;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=63072000" always;
location /zJvOFtjG8g3pTvi7xCsQP9ev {
proxy_pass http://127.0.0.1:11000;
proxy_http_version 1.1;
#### Set WebSocket headers ####
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
#### Set Proxy headers ####
proxy_set_header Accept-Encoding "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Front-End-Https on;
proxy_redirect off;
}
}
Save file. Enable virtual host:
ln -s /etc/nginx/sites-available/bridge.conf /etc/nginx/sites-enabled/
Restart Nginx and Tor
systemctl restart nginx
systemctl status nginx
systemctl enable torwebtunnel
systemctl start torwebtunnel
systemctl status torwebtunnel
Check log:
journalctl -u torwebtunnel
Results:
[notice] Bootstrapped 100% (done): Done
[notice] Now checking whether IPv4 ORPort xx.xx.xx.xx:10000 is reachable... (this may take up to 20 minutes -- look for log messages indicating success)
[notice] Self-testing indicates your ORPort xx.xx.xx.xx:10000 is reachable from the outside. Excellent. Publishing server descriptor.
[notice] Performing bandwidth self-test...done.
Install Docker Runtime
apt install curl
curl -fsSL https://get.docker.com -o get-docker.sh
sh ./get-docker.sh
Create environment file
truncate --size 0 .env
echo "URL=https://xxx.xxx.xxx/zJvOFtjG8g3pTvi7xCsQP9ev" >> .env
echo "OPERATOR_EMAIL=xxx@xxx.xxx" >> .env
echo "BRIDGE_NICKNAME=WTBr$(cat /dev/urandom | tr -cd 'qwertyuiopasdfghjklzxcvbnmMNBVCXZLKJHGFDSAQWERTUIOP0987654321'|head -c 10)" >> .env
echo "GENEDORPORT=4$(cat /dev/urandom | tr -cd '0987654321'|head -c 4)" >> .env
cat .env
Results:
URL=https://xxx.xxx.xxx/zJvOFtjG8g3pTvi7xCsQP9ev
OPERATOR_EMAIL=xxx@xxx.xxx
BRIDGE_NICKNAME=WTBrP6TzuRxSTD
GENEDORPORT=42535
Run Dockerized Webtunnel Server
Download the webtunnel docker-compose.yml
file, and bring up an instance.
curl https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/webtunnel/-/raw/main/release/container/docker-compose.yml?inline=false > docker-compose.yml
docker compose up -d
Get bridgeline and check it is running
Obtain the bridgeline and verify if it is working:
docker compose exec webtunnel-bridge get-bridge-line.sh
Results:
webtunnel [2001:db8:28de:4544:14ec:2f8c:6d9e:2688]:443 2418D877099DF2AF120FCC4BA4707255B8A97895 url=https://xxx.xxx.xxx/zJvOFtjG8g3pTvi7xCsQP9ev
Client Usage
Download torbrowser-install-win64-12.5a7_ALL.exe from Tor Project | Download Tor Browser Alpha
Run installer for Tor Browser Alpha.
Run Tor Browser Alpha.
Click Configure Connection.
Click Add a Bridge Manually.
Use the bridgeline displayed on the server (or get the bridgeline from https://bridges.torproject.org) and press Connect.
Click View logs. Click View Logs.
Results:
New control connection opened from 127.0.0.1.
New control connection opened from 127.0.0.1.
DisableNetwork is set. Tor will not make or accept non-control network connections. Shutting down all existing connections.
DisableNetwork is set. Tor will not make or accept non-control network connections. Shutting down all existing connections.
New control connection opened from 127.0.0.1.
Renaming old configuration file to "C:\Users\dcame\Downloads\Tor Browser\Browser\TorBrowser\Data\Tor\torrc.orig.1"
DisableNetwork is set. Tor will not make or accept non-control network connections. Shutting down all existing connections.
Switching to guard context "bridges" (was using "default")
DisableNetwork is set. Tor will not make or accept non-control network connections. Shutting down all existing connections.
Opening Socks listener on 127.0.0.1:9150
Opened Socks listener connection (ready) on 127.0.0.1:9150
Pluggable Transport process terminated with status code 0
Bootstrapped 1% (conn_pt): Connecting to pluggable transport
Bootstrapped 2% (conn_done_pt): Connected to pluggable transport
Proxy Client: unable to connect OR connection (handshaking (proxy)) with [2001:db8:28de:4544:14ec:2f8c:6d9e:2688]:443 ID=<none> RSA_ID=2418D877099DF2AF120FCC4BA4707255B8A97895 ("general SOCKS server failure")
Proxy Client: unable to connect OR connection (handshaking (proxy)) with [2001:db8:28de:4544:14ec:2f8c:6d9e:2688]:443 ID=<none> RSA_ID=2418D877099DF2AF120FCC4BA4707255B8A97895 ("general SOCKS server failure")
Proxy Client: unable to connect OR connection (handshaking (proxy)) with [2001:db8:28de:4544:14ec:2f8c:6d9e:2688]:443 ID=<none> RSA_ID=2418D877099DF2AF120FCC4BA4707255B8A97895 ("general SOCKS server failure")
Proxy Client: unable to connect OR connection (handshaking (proxy)) with [2001:db8:28de:4544:14ec:2f8c:6d9e:2688]:443 ID=<none> RSA_ID=2418D877099DF2AF120FCC4BA4707255B8A97895 ("general SOCKS server failure")
Proxy Client: unable to connect OR connection (handshaking (proxy)) with [2001:db8:28de:4544:14ec:2f8c:6d9e:2688]:443 ID=<none> RSA_ID=2418D877099DF2AF120FCC4BA4707255B8A97895 ("general SOCKS server failure")
New control connection opened from 127.0.0.1.
Application request when we haven't used client functionality lately. Optimistically trying known bridges again.
Proxy Client: unable to connect OR connection (handshaking (proxy)) with [2001:db8:28de:4544:14ec:2f8c:6d9e:2688]:443 ID=<none> RSA_ID=2418D877099DF2AF120FCC4BA4707255B8A97895 ("general SOCKS server failure")
Proxy Client: unable to connect OR connection (handshaking (proxy)) with [2001:db8:28de:4544:14ec:2f8c:6d9e:2688]:443 ID=<none> RSA_ID=2418D877099DF2AF120FCC4BA4707255B8A97895 ("general SOCKS server failure")
Proxy Client: unable to connect OR connection (handshaking (proxy)) with [2001:db8:28de:4544:14ec:2f8c:6d9e:2688]:443 ID=<none> RSA_ID=2418D877099DF2AF120FCC4BA4707255B8A97895 ("general SOCKS server failure")
Proxy Client: unable to connect OR connection (handshaking (proxy)) with [2001:db8:28de:4544:14ec:2f8c:6d9e:2688]:443 ID=<none> RSA_ID=2418D877099DF2AF120FCC4BA4707255B8A97895 ("general SOCKS server failure")
Proxy Client: unable to connect OR connection (handshaking (proxy)) with [2001:db8:28de:4544:14ec:2f8c:6d9e:2688]:443 ID=<none> RSA_ID=2418D877099DF2AF120FCC4BA4707255B8A97895 ("general SOCKS server failure")