pugleaf.net text-only Usenet servers, open for peering and reading.
SocialGo · HTMLGitHub @go-whileOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Usenet NNTP to Web Gateway - written in Go
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗A modern NNTP server and web gateway for Usenet/NetNews built in Go
go-pugleaf provides a complete newsgroup platform with:
Read BUGS.md first!
go.mod pins toolchain go1.27.2, downloaded automatically with GOTOOLCHAIN=auto)Step 1: Get the binaries
Choose one option:
build/, README.md and LICENSE)git clone https://github.com/go-while/go-pugleaf.git
cd go-pugleaf
./build_ALL.sh && cp build/* .
The webserver embeds its page templates, static files and favicon, so a binary renders the
templates it was built with from any working directory. The default cron jobs start
./pugleaf-fetcher and ./post-queue from the working directory, and an optional
./web/robots.txt is read from there. PUGLEAF_DEV_TEMPLATES=1 re-parses web/templates/
from disk on every request while editing templates.
Step 2: Initial configuration
# First run - store the hostname in the database (only needed once)
./webserver -nntphostname my.host.name
The data directory (-data, default ./data) is created on the first run. Later runs reuse the
stored hostname, so ./webserver is enough. All tools share the same -data directory.
webserver (cmd/web)Main web interface
./webserver -nntphostname your.domain.com
# Flags (run ./webserver -h for the full list)
-nntphostname string - your hostname; required on the first run, later runs reuse the stored value
-data string - path to the database and config directory (default: ./data)
-webport int - web server port, 1024-65535 (default: 11980, also with -webssl)
-webhost string - bind address (default: every interface; behind a reverse proxy use -webhost 127.0.0.1)
# SSL/TLS Configuration
-webssl - enable SSL for the web interface
-websslcert string - SSL certificate file (/path/to/fullchain.pem)
-websslkey string - SSL key file (/path/to/privkey.pem)
# One-shot maintenance (runs, then exits): -import-active, -write-active-file, -compare-active,
# -disable-active, -repair-watermarks, -find-orphan-dbs, -update-newsgroups-expiry-from-file, ...
# Cron jobs: -no-cronjobs disables them; -edit-cronjobs temporarily allows editing them in the admin UI.
The webserver has no embedded NNTP server: its -nntptcpport, -nntptlsport, -nntpcertfile and
-nntpkeyfile flags are accepted but ignored. Run pugleaf-nntp-server instead (see below).
Step 3: Create admin account
usermgr -create ... -admin works too)The usermgr tool manages web users from the command line. It is not part of build_ALL.sh:
build it with ./build_usermgr.sh (output: build/usermgr). It uses the same -data directory
as the webserver (default: ./data). Passwords are asked for on the terminal (12-72 characters).
# List all users (shows admin status)
usermgr -list
# Delete a user
usermgr -delete -username john
# Update a user's password
usermgr -update -username john
# Create a new user
usermgr -create -username john -email [email protected] -display "John Doe"
# Create a new admin user
usermgr -create -username admin -email [email protected] -display "Administrator" -admin
NNTP users (for pugleaf-nntp-server) are managed with pugleaf-nntpmgr (./build_nntpmgr.sh):
-create, -list, -update, -delete, -activate, -deactivate, -setpassword, with
-username, -password, -maxconns and -posting; see pugleaf-nntpmgr -h.
Step 4: Add newsgroups
Choose one method:
preload/ and active_files/. They may contain a large number of binary groups; modify as needed../pugleaf-fetcher -fetch-newsgroups-from-remote 'comp.*' -fetch-newsgroups-force
(see Manual Fetching below; needs an enabled provider, Step 5)# one-shot: imports the groups and exits
./webserver -import-active preload/active.2025-06
# imports the descriptions and then keeps running as the webserver
./webserver -update-newsgroups-descriptions-file preload/newsgroups.descriptions \
-update-overwrite-newsgroups-descriptions=false \
-update-newsgroups-descriptions-import-create-newsgroups=false
# import rocksolid light backups (-etc is required, -spool is optional)
./rslight-importer -data data/ -etc etc/ -spool spool/
# import Usenet mbox archives (archive.org collections), see cmd/mbox-importer/README.md
./build_mbox-importer.sh
./build/mbox-importer -dry-run de.comm.internet.commerce.mbox.gz # counts only, opens no database
./build/mbox-importer -data data/ -nntphostname news.example.org de.comm.internet.commerce.mbox.gz
./build/mbox-importer -data data/ -tmpdir /var/tmp pl.rec.gory.usenet.xz # a UAT archive, after the mbox collections
Optional: Import RockSolid Light backups
etc/menu.conf for section configurationetc/groups.txt per folder in etc/$section/ (e.g., etc/rocksolid/groups.txt)Step 5: Configure a provider and start fetching
-no-cronjobs turns them off). All default jobs are
disabled; enabling one is refused unless the webserver was started with -edit-cronjobs:./webserver -edit-cronjobs # temporarily; restart without the flag afterwards
pugleaf-fetcher (runs every 5 minutes:
./pugleaf-fetcher -group "" -max-batch 1000 ...). Enable post-queue too if users may post.For backfilling disable the cron job first and run pugleaf-fetcher directly. Each run fetches
at most -max-batch articles (10-1000, default 1000) per group and then exits, so repeat it until
the backfill is done. Like the webserver it needs -nntphostname on its first run and reads the
databases below -data (default ./data). ./pugleaf-fetcher -help prints usage examples.
# Initial backfill from specific date
./pugleaf-fetcher -group "news.*" -download-start-date 1980-01-01 # there is no end-date flag; use -max-batch to pace
# Continuous fetching (run after initial fetch)
./pugleaf-fetcher -group "news.*"
# All active groups (same as -group '$all'); -fetch-active-only=false fetches ONLY the inactive groups
./pugleaf-fetcher
# Add groups from the provider's list (dry run without -fetch-newsgroups-force; new groups are inactive)
./pugleaf-fetcher -fetch-newsgroups-from-remote 'comp.*' -exclude-prefix 'alt.binaries.*' -fetch-newsgroups-force
⚠️ Important: Stop the fetcher before adding new groups, or it will download all from scratch.
pugleaf-nntp-server, cmd/nntp-server)./pugleaf-nntp-server -nntphostname your.domain.com -nntptcpport 1119 \
-nntptlsport 1563 -nntpcertfile /path/to/fullchain.pem -nntpkeyfile /path/to/privkey.pem
# -data string database directory (default: ./data)
# -nntpbind string IP address to bind the listeners to (default: all interfaces)
# -nntptcpport int NNTP TCP port (0 = no plain listener; at least one of the two ports is required)
# -nntptlsport int NNTP TLS port (0 = no TLS listener); the cert/key also serve STARTTLS on the TCP port
# -maxconnections int maximum concurrent client connections (default: 500)
# -readauth require AUTHINFO before reader commands
# -plaintextauth string AUTHINFO without TLS: accept (default), advertise or refuse
# -maxartsize int maximum article size in bytes (0 = config default 32768)
# -xref string Xref: header: off, partial (default) or full
# -post-commit-wait d wait for the commit of a POSTed article before 240 (default 5s, 0 = no wait)
# -idletimeout, -articledelay, -groupdelay, -errordelay, -local430ttl: see -h
-xref sets the local Xref: header in HEAD/ARTICLE, OVER/XOVER (9th field) and HDR/XHDR:
off sends none (and LIST OVERVIEW.FMT has no Xref:full); partial (default) lists only the
group the article is read from, without lookups (none when it is read by message-id with no
group selected); full adds the other groups and numbers from the history index: one history
lookup per served article, or with -xref-batched-lookup (default true) one batched lookup per
chunk of up to 1000 lines of an OVER/XOVER or HDR/XHDR range (one statement per history shard
database); =false restores the per-line lookup for comparison. The numbers come from the history
index: existing data shows them in full only after a full history-rebuild run (see
cmd/history-rebuild/README.md); new articles get them on arrival.
The following binaries are built by build_ALL.sh (names as in build/):
Built with their own build_<tool>.sh script only:
cmd/<tool>)📖 For command-line options, run any binary with the -h flag to see available arguments and usage examples.
Build all binaries:
# Build all binaries (automatically generates checksums)
./build_ALL.sh
Verify checksums:
# Verify all executable checksums (from repository root)
sha256sum -c checksums.sha256
GPL v2 - see LICENSE
This project is inspired by the work of Thomas "Retro Guy" Miller and the original RockSolid Light project.
-- the pugleaf.net development team --