Restore SSH Access After Port Change
This guide describes how to recover SSH access on a Linux instance when it becomes unavailable after changing the SSH port.
SSH Access Unavailable After Port Change
On systems like Rocky Linux, CentOS, or Alma Linux where SELinux is enabled, changing the SSH port can lead to both the new and the default port (22) becoming inaccessible.
ssh: connect to host 172.16.3.232 port xx: Connection refused
This issue occurs even when the SSH daemon is running normally, if the changed port is either not allowed or not being listened to.
In particular, problems may arise if the new port is not allowed by SELinux policy.
You can resolve this either by restoring the port to 22 using a user script or by registering the new port in SELinux.
▶️ Solution
Note:
This guide is based on OpenAPI, but the same tasks can also be performed in the Kakao Cloud Console.
To use OpenAPI, complete the prerequisites described in the Getting Started with OpenAPI guide.
If you're unable to access your server after changing the SSH port, follow the steps below using OpenAPI.
Step 1. Check existing instance information
Use the Get instance OpenAPI
to retrieve the instance ID, root volume ID, instance type, security group, key pair, and other details.
Request
curl -X GET 'https://bcs.kr-central-2.kakaocloud.com/api/v1/instances/${INSTANCE_ID}' \
-H 'Accept: application/json' \
-H 'X-Auth-Token: ${API_TOKEN}'
Variable | Descriptions |
---|---|
INSTANCE_ID🖌︎ | Existing instance ID |
API_TOKEN🖌︎ | API authentication token |
Response Fields to Extract
Information | Response Body Field |
---|---|
Instance ID | instance.id |
Root Volume ID | From the volume where instance_attached_volume.is_root=true , get instance.attached_volumes.id |
Root Volume Size | From the volume where instance_attached_volume.is_root=true , get instance.attached_volumes.size |
Instance Flavor ID | instance.flavor.id |
Security Group Name | instance.security_groups.name |
Key Pair Name | instance.key_name |
Availability Zone | instance.availability_zone |
Step 2. Create an Image from the Instance
Use the Create image OpenAPI to create an image from the root volume of the problematic instance.
⚠️ Important Note When Creating an Image
If an image is created while the instance is running, data in memory may not be fully written to disk, potentially causing data inconsistency.
It is strongly recommended to stop the instance before creating the image.
Request
curl -X POST 'https://volume.kr-central-2.kakaocloud.com/api/v1/volumes/${ROOT_VOLUME_ID}/image' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'X-Auth-Token: ${API_TOKEN}' \
-d '{
"image": {
"name": "${IMAGE_NAME}",
"description": "${IMAGE_DESC}"
}
}'
Variable | Descriptions |
---|---|
ROOT_VOLUME_ID🖌︎ | Root volume ID from Step 1 |
API_TOKEN🖌︎ | API authentication token |
IMAGE_NAME🖌︎ | Image name |
IMAGE_DESC🖌︎ | Image description |
Response Fields to Retrieve
Field | Response Body Path |
---|---|
Image ID | image.id |
Step 3. Create a Port Configuration User Script
When creating a new instance based on the image, resolve the SSH port issue by including a user script (user_data
).
The user script runs on the first boot of the instance and must be provided in Base64 format (up to 16KB).
You can choose one of the following two methods:
Method 1: Reset SSH Port Configuration
-
Create and save the following script file (
restore-port-conf.sh
) on your local machine:#!/bin/bash
CONFIG_FILE="/etc/ssh/sshd_config"
BACKUP_FILE="/etc/ssh/sshd_config.bak"
# Create backup
sudo cp "$CONFIG_FILE" "$BACKUP_FILE"
# Comment out all Port configuration lines (only lines not already commented)
sudo sed -i '/^[[:space:]]*Port[[:space:]]\+[0-9]\{1,5\}[[:space:]]*$/s/^/#/' "$CONFIG_FILE"
echo "All Port configuration lines have been commented out. Backup saved at: $BACKUP_FILE" -
Encode the script into Base64 and save the output string.
base64 < restore-port-conf.sh | tr -d '\n'
# Example output: IyEvYmluL2Jhc2gKCkNPTkZJR19GSUxFP... (Save this string)
Method 2: Register New Port with SELinux
-
Create and save the following script file (
register-port-conf.sh
) on your local machine:#!/bin/bash
# New SSH port number (e.g., 2222)
NEW_PORT=2222
# 1. Add SSH port to SELinux
echo "[1/2] Registering port in SELinux..."
sudo semanage port -a -t ssh_port_t -p tcp "$NEW_PORT" 2>/dev/null \
|| echo "※ The port may already be registered. Continuing anyway."
# 2. Restart SSH service
echo "[2/2] Restarting sshd service..."
sudo systemctl restart sshd
echo "✅ SSH port $NEW_PORT registered and sshd restarted successfully" -
Encode the script into Base64 and save the output string.
base64 < register-port-conf.sh | tr -d '\n'
# Example output: IyEvYmluL2Jhc2gKCk5FV19QT1JU... (Save this string)
Step 4. Create a New Instance from the Image
Create a new instance using the image and the user script.
Use the Create instance OpenAPI to perform this operation.
Request
curl -X POST 'https://bcs.kr-central-2.kakaocloud.com/api/v1/instances' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'X-Auth-Token: ${API_TOKEN}' \
-d '{
"instance": {
"name": "${INSTANCE_ID}",
"description": "${INSTANCE_DESC}",
"count": 1,
"image_id": "${IMAGE_ID}",
"flavor_id": "${FLAVOR_ID}",
"availability_zone": "${AZ}",
"subnets": [
{
"id": "${SUBNET_ID}"
}
],
"volumes": [
{
"is_delete_on_termination": true,
"size": ${VOLUME_SIZE},
"source_type": "image",
"uuid": "${IMAGE_ID}",
"type_id": "${VOLUME_TYPE_ID}"
}
],
"key_name": "${KEY_NAME}",
"security_groups": [
{
"name": "${SG_NAME}"
}
],
"user_data": "${BASE_64}"
}
}'
Variable | Descriptions |
---|---|
API_TOKEN🖌︎ | API authentication token |
INSTANCE_ID🖌︎ | Name of the new instance |
INSTANCE_DESC🖌︎ | Description of the instance |
IMAGE_ID🖌︎ | Image ID generated in Step 2 |
FLAVOR_ID🖌︎ | Instance flavor ID |
AZ🖌︎ | Availability zone to create the instance in |
SUBNET_ID🖌︎ | Subnet ID |
VOLUME_SIZE🖌︎ | Volume size - same as the original root volume |
VOLUME_TYPE_ID🖌︎ | Volume type ID |
KEY_NAME🖌︎ | Key pair name |
SG_NAME🖌︎ | Security group name |
BASE_64🖌︎ | Base64-encoded user script |
💡 Tip
- To check the subnet ID: List subnets OpenAPI
- To check the volume type ID: List volume types OpenAPI
Step 5. Verify SSH Access to the New Instance
After the new instance finishes booting, attempt to connect via SSH to ensure everything is working properly.
# Default port 22 connection (expected behavior after recovery)
ssh -i ${pem-key-file} ${username}@${server-ip}
# Custom port connection (for temporary verification)
ssh -i ${pem-key-file} ${username}@${server-ip} -p ${port-number}