π Complete Guide: Setting Up a Webserver Behind OPNsense
π PURPOSE: This guide documents the entire process of exposing a webserver to the internet through an OPNsense firewall, including all the issues I faced and the solutions that worked.
π IMPORTANT NOTE ABOUT DYNAMIC IPs: My public IP changed during this process, which required updating my DNS records. If you're using a dynamic DNS service, make sure your client is configured to update automatically when your IP changes.
π₯οΈ Part 1: Server Preparation
1.1 Set a Static IP for Your Webserver
Option A: DHCP Reservation in OPNsense (Recommended)
Find your server's MAC address:
In OPNsense: Services > DHCPv4 > [LAN] > DHCP Static Mappings
Add entry with:
- MAC address
- Desired IP (e.g., 192.168.x.xxx)
- Hostname: webserver
Option B: Static IP on Server
# Example for Ubuntu/Debian
sudo nano /etc/netplan/01-netcfg.yaml
Configure (replace with your network range):
network:
version: 2
ethernets:
ens18:
addresses:
- 192.168.x.xxx/24
gateway4: 192.168.x.1
nameservers:
addresses: [192.168.x.1, 1.1.1.1]
1.2 Verify Gateway
Should show: default via 192.168.x.1 dev [interface]
1.3 Test Local Access
From another device on your LAN:
ping 192.168.x.xxx
curl http://192.168.x.xxx
π Part 2: OPNsense Configuration
2.1 Create Destination NAT (Port Forward) Rules
Navigate to Firewall > NAT > Destination Nat > Port Forward
Click Add to create a new rule
HTTP Rule (Port 80):
| Field | Value |
| Interface | WAN |
| Protocol | TCP |
| Destination | WAN address |
| Destination port | HTTP (80) |
| Redirect target IP | 192.168.x.xxx |
| Redirect target port | HTTP (80) |
| Description | Webserver HTTP |
HTTPS Rule (Port 443):
| Field | Value |
| Interface | WAN |
| Protocol | TCP |
| Destination | WAN address |
| Destination port | HTTPS (443) |
| Redirect target IP | 192.168.x.xxx |
| Redirect target port | HTTPS (443) |
| Description | Webserver HTTPS |
β οΈ CRITICAL STEP: For BOTH rules, scroll to the bottom and change:
| Field | Set to |
| Firewall rule | Pass (NOT "Manual") |
π WHY? This tells OPNsense: "This NAT rule itself allows the trafficβno separate WAN firewall rule needed." This bypasses any WAN rule ordering issues and was the key to getting it working.
2.3 Apply Changes
Click Apply at the bottom of the page.
π Part 3: Testing & Verification
3.1 Test Internally First
From another LAN device:
curl http://192.168.x.xxx
curl https://192.168.x.xxx
3.2 Find Your Public IP
In OPNsense: Check Interfaces > [WAN]
Or Google "what is my ip"
π WHAT I LEARNED: My public IP changed during this process, which meant I had to go back and update my DNS records. If you're using dynamic DNS, make sure your client updates automatically!
3.3 Test Externally
From a device NOT on your network (cellular data, friend's house):
http://[your-public-ip]
https://[your-public-ip]
3.4 Check Logs
In OPNsense: Firewall > Log Files > Live View
Look for entries showing your external IP and port 80/443 traffic.
π§ Part 4: Common Issues & Solutions
Issue 1: "No traffic in logs" / "Packets not reaching router"
| Likely Cause | Solution |
| Firewall rule set to Manual | Change to Pass in NAT rule |
| WAN rules stuck at bottom | Bypass with Pass option (no separate WAN rules needed) |
| CGNAT from ISP | Check if WAN IP is in 100.64.0.0/10 rangeβcall ISP for public IP |
Issue 2: Works Internally but Not Externally
| Check This | What to Look For |
| ISP blocking ports | Test with high port (8080) temporarily |
| NAT rule source | Should be any (not WAN net) |
| Webserver firewall | Temporarily disable: sudo ufw disable |
Issue 3: One Port Works, One Doesn't
| Scenario | Fix |
| HTTPS works, HTTP doesn't | Add missing floating rule or ensure both NAT rules set to Pass |
| HTTP works, HTTPS doesn't | Check webserver has HTTPS configured |
Issue 4: Can't Access from Internal Network Using Public IP
Enable NAT Reflection:
- Go to Firewall > Settings > Advanced
- Check Reflection for destination NAT
- Check Automatic outbound NAT for Reflection
- Apply
π¨ Part 5: Critical Lessons Learned
π THE MOST IMPORTANT SETTING:
Always set "Firewall rule" to "Pass" in your Destination NAT rules. This:
- β
Eliminates dependency on WAN rule order
- β
Bypasses stuck system rules
- β
Creates a self-contained port forward
π Rule Order Matters
- OPNsense processes rules top-to-bottom
- System rules (like "Default deny") can't be moved
- Place your rules above blocks, or use Pass option to bypass
π§ͺ Test Methodically
- Start with local access (LAN to server)
- Then test from outside (cellular data)
- Use logs to see if traffic reaches OPNsense
- Use floating rules with Quick as a diagnostic tool
π‘ When All Else Fails
- Create a floating rule with Quick checked
- Test with non-standard ports (8080) to rule out ISP blocking
- Check webserver's default gateway
- Verify webserver's own firewall
β
Checklist for Future Setup
- Server has static IP (e.g., 192.168.x.xxx)
- Default gateway points to OPNsense (192.168.x.1)
- Local access works (curl from LAN)
- Destination NAT rules created (port 80 + 443)
- Firewall rule set to "Pass" (NOT Manual)
- Changes applied
- Test from external device
- Logs show traffic
- DNS records updated if public IP changes
π This guide captures every hurdle I faced and the exact solutions that worked. Save it for future reference!
β Wapiti Labs
β Back to Projects