Skip to content

SysopNetwork/BBSFirewall

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

13 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—    β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—    β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—     β–ˆβ–ˆβ•—
  β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•    β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘    β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘
  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—    β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘ β–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘
  β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β•šβ•β•β•β•β–ˆβ–ˆβ•‘    β–ˆβ–ˆβ•”β•β•β•  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘
       β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘    β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
       β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β•    β•šβ•β•     β•šβ•β•β•šβ•β•  β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β•β•β•šβ•β•β• β•šβ•β•  β•šβ•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•

A lightweight TCP proxy firewall for BBS telnet connections, built with Node.js.

By Sysop Network β€” https://github.com/SysopNetwork/BBSFirewall

Node.js License Platform PM2


✨ Features

Feature Description
πŸ”€ TCP Proxy Forwards telnet connections to a backend BBS server
πŸ”’ SSH Server Encrypted SSH access on any port, proxied to the telnet backend
🌐 HTTPS Redirect Redirects both HTTP (port 80) and HTTPS (port 443) to a configured URL
πŸ”‘ Let's Encrypt Built-in cert setup script with auto-renewal, no downtime required
πŸ“‘ PROXY Protocol v1 Passes the real client IP to the backend BBS (requires compatible backend)
🌍 Country Blocking Block connections by country using a local GeoIP database
βœ… IP Whitelist Trusted IPs that bypass all firewall rules
🚫 IP Blocklist Permanently block specific IPs or CIDR ranges
⚑ Rate Limiting Automatic flood protection with configurable temporary blocks
πŸ”— Per-IP Connection Limit Cap simultaneous connections from a single IP
πŸ–₯️ Encoding Detection Automatic UTF-8/CP437 detection with separate backend routing
πŸ›‘ Graceful Shutdown Clean shutdown on SIGTERM/SIGINT, active sessions drain properly
βš™οΈ PM2 Ready Includes ecosystem.config.js for process management

πŸš€ Installation

Requirements

  • Node.js 14 or higher
  • Root or CAP_NET_BIND_SERVICE to bind ports below 1024 (23, 80, 443)
  • Linux recommended for production; runs anywhere Node.js runs

Quick start

# 1. Clone the repo
git clone https://github.com/SysopNetwork/BBSFirewall.git
cd BBSFirewall

# 2. Install dependencies
npm install

# 3. Create your config
cp .env.example .env
nano .env   # set BACKEND_HOST, BACKEND_PORT at minimum

# 4. Start it
npm start

Production (PM2)

npm install -g pm2

pm2 start ecosystem.config.js
pm2 save
pm2 startup   # follow the printed command to enable auto-start on boot

PM2 commands:

pm2 start ecosystem.config.js   # start
pm2 stop bbsfirewall            # stop
pm2 restart bbsfirewall         # restart
pm2 logs bbsfirewall            # tail logs
pm2 list                        # status

βš™οΈ Configuration

All settings live in .env. Copy .env.example to get started β€” every option is documented there.

🌐 Network

Variable Description Default
LISTEN_PORTPort to listen on for incoming telnet connections23
BACKEND_HOSTBackend BBS server hostname or IP127.0.0.1
BACKEND_PORTBackend BBS server port23
ENCODING_DETECTIONEnable automatic UTF-8/CP437 encoding detectionfalse
BACKEND_PORT_CP437Backend port for CP437 (DOS/ANSI) clients2323
BACKEND_PORT_UTF8Backend port for UTF-8 (Unicode) clients2423

πŸ”— Connection Limits

Variable Description Default
MAX_CONNECTIONSMaximum total simultaneous connections100
MAX_CONNECTIONS_PER_IPMax simultaneous connections from a single IP (0 = unlimited)0
CONNECTION_TIMEOUTConnection timeout in milliseconds (0 to disable)300000

🌍 Country Blocking

Variable Description Default
BLOCKED_COUNTRIESComma-separated ISO country codes to block (e.g. CN,RU,KP)(empty)
BLOCK_UNKNOWN_COUNTRIESBlock connections with undetermined countryfalse

πŸ›‘οΈ IP Lists

Variable Description Default
WHITELIST_PATHPath to IP whitelist file (bypasses all firewall rules)(empty)
BLOCKLIST_PATHPath to IP blocklist file (permanent blocks)(empty)

⚑ Rate Limiting

Variable Description Default
RATE_LIMIT_ENABLEDEnable connection flood protectiontrue
MAX_CONNECTIONS_PER_WINDOWMax connection attempts per IP per time window10
RATE_LIMIT_WINDOW_MSTime window in milliseconds60000
RATE_LIMIT_BLOCK_DURATION_MSTemporary block duration in milliseconds300000

πŸ“‘ PROXY Protocol

Variable Description Default
PROXY_PROTOCOL_ENABLEDPrepend real client IP to backend TCP streamfalse

🌐 Web Redirect

Variable Description Default
WEB_REDIRECT_ENABLEDRedirect HTTP traffic on port 80false
WEB_REDIRECT_URLDestination URL for redirects (used by both HTTP and HTTPS)(empty)

πŸ”’ HTTPS Redirect

Variable Description Default
HTTPS_REDIRECT_ENABLEDRedirect HTTPS traffic on port 443false
HTTPS_REDIRECT_PORTPort to listen on for HTTPS443
HTTPS_CERT_PATHPath to TLS certificate (fullchain)./certs/fullchain.pem
HTTPS_KEY_PATHPath to TLS private key./certs/privkey.pem
ACME_WEBROOTDirectory for Let's Encrypt challenge files./certs/webroot

πŸ“‹ Logging

Variable Description Default
LOG_LEVELLog level: debug, info, warn, errorinfo

πŸ”’ SSH Server

Variable Description Default
SSH_ENABLEDEnable the SSH serverfalse
SSH_LISTEN_PORTPort to listen on for SSH connections2222
SSH_HOST_KEYPath to SSH host private key file./ssh_host_key
SSH_CIPHERSComma-separated list of allowed SSH ciphers(see below)

πŸ”’ SSH Server

BBSFirewall includes an optional SSH server that accepts any username and password and proxies the session to the backend BBS via telnet. This lets users connect with a modern SSH client instead of a raw telnet client.

Setup

Generate an SSH host key (only needed once):

ssh-keygen -t rsa -b 4096 -f ssh_host_key -N "" -m PEM

Enable in .env:

SSH_ENABLED=true
SSH_LISTEN_PORT=22
SSH_HOST_KEY=./ssh_host_key

Connect from any SSH client β€” any username and password works:

ssh yourserver.example.com

Default SSH Ciphers

Includes both modern and legacy ciphers for old terminal clients:

  • aes128-gcm@openssh.com, aes256-gcm@openssh.com
  • aes128-ctr, aes192-ctr, aes256-ctr
  • aes128-cbc, aes192-cbc, aes256-cbc
  • 3des-cbc (for very old clients)

Note: Binary file transfers (Zmodem, Ymodem, etc.) do not work reliably over SSH due to PTY character processing. Use the telnet connection for file transfers and SSH for interactive browsing.


🌐 Web & HTTPS Redirect

BBSFirewall can redirect web browsers that hit your firewall's IP address to your BBS website.

HTTP redirect (port 80)

WEB_REDIRECT_ENABLED=true
WEB_REDIRECT_URL=https://yourbbs.example.com

HTTPS redirect (port 443)

Requires a TLS certificate. Run setup-certs.sh to get a free one from Let's Encrypt (see below).

HTTPS_REDIRECT_ENABLED=true
HTTPS_REDIRECT_PORT=443
HTTPS_CERT_PATH=./certs/fullchain.pem
HTTPS_KEY_PATH=./certs/privkey.pem

WEB_REDIRECT_URL is used as the destination for both HTTP and HTTPS redirects.

Note: On Linux, binding ports 80 and 443 requires root or the CAP_NET_BIND_SERVICE capability.


πŸ”‘ Let's Encrypt Certificates

BBSFirewall includes setup-certs.sh to get a free TLS certificate from Let's Encrypt using certbot's webroot method. The HTTP server stays running the whole time β€” no downtime.

Requirements

  • Port 80 must be reachable from the internet
  • WEB_REDIRECT_ENABLED=true in your .env
  • BBSFirewall must be running before you run the script
  • DNS must already point your domain to this server

Get a certificate

bash setup-certs.sh yourdomain.com --email you@example.com

The script will:

  1. Install certbot if it's not already there
  2. Verify port 80 is listening
  3. Run certbot in webroot mode (no service interruption)
  4. Copy the certificates to ./certs/
  5. Install a renewal hook that auto-copies new certs and restarts BBSFirewall
  6. Print the .env lines to add

Manual renewal

bash setup-certs.sh yourdomain.com --renew

Renewal is also automatic via certbot's built-in systemd timer β€” you don't have to think about it.


πŸ“‘ PROXY Protocol v1

BBSFirewall can prepend a PROXY Protocol v1 header to every backend connection so the destination BBS can see the real client IP instead of the firewall's IP.

PROXY_PROTOCOL_ENABLED=true

When enabled, every connection to the backend starts with:

PROXY TCP4 203.0.113.45 192.0.2.1 56324 23

Fields: protocol, real client IP, proxy IP, client port, proxy port.

This works for both telnet and SSH connections.

⚠️ Important: The backend BBS software must support PROXY Protocol, or have a module/plugin that reads and strips the header before the BBS sees it. Enabling this against an incompatible backend will break all connections β€” the BBS will receive the header line as garbage data at the start of every session.

Compatible backends include HAProxy, Nginx, Synchronet, WWIV, Mystic, and any software with a PROXY Protocol module. Standard MajorBBS/Worldgroup requires a companion MBBS module to handle the header.

Full spec: https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt


🌍 Country Blocking

Block connections from specific countries using a local MaxMind GeoLite2 database. No external API calls β€” the lookup happens entirely on your server.

Setup

npm run setup-geoip

Follow the on-screen instructions. A free MaxMind account is required at maxmind.com.

Configuration

BLOCKED_COUNTRIES=CN,RU,KP,IR
BLOCK_UNKNOWN_COUNTRIES=false

Use ISO 3166-1 alpha-2 two-letter country codes.


πŸ›‘οΈ IP Filtering & Rate Limiting

Whitelist

IPs in the whitelist bypass all firewall rules β€” country blocking, rate limiting, blocklist, per-IP limits. Use this for trusted admin IPs.

cp whitelist.txt.example whitelist.txt
# Add your trusted IPs β€” one per line, CIDR ranges supported
WHITELIST_PATH=./whitelist.txt

Blocklist

Permanently blocked IPs. Rejected immediately on connect regardless of any other setting.

cp blocklist.txt.example blocklist.txt
# Add IPs to block β€” one per line, CIDR ranges supported
BLOCKLIST_PATH=./blocklist.txt

Rate Limiting

Automatically blocks IPs that hammer the connection too frequently. Temporary blocks expire after RATE_LIMIT_BLOCK_DURATION_MS.

RATE_LIMIT_ENABLED=true
MAX_CONNECTIONS_PER_WINDOW=10
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_BLOCK_DURATION_MS=300000

Connection Decision Order

Every incoming connection goes through these checks in order:

Step Check Action
1 βœ… Whitelist Matched IPs are allowed immediately β€” all other checks skipped
2 🚫 Blocklist Permanent block
3 ⚑ Rate limit Temporary block if threshold exceeded
4 πŸ”— Per-IP connection limit Reject if over MAX_CONNECTIONS_PER_IP
5 🌍 GeoIP country check Block if country is in BLOCKED_COUNTRIES
6 πŸ”€ Forward Connect to backend BBS

πŸ–₯️ Encoding Detection

BBSFirewall can detect whether a connecting SSH client prefers UTF-8 or CP437 and route them to separate backend ports. Useful if your BBS software runs separate instances for each encoding.

ENCODING_DETECTION=true
BACKEND_PORT_CP437=2323
BACKEND_PORT_UTF8=2423

Detection for SSH clients is based on the client's LANG/LC_ALL environment variables and terminal type. Telnet connections always default to CP437 β€” there's no reliable way to detect encoding before the connection is established.


πŸ“ Architecture

BBSFirewall/
β”œβ”€β”€ server.js              # Main entry point, connection manager, graceful shutdown
β”œβ”€β”€ proxy.js               # Bidirectional TCP proxy handler
β”œβ”€β”€ ssh.js                 # SSH server β€” accepts any credentials, proxies to telnet
β”œβ”€β”€ web-redirect.js        # HTTP + HTTPS redirect server with ACME challenge support
β”œβ”€β”€ proxy-protocol.js      # PROXY Protocol v1 header builder
β”œβ”€β”€ config.js              # Configuration loading and validation
β”œβ”€β”€ logger.js              # Log level filtering
β”œβ”€β”€ geoip.js               # MaxMind GeoLite2 country lookup
β”œβ”€β”€ ipfilter.js            # IP lists, rate limiting, per-IP connection tracking
β”œβ”€β”€ encoding-detector.js   # UTF-8/CP437 detection logic
β”œβ”€β”€ download-geoip.js      # GeoIP database setup helper
β”œβ”€β”€ setup-certs.sh         # Let's Encrypt certificate setup script
β”œβ”€β”€ ecosystem.config.js    # PM2 process config
β”œβ”€β”€ package.json
β”œβ”€β”€ .env.example           # Documented example configuration
β”œβ”€β”€ whitelist.txt.example
β”œβ”€β”€ blocklist.txt.example
└── data/                  # GeoIP database (not included, run setup-geoip)

πŸ† Credits

BBSFirewall is developed and maintained by Mark Laudenbach at Sysop Network.

Built on the foundation of bbsfw by Ryan Fantus. Solid starting point β€” thanks for putting that together.


πŸ“„ License

MIT β€” Copyright (c) 2026 Sysop Network

About

BBS Firewall - geo ip blocking telnet firewall for retro BBSes. Also has rate limit dynamic IP blocking and supports blocklists.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors