Build threat models for political dissidents against state-level adversaries using Tor (with bridges), compartmentalized devices, encrypted offline storage, out-of-band authentication, and Signal for communications. Assume ISP-level monitoring, device seizure risk, and forced cooperation from service providers—implement defense-in-depth across every layer of your digital infrastructure.
Understanding the Adversary
State surveillance operates on multiple vectors that typical privacy tools don’t address. Your threat model must account for:
- ISP-level traffic analysis: Deep packet inspection can identify encrypted traffic patterns, connection timings, and metadata even without decryption
- Legal compelled cooperation: Service providers can be forced to hand over data, log additional information, or insert backdoors under legal authority
- Device compromise: Border crossings, arrests, or coerced device access provide physical access vectors
- Social graph analysis: Correlation of communication patterns, location data, and social connections reveals networks
- Zero-day exploits: State actors maintain offensive capabilities not available to criminal threat actors
The technical sophistication and legal authority of your adversary means that single-tool solutions fail. Defense requires defense-in-depth across every layer of your digital infrastructure.
Asset Inventory and Prioritization
Before implementing protections, identify what you’re protecting. For political dissidents, assets typically include:
- Communication metadata: Who you contact, when, and how often reveals network structure
- Location data: Movement patterns identify meetings, residences, and routines
- Files and documents: Research, contacts, communications, and organizational materials
- Identity linkages: Connections between your online identities and physical person
- Device integrity: The hardware and software you use must remain uncompromised
Rate each asset by consequence if compromised. A contact list disclosure might endanger others; encrypted communication content might not be readable but metadata still exposes relationships.
Network-Level Protections
Your network traffic reveals significant information even when content is encrypted. Implement these countermeasures:
Traffic Analysis Resistance
# Example: Configure iptables to randomize packet timing
# This adds jitter to outbound connections to defeat timing analysis
iptables -A OUTPUT -p tcp --tcp-flags ALL SYN,ACK -m hashlimit \
--hashlimit-above 10/sec --hashlimit-burst 20 \
--hashlimit-mode srcip,dstip --hashlimit-name rand_jitter \
-j DROP
Tor remains the most effective tool for defeating network traffic analysis, but usage patterns matter. Configure your Tor client to use obfs4 bridges and enable traffic normalization:
# torrc configuration for high-security environments
UseBridges 1
Bridge obfs4 <bridge-ip> <fingerprint> cert=<cert> iat-mode=2
ClientTransportPlugin obfs4 exec /usr/bin/obfs4proxy
ExcludeExitNodes {ru},{cn},{ir},{kp}
StrictNodes 1
DNS Leak Prevention
DNS requests leak your browsing activity even over VPN. Use DNSCrypt or DNS over HTTPS with a privacy-respecting resolver:
# Python example: Verify DNS resolution doesn't leak
import socket
import subprocess
def check_dns_leak():
"""Test if DNS queries leak outside your tunnel"""
test_domains = ['example.com', 'privacytools.io']
# Query directly to check what resolver is being used
result = subprocess.run(
['nslookup', test_domains[0]],
capture_output=True, text=True
)
# Parse result to identify DNS server used
return result.stdout
# Implement: Route ALL DNS through your protected tunnel
# Use a local DNS forwarder like dnsmasq or cloudflared
Device Security Implementation
Physical device compromise defeats any software security. Implement these hardening measures:
Air-Gapped Sensitive Workstations
For the highest-risk work, air-gapped computers disconnected from all networks provide the strongest security:
# Script to verify air-gap before sensitive operations
#!/bin/bash
# airgap-check.sh - Verify no network interfaces are active
check_network() {
interfaces=$(ip link show | grep -E '^[0-9]+:' | awk -F': ' '{print $2}')
for iface in $interfaces; do
state=$(cat /sys/class/net/$iface/operstate 2>/dev/null)
if [ "$state" = "up" ]; then
echo "WARNING: Network interface $iface is UP"
return 1
fi
done
echo "Air-gap verified - no active network interfaces"
return 0
}
check_wireless() {
rfkill list all | grep -q "Soft blocked: no"
if [ $? -eq 0 ]; then
# Check if any wireless is enabled
ip link show | grep -q "wlan"
if [ $? -eq 0 ]; then
echo "WARNING: Wireless interfaces present"
return 1
fi
fi
return 0
}
check_network && check_wireless || { echo "NETWORK DETECTED - ABORT"; exit 1; }
USB Device Control
Malicious USB devices are common state surveillance vectors:
# Disable USB storage while allowing keyboards/mice
# Add to udev rules (/etc/udev/rules.d/usb-security.rules)
# Block USB storage devices
ACTION=="add", SUBSYSTEM=="usb", ENV{ID_USB_DRIVER}=="usb-storage", RUN+="/bin/sh -c 'echo 0 > /sys$DEVPATH/authorized'"
# Log all USB device connections
SUBSYSTEM=="usb", ACTION=="add", RUN+="/usr/bin/logger 'USB device connected: $ATTRS{serial} $ATTRS{product}'"
Communication Security
Metadata often matters more than content. Implement these communication patterns:
Signal Configuration for High-Risk Use
Signal provides strong encryption but metadata protection requires configuration:
- Enable disappearing messages with short timers (5 minutes for sensitive conversations)
- Use Signal registration lock to prevent SIM swap takeover
- Enable link previews to OFF to prevent leaking visited URLs to Signal servers
- Disable cloud backup for Signal data
Asynchronous Communication
Real-time communication reveals presence. Use asynchronous channels when possible:
# Consider these tools for asynchronous secure communication
- ProtonMail (encrypted email with no metadata logging)
- Bitmessage (decentralized messaging with no central servers)
- Briar (mesh-network messaging that works without internet)
- Session (no phone number requirement, onion-routed)
Operational Security Patterns
Technical measures fail without operational discipline:
Compartmentalization
Never mix personal and sensitive identities. Use separate:
- Devices for different threat levels
- Email accounts for different contexts
- Physical locations for sensitive activities
- Communication channels for different contacts
Device Border Security
Border crossings are high-risk for device inspection:
# Create encrypted container for sensitive data before travel
# Using LUKS with plausible deniability
# Create hidden volume (second encrypted container within first)
cryptsetup luksFormat --type luks2 /dev/sdX1
# Use decoy password for first layer, real password for hidden volume
Regular Security Hygiene
- Rotate credentials regularly (monthly for high-risk accounts)
- Use unique passwords generated by password manager
- Enable hardware 2FA (YubiKey) where possible
- Verify PGP signatures before opening sensitive documents
Recovery and Incident Response
Plan for compromise:
- Pre-arranged dead man’s switch: Trusted contact receives encrypted messages at intervals
- Device wipe capability: Faraday bags enable remote wipe triggers
- Account recovery plan: Pre-established recovery emails and procedures
- Evidence of compromise: Hash prints of sensitive files for detection
# Example: Dead man switch using scheduled encrypted emails
# Run via cron to send if you don't check in
import smtplib
from email.mime.text import MIMEText
from datetime import datetime, timedelta
import hashlib
LAST_CHECKIN_FILE = "/secure/path/last_checkin.timestamp"
RECIPIENT = "trusted_contact@example.com"
def check_in():
with open(LAST_CHECKIN_FILE, 'w') as f:
f.write(str(datetime.now().timestamp()))
def should_trigger():
with open(LAST_CHECKIN_FILE, 'r') as f:
last = datetime.fromtimestamp(float(f.read()))
return datetime.now() - last > timedelta(days=3)
def send_alert():
# Send encrypted message with instructions
msg = MIMEText("I have not checked in. Execute contingency plan.")
msg['Subject'] = "ALERT: No check-in received"
msg['From'] = "sender@example.com"
msg['To'] = RECIPIENT
# Send via your configured SMTP
if should_trigger():
send_alert()
Related Articles
- Threat Model Assessment For High Risk Journalist In Hostile
- Threat Model For Activist In Authoritarian Country Digital S
- Threat Model For Corporate Whistleblower Protecting Evidence
- Threat Model For Human Rights Worker In Conflict Zone Guide
- Threat Model For Medical Marijuana Patient In Non Legal Stat
Built by theluckystrike — More at zovo.one