Anonymization

Network anonymization and privacy techniques. Proxychains, Tor, VPN stacking, I2P, Whonix, MAC spoofing, metadata stripping, browser fingerprint hardening, and censorship circumvention.

#Network Anonymization

#Proxychains

Routes TCP connections through a chain of proxy servers, hiding the true source IP from the destination.

# /etc/proxychains4.conf
# Choose ONE chain mode:

dynamic_chain    # Skip dead proxies, continue through chain
# strict_chain  # All proxies must be up, in exact order
# round_robin_chain  # Rotate proxies round-robin per connection
# random_chain  # Random order each connection

proxy_dns        # CRITICAL - prevents DNS leaks
remote_dns_subnet 224   # Subnet for internal DNS mapping
tcp_read_time_out 15000
tcp_connect_time_out 8000

# Proxy list (bottom of file)
[ProxyList]
socks5 127.0.0.1 9050        # Tor
socks5 10.10.10.1 1080       # Custom SOCKS5
http   192.168.1.100 8080    # HTTP proxy

Usage with common tools:

# Basic usage pattern
proxychains4 <command>

# Nmap (must use TCP connect scan - no SYN/UDP)
proxychains4 nmap -sT -Pn -n --top-ports 100 10.10.10.5

# curl
proxychains4 curl https://check.torproject.org

# Firefox
proxychains4 firefox &

# Metasploit
proxychains4 msfconsole

Chain modes compared:

Mode Behavior Use Case
dynamic_chain Skips dead proxies, continues General use, fault-tolerant
strict_chain All proxies must respond, in order When exact path matters
round_robin_chain Rotates through proxy list Load balancing across proxies
random_chain Random proxy per connection Harder to fingerprint pattern

Supported proxy types:

Type Keyword Auth Support Notes
SOCKS4 socks4 No TCP only, no DNS via proxy
SOCKS5 socks5 Yes (user/pass) TCP + UDP (limited), DNS via proxy
HTTP http Yes (Basic/NTLM) CONNECT method, HTTP tunneling

Common pitfall: if proxy_dns is not enabled, DNS queries go directly to the system resolver, leaking your real IP to the DNS server. Always verify with tcpdump -i eth0 port 53 while proxychains is active.

#Tor

The Onion Router - encrypts traffic through 3 relays (guard, middle, exit). Each relay only knows the previous and next hop.

# Install and start Tor
sudo apt install tor
sudo systemctl enable --now tor

# Default SOCKS5 proxy
# 127.0.0.1:9050 (Tor service)
# 127.0.0.1:9150 (Tor Browser)

# Verify Tor is running
ss -tlnp | grep 9050

Proxychains + Tor:

# /etc/proxychains4.conf
[ProxyList]
socks5 127.0.0.1 9050

torsocks for transparent routing:

# Wraps application to route through Tor
torsocks curl https://check.torproject.org
torsocks ssh user@host
torsocks wget http://target.com/file.zip

# Check current Tor exit IP
torsocks curl -s https://api.ipify.org && echo

Circuit rotation:

# Force new Tor circuit (new exit node)
sudo systemctl reload tor

# Or via control port (must enable in torrc)
# /etc/tor/torrc:
#   ControlPort 9051
#   HashedControlPassword <hash>

# Generate hashed password for torrc
tor --hash-password "mypassword"

# Request new circuit via control port
echo -e 'AUTHENTICATE "mypassword"\r\nSIGNAL NEWNYM\r\nQUIT' \
  | nc 127.0.0.1 9051

# Using stem (Python library) for control
pip install stem
python3 -c "
from stem import Signal
from stem.control import Controller
with Controller.from_port(port=9051) as c:
    c.authenticate('mypassword')
    c.signal(Signal.NEWNYM)
    print('New circuit requested')
"

#Tor Stream Isolation

Prevents different applications from sharing the same Tor circuit. Each IsolateSOCKSAuth port gets its own circuit.

# /etc/tor/torrc - Stream isolation ports
SocksPort 9050              # Default (shared circuits)
SocksPort 9052 IsolateDestAddr IsolateDestPort
SocksPort 9053 IsolateSOCKSAuth IsolateClientAddr
SocksPort 9054 IsolateDestAddr

# Each port gets separate circuits
# 9052: new circuit per unique destination
# 9053: new circuit per auth + client
# 9054: new circuit per destination address

Application-specific isolation:

# Browser on port 9050 (default)
# curl on port 9052 (isolated by destination)
curl --socks5-hostname 127.0.0.1:9052 https://target.com

# SSH on port 9053 (isolated by auth)
torsocks -P 9053 ssh user@host

# In proxychains, use different configs:
# proxychains4 -f /etc/proxychains-9052.conf curl ...

#Tor Bridges and Transports

Bridges are unlisted Tor relays used to bypass censorship. Pluggable transports disguise Tor traffic.

# /etc/tor/torrc - obfs4 bridge
UseBridges 1
ClientTransportPlugin obfs4 exec /usr/bin/obfs4proxy

Bridge obfs4 IP:PORT FINGERPRINT cert=... iat-mode=0
# Get bridges: https://bridges.torproject.org
# /etc/tor/torrc - Snowflake (looks like WebRTC)
UseBridges 1
ClientTransportPlugin snowflake exec /usr/bin/snowflake-client

Bridge snowflake 192.0.2.3:80 2B280B23E1107BB62ABFC40DDCC8824814F80A72 \
  fingerprint=2B280B23E1107BB62ABFC40DDCC8824814F80A72 \
  url=https://snowflake-broker.torproject.net.global.prod.fastly.net/ \
  fronts=cdn.sstatic.net,www.phpmyadmin.net \
  ice=stun:stun.l.google.com:19302,stun:stun.antisip.com:3478 \
  utls-imitate=hellorandomizedalpn
# /etc/tor/torrc - meek-azure (looks like Azure traffic)
UseBridges 1
ClientTransportPlugin meek_lite exec /usr/bin/obfs4proxy

Bridge meek_lite 192.0.2.18:80 BE776A53492E1E044A26F17306E1BC46A55A1625 \
  url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com

Available transport types:

Transport Disguise Speed Detection Resistance
obfs4 Randomized bytes Good High
Snowflake WebRTC video call Moderate Very high
meek Cloud CDN HTTPS Slow Very high
webtunnel HTTPS website Good Very high

#Tor Hidden Services

Host services accessible only via .onion addresses. Traffic never leaves the Tor network.

# /etc/tor/torrc - Hidden service for C2
HiddenServiceDir /var/lib/tor/c2_service/
HiddenServicePort 443 127.0.0.1:8443

# Multi-port service
HiddenServiceDir /var/lib/tor/multi_service/
HiddenServicePort 80 127.0.0.1:8080
HiddenServicePort 22 127.0.0.1:22

# After restart, .onion address in:
# /var/lib/tor/c2_service/hostname
# Restart Tor, get .onion address
sudo systemctl restart tor
sudo cat /var/lib/tor/c2_service/hostname

OnionShare for anonymous file sharing:

# Install
sudo apt install onionshare-cli

# Share files (creates temporary .onion)
onionshare-cli --receive   # Receive files anonymously
onionshare-cli file.zip    # Share file via .onion link
onionshare-cli --chat      # Anonymous chat room

# Persistent address (keeps same .onion)
onionshare-cli --persistent ~/.onionshare file.zip

Monitor Tor with Nyx (formerly arm):

# Install and run Tor monitor
sudo apt install nyx
nyx  # Requires ControlPort enabled in torrc
# Shows bandwidth, circuits, connections in real-time

#VPN

Encrypts all traffic between client and VPN server. Replaces your visible IP with the server's IP.

WireGuard quick setup:

# Install
sudo apt install wireguard

# Generate keys (server)
wg genkey | tee server_private.key | wg pubkey > server_public.key

# Generate keys (client)
wg genkey | tee client_private.key | wg pubkey > client_public.key

# Generate preshared key (additional encryption layer)
wg genpsk > preshared.key
# /etc/wireguard/wg0.conf (Server)
[Interface]
PrivateKey = <server_private_key>
Address = 10.0.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = <client_public_key>
PresharedKey = <preshared_key>
AllowedIPs = 10.0.0.2/32
# /etc/wireguard/wg0.conf (Client)
[Interface]
PrivateKey = <client_private_key>
Address = 10.0.0.2/24
DNS = 10.0.0.1

[Peer]
PublicKey = <server_public_key>
PresharedKey = <preshared_key>
Endpoint = <server_ip>:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
# Bring interface up/down
sudo wg-quick up wg0
sudo wg-quick down wg0
sudo wg show

VPN + Tor combinations:

Setup Flow Pros Cons
VPN then Tor You > VPN > Tor > Dest ISP sees VPN only, not Tor usage VPN provider knows you use Tor
Tor then VPN You > Tor > VPN > Dest Exit node can't see traffic, VPN sees Tor exit IP VPN sees traffic content (if not E2E encrypted)

Kill switch (prevent leaks if VPN drops):

# iptables kill switch - only allow traffic through VPN
VPN_SERVER="<vpn_server_ip>"
VPN_IF="wg0"  # or tun0 for OpenVPN

# Flush and set default DROP
sudo iptables -F
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT DROP

# Block ALL IPv6 (prevents IPv6 leaks)
sudo ip6tables -P INPUT DROP
sudo ip6tables -P FORWARD DROP
sudo ip6tables -P OUTPUT DROP

# Allow loopback
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT

# Allow VPN establishment
sudo iptables -A OUTPUT -d $VPN_SERVER -j ACCEPT
sudo iptables -A INPUT -s $VPN_SERVER -j ACCEPT

# Allow all traffic through VPN interface
sudo iptables -A OUTPUT -o $VPN_IF -j ACCEPT
sudo iptables -A INPUT -i $VPN_IF -j ACCEPT

# Allow LAN (optional - remove for maximum isolation)
sudo iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
sudo iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT

# Save rules persistently
sudo apt install iptables-persistent
sudo netfilter-persistent save

DNS leak prevention:

# Force DNS through VPN only
echo "nameserver 10.0.0.1" | sudo tee /etc/resolv.conf

# Prevent resolv.conf overwrite by DHCP/NetworkManager
sudo chattr +i /etc/resolv.conf

# Verify: check for leaks
# These should show VPN IP, not real IP
curl -s https://api.ipify.org && echo
dig +short myip.opendns.com @resolver1.opendns.com

# Verify no plaintext DNS escaping
sudo tcpdump -i eth0 port 53 -c 5
# Should capture nothing if DNS goes through VPN

#I2P and Overlay Networks

#I2P (Invisible Internet Project)

Garlic routing network - bundles multiple messages together. Designed for internal services (eepsites) rather than clearnet access.

# Install I2P
sudo apt install apt-transport-https
wget -q -O - https://geti2p.net/_static/i2p-archive-keyring.gpg \
  | sudo tee /usr/share/keyrings/i2p-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/i2p-archive-keyring.gpg] \
  https://deb.i2p2.de/ $(lsb_release -sc) main" \
  | sudo tee /etc/apt/sources.list.d/i2p.list
sudo apt update && sudo apt install i2p i2p-keyring

# Start I2P router
i2prouter start
# Web console: http://127.0.0.1:7657

# Or as system service
sudo systemctl enable --now i2p

I2P proxy configuration:

# I2P provides several local proxies:
HTTP proxy:    127.0.0.1:4444  (for .i2p sites)
HTTPS proxy:   127.0.0.1:4445
SOCKS proxy:   127.0.0.1:4447  (must enable in console)
IRC:           127.0.0.1:6668
SMTP:          127.0.0.1:7659
POP3:          127.0.0.1:7660
# Access .i2p eepsites
curl --proxy http://127.0.0.1:4444 http://stats.i2p

# Configure browser: set HTTP proxy to 127.0.0.1:4444
# Only use for .i2p domains

Tor vs I2P:

Feature Tor I2P
Primary use Clearnet anonymity Internal network services
Routing Onion (circuit-based) Garlic (packet-based)
Latency Moderate Higher
Hidden services .onion .i2p (eepsites)
Outproxy (clearnet) Built-in (exit nodes) Limited, unreliable
Threat model Exit node surveillance Peer enumeration

#Whonix / Tails

Whonix - two-VM architecture for Tor isolation:

Component Role
Gateway VM Runs Tor, all traffic forced through it
Workstation Isolated VM, no direct network - routes via Gateway
Workstation -> Gateway (Tor) -> Internet
              No IP leaks possible - Workstation
              has no knowledge of real IP or network

Setup: runs on VirtualBox, KVM, or Qubes OS. Pre-built OVA images available at whonix.org.

Tails - amnesic live OS:

  • Boots from USB, leaves no trace on host
  • All traffic routed through Tor by default
  • RAM is wiped on shutdown (with kernel parameter)
  • Persistent encrypted volume optional
  • Includes pre-installed tools (OnionShare, KeePassXC, mat2)

When to use which:

Scenario Best Choice
Daily research from desktop Whonix
Physical engagement, on-site Tails USB
Maximum compartmentalization Qubes OS + Whonix
Quick anonymous browsing Tor Browser
Untrusted hardware Tails USB (amnesic)

Qubes OS + Whonix: each activity runs in a separate VM (disposable). Network VM handles Tor. Strongest desktop isolation model.

#Censorship Circumvention

#Protocol Obfuscation Tools

When Tor itself is blocked or detectable, use additional circumvention tools.

V2Ray / Xray:

# Install V2Ray
bash <(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh)

# V2Ray with VMess + WebSocket + TLS
# Looks like normal HTTPS traffic to a website
// /usr/local/etc/v2ray/config.json (client)
{
  "inbounds": [{
    "port": 1080,
    "protocol": "socks",
    "settings": { "auth": "noauth" }
  }],
  "outbounds": [{
    "protocol": "vmess",
    "settings": {
      "vnext": [{
        "address": "your-server.com",
        "port": 443,
        "users": [{
          "id": "your-uuid-here",
          "alterId": 0,
          "security": "auto"
        }]
      }]
    },
    "streamSettings": {
      "network": "ws",
      "security": "tls",
      "wsSettings": { "path": "/secret-path" },
      "tlsSettings": { "serverName": "your-server.com" }
    }
  }]
}
# Start V2Ray
sudo systemctl enable --now v2ray

# Use via SOCKS5 proxy
curl --socks5-hostname 127.0.0.1:1080 https://check.torproject.org

Other circumvention tools:

Tool Technique Notes
V2Ray/Xray VMess/VLESS over WS+TLS Looks like HTTPS, highly configurable
Shadowsocks AEAD encrypted proxy Lightweight, widely deployed
Psiphon Multi-protocol (SSH, VPN, HTTP) Easy to use, auto-selects best method
Lantern P2P + CDN fronting Good for casual use
Hysteria QUIC-based proxy Very fast, good for high-latency networks
REALITY (Xray) TLS 1.3 mimicry Steals TLS fingerprint of real sites

#Domain Fronting

Makes traffic appear to go to an allowed domain (e.g., CDN) while actually reaching a blocked destination. Relies on the CDN routing based on the Host header rather than the SNI.

# Domain fronting concept:
# TLS SNI:    allowed-cdn.com   (what censors see)
# HTTP Host:  blocked-c2.com    (where traffic actually goes)

# Example with curl
curl -H "Host: blocked-c2.com" \
  https://allowed-cdn.com/path

# Many CDN providers have restricted this
# Still works with some cloud providers and specific configurations

Note: major CDN providers (CloudFront, Google, Azure) have largely blocked domain fronting. Research current options before relying on this technique.

#Identity OPSEC

#MAC Spoofing

Changes the hardware MAC address visible on the local network. Important for Wi-Fi engagements to avoid device tracking.

# Install
sudo apt install macchanger

# View current MAC
macchanger -s eth0
ip link show eth0

# Interface MUST be down before changing
sudo ip link set eth0 down

# Set random MAC
sudo macchanger -r eth0

# Set random vendor MAC (looks legitimate)
sudo macchanger -a eth0

# Set specific MAC
sudo macchanger -m XX:XX:XX:XX:XX:XX eth0

# Restore original (permanent) MAC
sudo macchanger -p eth0

# Bring back up
sudo ip link set eth0 up

Persistent MAC change via NetworkManager:

# /etc/NetworkManager/conf.d/mac-randomize.conf
[device]
wifi.scan-rand-mac-address=yes

[connection]
wifi.cloned-mac-address=random
ethernet.cloned-mac-address=random
connection.stable-id=${CONNECTION}/${BOOT}
sudo systemctl restart NetworkManager

Persistent via systemd service (runs before network starts):

# /etc/systemd/system/[email protected]
[Unit]
Description=MAC spoofing for %i
Before=network-pre.target
Wants=network-pre.target
BindsTo=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device

[Service]
Type=oneshot
ExecStart=/usr/bin/ip link set dev %i down
ExecStart=/usr/bin/macchanger -r %i
ExecStart=/usr/bin/ip link set dev %i up
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
sudo systemctl enable [email protected]

#Browser Fingerprinting

Websites can identify you without cookies by combining browser characteristics into a unique fingerprint.

Fingerprint vectors:

Vector What It Reveals
User-Agent Browser, OS, version
Canvas GPU/rendering engine uniqueness
WebGL Graphics hardware details
Fonts Installed font list
Screen Resolution, color depth
Timezone Geographic region
Audio AudioContext processing fingerprint
Navigator CPU cores, memory, platform
TLS/JA3 TLS client fingerprint (hard to spoof)

Firefox hardening (about:config):

# Resist fingerprinting (master switch - changes many settings)
privacy.resistFingerprinting = true
# Sets: UTC timezone, standard fonts, rounded screen size,
# generic user-agent, disabled Canvas/WebGL readback

# Disable WebRTC (prevents IP leak via STUN)
media.peerconnection.enabled = false

# Disable WebGL entirely
webgl.disabled = true

# Enhanced Tracking Protection
privacy.trackingprotection.enabled = true

# Total Cookie Protection (dynamic First-Party Isolation)
# Replaces deprecated privacy.firstparty.isolate
network.cookie.cookieBehavior = 5

# Disable telemetry
datareporting.policy.dataSubmissionEnabled = false
datareporting.healthreport.uploadEnabled = false

# Disable Pocket, Normandy, studies
extensions.pocket.enabled = false
app.normandy.enabled = false
app.shield.optoutstudies.enabled = false

# HTTPS-Only Mode
dom.security.https_only_mode = true

Recommended extensions (2026-current):

  • uBlock Origin - ad/tracker blocking (still the gold standard)
  • NoScript - blocks JavaScript per-site
  • Canvas Blocker - randomizes canvas, WebGL, audio fingerprint
  • Skip Redirect - removes tracking redirects

Tor Browser is pre-hardened: all users share the same fingerprint. Best option when maximum anonymity is needed. Do not install additional extensions in Tor Browser - it makes you more unique.

VM-based browser isolation: run the browser in a disposable VM (Qubes, VirtualBox snapshot). Destroy after use - no persistent state.

#Metadata Stripping

Files contain hidden metadata (author name, GPS coordinates, timestamps, software version) that can deanonymize you.

View metadata:

# Install exiftool
sudo apt install libimage-exiftool-perl

# View all metadata
exiftool image.jpg
exiftool document.pdf
exiftool report.docx

# View specific fields
exiftool -GPSLatitude -GPSLongitude image.jpg
exiftool -Author -Creator -Producer document.pdf

# Recursive - check all files in directory
exiftool -r -GPSPosition *.jpg

Remove metadata:

# Strip ALL metadata from image
exiftool -all= image.jpg

# Strip metadata from all JPGs in directory
exiftool -all= -overwrite_original *.jpg

# Strip metadata but keep orientation
exiftool -all= -tagsfromfile @ -Orientation image.jpg

# Strip metadata from all supported types recursively
exiftool -all= -overwrite_original -r ./directory/

mat2 (Metadata Anonymisation Toolkit 2):

# Install
sudo apt install mat2

# Check file metadata
mat2 --show document.pdf

# Clean file (creates cleaned copy with .cleaned suffix)
mat2 document.pdf
# Output: document.cleaned.pdf

# Clean in place
mat2 --inplace document.pdf

# Lightweight mode (faster, less thorough)
mat2 --lightweight document.pdf

# List supported formats
mat2 --list
# Images (JPEG, PNG, TIFF, SVG), PDFs, Office docs
# (DOCX, XLSX, PPTX, ODP, ODS, ODT), audio (FLAC,
# OGG, MP3), video, archives (ZIP, TAR), torrents

PDF metadata cleaning:

# View PDF metadata
exiftool document.pdf
pdfinfo document.pdf
strings document.pdf | grep -i "author\|creator\|producer"

# Remove with exiftool
exiftool -all= document.pdf

# Remove with qpdf (strips and re-linearizes)
qpdf --empty --pages document.pdf -- cleaned.pdf

# Flatten PDF (removes editing history, comments, forms)
gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
  -sOutputFile=clean.pdf document.pdf

OPSEC fail examples:

Failure Consequence
GPS in photo EXIF Physical location revealed
Author field in DOCX Real name exposed
Software version in PDF OS/tool identification
Unique font in screenshot System fingerprinting
Camera serial in EXIF Device attribution
Printer tracking dots Specific printer identified
Timezone in document XML Geographic region narrowed

#Sock Puppets

Fake identities for engagement work. Must be consistent and compartmentalized.

Creation principles:

  • Backstory: age, job, interests, location - keep it simple and memorable
  • Consistency: same persona across all platforms for that identity
  • Compartmentalization: never mix sock puppet activity with real identity
  • Separate everything: different browser/VM, different IP, different device

Email:

ProtonMail or Tuta (formerly Tutanota)
- Register over Tor
- Use sock puppet name
- Never access from real IP
- Consider using a recovery email from another sock puppet
- Enable Tor onion access if available

Phone numbers:

Service Notes
MySudo Virtual numbers, multiple lines
TextNow Free US number, works for some verifications
Prepaid SIM Buy with cash, activate away from home
Google Voice Requires existing US number
JMP.chat XMPP-based phone number, pay with crypto

Social media:

  • Build profile gradually - do not create and immediately engage
  • Post generic content first (news shares, memes)
  • Age the account before using operationally
  • Use AI-generated photos for profile pictures
  • Match photo demographics to backstory (age, gender)
  • Use different writing style than your real accounts
  • Vary posting times to not match your real timezone

Compartmentalization rules:

Per sock puppet, maintain SEPARATE:
- Browser profile or VM (ideally disposable)
- VPN/Tor circuit (stream isolation)
- Email address
- Phone number
- Writing style and vocabulary
- Login times (avoid patterns matching your timezone)
- Password manager vault
- Payment methods (crypto, prepaid cards)

#Secure Communications

#Encrypted Messaging

Platform Type E2E Default Phone # required Notes
Olvid Decentralized Yes No No server trust needed - crypto verification is fully client-side. No phone/email required. ANSSI (French NSA) certified. Theoretically the most secure: even if the server is compromised, messages remain confidential.
Signal Centralized Yes Yes Gold standard for usability, minimal metadata. Phone number = identity linkage.
Session Decentralized Yes No No phone number, onion routing via Oxen network. Weaker crypto review than Signal.
Briar P2P Yes No Tor-based, no server, works offline via Bluetooth/Wi-Fi. Android only.
SimpleX P2P Yes No No user identifiers at all - not even random IDs. Best metadata privacy.
Matrix/Element Federated Optional No Self-hostable, cross-platform. Metadata visible to homeserver admin.
Wire Centralized Yes No Business-friendly. Swiss jurisdiction. Some metadata concerns.

Why Olvid stands out: Unlike Signal (which trusts Signal's server for key distribution), Olvid performs mutual authentication and key exchange entirely on-device via QR codes or numeric verification. The server is a "dumb relay" that never sees keys, contact lists, or metadata. Even a fully compromised Olvid server cannot decrypt messages or learn who talks to whom. ANSSI certification (France) validates this architecture.

PGP/GPG for email:

# Generate key pair (use ed25519 for modern, RSA 4096 for compat)
gpg --full-generate-key
# Choose: ECC (Curve 25519) or RSA 4096
# Set expiration (1-2 years recommended)

# Export public key
gpg --armor --export [email protected] > pubkey.asc

# Import someone's public key
gpg --import their_pubkey.asc

# Verify key fingerprint (out of band!)
gpg --fingerprint [email protected]

# Encrypt a message
gpg --encrypt --armor --recipient [email protected] message.txt

# Decrypt
gpg --decrypt message.txt.asc

# Sign a message
gpg --clearsign message.txt

# Verify signature
gpg --verify message.txt.asc

# Encrypt + sign
gpg --encrypt --sign --armor -r [email protected] message.txt

Signal best practices:

- Enable disappearing messages (short timer)
- Verify safety numbers in person
- Use registration lock PIN
- Disable link previews
- Use a dedicated number (not personal)
- Enable screen security (prevents screenshots)
- Use relay calls (hides IP from contact)

#Operational Comms

Separate devices per engagement: never use the same phone/laptop for two different operations. If one is compromised, the other stays clean.

Burner phones:

  • Buy with cash at a store away from home/work
  • Activate on public Wi-Fi away from home
  • Never power on near your real phone or home
  • Never insert your real SIM
  • Disable all location services
  • Dispose of after engagement (factory reset + physical destruction)

Digital dead drops:

# Encrypted paste with expiry
# Use PrivateBin (self-hosted) or onion-based paste sites

# Share via Tor hidden service paste
torsocks curl -X POST \
  -d "content=<encrypted_message>&expiry=1hour&burn=true" \
  http://paste_onion_address.onion/api

# One-time secret sharing
# https://onetimesecret.com (or self-host)

Steganography - hide data inside images:

# steghide - embed file in JPEG/BMP
sudo apt install steghide

# Embed secret.txt into image.jpg
steghide embed -cf image.jpg -ef secret.txt -p "passphrase"

# Extract hidden data
steghide extract -sf image.jpg -p "passphrase"

# Check if file has hidden data
steghide info image.jpg
# OpenStego - GUI and CLI, supports PNG
sudo apt install openstego

# Embed
openstego embed -mf secret.txt -cf cover.png \
  -sf output.png -p "passphrase"

# Extract
openstego extract -sf output.png -p "passphrase"

#Physical OPSEC

#Public Network Practices

Using public networks for anonymous operations requires discipline.

Wi-Fi operational security:

Before connecting:
1. Spoof MAC address (macchanger -r wlan0)
2. Disable Bluetooth and NFC
3. Cover or disable webcam
4. Use a privacy screen filter
5. Boot from Tails USB

Location selection:
- Choose busy locations (library, cafe, airport)
- Rotate locations - never use the same one twice
- Ensure no direct camera angle on your screen
- Sit with your back to a wall
- Stay within 30 minutes to limit exposure

After operation:
- Disconnect and disable Wi-Fi
- Do not visit the location with your real devices
- Change MAC address again before next use

Device compartmentalization:

Device Purpose Network
Daily laptop Normal activities Home/work network
Op laptop Engagement work Public Wi-Fi + Tor
Burner phone Sock puppet accounts Prepaid data + VPN
Tails USB High-risk operations Public Wi-Fi + Tor

#Cryptocurrency Anonymity

Basic rules for anonymous payments:

Privacy coins:
- Monero (XMR): private by default, ring signatures
- Zcash (shielded): optional privacy, zk-SNARKs

Bitcoin privacy (harder):
- Use CoinJoin / Wasabi Wallet
- Never reuse addresses
- Use Tor for all transactions
- Do not link KYC exchanges to anonymous wallets

Payment flow for services:
Cash -> Bitcoin ATM (no KYC) -> Monero swap -> Payment
  OR
Cash -> P2P exchange (Bisq) -> Monero -> Payment

For detailed cryptocurrency OPSEC, see the dedicated Crypto OPSEC sheet.

#DNS Privacy

#DNS over HTTPS (DoH)

Standard DNS sends queries in plaintext - your ISP (and anyone on the network) can see every domain you resolve. DoH encrypts DNS inside HTTPS.

Firefox DoH configuration:

Settings > Privacy & Security > DNS over HTTPS
  - Enable "Max Protection"
  - Provider: Cloudflare or Custom

# Or via about:config:
network.trr.mode = 3         # 3 = DoH only (no fallback)
network.trr.uri = https://mozilla.cloudflare-dns.com/dns-query

System-wide DoH with cloudflared:

# Install cloudflared
# Download from: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/
sudo dpkg -i cloudflared-linux-amd64.deb

# Run as DNS-over-HTTPS proxy
sudo cloudflared proxy-dns \
  --address 127.0.0.1 \
  --port 5053 \
  --upstream https://1.1.1.1/dns-query \
  --upstream https://1.0.0.1/dns-query

# Point system DNS to local proxy
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf
# Note: if using port 5053, configure local resolver
# to forward to 127.0.0.1:5053

Common DoH providers:

Provider Address
Cloudflare https://1.1.1.1/dns-query
Quad9 https://dns.quad9.net/dns-query
Mullvad https://dns.mullvad.net/dns-query
NextDNS https://dns.nextdns.io/<config-id>
Wikimedia https://wikimedia-dns.org/dns-query

#DNS over TLS (DoT)

Encrypts DNS queries over TLS on port 853. More transparent than DoH (network admins can see it is DNS traffic, but not the content).

systemd-resolved configuration:

# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com 9.9.9.9#dns.quad9.net
DNSOverTLS=yes
DNSSEC=yes
FallbackDNS=
Domains=~.
# Restart and verify
sudo systemctl restart systemd-resolved

# Check status
resolvectl status
resolvectl query example.com

Stubby client:

# Install
sudo apt install stubby

# Default config: /etc/stubby/stubby.yml
# Pre-configured with Cloudflare and Quad9 over TLS
# /etc/stubby/stubby.yml (key sections)
resolution_type: GETDNS_RESOLUTION_STUB
dns_transport_list:
  - GETDNS_TRANSPORT_TLS

listen_addresses:
  - 127.0.0.1@53

upstream_recursive_servers:
  - address_data: 1.1.1.1
    tls_auth_name: "cloudflare-dns.com"
  - address_data: 9.9.9.9
    tls_auth_name: "dns.quad9.net"
# Start stubby
sudo systemctl enable --now stubby

# Point resolv.conf to stubby
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf
sudo chattr +i /etc/resolv.conf

# Verify TLS is working
sudo tcpdump -i eth0 port 853 -c 5
# Should see traffic to 1.1.1.1:853 or 9.9.9.9:853

# Verify NO plaintext DNS
sudo tcpdump -i eth0 port 53 -c 5
# Should see NO traffic if DoT is working

Verify DNS privacy:

# Check which DNS server is answering
dig +short whoami.akamai.net
dig +short txt ch whoami.cloudflare @1.1.1.1

# Check for DNS leaks
curl -s https://ipleak.net/json/ | python3 -m json.tool

# tcpdump - confirm no plaintext DNS
sudo tcpdump -i eth0 port 53 -c 10 &
# Generate DNS traffic, then check tcpdump output
dig example.com
# If DoH/DoT is working, tcpdump captures nothing

#Anonymity Advisor

#What Setup Do You Need?

Use the advisor below to determine the recommended anonymization setup based on your threat model and operational requirements.

#Leak Tests

#DNS Leak Test

Check whether your DNS queries escape the tunnel (VPN/Tor) and reveal your real resolver or ISP.

DNS Leak Test

Generates unique subdomains and resolves them. If your DNS requests go through your ISP instead of the VPN tunnel, you have a DNS leak.

#WebRTC Leak Test

Detect WebRTC exposing your real IP behind a VPN/proxy via STUN/ICE candidate enumeration.

WebRTC Leak Test

WebRTC can leak your real local and public IP even behind a VPN. This test uses the browser's RTCPeerConnection API to detect exposed IPs.

#Also See

#Cyber Aurelien Guidi