ircu2/tools/iauthd-ts
mihaiitdata 5fdc1cc27c Adaugă codul complet al proiectului underchat-ircd 2026-02-13 00:04:12 +02:00
..
src Adaugă codul complet al proiectului underchat-ircd 2026-02-13 00:04:12 +02:00
tests Adaugă codul complet al proiectului underchat-ircd 2026-02-13 00:04:12 +02:00
CLAUDE.md Adaugă codul complet al proiectului underchat-ircd 2026-02-13 00:04:12 +02:00
README.md Adaugă codul complet al proiectului underchat-ircd 2026-02-13 00:04:12 +02:00
package-lock.json Adaugă codul complet al proiectului underchat-ircd 2026-02-13 00:04:12 +02:00
package.json Adaugă codul complet al proiectului underchat-ircd 2026-02-13 00:04:12 +02:00
tsconfig.json Adaugă codul complet al proiectului underchat-ircd 2026-02-13 00:04:12 +02:00
users.example Adaugă codul complet al proiectului underchat-ircd 2026-02-13 00:04:12 +02:00
vitest.config.ts Adaugă codul complet al proiectului underchat-ircd 2026-02-13 00:04:12 +02:00

README.md

iauthd-ts

A TypeScript implementation of an IAuth daemon for Nefarious IRCd. This daemon performs real-time DNS-based blacklist (DNSBL) lookups on connecting clients and can block, mark, or whitelist users based on the results.

This is a port of the original Perl iauthd.pl to TypeScript/Node.js.

Features

  • DNSBL Lookups: Check connecting clients against multiple DNS blacklists
  • Flexible Matching: Match by index value or bitmask
  • Caching: DNS results are cached to reduce lookup overhead
  • SASL Authentication: Handle SASL PLAIN authentication directly in IAuth (no services required)
  • SASL/LOC Support: Exempt authenticated users from blocks
  • WEBIRC Support: Re-check real IP for trusted proxy connections
  • Marking: Tag users with marks visible to operators
  • Class Assignment: Assign users to connection classes based on DNSBL results
  • Whitelisting: Exempt users matching certain DNSBLs from all blocks

How It Works

┌─────────────┐     stdin/stdout      ┌─────────────┐
│  Nefarious  │ ◄──────────────────►  │  iauthd-ts  │
│    IRCd     │    IAuth Protocol     │             │
└─────────────┘                       └──────┬──────┘
                                             │
                                             │ DNS queries
                                             ▼
                                      ┌─────────────┐
                                      │   DNSBL     │
                                      │  Servers    │
                                      └─────────────┘
  1. Client Connects: IRCd sends client info to iauthd-ts via the IAuth protocol
  2. DNSBL Lookup: iauthd-ts reverses the client IP and queries configured DNSBLs
  3. Result Processing: Responses are checked against configured index/bitmask rules
  4. Decision: Client is accepted (with optional marks/class) or rejected
  5. Response: iauthd-ts sends the decision back to IRCd

IAuth Protocol

iauthd-ts communicates with Nefarious via stdin/stdout using the IAuth protocol:

Direction Message Description
IRCd → iauthd C <id> <ip> <port> <serverip> <serverport> Client introduction
IRCd → iauthd H <id> <class> Hurry up (registration timeout approaching)
IRCd → iauthd R <id> <account> Client authenticated via SASL/LOC
IRCd → iauthd D <id> Client disconnected
iauthd → IRCd D <id> <ip> <port> [class] Accept client
iauthd → IRCd k <id> <ip> <port> :<reason> Reject client
iauthd → IRCd m <id> <ip> <port> MARK <data> Mark client
IRCd → iauthd A <id> <ip> <port> S <mechanism> [:<certfp>] SASL auth start
IRCd → iauthd A <id> <ip> <port> H :<user@host:ip> SASL host info
IRCd → iauthd a <id> <ip> <port> :<data> SASL auth data
iauthd → IRCd c <id> <ip> <port> :<challenge> SASL challenge
iauthd → IRCd L <id> <ip> <port> <account> SASL login success
iauthd → IRCd f <id> <ip> <port> SASL auth failed
iauthd → IRCd l <id> <ip> <port> :<mechanisms> SASL mechanism list
iauthd → IRCd Z <id> <ip> <port> SASL auth complete

Requirements

  • Node.js 18 or later
  • npm

Installation

From Source

cd tools/iauthd-ts
npm install
npm run build

Docker

iauthd-ts is automatically built as part of the Nefarious Docker image. The compiled files are located at /home/nefarious/ircd/iauthd-ts/.

Configuration

iauthd-ts reads configuration from #IAUTH directives in the config file. These can be embedded in your ircd.conf since IRCd ignores lines starting with #.

Directives

POLICY

#IAUTH POLICY RTAWUwFr

Sets the IAuth policy flags. See doc/readme.iauth for details.

DNSTIMEOUT

#IAUTH DNSTIMEOUT 5

Seconds to wait for DNSBL lookups. Default: 5

CACHETIME

#IAUTH CACHETIME 86400

Seconds to cache DNSBL results. Default: 86400 (24 hours)

BLOCKMSG

#IAUTH BLOCKMSG Sorry! Your connection has been rejected due to poor reputation.

Message shown to blocked users.

DEBUG

#IAUTH DEBUG

Enable debug output.

SASLDB

#IAUTH SASLDB /path/to/users

Path to the SASL users file. When set, iauthd-ts will handle SASL PLAIN authentication directly instead of routing to services. The policy must include 'S' for this to work.

SASLFAILMSG

#IAUTH SASLFAILMSG Authentication failed

Message shown when SASL authentication fails.

DNSBL

#IAUTH DNSBL server=<server> [options...]

Options:

Option Description
server=<host> DNSBL server hostname (required)
index=<n,n,...> Match if response equals any of these values
bitmask=<n> Match if response AND bitmask is non-zero
mark=<tag> Apply this mark to matching clients
block=all Block all matching clients
block=anonymous Block matching clients unless SASL authenticated
class=<name> Assign matching clients to this connection class
whitelist Matching clients are exempt from all blocks
cachetime=<n> Override cache time for this DNSBL

Example Configuration

# IAuth Configuration
#IAUTH POLICY RTAWUwFr
#IAUTH CACHETIME 86400
#IAUTH DNSTIMEOUT 5
#IAUTH BLOCKMSG Sorry! Your connection has been rejected due to poor reputation.

# Block open proxies and drones (unless authenticated)
#IAUTH DNSBL server=dnsbl.dronebl.org index=2,3,5,6,7,8,9,10,13,14,15 mark=dronebl block=anonymous

# Mark Tor exit nodes but don't block
#IAUTH DNSBL server=rbl.efnetrbl.org index=4 mark=tor

# Block other bad actors
#IAUTH DNSBL server=rbl.efnetrbl.org index=1,2,3,5 mark=efnetrbl block=anonymous

# Whitelist from a private DNSBL
#IAUTH DNSBL server=whitelist.example.com whitelist cachetime=3600

SASL Authentication Configuration

To enable SASL authentication handling in iauthd-ts (instead of routing to services):

  1. Create a users file (users or any path you prefer):

    # Format: username:passwordhash
    # Use genhash.ts to create hashes
    admin:$5$salt$hashedpassword
    user1:$6$salt$hashedpassword
    
  2. Generate password hashes:

    npx tsx src/genhash.ts mypassword sha256
    # Output: $5$randomsalt$hashedpasswordvalue
    
  3. Configure iauthd-ts:

    #IAUTH POLICY RTAWUwFrS
    #IAUTH SASLDB /path/to/users
    #IAUTH SASLFAILMSG Invalid username or password
    

    The S in the policy enables SASL handling.

  4. Supported hash formats:

    • $5$salt$hash - SHA-256 (recommended)
    • $6$salt$hash - SHA-512
    • $1$salt$hash - MD5 (legacy)
    • Plain text (for testing only)

The users file is automatically reloaded when modified (checked on each SASL attempt).

Modular Authentication Providers

iauthd-ts supports a modular authentication system with multiple backends. Providers are tried in priority order (lower number = tried first) until one succeeds.

AUTH Directive

#IAUTH AUTH provider=<type> [options...]

File Provider

Uses a static users file (same as SASLDB but with explicit provider syntax):

#IAUTH AUTH provider=file path=/path/to/users priority=50

LDAP Provider

Note: LDAP support has not yet been tested with real LDAP servers. Please report any issues.

Two modes are supported:

Direct Bind Mode - Binds directly as the user:

#IAUTH AUTH provider=ldap uri=ldap://ldap.example.com:389 mode=direct userdn=uid=%s,ou=users,dc=example,dc=com

Search Mode - Admin bind, search for user, then bind as user:

#IAUTH AUTH provider=ldap uri=ldaps://ldap.example.com:636 mode=search basedn=ou=users,dc=example,dc=com binddn=cn=admin,dc=example,dc=com bindpass=secret userfilter=(uid=%s) groupdn=cn=ircusers,ou=groups,dc=example,dc=com

LDAP Options:

Option Required Mode Description
uri Yes Both LDAP server URI (ldap:// or ldaps://)
mode Yes Both direct or search
userdn Yes direct DN template with %s for username
basedn Yes search Base DN for user search
binddn Yes search Admin bind DN
bindpass Yes search Admin bind password
userfilter Yes search Search filter with %s for username
groupdn No search Group DN for membership check
accountattr No Both Attribute to use as account name
timeout No Both Connection timeout in ms (default: 5000)
priority No Both Provider priority (default: 100)

Keycloak Provider

Authenticates via Keycloak using Resource Owner Password Credentials (ROPC) grant:

#IAUTH AUTH provider=keycloak url=https://keycloak.example.com realm=myrealm clientid=irc-client

With client secret (for confidential clients):

#IAUTH AUTH provider=keycloak url=https://keycloak.example.com realm=myrealm clientid=irc-client clientsecret=mysecret

Keycloak Options:

Option Required Description
url Yes Keycloak server URL
realm Yes Realm name
clientid Yes Client ID
clientsecret No Client secret (for confidential clients)
accountattr No JWT claim to use as account name (default: preferred_username)
timeout No Request timeout in ms (default: 5000)
priority No Provider priority (default: 100)

Multiple Providers (Fallback Chain)

Configure multiple providers with different priorities. Lower priority = tried first:

#IAUTH AUTH provider=ldap uri=ldaps://ldap.example.com mode=direct userdn=uid=%s,ou=users,dc=example,dc=com priority=10
#IAUTH AUTH provider=keycloak url=https://keycloak.example.com realm=irc clientid=irc-client priority=20
#IAUTH AUTH provider=file path=/path/to/local-users priority=100

Usage

Command Line

node dist/index.js -c <configfile> [-v] [-d]

Options:
  -c, --config   Config file to read (required)
  -v, --verbose  Enable verbose output in iauthd
  -d, --debug    Enable debug output in IRCd
  -h, --help     Show help

IRCd Configuration

Add to your ircd.conf:

IAuth {
  program = "node" "/path/to/iauthd-ts/dist/index.js" "-v" "-c" "/path/to/ircd.conf";
};

For Docker deployments:

IAuth {
  program = "node" "/home/nefarious/ircd/iauthd-ts/index.js" "-v" "-c" "/home/nefarious/ircd/ircd.conf";
};

Monitoring

To see IAuth debug messages as an operator:

/quote mode YourNick +s 262144

Statistics

IAuth statistics are available via /stats iauth and include:

  • Uptime
  • Cache size
  • Total passed/rejected clients
  • Per-DNSBL hit counts

Development

Project Structure

iauthd-ts/
├── src/
│   ├── index.ts      # CLI entry point
│   ├── iauth.ts      # Main IAuth daemon class
│   ├── config.ts     # Configuration parser
│   ├── dnsbl.ts      # DNSBL lookup and caching
│   ├── sasl.ts       # SASL authentication handling
│   ├── genhash.ts    # Password hash generator utility
│   └── types.ts      # TypeScript interfaces
├── users.example     # Example SASL users file
├── tests/
│   ├── config.test.ts   # Config parser tests
│   ├── dnsbl.test.ts    # DNSBL function tests
│   ├── iauth.test.ts    # Integration tests
│   └── stress.ts        # Memory stress test
├── dist/             # Compiled JavaScript (after build)
├── package.json
├── tsconfig.json
└── vitest.config.ts

Building

npm install          # Install dependencies
npm run build        # Compile TypeScript to dist/

Running Tests

npm test             # Run all tests
npm run test:watch   # Watch mode (re-run on changes)
npm run test:coverage # Generate coverage report

Test Coverage

The test suite includes:

  • Unit tests (45 tests): Config parsing, IP handling, DNSBL matching, caching
  • Protocol integration tests (17 tests): IAuth protocol simulation
  • DNSBL integration tests (32 tests): Full pipeline with mocked DNS responses

DNSBL Integration Tests

The DNSBL integration tests (tests/dnsbl-integration.test.ts) use a mock DNS resolver to test realistic scenarios:

Category Tests
Index matching Exact match, multiple indices, no match, NXDOMAIN
Bitmask matching Single bit, multiple bits, no bits match
block=all Blocks both anonymous and authenticated
block=anonymous Blocks anonymous, allows SASL-authenticated
Mark only Accepts client but applies mark
Whitelist Overrides subsequent blocking DNSBLs
Multiple DNSBLs Accumulates marks, any block triggers rejection
Same server/different indices AfterNET pattern (whitelist=2, rbl=250, cloud=251)
Class assignment Assigns connection class from matching DNSBL
Real-world simulation Full AfterNET production config scenarios

Stress Testing

The stress test simulates thousands of concurrent connections to verify:

  • Memory stability (no leaks in client tracking)
  • Cache behavior
  • Performance under load
npm run stress                      # Default: 5000 clients, 120s max
npm run stress -- --clients=10000   # More clients
npm run stress -- --duration=60     # Shorter duration
npm run stress -- -v                # Verbose output

Example output:

============================================================
iauthd-ts Memory Stress Test
============================================================
Clients to simulate: 5000
Max concurrent: 100
Max duration: 120s
============================================================

Sent: 5000 | Accepted: 4994 | Rejected: 6 | Active: 0 | Cache: 5000 | Rate: 520.3/s

============================================================
STRESS TEST RESULTS
============================================================
Total clients sent:     5000
Total clients accepted: 4994
Total clients rejected: 6
Unprocessed clients:    0
Total time:             9.61s
Average rate:           520.29 clients/s

MEMORY ANALYSIS
------------------------------------------------------------
✅ Memory usage appears stable.
✅ All clients were processed correctly.
============================================================

Development Mode

Run directly from TypeScript without compiling:

npm run dev -- -c /path/to/config

Comparison with iauthd.pl

Feature iauthd.pl (Perl) iauthd-ts (TypeScript)
Runtime Perl + POE Node.js
Async Model POE event loop Native async/await
Type Safety None Full TypeScript types
Testing None 62 tests + stress test
Dependencies 5 CPAN modules 0 runtime deps

Troubleshooting

iauthd-ts not starting

  • Check that Node.js 18+ is installed: node --version
  • Verify config file path is correct and readable
  • Check for syntax errors in #IAUTH directives

Clients timing out

  • Increase DNSTIMEOUT if DNSBL servers are slow
  • Check network connectivity to DNSBL servers
  • Verify DNS resolution is working: host 2.0.0.127.dnsbl.example.com

High memory usage

  • Reduce CACHETIME to expire entries sooner
  • Monitor with stress test: npm run stress
  • Check for many unique IPs (each gets cached)

Debug output

Run with -v flag and set operator snomask:

/quote mode YourNick +s 262144

License

GPL-2.0 - Same as Nefarious IRCd