Posting to Usenet Anonymously

NeoMutt + Mail2News gateway over Tor — no account, no IP, no trace

Why Usenet

Usenet is older than the web. And unlike almost everything built after it, it is still federated, still decentralised, still running. If you want to write something and have it propagate across servers you do not control — without creating an account, without giving anyone your email address — Usenet remains one of the few places where that is possible.

This article explains exactly how we post to Usenet from NeoMutt using the mail2news gateway running on this server. Every step is reproducible. No cloud, no third-party relay, no clearnet exposure.

How mail2news works

Mail2news is a gateway that accepts an email message and injects it into Usenet as a newsgroup article. You format an email with a Newsgroups: header, send it to the gateway address, and the gateway posts it on your behalf.

Our gateway runs as a Tor hidden service. You send the mail via SMTP to an .onion address. The gateway forwards it to Peanny NNTP, a well-connected Usenet server. From there it propagates normally.

Your IP address never touches the gateway. The From address is ephemeral — a .invalid domain that cannot be replied to or traced. There is no authentication required.

Prerequisites

Install these packages before starting:

# Arch
pacman -S neomutt tor torsocks swaks

# Debian / Ubuntu
apt install neomutt tor torsocks swaks

You need Tor running locally on 127.0.0.1:9050. On most systems: systemctl enable --now tor.

The mail2news account config

Create ~/.config/neomutt/accounts/mail2news. This configures NeoMutt to use the onion SMTP relay with an ephemeral From address. No IMAP — this account is send-only.

# ~/.config/neomutt/accounts/mail2news

# Ephemeral From — .invalid domain cannot be traced or replied to
set from     = "nobody@virebent.invalid"
set realname = "anonymous"

# No inbox — send only
set folder   = ""
set spoolfile = ""

# SMTP via Tor hidden service — virebent.art mail2news onion relay
set smtp_url = "smtp://xilb7y4kj6u6qfo45o3yk2kilfv54ffukzei3puonuqlncy7cn2afwyd.onion:25"
set smtp_pass = ""
set ssl_starttls = no
set ssl_force_tls = no

my_hdr X-Mailer: NeoMutt

The SMTP onion address above is the mail2news gateway on this server. It accepts unauthenticated SMTP on port 25 and forwards to Peanny NNTP.

The Tor NeoMutt profile

Do not use the mail2news account from a clearnet NeoMutt session. Create a dedicated Tor profile at ~/.config/neomutt/neomuttrc.tor:

# ~/.config/neomutt/neomuttrc.tor
# Launch with: torsocks neomutt -F ~/.config/neomutt/neomuttrc.tor

source ~/.config/neomutt/neomuttrc.common
source ~/.config/neomutt/accounts/mail2news

macro index,pager <F9> "<shell-escape>~/.config/neomutt/m2n-prompt.sh<enter>" "Post to Usenet"

Launch it with:

torsocks neomutt -F ~/.config/neomutt/neomuttrc.tor

torsocks wraps the entire NeoMutt process through your local Tor SOCKS5 proxy. The SMTP connection to the .onion address is routed through Tor. Your real IP is never used.

The posting script

NeoMutt's built-in compose workflow does not handle Newsgroups: headers cleanly. We use a shell script that prompts for newsgroup and subject, opens your editor, then sends via swaks through torsocks.

Save as ~/.config/neomutt/m2n-prompt.sh and chmod +x it:

#!/bin/bash
# Mail2News posting script — NeoMutt + torsocks + swaks
set -euo pipefail

M2N_TO="mail2news@xilb7y4kj6u6qfo45o3yk2kilfv54ffukzei3puonuqlncy7cn2afwyd.onion"
SMTP_HOST="xilb7y4kj6u6qfo45o3yk2kilfv54ffukzei3puonuqlncy7cn2afwyd.onion"
SMTP_PORT="25"
FROM="nobody@virebent.invalid"

clear
echo "=== MAIL2NEWS — Usenet Post ==="
echo

printf "Newsgroup(s) [comma-separated]: "
read -r NEWSGROUP
[ -z "$NEWSGROUP" ] && echo "Aborted." && exit 1
NEWSGROUP=$(echo "$NEWSGROUP" | sed 's/ *, */,/g')

printf "Subject: "
read -r SUBJECT
[ -z "$SUBJECT" ] && echo "Aborted." && exit 1

REFERENCES=""
if echo "$SUBJECT" | grep -qi "^re:"; then
    printf "References (Message-ID of original): "
    read -r REFERENCES
fi

MSGFILE=$(mktemp /tmp/m2n-body.XXXXXX)
echo "" > "$MSGFILE"
echo "-- " >> "$MSGFILE"
echo "posted via virebent.art mail2news" >> "$MSGFILE"

${EDITOR:-vim} "$MSGFILE"

DRAFTFILE=$(mktemp /tmp/m2n-draft.XXXXXX)
{
    printf "To: %s\n"          "$M2N_TO"
    printf "From: %s\n"        "$FROM"
    printf "Subject: %s\n"     "$SUBJECT"
    [ -n "$REFERENCES" ] && printf "References: %s\n" "$REFERENCES"
    printf "Newsgroups: %s\n"  "$NEWSGROUP"
    printf "\n"
    cat "$MSGFILE"
} > "$DRAFTFILE"

clear
echo "=== REVIEW ==="
cat "$DRAFTFILE"
echo
printf "[s]end  [e]dit  [q]uit: "
read -r CHOICE

case "$CHOICE" in
    e|E) ${EDITOR:-vim} "$DRAFTFILE" ;;
    q|Q) rm -f "$MSGFILE" "$DRAFTFILE"; echo "Cancelled."; exit 0 ;;
esac

echo
echo "Sending via Tor..."

torsocks swaks \
    --server "${SMTP_HOST}:${SMTP_PORT}" \
    --from   "$FROM" \
    --to     "$M2N_TO" \
    --data   "@${DRAFTFILE}" \
    --timeout 60 \
    2>&1 | tee /tmp/m2n-smtp.log

if grep -q "250 " /tmp/m2n-smtp.log; then
    echo
    echo "Sent to: $NEWSGROUP"
else
    echo
    echo "ERROR — check /tmp/m2n-smtp.log"
fi

rm -f "$MSGFILE" "$DRAFTFILE"
printf "\nPress Enter to return to NeoMutt..."
read -r

Usage

The macro in the Tor profile binds F9 to the script. Press F9 from the index or pager, answer the prompts, write your post in the editor, review, send.

That is the entire workflow. No accounts, no registration, no clearnet traffic. The post arrives at Peanny's NNTP server and propagates from there.

What happens on the server side

The mail2news gateway on this server runs Postfix with a smtp_tor transport — a torsocks wrapper around the standard Postfix SMTP client. Outbound delivery to Peanny uses a Tor exit node, so neither your IP nor the server's public IP appears in the path to the newsgroup.

The Newsgroups: header you provide is passed through unchanged. The From: you set in the script is what appears in the article. Use anything ending in .invalid — it is not a real domain and cannot be contacted.

Quick reference

# Gateway address (mail2news → Peanny NNTP)
mail2news@xilb7y4kj6u6qfo45o3yk2kilfv54ffukzei3puonuqlncy7cn2afwyd.onion

# Launch the Tor NeoMutt profile
torsocks neomutt -F ~/.config/neomutt/neomuttrc.tor

# Post directly from the shell (no NeoMutt)
torsocks swaks \
    --server xilb7y4kj6u6qfo45o3yk2kilfv54ffukzei3puonuqlncy7cn2afwyd.onion:25 \
    --from   nobody@virebent.invalid \
    --to     mail2news@xilb7y4kj6u6qfo45o3yk2kilfv54ffukzei3puonuqlncy7cn2afwyd.onion \
    --header "Newsgroups: misc.test" \
    --header "Subject: test post" \
    --body   "This is a test."

Full configuration

The complete NeoMutt multi-account configuration including the mail2news profile: