Skip to main content
Back to Category

Port Access Issues: Firewall and Service Troubleshooting

Guide to diagnosing port access issues using netstat, ss, iptables, ufw, and service listening configuration.

Read time: 13 min Troubleshooting
portfirewallnetstatssiptablesufwservice

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:

hljs bash
# 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

hljs bash
# 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))
FieldDescription
State LISTENPort is actively listening
0.0.0.0:portAccessible from all interfaces
127.0.0.1:portOnly accessible from localhost
ProcessProcess 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)

hljs bash
# 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

hljs bash
# 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

hljs bash
# 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)

hljs bash
# 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

hljs bash
# 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

hljs nginx
server {
    listen 80;              # Listen on all interfaces
    listen [::]:80;         # Including IPv6
    server_name example.com;
}

MySQL/MariaDB

hljs ini
# /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

hljs ini
# /etc/postgresql/15/main/postgresql.conf
listen_addresses = '*'    # All interfaces
port = 5432
hljs bash
# /etc/postgresql/15/main/pg_hba.conf
host    all    all    0.0.0.0/0    md5

Redis

hljs ini
# /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

hljs bash
# 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

hljs bash
#!/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

IssueCauseSolution
Port not listeningService not runningsystemctl start service_name
Listening on 127.0.0.1Bind address is localhostChange to 0.0.0.0 in config
Firewall blockingNo port ruleOpen port with iptables/ufw/firewalld
Path Panel blockingNo filter ruleCreate rule in Path Panel
Connection refusedService port changedCheck service configuration
TimeoutNetwork or firewall issueCheck 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.