How to Configure Custom SSH Ports on AWS EC2: Solving Security Group and iptables Issues


4 views

When modifying SSH ports on AWS EC2 instances, you need to address both AWS security groups and the instance's local firewall (iptables). Here's what we observed in the case:

# Original sshd_config line
#Port 23453

# Modified to
Port 23453

The AWS security group requires explicit rules for custom ports. While port 22 is open by default, custom ports need manual configuration:

Type: Custom TCP Rule
Port Range: 23453
Source: 0.0.0.0/0

Even with correct security groups, iptables can block connections. The initial rules showed:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

Notice the explicit rule for port 22 (ssh) but nothing for our custom port 23453.

We need two specific iptables rules for the custom port:

# Allow new connections on port 23453
sudo iptables -A INPUT -p tcp --dport 23453 -m state --state NEW -j ACCEPT

# Persist rules after reboot (RHEL/CentOS specific)
sudo service iptables save

After making changes, verify with these commands:

# Check listening ports
sudo netstat -ntlp | grep 23453

# Test iptables rules
sudo iptables -L -n -v | grep 23453

# Test connectivity from local machine
telnet ec2-public-dns 23453

The final working iptables configuration included:

Chain INPUT (policy ACCEPT)
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:23453 state NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:ssh
  • Always keep an active SSH session when testing port changes
  • Consider using AWS Session Manager as a backup access method
  • Check both IPv4 and IPv6 iptables rules if applicable
  • Verify VPC network ACLs aren't blocking the port

When modifying SSH ports on AWS EC2 instances, many developers encounter connection issues because they only configure one security layer while forgetting the other. The AWS infrastructure requires both proper security group configuration AND correct instance-level firewall rules.

First confirm your security group allows inbound traffic on both standard and custom ports:

Type: SSH | Protocol: TCP | Port Range: 22 | Source: 0.0.0.0/0
Type: Custom TCP | Protocol: TCP | Port Range: 23453 | Source: 0.0.0.0/0

On RHEL/CentOS systems, iptables requires explicit rules for custom ports. The key difference between your initial attempt and working solution was the state NEW parameter:

# Non-working rule (missing state specification)
iptables -A INPUT -p tcp --dport 23453 -j ACCEPT

# Working rule (explicitly allows new connections)
iptables -A INPUT -p tcp --dport 23453 -m state --state NEW -j ACCEPT

For rules to survive reboots on RHEL systems:

# Save current iptables rules
sudo service iptables save

# On modern systems using firewalld:
sudo firewall-cmd --permanent --add-port=23453/tcp
sudo firewall-cmd --reload

When troubleshooting, these commands prove invaluable:

# Check listening ports
sudo netstat -tulnp | grep 23453

# Verify SSH daemon configuration
sudo grep Port /etc/ssh/sshd_config

# Test connectivity without establishing full connection
telnet ec2-public-dns 23453

Here's a full configuration sequence for RHEL-based EC2 instances:

# 1. Modify SSH config
sudo sed -i 's/#Port 22/Port 23453/' /etc/ssh/sshd_config

# 2. Add firewall rule
sudo iptables -I INPUT 4 -p tcp --dport 23453 -m state --state NEW -j ACCEPT

# 3. Make rules persistent
sudo service iptables save

# 4. Restart SSH service
sudo systemctl restart sshd

# 5. Verify configuration
sudo iptables -L -n -v | grep 23453
sudo ss -tulnp | grep sshd