Skip to content

IRC Gateway

Build Status

WebSocket to IRC gateway for Simple IRC Client.

Local Development

pnpm install
pnpm start

Gateway runs on ws://localhost:8667/irc

Testing

pnpm test           # Run tests once
pnpm run test:watch # Run tests in watch mode
pnpm run lint       # TypeScript + ESLint checks

Server Deployment

Docker / Podman

docker build -t simple-irc-gateway .

docker run -d \
  --name sic-gateway \
  --restart unless-stopped \
  -p 8667:8667 \
  -p 113:8113 \
  -e PORT=8667 \
  -e HOST=0.0.0.0 \
  -e IDENTD_ENABLED=true \
  -e IDENTD_PORT=8113 \
  simple-irc-gateway

The container runs as the non-root node user. Identd binds to a high port (8113) inside the container, mapped to host port 113 via -p 113:8113 β€” no CAP_NET_BIND_SERVICE needed.

Reverse Proxy (Caddy)

sudo apt install caddy

/etc/caddy/Caddyfile:

irc.yourdomain.com {
    reverse_proxy /irc localhost:8667
}
sudo systemctl reload caddy

Reverse Proxy (Nginx)

server {
    listen 443 ssl http2;
    server_name irc.yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location /irc {
        proxy_pass http://127.0.0.1:8667;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_read_timeout 86400;
    }
}

Automated Deployment (GitHub Actions)

CI deploys via a non-privileged deploy user with scoped sudo β€” it never logs in as root. Provision the server once as root:

# from a checkout of this repo on the server (or after scp-ing the deploy/ dir)
sudo DEPLOY_PUBKEY="$(cat deploy_key.pub)" bash deploy/bootstrap.sh

bootstrap.sh creates the deploy user, installs its SSH key, installs podman + caddy, creates /opt/sic-gateway (deploy-owned), and writes a scoped /etc/sudoers.d/sic-deploy granting only the binaries deploys need (systemctl, podman, nft, apt-get, tee, the firewall script). The private half of DEPLOY_PUBKEY is the GitHub Actions SSH_KEY secret. Re-run bootstrap.sh (as root) after changing the package set or sudoers scope.

Environment Variables

Variable Default Description
PORT 8667 Server port
HOST 0.0.0.0 Bind address
PATH_PREFIX /irc WebSocket path
WEBIRC_PASSWORD - WEBIRC password (optional)
WEBIRC_GATEWAY gateway WEBIRC gateway name
ALLOWED_SERVERS - Comma-separated list (e.g., irc.libera.chat:6697)
IDENTD_ENABLED false Enable identd (RFC 1413) server
IDENTD_PORT 113 Identd listen port
IDENTD_TIMEOUT 30 Identd connection timeout (seconds)

Identd (RFC 1413)

IRC servers query port 113 on connecting clients to verify identity. Without identd, users appear with an unverified ident (prefixed with ~). Enabling the built-in identd server lets the gateway respond with the correct username.

Enable identd

Set IDENTD_ENABLED=true and configure the port. When running in Docker/Podman, use a high port inside the container (e.g. IDENTD_PORT=8113) and map it to host port 113 with -p 113:8113. This avoids needing any special capabilities.

Client ident parameter

WebSocket clients can pass a custom ident username via the ident query parameter:

ws://gateway:8667/webirc?host=irc.example.com&port=6697&tls=true&ident=myuser

If not provided, the gateway derives a username from the client's IP address.

WEBIRC

To forward real client IPs to IRC servers:

  1. Request WEBIRC access from the IRC network
  2. Set WEBIRC_PASSWORD environment variable
  3. Gateway sends client IP to IRC server

Frontend Configuration

Update your frontend to connect to the gateway:

const WS_URL = 'wss://irc.yourdomain.com/irc';

About

🌐 IRC gateway

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages