⚡ 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 lightweight SQLite database (bashforward.db), making them persistent, reproducible, and easy to audit.

🔁 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 four 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.dbSQLite database (auto‑created).

⚙️ Installation & Prerequisites

Clone the repository and ensure dependencies are installed:


apt install git -y
git clone https://github.com/babywhale321/bashforward.git
cd bashforward
chmod +x *.sh

Required packages (auto‑detected):

Run the main menu as root:

sudo ./bashforward.sh
📌 Note: All scripts assume they are executed from the same directory as the database file (bashforward.db). The database is created automatically when needed.

🧩 Main Menu (bashforward.sh)

The entry point displays a clean menu:

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

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

q. Quit

Each option calls the respective 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.

⚠️ Important: The script expects Certbot to be installed and the NGINX service to be managed via systemd (systemctl reload nginx). The webroot directory is created if missing.

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. The tables are created automatically when the respective script runs for the first time:

-- 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.

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