feat: add CertFP authentication with SASL EXTERNAL
Per-network, per-nick client certificates (EC P-256, self-signed, 10-year validity) stored as combined PEM files. Authentication cascade: SASL EXTERNAL > SASL PLAIN > NickServ IDENTIFY. New commands: GENCERT, CERTFP, DELCERT. GENCERT auto-registers the fingerprint with NickServ CERT ADD when the network is connected. Includes email verification module for NickServ registration and expanded NickServ interaction (IDENTIFY, REGISTER, VERIFY).
This commit is contained in:
@@ -196,6 +196,55 @@ autojoin = true # auto-join channels on ready (default: true)
|
||||
password = "" # IRC server password (optional, for PASS command)
|
||||
```
|
||||
|
||||
## CertFP Authentication
|
||||
|
||||
The bouncer supports client certificate fingerprint (CertFP) authentication
|
||||
via SASL EXTERNAL. Each certificate is unique per (network, nick) pair and
|
||||
stored as a combined PEM file at `{data_dir}/certs/{network}/{nick}.pem`.
|
||||
|
||||
### Authentication Cascade
|
||||
|
||||
When connecting, the bouncer selects the strongest available method:
|
||||
|
||||
| Priority | Method | Condition |
|
||||
|----------|--------|-----------|
|
||||
| 1 | SASL EXTERNAL | Stored creds + cert file exists |
|
||||
| 2 | SASL PLAIN | Stored creds, no cert |
|
||||
| 3 | NickServ IDENTIFY | Fallback after SASL failure |
|
||||
|
||||
### Setup
|
||||
|
||||
1. Generate a certificate:
|
||||
```
|
||||
/msg *bouncer GENCERT libera
|
||||
```
|
||||
This creates an EC P-256 self-signed cert (10-year validity) and
|
||||
auto-sends `NickServ CERT ADD <fingerprint>` if the network is connected.
|
||||
|
||||
2. Reconnect to use CertFP:
|
||||
```
|
||||
/msg *bouncer RECONNECT libera
|
||||
```
|
||||
The bouncer will now present the client certificate during TLS and
|
||||
authenticate via SASL EXTERNAL.
|
||||
|
||||
3. Verify the fingerprint is registered:
|
||||
```
|
||||
/msg *bouncer CERTFP libera
|
||||
```
|
||||
|
||||
### Certificate Storage
|
||||
|
||||
Certificates are stored alongside the config file:
|
||||
|
||||
```
|
||||
{data_dir}/certs/
|
||||
libera/
|
||||
fabesune.pem # cert + private key (chmod 600)
|
||||
oftc/
|
||||
mynick.pem
|
||||
```
|
||||
|
||||
## Bouncer Commands
|
||||
|
||||
Send a PRIVMSG to `*bouncer` (or `bouncer`) from your IRC client to inspect
|
||||
@@ -248,6 +297,14 @@ Responses arrive as NOTICE messages from `*bouncer`.
|
||||
| `REGISTER <network>` | Trigger NickServ registration attempt |
|
||||
| `DROPCREDS <network> [nick]` | Delete stored NickServ credentials |
|
||||
|
||||
### CertFP
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `GENCERT <network> [nick]` | Generate client cert, auto-register with NickServ |
|
||||
| `CERTFP [network]` | Show certificate fingerprints (all or per-network) |
|
||||
| `DELCERT <network> [nick]` | Delete a client certificate |
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
@@ -272,6 +329,12 @@ Responses arrive as NOTICE messages from `*bouncer`.
|
||||
/msg *bouncer REGISTER libera
|
||||
/msg *bouncer DROPCREDS libera
|
||||
/msg *bouncer DROPCREDS libera oldnick
|
||||
/msg *bouncer GENCERT libera
|
||||
/msg *bouncer GENCERT libera fabesune
|
||||
/msg *bouncer CERTFP
|
||||
/msg *bouncer CERTFP libera
|
||||
/msg *bouncer DELCERT libera
|
||||
/msg *bouncer DELCERT libera fabesune
|
||||
```
|
||||
|
||||
### Example Output
|
||||
|
||||
Reference in New Issue
Block a user