Port Access Issues: Firewall and Service Troubleshooting
Guide to diagnosing port access issues using netstat, ss, iptables, ufw, and service listening configuration.
Table of Contents
Introduction
Being unable to access a service running on your server from outside is usually caused by port access issues. In this guide, we will explain in detail the tools and methods you can use to systematically diagnose and resolve port access problems.
Checking Port Status
Port Check with ss Command
The ss command is used on modern Linux systems to display socket statistics:
# List all listening TCP ports
ss -tlnp
# List all listening UDP ports
ss -ulnp
# Check a specific port
ss -tlnp | grep :80
ss -tlnp | grep :443
ss -tlnp | grep :3306
# Show all connections (listening + established)
ss -tanp
# Detailed socket information
ss -tlnp -e
Interpreting ss Output
# Example output:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3))
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=5678,fd=6))
LISTEN 0 128 127.0.0.1:3306 0.0.0.0:* users:(("mysqld",pid=9012,fd=22))
| Field | Description |
|---|---|
| State LISTEN | Port is actively listening |
| 0.0.0.0:port | Accessible from all interfaces |
| 127.0.0.1:port | Only accessible from localhost |
| Process | Process information listening on the port |
If a service is listening on 127.0.0.1, it cannot be accessed from outside. You need to change the bind-address or listen directive to 0.0.0.0 in the service configuration.
netstat Command (Legacy Systems)
# List all listening ports
netstat -tlnp
# All ports including UDP
netstat -tulnp
# Check specific port
netstat -tlnp | grep :8080
# Show connection counts
netstat -an | grep :80 | wc -l
Firewall Check
Checking with iptables
# List all rules
sudo iptables -L -n -v
# Check INPUT chain
sudo iptables -L INPUT -n -v --line-numbers
# Check NAT table
sudo iptables -t nat -L -n -v
# Search for rules on a specific port
sudo iptables -L -n -v | grep 80
Opening Ports with iptables
# Open TCP port 80
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Open TCP port 443
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Port access from specific IP
sudo iptables -A INPUT -p tcp -s 192.168.1.100 --dport 3306 -j ACCEPT
# Open port range
sudo iptables -A INPUT -p tcp --dport 8000:9000 -j ACCEPT
# Save rules
sudo iptables-save > /etc/iptables/rules.v4
sudo netfilter-persistent save
UFW (Uncomplicated Firewall)
# Check UFW status
sudo ufw status verbose
# List numbered rules
sudo ufw status numbered
# Open ports
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 8080/tcp
# Port access from specific IP
sudo ufw allow from 192.168.1.100 to any port 3306
# Open port range
sudo ufw allow 8000:9000/tcp
# Delete rule
sudo ufw delete allow 8080/tcp
# Enable UFW
sudo ufw enable
# Reload UFW
sudo ufw reload
firewalld
# Check active zone
sudo firewall-cmd --get-active-zones
# List all rules
sudo firewall-cmd --list-all
# Open port (temporary)
sudo firewall-cmd --add-port=80/tcp
# Open port (permanent)
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload
# Add service
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Service Listening Configuration
Nginx
server {
listen 80; # Listen on all interfaces
listen [::]:80; # Including IPv6
server_name example.com;
}
MySQL/MariaDB
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
bind-address = 0.0.0.0 # Listen on all interfaces (for remote access)
# bind-address = 127.0.0.1 # Localhost only (default, secure)
port = 3306
PostgreSQL
# /etc/postgresql/15/main/postgresql.conf
listen_addresses = '*' # All interfaces
port = 5432
# /etc/postgresql/15/main/pg_hba.conf
host all all 0.0.0.0/0 md5
Redis
# /etc/redis/redis.conf
bind 0.0.0.0
port 6379
protected-mode yes
requirepass STRONG_PASSWORD
When exposing database and cache services externally, always use strong passwords and IP restrictions. Otherwise, your server becomes vulnerable to attacks.
External Port Testing
# Remote port test from local machine
nc -zv SERVER_IP 80
nc -zv SERVER_IP 443
# Detailed port scan with nmap
nmap -p 80,443,3306,5432,6379 SERVER_IP
# Service version detection
nmap -sV -p 80,443 SERVER_IP
# HTTP port test with curl
curl -I http://SERVER_IP:80
curl -I https://SERVER_IP:443
REXE Path Panel Integration
On REXE servers, when an IP has no rules at all, all ports are open. When your IP has at least one rule, Default Block is automatically activated and only the allowed ports stay open. To allow external access to your service, you need to create a filter rule for the relevant port in Path Panel:
1. Log in to Path Panel (x.rexe.tr)
2. Click on the relevant IP address
3. Click "Add New Rule"
4. Protocol: TCP (or UDP)
5. Direction: Symmetric (bidirectional)
6. Destination Port: The port you want to open
7. Action: Allow
8. Save the rule and wait for propagated status
Even if the panel shows the rule as not yet propagated (not updated), the rule has most likely already been deployed within 2-5 minutes. The status may update with a delay due to the panel's status-check interval or the time it takes for the rule to be applied across all nodes on the Path side (except ours). This is only a visual delay in the panel; the port has in fact already been opened in the system.
Troubleshooting Script
#!/bin/bash
PORT=$1
SERVER_IP=$2
if [ -z "$PORT" ] || [ -z "$SERVER_IP" ]; then
echo "Usage: $0 <port> <server_ip>"
exit 1
fi
echo "=== Port $PORT Access Check ==="
echo -e "\n[1] Service Listening Check:"
ss -tlnp | grep ":$PORT" || echo "Port $PORT is not listening!"
echo -e "\n[2] Firewall Check:"
if command -v ufw &> /dev/null; then
sudo ufw status | grep "$PORT"
else
sudo iptables -L -n | grep "$PORT"
fi
echo -e "\n[3] External Access Test:"
nc -zv -w 5 $SERVER_IP $PORT 2>&1
echo -e "\n=== Check Complete ==="
Common Issues and Solutions
| Issue | Cause | Solution |
|---|---|---|
| Port not listening | Service not running | systemctl start service_name |
| Listening on 127.0.0.1 | Bind address is localhost | Change to 0.0.0.0 in config |
| Firewall blocking | No port rule | Open port with iptables/ufw/firewalld |
| Path Panel blocking | No filter rule | Create rule in Path Panel |
| Connection refused | Service port changed | Check service configuration |
| Timeout | Network or firewall issue | Check with traceroute and mtr |
Conclusion
To resolve port access issues, you need to perform a three-layer check: service listening status, server firewall rules, and REXE Path Panel rules. First ensure the service is listening on the correct port and interface, then check firewall rules, and finally create the necessary rules in Path Panel.
Related Articles
SSH Connection Problem: Can't Connect to Server
SSH connection troubleshooting guide: Path.net firewall rules, Default Block, creating a filter rule for SSH port, and step-by-step troubleshooting.
RDP Connection Problem: Can't Connect to Windows Server
RDP connection troubleshooting guide: Path.net firewall rules, Default Block, creating a filter rule for RDP port, and step-by-step troubleshooting.
How to Run an MTR Test and Submit Results to Support
Guide to running MTR network tests with WinMTR and Linux MTR, creating ICMP filter rules, and submitting results to support. Diagnose packet loss and latency.