Oracle APEX Public URL Timeout on OCI
How a WireGuard DNAT rule redirected application traffic away from a healthy local Tomcat/ORDS service
Overview:
An Oracle APEX application hosted on an Oracle Cloud Infrastructure (OCI) compute instance was reachable locally but timed out when accessed using its public IP address on TCP port 8080. The investigation moved from application health and OCI ingress settings to packet-level inspection and Linux NAT rules. The evidence pointed to an unexpected destination NAT (DNAT) rule forwarding requests to an unreachable WireGuard peer, rather than to the local ORDS service.
The TCP 8080 DNAT rule was removed successfully using iptables -t nat -D PREROUTING 2. A subsequent PREROUTING listing confirmed the 8080 redirect was absent while the 8000 and 65535 entries remained.
Environment and symptoms:
Platform: Oracle Cloud Infrastructure (OCI), Oracle Linux compute
Application stack: Oracle APEX via ORDS on Apache Tomcat 9
Instance network: Private address <OCI_PRIVATE_IP>, interface enp0s5
Application port: TCP 8080
Tunnel interface: WireGuard ns0, address 10.0.0.1/24
Observed failure: Browser ERR_CONNECTION_TIMED_OUT via public URL
1. Verify the application before changing networking
The Tomcat Java process was running under the oracle account (PID 241861) using JDK 17.0.12, Apache Tomcat 9.0.106 and ORDS configuration at /u01/softwares/ords/conf/. The process was independently verified with ps -ef | grep 241861. Port inspection confirmed Java was listening on all interfaces, not only localhost:
sudo ss -tlnp | grep ‘:8080’
# Observed: LISTEN … *:8080 … java
Both local and private-IP requests returned HTTP 302, redirecting /ords/ to /ords/_/landing:
curl -v http://127.0.0.1:8080/ords/
curl -v http://<OCI_PRIVATE_IP>:8080/ords/
This established that the web service was responsive on the host. A public timeout was therefore more likely to involve network handling than an ORDS startup failure.
2. Review OCI ingress and host firewall
The OCI security list allowed ingress broadly, and SSH to the instance worked. This did not prove that all traffic was being delivered to the correct process, but it made a simple missing security-list rule less likely.
sudo firewall-cmd — list-all
sudo iptables -L INPUT -n -v — line-numbers
Firewalld reported that it was not running, and the INPUT chain did not show a TCP 8080 block. Importantly, an absent iptables.service unit does not imply that the Linux kernel has no active iptables rules. NAT rules can remain active without a dedicated systemd service.
3. Capture packets during a public connection attempt
sudo tcpdump -ni any ‘tcp port 8080’
During an external access attempt, TCP SYN packets arrived at the instance on <OCI_PRIVATE_IP>:8080. The capture also showed traffic addressed to <WG_PEER_IP>:8080, without a successful TCP handshake. This was the key clue: packets were reaching the host but being redirected.
4. Inspect the NAT table
sudo iptables -t nat -L -n -v — line-numbers
sudo iptables -t nat -S PREROUTING
The PREROUTING chain contained three DNAT rules, all tagged ns0-dnat:
-A PREROUTING -i enp0s5 -p tcp — dport 8000 -m comment — comment ns0-dnat -j DNAT — to-destination <WG_PEER_IP>:8000
-A PREROUTING -i enp0s5 -p tcp — dport 8080 -m comment — comment ns0-dnat -j DNAT — to-destination <WG_PEER_IP>:8080
Get Bdkdinesh’s stories in your inbox
Join Medium for free to get updates from this writer.
-A PREROUTING -i enp0s5 -p tcp — dport 65535 -m comment — comment ns0-dnat -j DNAT — to-destination <WG_PEER_IP>:65535
The 8080 rule explained why a healthy Tomcat listener was not receiving public connections: traffic entering through enp0s5 was translated to a different destination before local socket delivery.
5. Investigate the WireGuard destination
ip -br addr
ip -d link show ns0
sudo wg show
sudo wg show ns0 endpoints
ip route get <WG_PEER_IP>
ping -c 4 <WG_PEER_IP>
The ns0 interface was identified as WireGuard with local tunnel address 10.0.0.1/24. WireGuard peer configuration included <WG_PEER_IP>/32, but peer endpoints were shown as (none). Attempts to reach <WG_PEER_IP> failed with Destination Host Unreachable / No route to host. This supported the conclusion that DNAT was forwarding traffic to an unavailable tunnel endpoint.
Checks for active WireGuard-related systemd services and processes found none. The wg-quick@.service template was installed but disabled. This does not establish who originally created the interface or whether a custom startup mechanism will recreate it.
Root cause
The strongest supported explanation is an unexpected iptables DNAT rule redirecting incoming TCP 8080 traffic from the OCI instance to the unreachable WireGuard peer <WG_PEER_IP>:8080. Oracle APEX/ORDS was running locally on the instance, but the public connection path was being diverted away from it.
Corrective action performed and validation
After reviewing the existing PREROUTING rules, the targeted remediation was performed: remove only the DNAT entry for TCP 8080, preserving the other port forwards. Backing up the rule set and obtaining approval are recommended precautions; the provided logs do not establish whether a backup was actually taken.
# Recommended precaution before modification: iptables-save > /root/iptables-before-apex-test.rules
# Verified initial PREROUTING order: 8000, 8080, 65535
# Executed command (completed without error):
iptables -t nat -D PREROUTING 2
iptables -t nat -S PREROUTING
Observed after the change: PREROUTING policy ACCEPT; DNAT entries for 8000 and 65535 remained; no DNAT entry for TCP 8080 was present. This verifies removal of the redirect at the time of inspection. The ss -antp | grep 80 command was shown without output, so it is not used as evidence of socket state.
Next validation from an external Windows client: Test-NetConnection <PUBLIC_IP> -Port 8080, followed by loading the original APEX URL and checking HTTP response. These post-change tests are not documented in the available record.
If a rollback is approved and needed, first confirm that the 8080 rule is still absent, then reinsert the exact prior rule:
sudo iptables -t nat -I PREROUTING 2 -i enp0s5 -p tcp — dport 8080 -m comment — comment ns0-dnat -j DNAT — to-destination <WG_PEER_IP>:8080
Bringing down ns0 with ip link set ns0 down would interrupt tunnel traffic but would not automatically delete the DNAT rule. For this APEX incident, stopping the tunnel alone is not a sufficient corrective action. Permanent removal should wait until the service owner, persistence mechanism, and dependencies are understood.
Lessons learned
• A healthy local application does not guarantee public reachability.
• An OCI security list allowing traffic does not rule out host-level NAT or routing issues.
• tcpdump can reveal where traffic is actually going after it reaches the instance.
• Firewalld and iptables.service status are not reliable substitutes for inspecting active kernel rules.
• Investigate unexpected tunnel and NAT configurations before removing them; preserve rollback options.
Conclusion and current outcome
The root cause was a host-level DNAT rule that sent incoming TCP 8080 requests to an unreachable WireGuard peer instead of the healthy local ORDS/Tomcat listener. The targeted 8080 DNAT rule was removed, and the follow-up NAT listing verified its absence; the 8000 and 65535 rules were left intact. This is a confirmed network-configuration correction, not yet a confirmed end-to-end application recovery: an external connection test and successful APEX page load remain to be recorded.




