diff --git a/README.md b/README.md
index 5c91d9f..0f24a3a 100644
--- a/README.md
+++ b/README.md
@@ -13,11 +13,19 @@
What •
Setup •
+ IRC •
+ Deploy •
Commands •
Config •
License
+
+ Website •
+ Public Servers •
+ Documentation
+
+
@@ -40,21 +48,25 @@ Each server is fully independent — no central authority, no account federation
```mermaid
graph TD
subgraph Server["Server"]
+ ChatSvc["ChatService"]
Hub["SignalR ChatHub"]
+ IRC["IRC Gateway :6667"]
Auth["JWT Auth"]
DB["SQLite DB (EF Core)"]
Files["File Storage"]
end
- subgraph Client["Client"]
+ subgraph Clients["Clients"]
TUI["Terminal GUI (TUI)"]
- Theme["Theme Engine"]
- API["API Client (auto-refresh)"]
+ IRCClient["IRC Client (irssi, WeeChat, ...)"]
end
- API -- "WebSocket" --> Hub
- API -- "REST" --> Auth
- Hub --> DB
+ TUI -- "WebSocket" --> Hub
+ TUI -- "REST" --> Auth
+ IRCClient -- "TCP" --> IRC
+ Hub --> ChatSvc
+ IRC --> ChatSvc
+ ChatSvc --> DB
Auth --> DB
Files --> DB
```
@@ -65,6 +77,7 @@ graph TD
- **Self-hostable** — your server, your rules, your data
- **Real-time messaging** via SignalR WebSockets
+- **IRC gateway** — native IRC clients connect alongside TUI users, full cross-protocol messaging
- **JWT auth** with short-lived access tokens and 30-day refresh tokens
- **Channels** — create, set topics, delete (no 47-step permission wizard required)
- **File & image uploads** with actual validation (magic bytes, not just trusting the extension)
@@ -122,6 +135,66 @@ Connect, register, chat. That's the whole onboarding flow.
dotnet build src/EchoHub.slnx
```
+## IRC Gateway
+
+EchoHub includes a built-in IRC protocol gateway. Any standard IRC client can connect to the same server and chat alongside TUI users — messages flow both ways in real time.
+
+### Enable It
+
+In the server's `appsettings.json`:
+
+```json
+{
+ "Irc": {
+ "Enabled": true,
+ "Port": 6667,
+ "ServerName": "echohub",
+ "Motd": "Welcome to EchoHub IRC Gateway!"
+ }
+}
+```
+
+### Connect
+
+```bash
+# irssi
+irssi -c your-server.com -p 6667 -w -n
+
+# WeeChat
+/server add echohub your-server.com/6667 -password= -nicks=
+/connect echohub
+```
+
+IRC users must have an existing EchoHub account (no registration via IRC). Auth works via `PASS`/`NICK`/`USER` or SASL PLAIN.
+
+### What Works
+
+| Feature | How it maps to IRC |
+| ------- | ------------------ |
+| Text messages | Standard `PRIVMSG` (long messages split at ~400 byte chunks) |
+| Images | `[Image: filename]` + download URL + ASCII art line-by-line |
+| File uploads | `[File: filename] /api/files/{id}` |
+| Channels | `JOIN`, `PART`, `NAMES`, `TOPIC`, `LIST` |
+| Presence | `AWAY`, `WHO`, `WHOIS` |
+| Status | Maps to IRC away/here |
+
+### TLS
+
+If running behind **nginx** (recommended), let nginx handle TLS -- see [Deployment with nginx](#deployment-with-nginx) below.
+
+For direct TLS without a reverse proxy, the IRC gateway can terminate TLS itself:
+
+```json
+{
+ "Irc": {
+ "TlsEnabled": true,
+ "TlsPort": 6697,
+ "TlsCertPath": "/path/to/cert.pfx",
+ "TlsCertPassword": "your-password"
+ }
+}
+```
+
## Client Commands
| Command | Description |
@@ -172,35 +245,107 @@ dotnet build src/EchoHub.slnx
| `Jwt:Secret` | *(auto-generated)* | JWT signing key |
| `Server:Name` | `My EchoHub Server` | Server display name |
| `Server:Description` | `A self-hosted EchoHub chat server` | Server description |
+| `Server:PublicServer` | `false` | List on the [public directory](https://echohub.voidcube.cloud/servers) |
+| `Server:PublicHost` | *(empty)* | Public hostname for directory listing |
+| `Irc:Enabled` | `false` | Enable the IRC gateway |
+| `Irc:Port` | `6667` | IRC listen port |
+| `Irc:TlsEnabled` | `false` | Enable TLS for IRC |
+| `Irc:TlsPort` | `6697` | IRC TLS port |
+| `Irc:ServerName` | `echohub` | IRC server name in protocol messages |
+| `Irc:Motd` | `Welcome to EchoHub IRC Gateway!` | Message of the day |
| `Cors:AllowedOrigins` | *(all origins)* | CORS whitelist |
-Logging uses Serilog — console + daily rolling files with 14-day retention. Configure it in the `Serilog` section of appsettings.
+Logging uses Serilog — console + daily rolling files with 14-day retention. Configure in the `Serilog` section.
+
+## Deployment with nginx
+
+Most production deployments run behind nginx. Here's a config that handles both the HTTP/WebSocket server and the IRC gateway:
+
+```nginx
+# HTTP + WebSocket (EchoHub Server API + SignalR)
+server {
+ listen 443 ssl;
+ server_name echohub.example.com;
+
+ ssl_certificate /etc/letsencrypt/live/echohub.example.com/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/echohub.example.com/privkey.pem;
+
+ location / {
+ proxy_pass http://127.0.0.1:5000;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ # Required for SignalR WebSocket
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $http_connection;
+
+ proxy_read_timeout 86400s;
+ proxy_send_timeout 86400s;
+ }
+
+ # Increase max upload size for file sharing
+ client_max_body_size 10m;
+}
+
+# HTTP → HTTPS redirect
+server {
+ listen 80;
+ server_name echohub.example.com;
+ return 301 https://$host$request_uri;
+}
+
+# IRC TLS (port 6697 → plain IRC on 6667)
+stream {
+ upstream irc_backend {
+ server 127.0.0.1:6667;
+ }
+
+ server {
+ listen 6697 ssl;
+ proxy_pass irc_backend;
+
+ ssl_certificate /etc/letsencrypt/live/echohub.example.com/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/echohub.example.com/privkey.pem;
+ }
+}
+```
+
+With this setup, keep the EchoHub IRC gateway's `TlsEnabled` set to `false` — nginx terminates TLS. See the full example at [`examples/nginx.conf`](examples/nginx.conf).
## Project Structure
```text
src/
-├── EchoHub.Core/ # Shared models, DTOs, contracts, validation
-│ ├── Constants/ # ValidationConstants, HubConstants
-│ ├── Contracts/ # IEchoHubClient (SignalR interface)
-│ ├── DTOs/ # Record DTOs
-│ └── Models/ # Entity models
+├── EchoHub.Core/ # Shared models, DTOs, contracts, validation
+│ ├── Constants/ # ValidationConstants, HubConstants
+│ ├── Contracts/ # IChatService, IChatBroadcaster, IEchoHubClient
+│ ├── DTOs/ # Record DTOs
+│ └── Models/ # Entity models
│
-├── EchoHub.Server/ # ASP.NET Core server
-│ ├── Auth/ # JWT token service
-│ ├── Controllers/ # REST API endpoints
-│ ├── Data/ # EF Core DbContext + migrations
-│ ├── Hubs/ # SignalR ChatHub
-│ ├── Services/ # Presence, file storage, image processing
-│ └── Setup/ # First-run setup, DB initialization
+├── EchoHub.Server/ # ASP.NET Core server
+│ ├── Auth/ # JWT token service
+│ ├── Controllers/ # REST API endpoints
+│ ├── Data/ # EF Core DbContext + migrations
+│ ├── Hubs/ # SignalR ChatHub
+│ ├── Services/ # ChatService, presence, file storage, image processing
+│ └── Setup/ # First-run setup, DB initialization
│
-├── EchoHub.Client/ # Terminal.Gui TUI client
-│ ├── Config/ # Client configuration
-│ ├── Services/ # API client, SignalR connection
-│ ├── Themes/ # 6 built-in themes
-│ └── UI/ # MainWindow, dialogs, chat renderer
+├── EchoHub.Server.Irc/ # IRC protocol gateway
+│ ├── IrcGatewayService # TCP listener (BackgroundService)
+│ ├── IrcCommandHandler # IRC command dispatch (JOIN, PRIVMSG, etc.)
+│ ├── IrcBroadcaster # Fans chat events to IRC connections
+│ └── IrcMessageFormatter # MessageDto → IRC PRIVMSG lines
│
-└── EchoHub.slnx # Solution file
+├── EchoHub.Client/ # Terminal.Gui TUI client
+│ ├── Config/ # Client configuration
+│ ├── Services/ # API client, SignalR connection
+│ ├── Themes/ # 13 built-in themes
+│ └── UI/ # MainWindow, dialogs, chat renderer
+│
+└── EchoHub.slnx # Solution file
```
## License
diff --git a/docs/api/core-articles/index.md b/docs/api/core-articles/index.md
index 852da7d..d8545b1 100644
--- a/docs/api/core-articles/index.md
+++ b/docs/api/core-articles/index.md
@@ -5,5 +5,5 @@ Articles related to the EchoHub.Core shared library.
## Topics
- Data models and DTOs
-- SignalR contract interface
+- Contract interfaces (IChatService, IChatBroadcaster, IEchoHubClient)
- Validation constants and shared rules
diff --git a/docs/api/index.md b/docs/api/index.md
index 3978198..b62904c 100644
--- a/docs/api/index.md
+++ b/docs/api/index.md
@@ -10,8 +10,12 @@ Terminal.Gui v2 TUI application -- UI components, services, themes, and configur
### Core
-Shared library -- DTOs, models, constants, and the SignalR client contract.
+Shared library -- DTOs, models, constants, and contracts (`IChatService`, `IChatBroadcaster`, `IEchoHubClient`).
### Server
-ASP.NET Core server -- controllers, hubs, authentication, and data access.
+ASP.NET Core server -- controllers, hubs, ChatService, SignalRBroadcaster, authentication, and data access.
+
+### Server.Irc
+
+IRC protocol gateway -- TCP listener, command handler, IrcBroadcaster, and message formatter.
diff --git a/docs/api/server-articles/index.md b/docs/api/server-articles/index.md
index cafad01..6cafdf8 100644
--- a/docs/api/server-articles/index.md
+++ b/docs/api/server-articles/index.md
@@ -6,6 +6,8 @@ Articles related to the EchoHub server built with ASP.NET Core.
- Authentication and JWT tokens
- SignalR hub and real-time messaging
+- IRC gateway and protocol bridging
+- ChatService and broadcaster pattern
- File upload and validation
- Rate limiting configuration
- Database schema and migrations
diff --git a/docs/api/toc.yml b/docs/api/toc.yml
index 78334db..79092df 100644
--- a/docs/api/toc.yml
+++ b/docs/api/toc.yml
@@ -16,3 +16,7 @@
href: ../_api_meta/server/toc.yml
- name: Articles
href: server-articles/
+- name: Server.Irc
+ items:
+ - name: API Reference
+ href: ../_api_meta/server-irc/toc.yml
diff --git a/docs/articles/architecture.md b/docs/articles/architecture.md
index 9b67ffd..bc59652 100644
--- a/docs/articles/architecture.md
+++ b/docs/articles/architecture.md
@@ -4,6 +4,16 @@
EchoHub follows a decentralized model where each server is fully independent. There is no central authority or account federation. Users create one account per server.
+The server exposes two protocol interfaces to the same chat backend:
+
+```text
+IRC Client ──► TCP :6667 ──► IrcGateway ──┐
+ ├──► ChatService ──► DB + PresenceTracker
+TUI Client ──► WebSocket ──► ChatHub ─────┘
+```
+
+Both protocols call into a shared `IChatService` for business logic. Events fan out to all registered `IChatBroadcaster` implementations (SignalR and IRC).
+
## Components
### EchoHub.Core
@@ -12,7 +22,7 @@ Shared library containing:
- **Models**: `User`, `Channel`, `Message`, `RefreshToken`
- **DTOs**: Record types for API requests/responses
-- **Contracts**: `IEchoHubClient` -- the strongly-typed SignalR client interface
+- **Contracts**: `IChatService` (protocol-agnostic chat operations), `IChatBroadcaster` (event fan-out interface), `IEchoHubClient` (SignalR client interface)
- **Constants**: `ValidationConstants` (shared regex patterns), `HubConstants`
### EchoHub.Server
@@ -20,10 +30,21 @@ Shared library containing:
ASP.NET Core web application:
- **Controllers**: REST API endpoints for auth, channels, users, files, server info
-- **Hubs**: SignalR `ChatHub` for real-time messaging
+- **Hubs**: SignalR `ChatHub` -- thin adapter delegating to `IChatService`
- **Auth**: JWT token service (15-min access tokens, 30-day refresh tokens)
- **Data**: EF Core with SQLite
-- **Services**: Presence tracking, file storage, image-to-ASCII conversion
+- **Services**: `ChatService` (core business logic), `SignalRBroadcaster`, presence tracking, file storage, image-to-ASCII conversion
+
+### EchoHub.Server.Irc
+
+IRC protocol gateway (separate project for clean separation of concerns):
+
+- **IrcGatewayService**: `BackgroundService` with TCP listener on configured port(s), optional TLS
+- **IrcCommandHandler**: Per-client IRC command dispatch -- handles `CAP`/`SASL`, `NICK`/`USER`/`PASS`, `JOIN`/`PART`/`PRIVMSG`/`QUIT`, `NAMES`/`TOPIC`/`WHO`/`WHOIS`/`AWAY`/`LIST`/`MODE`/`MOTD`
+- **IrcBroadcaster**: `IChatBroadcaster` implementation that formats chat events as IRC protocol lines, with echo suppression (IRC convention)
+- **IrcMessageFormatter**: Converts `MessageDto` to IRC `PRIVMSG` lines -- splits long text at word boundaries (~400 byte chunks), sends images as ASCII art line-by-line
+
+IRC users authenticate with existing EchoHub accounts via `PASS`/`NICK`/`USER` or SASL PLAIN (BCrypt verification against the database).
### EchoHub.Client
@@ -31,11 +52,22 @@ Terminal.Gui v2 TUI application:
- **UI**: Main window, dialogs, chat renderer with ANSI color support
- **Services**: API client with automatic token refresh, SignalR connection wrapper
-- **Themes**: 6 built-in color themes
+- **Themes**: 13 built-in color themes
- **Config**: Client configuration management
## Communication
-- REST API for authentication, profile management, channel CRUD, file uploads
-- SignalR WebSocket for real-time messaging and presence updates
+- **REST API** for authentication, profile management, channel CRUD, file uploads
+- **SignalR WebSocket** for real-time messaging and presence updates (TUI client)
+- **IRC TCP** for real-time messaging via standard IRC protocol (IRC clients)
- JWT tokens passed via query string for SignalR authentication
+- IRC authentication via PASS/SASL PLAIN against BCrypt password hashes
+
+## Broadcaster Pattern
+
+The `IChatBroadcaster` interface allows multiple protocols to receive chat events:
+
+- **SignalRBroadcaster**: Wraps `IHubContext`, filters out IRC connections
+- **IrcBroadcaster**: Iterates live IRC connections in a channel, formats events as IRC protocol lines
+
+Both are registered in DI and called by `ChatService` when events occur. This means a message sent from an IRC client appears in the TUI client, and vice versa.
diff --git a/docs/articles/getting-started.md b/docs/articles/getting-started.md
index 9f31bf1..2d45cad 100644
--- a/docs/articles/getting-started.md
+++ b/docs/articles/getting-started.md
@@ -4,6 +4,8 @@
- [.NET 10 SDK](https://dotnet.microsoft.com/download)
+Or grab a self-contained binary from [Releases](https://github.com/HueByte/EchoHub/releases) -- no runtime needed.
+
## Run the Server
```bash
@@ -24,6 +26,37 @@ dotnet run --project src/EchoHub.Client
Connect to a server, register an account, and start chatting.
+## Connect via IRC
+
+Enable the IRC gateway in the server's `appsettings.json`:
+
+```json
+{
+ "Irc": {
+ "Enabled": true,
+ "Port": 6667
+ }
+}
+```
+
+Then connect with any standard IRC client:
+
+```bash
+irssi -c localhost -p 6667 -w -n
+```
+
+IRC users must have an existing EchoHub account. Authentication works via `PASS`/`NICK`/`USER` or SASL PLAIN. Messages flow bidirectionally between IRC and TUI clients.
+
+For TLS, set `TlsEnabled: true`, `TlsPort: 6697`, and provide a PKCS#12 certificate path.
+
+See the [Architecture](architecture.md) page for details on how the IRC gateway integrates with the chat service.
+
+## Configuration
+
+Server configuration is in `appsettings.json` (auto-generated on first run). See the [example config](https://github.com/HueByte/EchoHub/blob/master/src/EchoHub.Server/appsettings.example.json) for all available options.
+
+To list your server on the [public directory](https://echohub.voidcube.cloud/servers), set `Server:PublicServer` to `true` and `Server:PublicHost` to your server's public address.
+
## Build from Source
```bash
diff --git a/docs/changelog/index.md b/docs/changelog/index.md
index 90c9628..f34555b 100644
--- a/docs/changelog/index.md
+++ b/docs/changelog/index.md
@@ -4,5 +4,6 @@ Release history for EchoHub.
## Releases
+- [v0.2.0](v0.2.0.md) - IRC Gateway
- [v0.1.1](v0.1.1.md) - Directory Connection Self-Healing
- [v0.1.0](v0.1.0.md) - Initial Release
diff --git a/docs/changelog/toc.yml b/docs/changelog/toc.yml
index 32cbada..b3b5122 100644
--- a/docs/changelog/toc.yml
+++ b/docs/changelog/toc.yml
@@ -1,5 +1,7 @@
- name: Overview
href: index.md
+- name: v0.2.0
+ href: v0.2.0.md
- name: v0.1.1
href: v0.1.1.md
- name: v0.1.0
diff --git a/docs/changelog/v0.2.0.md b/docs/changelog/v0.2.0.md
new file mode 100644
index 0000000..1e9b7cd
--- /dev/null
+++ b/docs/changelog/v0.2.0.md
@@ -0,0 +1,21 @@
+# v0.2.0 - IRC Gateway
+
+## Features
+
+- **IRC protocol gateway** -- native IRC clients (irssi, WeeChat, HexChat, etc.) can connect to EchoHub servers
+- **Cross-protocol messaging** -- messages flow bidirectionally between IRC and TUI clients in real time
+- **SASL PLAIN authentication** -- IRC clients can authenticate via SASL or traditional PASS/NICK/USER
+- **Full IRC command support** -- JOIN, PART, PRIVMSG, QUIT, NAMES, TOPIC, WHO, WHOIS, AWAY, LIST, MODE, MOTD
+- **TLS support** -- optional encrypted IRC connections on port 6697
+- **Image-to-IRC formatting** -- images appear as ASCII art line-by-line with download URLs
+- **Message splitting** -- long messages automatically split at word boundaries (~400 byte chunks)
+- **Configurable MOTD** -- server message of the day for IRC clients
+
+## Architecture Changes
+
+- Extracted shared business logic from `ChatHub` into protocol-agnostic `IChatService`
+- Introduced `IChatBroadcaster` pattern for multi-protocol event fan-out
+- `ChatHub` refactored to thin adapter delegating to `IChatService`
+- `ChannelsController` updated to use `IChatService` for broadcasts
+- New `EchoHub.Server.Irc` project for clean separation of concerns
+- `IChatService` and `IChatBroadcaster` interfaces live in `EchoHub.Core/Contracts`
diff --git a/docs/docfx.json b/docs/docfx.json
index 7e28fca..52df4c8 100644
--- a/docs/docfx.json
+++ b/docs/docfx.json
@@ -30,6 +30,16 @@
],
"dest": "_api_meta/client",
"filter": "filterConfig.yml"
+ },
+ {
+ "src": [
+ {
+ "src": "../src/EchoHub.Server.Irc/bin/Release/net10.0",
+ "files": ["EchoHub.Server.Irc.dll"]
+ }
+ ],
+ "dest": "_api_meta/server-irc",
+ "filter": "filterConfig.yml"
}
],
"build": {
@@ -55,6 +65,12 @@
"dest": "api/client",
"files": ["*.yml"],
"exclude": ["toc.yml"]
+ },
+ {
+ "src": "_api_meta/server-irc",
+ "dest": "api/server-irc",
+ "files": ["*.yml"],
+ "exclude": ["toc.yml"]
}
],
"resource": [
diff --git a/docs/index.md b/docs/index.md
index 6c8b7cd..cf75e8f 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -4,11 +4,13 @@ _layout: landing
# EchoHub Documentation
-Welcome to the EchoHub documentation. EchoHub is a decentralized, IRC-like chat application built with .NET 10 and SignalR.
+Welcome to the EchoHub documentation. EchoHub is a decentralized, IRC-style chat platform. Self-hosted, terminal-first, with a built-in IRC gateway so native IRC clients can connect alongside the TUI client.
+
+**Website:** [echohub.voidcube.cloud](https://echohub.voidcube.cloud/) | **Public Servers:** [Server Directory](https://echohub.voidcube.cloud/servers)
## Quick Links
- [Getting Started](articles/getting-started.md) - Set up and run EchoHub
-- [Architecture](articles/architecture.md) - Understand the system design
+- [Architecture](articles/architecture.md) - System design and IRC gateway
- [API Reference](api/index.md) - Generated C# API documentation
- [Changelog](changelog/index.md) - Release history
diff --git a/examples/nginx.conf b/examples/nginx.conf
new file mode 100644
index 0000000..ca07536
--- /dev/null
+++ b/examples/nginx.conf
@@ -0,0 +1,94 @@
+# EchoHub nginx configuration example
+#
+# This config handles:
+# - HTTPS reverse proxy for the HTTP API + SignalR WebSocket
+# - TLS termination for IRC on port 6697
+# - HTTP → HTTPS redirect
+#
+# Prerequisites:
+# - EchoHub Server running on 127.0.0.1:5000
+# - IRC gateway enabled on port 6667 (Irc:Enabled = true, Irc:TlsEnabled = false)
+# - TLS certificate (e.g. from Let's Encrypt)
+#
+# Usage:
+# 1. Copy this file to /etc/nginx/sites-available/echohub
+# 2. Replace "echohub.example.com" with your domain
+# 3. Update certificate paths
+# 4. ln -s /etc/nginx/sites-available/echohub /etc/nginx/sites-enabled/
+# 5. nginx -t && systemctl reload nginx
+#
+# Note: The "stream" block for IRC TLS must go in the main nginx.conf
+# (outside the http block), not in sites-available. See the bottom of
+# this file for the stream config.
+
+# --- Place this in /etc/nginx/sites-available/echohub ---
+
+# HTTP → HTTPS redirect
+server {
+ listen 80;
+ listen [::]:80;
+ server_name echohub.example.com;
+
+ return 301 https://$host$request_uri;
+}
+
+# HTTPS — API + SignalR WebSocket
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ server_name echohub.example.com;
+
+ ssl_certificate /etc/letsencrypt/live/echohub.example.com/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/echohub.example.com/privkey.pem;
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers HIGH:!aNULL:!MD5;
+
+ # File upload limit (match EchoHub's MaxFileSizeBytes)
+ client_max_body_size 10m;
+
+ location / {
+ proxy_pass http://127.0.0.1:5000;
+ proxy_http_version 1.1;
+
+ # Standard proxy headers
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ # Required for SignalR WebSocket upgrade
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $http_connection;
+
+ # Long timeout for WebSocket connections
+ proxy_read_timeout 86400s;
+ proxy_send_timeout 86400s;
+
+ # Disable buffering for real-time
+ proxy_buffering off;
+ }
+}
+
+# --- Place this in /etc/nginx/nginx.conf (outside the http block) ---
+
+# IRC TLS termination (port 6697 → plain IRC on 6667)
+# The stream module handles raw TCP, not HTTP.
+#
+# stream {
+# upstream irc_backend {
+# server 127.0.0.1:6667;
+# }
+#
+# server {
+# listen 6697 ssl;
+# listen [::]:6697 ssl;
+# proxy_pass irc_backend;
+#
+# ssl_certificate /etc/letsencrypt/live/echohub.example.com/fullchain.pem;
+# ssl_certificate_key /etc/letsencrypt/live/echohub.example.com/privkey.pem;
+# ssl_protocols TLSv1.2 TLSv1.3;
+#
+# # Timeout for idle IRC connections (24 hours)
+# proxy_timeout 86400s;
+# }
+# }