bashforward

External Port Forwarding - WireGuard Server - NGINX Reverse Proxy

GitHub repositorybashforward.com

bashforward provides interactive menus for port forwarding (iptables DNAT), WireGuard VPN user administration, and NGINX reverse proxy with Let's Encrypt automation. All rules and configurations are stored in a SQLite database (bashforward.db)

Port Forwarding

DNAT rules for IPv4/IPv6 using iptables/ip6tables. Custom chains ensure clean management, with systemd service for boot persistence.

WireGuard Menu

Interactive setup & client management. Based on Nyr/wireguard-install, extended with SQLite storage. QR codes, DNS selection, IPv6 support.

NGINX Reverse Proxy

Automatic generation of reverse‑proxy configs. HTTP → HTTPS with Certbot webroot integration. Database‑driven domain/backend mapping.


Project Structure

The suite consists of five main scripts (plus a shared SQLite database):

FilePurpose
bashforward.shMain launcher – menu to enter sub‑tools.
bashforward-portforwarding.shPort forwarding (DNAT) manager.
bashforward-nyr-wireguard.shWireGuard installation & client manager.
bashforward-nginx.shNGINX reverse proxy + Let's Encrypt automation.
bashforward-installer.shInstaller script for dependencies, database, and tables.
bashforward.dbSQLite database (auto‑created).

Installation

Quick Install (Recommended)

The easiest way to get started is to run the automated installer:


git clone https://github.com/babywhale321/bashforward.git
cd bashforward
chmod +x *.sh
sudo ./bashforward-installer.sh

The installer will:

Note: All scripts assume they are executed from the same directory as the database file (bashforward.db). The database is created automatically with the installer script.

Main Menu (bashforward.sh)

======================= bashforward =======================

1. Port Forwarding Menu  2. Wireguard Menu  3. NGINX menu

q. Quit

Each option calls the appropriate sub‑script in a new Bash session.


Port Forwarding Module

bashforward-portforwarding.sh manages DNAT port forwards using iptables (IPv4) and ip6tables (IPv6). All entries are stored in the portforward_entries table.

Key Features

Menu Options

Database Schema: portforward_entries

ColumnTypeDescription
idINTEGER PRIMARY KEYAuto‑increment ID
ip_versionTEXT'v4' or 'v6'
external_portINTEGERPublic listening port
dest_ipTEXTTarget internal IP
dest_portINTEGERTarget port on dest_ip

Example Rule Creation


Enter the IP version (v4/v6): v4
Enter the external port (1-65535): 8080
Enter the destination IP (v4): 10.7.0.2
Enter the destination port (1-65535): 22

The script adds two DNAT rules (TCP+UDP) and a MASQUERADE rule for return traffic. After each change, the systemd service is updated and the rules are applied instantly.

Under the Hood

ensure_iptables_chains() creates the custom chains and adds jump rules if missing. regenerate_script() builds a fresh port-forwarding.sh that flushes the custom chains and re‑adds all DNAT rules. The systemd service runs this script on start.

IPv6 rules use the same logic with ip6tables.


WireGuard Module

bashforward-nyr-wireguard.sh is a fork/adaptation of Nyr/wireguard-install extended with SQLite storage and integration into the bashforward ecosystem.

First‑time Installation

If /etc/wireguard/wg0.conf does not exist, the script guides through a full WireGuard setup:

Client Management Menu

After installation, the script presents a menu for ongoing administration:

Database Schema: wireguard_entries

ColumnTypeDescription
idINTEGER PRIMARY KEYAuto‑increment
nameTEXT UNIQUEClient identifier (sanitized)
public_keyTEXTWireGuard public key
preshared_keyTEXTPreshared key for post‑quantum resistance
ipv4_octetINTEGERLast octet of the client IP (10.7.0.2‑10.7.0.254)
dnsTEXTDNS servers for the client config
created_atDATETIMETimestamp (auto)

Client DNS Selection

The script offers several preset DNS options (Google, Cloudflare, Quad9, etc.) or custom resolvers. The chosen DNS is embedded in the generated .conf file.

Peer Management

When adding a client, the script automatically:

IPv6 support: If an IPv6 address was detected during setup, the ULA prefix fddd:2c4:2c4:2c4::/64 is used, and each client gets a matching IPv6 address (e.g., fddd:2c4:2c4:2c4::octet/128).

Persistence & Firewall

The systemd service wg-iptables.service manages NAT and firewall rules. It is created during installation and remains active. The service uses ExecStart and ExecStop to add/remove rules cleanly.


NGINX Reverse Proxy Module

bashforward-nginx.sh provides a database‑driven NGINX reverse proxy with automatic Let's Encrypt certificate issuance using Certbot webroot method.

How It Works

Database Schema: nginx_entries

ColumnTypeDescription
idINTEGER PRIMARY KEYAuto‑increment
domainTEXT UNIQUEDomain name (e.g., app.example.com)
backend_hostTEXTUpstream server IP/hostname
backend_portINTEGERUpstream port
sslINTEGER1 = SSL enabled, 0 = HTTP only

Menu Options

Adding a Domain with SSL


Domain (e.g., example.com): myapp.example.org
Backend host (IP or hostname): 10.7.0.2
Backend port: 80
Enable SSL (via Certbot)? (y/n): y

The process:

  1. Inserts the record into the database.
  2. Regenerates reverse-proxy-generated.conf with an HTTP server block (including the .well-known/acme-challenge location).
  3. Reloads NGINX.
  4. Runs Certbot in webroot mode to obtain the certificate.
  5. Regenerates the config again, this time including the HTTPS server block with SSL directives.
  6. Final NGINX reload.

The webroot (/var/www/html) is used for ACME challenges. Ensure port 80 is reachable.

Configuration Details

Generated server blocks include 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;

If SSL is enabled and certificates exist, the HTTPS block listens on port 443 and references /etc/letsencrypt/live/domain/fullchain.pem and privkey.pem.

Backup & Safety

Before overwriting the generated config, a backup is saved as reverse-proxy-generated.conf.bak. If the NGINX configuration test fails, the backup is restored automatically.


Shared SQLite Database

All three modules share the same bashforward.db file.

-- portforward_entries
CREATE TABLE IF NOT EXISTS portforward_entries (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    ip_version TEXT NOT NULL,
    external_port INTEGER NOT NULL,
    dest_ip TEXT NOT NULL,
    dest_port INTEGER NOT NULL
);

-- wireguard_entries
CREATE TABLE IF NOT EXISTS wireguard_entries (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT UNIQUE NOT NULL,
    public_key TEXT NOT NULL,
    preshared_key TEXT NOT NULL,
    ipv4_octet INTEGER UNIQUE NOT NULL,
    dns TEXT,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- nginx_entries
CREATE TABLE IF NOT EXISTS nginx_entries (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    domain TEXT UNIQUE NOT NULL,
    backend_host TEXT NOT NULL,
    backend_port INTEGER NOT NULL,
    ssl INTEGER DEFAULT 0
);

Advanced Usage & Customization

License & Credits

bashforward is created by Kyle Schroeder (BabyWhale).
The WireGuard module is based on Nyr/wireguard-install (MIT License).
This documentation is part of the bashforward project.

The entire project is released under the MIT License. See the LICENSE file for details.

For issues, contributions, or feature requests, please visit the GitHub repository.