High-performance NNTP reader service for production Usenet deployments. Vector.NNRPD is a .NET 8 worker that accepts TCP connections, runs the NNTP session loop, and integrates authentication, TLS, PROXY protocol parsing, and operational policy. The design targets long-lived, multi-core hosts (Windows services and Linux with systemd) and wire throughput suitable for hyperscale reader front ends.
Vector.NNRPD is active infrastructure code, not a demo server. Session transport, authentication plumbing, and configuration are the current focus. Full reader data-plane coverage (distributed article storage, complete RFC command matrices, and golden transcripts for every extension) is tracked incrementally; see docs/ for what is implemented today versus planned.
- NNTP session engine — accept loop, CRLF framing, command classification and dispatch, pre-encoded fixed responses on hot paths, and session lifecycle controls (admission gating, in-flight tracking, graceful drain).
- Reader authentication — pluggable AAA handlers: RADIUS, LDAP, SQL, external exec, and local JSON accounts; fail-closed defaults and explicit result mapping for protocol responses.
- Security and policy — cleartext and implicit TLS listeners,
STARTTLS, optional Let's Encrypt certificate automation, PROXY v1/v2 behind trusted load balancers, Redis-backed coordination for rate limits and session accounting where enabled. - Operations — structured logging (Serilog), OpenTelemetry metrics hooks, health checks for directory and RADIUS backends, validated
nnrpd.jsonconfiguration with environment overlays. - Performance tooling — BenchmarkDotNet projects and a skeleton load harness for soak and allocation regression checks in CI.
| Item | Version / notes |
|---|---|
| .NET SDK | 9.0.100 or newer (global.json; C# 13 on net8.0) |
| Runtime | .NET 8 |
| Platform | x64 only |
| Optional | Redis (integration tests and coordination features), RabbitMQ (message bus), RADIUS/LDAP/SQL endpoints per handler configuration |
Linux CI runs Redis-backed tests via a service container. Windows CI sets SKIP_REDIS_INTEGRATION_TESTS=true when Redis is unavailable.
git clone <repository-url>
cd Vector.NNRPD
cp nnrpd-example.json nnrpd.json
# Edit nnrpd.json: listeners, aaa handlers, secrets (use user secrets or environment variables).
dotnet restore Vector.NNRPD.sln -p:Platform=x64
dotnet build Vector.NNRPD.sln -c Release -p:Platform=x64
dotnet run --project Vector.NNRPD.csproj -c Release -p:Platform=x64On first run, bind addresses, ports, and handler endpoints must match your environment. For local development without Redis coordination, see aaa.redis.coordination_enabled in docs/nnrpd-json.md.
Release builds used by tests and benchmarks are framework-dependent. For a single-file, self-contained deployment, publish with a runtime identifier:
dotnet publish Vector.NNRPD.csproj -c Release -p:Platform=x64 -r linux-x64 --self-contained trueAdjust -r for win-x64 or your target RID.
All host settings live in nnrpd.json, with optional nnrpd.<Environment>.json overlays loaded by the host builder.
| Section | Purpose |
|---|---|
Host |
Reader vs transit profile selection |
Server |
Listeners, TLS, PROXY, limits, metrics |
aaa |
Required authentication handler chain and Redis coordination |
LetsEncrypt |
Optional ACME certificate issuance |
RabbitMQ |
Optional message bus |
Start from nnrpd-example.json. Detailed option reference: docs/nnrpd-json.md. Handler-specific guides: RADIUS, LDAP, files, exec. PROXY and TLS ordering: docs/proxy-deployment.md, docs/rfc-nntp-security-ordering.md.
Do not commit secrets. Use .NET user secrets or environment variables for passwords, RADIUS shared secrets, and certificate material.
dotnet restore Vector.NNRPD.sln -p:Platform=x64
dotnet build Vector.NNRPD.sln -c Release -p:Platform=x64
dotnet test Vector.NNRPD.sln -c Release -p:Platform=x64 --verbosity normaldotnet run --project benchmarks/Vector.NNRPD.Benchmarks/Vector.NNRPD.Benchmarks.csproj \
-c Release -p:Platform=x64 -- -j short -f '*'dotnet run --project benchmarks/Vector.NNRPD.SkeletonLoad/Vector.NNRPD.SkeletonLoad.csproj \
-c Release -- <connections> <seconds> <host> <port>Linux tuning and multi-process notes: benchmarks/Vector.NNRPD.SkeletonLoad/LINUX-RUNBOOK.txt.
The CI workflow restores, builds, tests, and runs short BenchmarkDotNet jobs on ubuntu-latest and windows-latest (x64). CodeQL runs on the default branch schedule.
The repository is a single worker assembly with namespace and folder boundaries for protocol core, authentication handlers, and infrastructure adapters.
Host (Program.cs, nnrpd.json)
→ Core.Sockets (listeners, sessions, dispatch, metrics)
→ Core.Sockets.Authentication (reader auth contracts)
→ Auth.Handler.* (RADIUS, LDAP, SQL, exec, files)
→ Core.MessageBus, Core.LetsEncrypt, Filters (supporting modules)
Article persistence is not hosted inside the NNRPD process: storage is intended to be provided by separate distributed workers; the binary storage framing is documented in docs/storage-protocol.md. Deeper layering and hot-path file list: docs/architecture-overview.md. NNTP RFC index: docs/rfc-index.md.
Deployment targets: Windows services and Linux with systemd are first-class. Container images and ARM builds are out of scope for the current repository story.
Vector.NNRPD is critical infrastructure. Authentication and authorization default to deny on internal errors; accounting failures must not upgrade a deny to allow. Session and I/O paths must not leak unhandled exceptions into the host process. New behavior on transport, auth, and storage boundaries needs automated tests covering success, failure, cancellation, and malformed input. Full expectations: CONTRIBUTING.md.
| Topic | Location |
|---|---|
| Configuration reference | docs/nnrpd-json.md |
| Architecture | docs/architecture-overview.md |
| AAA / VectorAuth | docs/vectorauth-spec.md |
| NNTP responses | docs/nntp-responses.md |
| Storage wire format | docs/storage-protocol.md |
| Contributing, style, tests | CONTRIBUTING.md |
| Third-party notices | THIRD_PARTY_NOTICES.md |
Licensed under the Apache License, Version 2.0.