Local network tool that transparently redirects all X/Twitter traffic to xcancel.com, allowing you to browse Twitter content without directly accessing X's servers.
Complete end-to-end walkthroughs for common xcancel-forwarder configurations.
Each example includes the full setup process, verification steps, and typical issues you might encounter.
Scenario: You have Pi-hole running on a Raspberry Pi. You want network-wide redirect that works on your Mac and iPhone.
Your Network:
192.168.1.2192.168.1.10192.168.1.100192.168.1.0/24, gateway 192.168.1.1# On your laptop
cd ~/
git clone https://github.com/ryantenney/xcancel-forwarder.git
cd xcancel-forwarder
# Create environment file
cp .env.example .env
vim .env
Edit .env:
NGINX_IP=192.168.1.100
LAN_INTERFACE=en0 # Your Mac's interface
LAN_SUBNET=192.168.1.0/24
LAN_GATEWAY=192.168.1.1
Edit docker-compose.yaml:
# Install mkcert
brew install mkcert
# Create and install CA
mkcert -install
# Generate certificates
mkcert twitter.com x.com "*.twitter.com" "*.x.com" t.co "*.t.co"
# Move to nginx directory
mv twitter.com+5.pem nginx/ssl/server.crt
mv twitter.com+5-key.pem nginx/ssl/server.key
docker compose up -d
# Check status
docker compose ps
# Should show nginx Up/healthy
# Test from another device (not Mac - macvlan limitation)
# From iPhone:
curl http://192.168.1.100
# Should return 301 to xcancel.com
http://192.168.1.2/admintwitter.com → 192.168.1.100x.com → 192.168.1.100t.co → 192.168.1.100*.twitter.com → twitter.com*.x.com → x.com# Test from Mac
nslookup twitter.com
# Should return 192.168.1.100
# Test other domains
nslookup google.com
# Should return real IP (Pi-hole forwarding)
# mkcert already installed it
# Verify:
security find-certificate -c "mkcert" -a
# Should show your CA
https://twitter.commkcert -CAROOT
# Shows location, usually: /Users/yourname/Library/Application Support/mkcert
rootCA.pem file to yourselfhttps://twitter.comMac can’t test redirect:
iPhone shows certificate warning:
iPhone not redirecting:
Scenario: No existing DNS server. You want simplest setup with Caddy for entire home network.
Your Network:
192.168.1.50192.168.1.100192.168.1.101192.168.1.0/24, gateway 192.168.1.1192.168.1.1git clone https://github.com/ryantenney/xcancel-forwarder.git
cd xcancel-forwarder
cp .env.example .env
vim .env
Edit .env:
LAN_INTERFACE=eth0
LAN_SUBNET=192.168.1.0/24
LAN_GATEWAY=192.168.1.1
NGINX_IP=192.168.1.100
DNSMASQ_IP=192.168.1.101
Edit dnsmasq/dnsmasq.conf:
# Update nginx IP
address=/twitter.com/192.168.1.100
address=/x.com/192.168.1.100
address=/t.co/192.168.1.100
# Upstream DNS (Cloudflare)
server=1.1.1.1
server=1.0.0.1
Edit docker-compose.caddy.yaml:
# Install mkcert (Linux example)
sudo apt install mkcert
# Create and install CA
mkcert -install
# Generate certificates
mkcert twitter.com x.com "*.twitter.com" "*.x.com" t.co "*.t.co"
# Move to Caddy directory
mv twitter.com+5.pem caddy/ssl/server.crt
mv twitter.com+5-key.pem caddy/ssl/server.key
docker compose -f docker-compose.caddy.yaml up -d
# Check both containers
docker compose ps
# Should show caddy and dnsmasq both Up
# From another computer/phone on network
nslookup twitter.com 192.168.1.101
# Should return 192.168.1.100
curl -I http://192.168.1.100
# Should return 301 to xcancel.com
http://192.168.1.1192.168.1.101 (your dnsmasq)1.1.1.1 (fallback)All devices need to get new DHCP lease:
Windows:
rootCA.pem from Docker hostLinux:
sudo cp rootCA.pem /usr/local/share/ca-certificates/xcancel-ca.crt
sudo update-ca-certificates
Android:
rootCA.pem to phoneiOS: See Example 1 step 9
Test from multiple devices:
# Each device
nslookup twitter.com
# Should return 192.168.1.100
# Browser test
# Visit https://twitter.com
# Should redirect without warnings
Some devices still using old DNS:
DNS not working from Docker host:
dnsmasq port 53 conflict:
sudo systemctl stop systemd-resolvedScenario: You can access your router’s DNS settings. Simple setup for Android phone.
Your Network:
192.168.0.5192.168.0.5192.168.0.0/24192.168.0.1 (supports static DNS)git clone https://github.com/ryantenney/xcancel-forwarder.git
cd xcancel-forwarder
# Use default .env (bridge mode)
# No changes needed for bridge networking
# Edit nginx/conf.d/xcancel-redirect.conf
# Comment out SSL-related lines:
# - Lines 3, 5, 9, 13-18, 20-21
# Or just remove the HTTPS server block
docker compose up -d
# Test
curl -I http://localhost
# Should return 301 to xcancel.com
http://192.168.0.1twitter.com → 192.168.0.5x.com → 192.168.0.5t.co → 192.168.0.5Note: Not all routers support this. If yours doesn’t, use dnsmasq instead.
Since router DNS may not support wildcards:
192.168.0.1Alternative: Leave Wi-Fi on DHCP and edit /etc/hosts (requires root).
http://twitter.com (note: HTTP, not HTTPS)HTTP only:
Manual DNS on Android:
To add HTTPS:
Scenario: Single laptop, don’t want to run DNS server, simplest possible setup.
Your Setup:
git clone https://github.com/ryantenney/xcancel-forwarder.git
cd xcancel-forwarder
# Use all defaults - no .env changes needed
# Edit nginx/conf.d/xcancel-redirect.conf
# Comment out HTTPS server block (lines 9-23)
# Keep only HTTP server block
docker compose up -d
# Test
curl -I http://localhost
# Should return 301
macOS/Linux:
sudo vim /etc/hosts
# Add these lines:
127.0.0.1 twitter.com www.twitter.com
127.0.0.1 x.com www.x.com
127.0.0.1 t.co
Windows:
# Run as Administrator
notepad C:\Windows\System32\drivers\etc\hosts
# Add these lines:
127.0.0.1 twitter.com www.twitter.com
127.0.0.1 x.com www.x.com
127.0.0.1 t.co
macOS:
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
Windows:
ipconfig /flushdns
Linux:
sudo systemd-resolve --flush-caches
# Test DNS
nslookup twitter.com
# Should return 127.0.0.1
# Test redirect
curl -I http://twitter.com
# Should return 301 to xcancel.com
# Browser
# Visit http://twitter.com
# Should redirect to xcancel.com
Wildcard subdomains don’t work:
mobile.twitter.com won’t redirectHTTPS shows warnings:
Single device only:
Perfect for:
Not suitable for:
Scenario: You already run nginx as reverse proxy (or nginx-proxy-manager). You want to add Twitter redirect without disrupting existing setup.
Your Setup:
Don’t run xcancel-forwarder containers. Just add redirect rules.
# Add to your existing nginx config
sudo vim /etc/nginx/sites-available/twitter-redirect
# Add this:
server {
listen 80;
listen [::]:80;
server_name twitter.com www.twitter.com x.com www.x.com t.co www.t.co;
location / {
return 301 https://xcancel.com$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name twitter.com www.twitter.com x.com www.x.com t.co www.t.co;
# Use your existing SSL certificates or create new ones
ssl_certificate /etc/letsencrypt/live/twitter.local/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/twitter.local/privkey.pem;
location / {
return 301 https://xcancel.com$request_uri;
}
}
Since Let’s Encrypt won’t issue certificates for twitter.com (you don’t own it), use self-signed:
# Create certificate
sudo mkcert -install
sudo mkcert twitter.com x.com "*.twitter.com" "*.x.com" t.co "*.t.co"
# Or use your existing CA
# Enable site
sudo ln -s /etc/nginx/sites-available/twitter-redirect /etc/nginx/sites-enabled/
# Test config
sudo nginx -t
# Reload
sudo systemctl reload nginx
# Test
curl -I http://your-server-ip
# Set Host header to test:
curl -I -H "Host: twitter.com" http://your-server-ip
# Should return 301
Use Pi-hole, dnsmasq, or router DNS to point domains to your nginx server IP.
Run xcancel-forwarder on ports 8080/8443, proxy from main nginx.
# docker-compose.yaml (bridge mode)
services:
nginx:
ports:
- "8080:80"
- "8443:443"
docker compose up -d
# In your main nginx config
server {
listen 80;
server_name twitter.com x.com t.co;
location / {
proxy_pass http://localhost:8080;
}
}
server {
listen 443 ssl;
server_name twitter.com x.com t.co;
# Your SSL config...
location / {
proxy_pass https://localhost:8443;
}
}
curl -I -H "Host: twitter.com" http://localhost
# Should return 301 from proxied xcancel-forwarder
Option A (add rules):
Option B (proxy to containers):
| Example | DNS Method | Web Server | SSL | Complexity | Best For |
|---|---|---|---|---|---|
| #1 | Pi-hole | nginx | mkcert | Medium | Existing Pi-hole users |
| #2 | dnsmasq | Caddy | mkcert | Medium | Whole network, no Pi-hole |
| #3 | Router | nginx | None | Low | Router with static DNS |
| #4 | Hosts file | nginx | None | Low | Single device testing |
| #5 | Any | Existing | Your choice | Medium | Existing reverse proxy |
Have a different setup? Submit a PR with your example!
Include: