EC2 SSH Connection Timeout: Cara Debug Security Group dan Inbound Rules yang Benar
Kamu baru saja meluncurkan EC2 instance, menjalankan perintah ssh ec2-user@<IP>, dan terminal hanya diam — tidak ada respons, tidak ada pesan error yang jelas, hanya connection timed out setelah beberapa detik. Ini adalah salah satu masalah paling umum yang dihadapi engineer saat pertama kali mengakses EC2, dan hampir selalu berakar pada konfigurasi Security Group atau lapisan jaringan di atasnya.
TL;DR: EC2 SSH Connection Timeout
| Lapisan | Yang Perlu Dicek | Perintah Verifikasi |
|---|---|---|
| Security Group | Inbound rule TCP port 22 dari IP kamu | aws ec2 describe-security-groups |
| Network ACL | Allow inbound port 22 dan outbound ephemeral ports | aws ec2 describe-network-acls |
| Route Table | Default route ke Internet Gateway (subnet publik) | aws ec2 describe-route-tables |
| Public IP | Instance punya public IP atau Elastic IP | aws ec2 describe-instances |
| Instance State | Status 'running', bukan 'pending' atau 'stopped' | aws ec2 describe-instance-status |
Bagaimana SSH dan Security Group Bekerja di EC2
Security Group di EC2 adalah stateful firewall yang beroperasi di level instance — bukan di level subnet. 'Stateful' berarti jika kamu mengizinkan inbound traffic, response traffic keluar secara otomatis diizinkan tanpa perlu aturan outbound eksplisit. Ini berbeda dengan Network ACL yang stateless.
Ketika kamu menjalankan perintah SSH, paket TCP SYN dikirim ke port 22 instance. Jika Security Group tidak memiliki inbound rule yang cocok, paket tersebut di-drop secara diam-diam — tidak ada ICMP 'port unreachable', tidak ada RST. Itulah mengapa hasilnya adalah timeout, bukan connection refused. Connection refused justru berarti paket sampai ke instance tapi tidak ada proses yang mendengarkan di port tersebut — artinya Security Group sudah benar.
Analogi: Security Group seperti penjaga gedung yang memblokir tamu di pintu masuk tanpa memberi tahu mereka alasannya. Tamu hanya berdiri menunggu sampai menyerah. Network ACL adalah penjaga di gerbang kompleks — lebih awal dalam perjalanan, dan tidak mengingat siapa yang sudah masuk.
ssh ec2-user@IP"] --> IGW["Internet Gateway"] IGW --> NACL["Network ACL
(Stateless - Subnet Level)"] NACL --> SG["Security Group
(Stateful - Instance Level)"] SG --> SSHD["SSH Daemon
port 22 di Instance"] NACL -- "DROP: no matching rule" --> Timeout1["Connection Timeout"] SG -- "DROP: no inbound rule" --> Timeout2["Connection Timeout"] style Timeout1 fill:#ff4444,color:#fff style Timeout2 fill:#ff4444,color:#fff style SG fill:#ff9900,color:#fff style NACL fill:#ff9900,color:#fff style SSHD fill:#2ecc71,color:#fff
- Client mengirim paket TCP SYN ke port 22 public IP instance.
- Paket melewati Internet Gateway dan masuk ke VPC.
- Network ACL (stateless) dievaluasi pertama di level subnet — inbound dan outbound harus eksplisit diizinkan.
- Security Group (stateful) dievaluasi di level instance — hanya inbound rule yang perlu dikonfigurasi untuk SSH.
- Jika semua lolos, paket sampai ke SSH daemon (sshd) di instance.
- Jika Security Group atau NACL memblokir, paket di-drop — hasilnya connection timed out.
Langkah Diagnosis EC2 SSH Connection Timeout
Langkah 1: Verifikasi Instance Sedang Berjalan dan Punya Public IP
Sebelum menyentuh Security Group, pastikan instance-nya sendiri dalam kondisi yang bisa diakses. Instance yang masih dalam status pending belum siap menerima koneksi, dan instance tanpa public IP tidak bisa diakses langsung dari internet — tidak peduli Security Group-nya seperti apa.
aws ec2 describe-instances \
--instance-ids i-0123456789abcdef0 \
--query 'Reservations[*].Instances[*].{State:State.Name,PublicIP:PublicIpAddress,PrivateIP:PrivateIpAddress,SubnetId:SubnetId}' \
--output table \
--region us-east-1
Pastikan kolom State menunjukkan running dan PublicIP tidak kosong. Jika instance berada di subnet privat dan kamu mengakses via bastion host atau VPN, kolom PublicIP boleh kosong — tapi alur akses-nya berbeda.
Langkah 2: Periksa Inbound Rules Security Group untuk Port 22
Ini adalah penyebab paling umum. Security Group baru yang dibuat tanpa template 'Allow SSH' tidak memiliki inbound rule apapun — semua traffic inbound di-deny secara default. Kamu perlu inbound rule TCP port 22 yang mengizinkan source IP kamu.
aws ec2 describe-security-groups \
--group-ids sg-0123456789abcdef0 \
--query 'SecurityGroups[*].IpPermissions' \
--output json \
--region us-east-1
Cari entry dengan FromPort: 22, ToPort: 22, IpProtocol: tcp. Pada bagian IpRanges, pastikan ada CIDR yang mencakup IP publik kamu. Menggunakan 0.0.0.0/0 memang memudahkan debugging, tapi di lingkungan produksi batasi ke IP spesifik atau CIDR tim kamu.
Jika rule belum ada, tambahkan dengan perintah berikut — ganti 203.0.113.10/32 dengan IP publik kamu yang sebenarnya:
aws ec2 authorize-security-group-ingress \
--group-id sg-0123456789abcdef0 \
--protocol tcp \
--port 22 \
--cidr 203.0.113.10/32 \
--region us-east-1
Langkah 3: Periksa Network ACL Subnet
Security Group yang sudah benar tapi SSH masih timeout? Network ACL adalah tersangka berikutnya. Berbeda dengan Security Group, NACL bersifat stateless — kamu harus mengizinkan inbound port 22 DAN outbound ephemeral ports (1024-65535) secara eksplisit. Banyak engineer lupa bagian outbound ini karena terbiasa dengan model stateful Security Group.
aws ec2 describe-network-acls \
--filters Name=association.subnet-id,Values=subnet-0123456789abcdef0 \
--query 'NetworkAcls[*].{AclId:NetworkAclId,Entries:Entries}' \
--output json \
--region us-east-1
Periksa output-nya: harus ada rule inbound yang mengizinkan TCP port 22 (atau range yang mencakupnya) dengan RuleAction: allow, dan rule outbound yang mengizinkan TCP port 1024-65535 untuk response traffic. Default NACL yang dibuat otomatis oleh AWS mengizinkan semua traffic — masalah biasanya muncul jika kamu menggunakan custom NACL.
Langkah 4: Verifikasi Route Table Subnet Mengarah ke Internet Gateway
Instance dengan public IP tapi subnet-nya tidak punya route ke Internet Gateway tetap tidak bisa diakses dari internet. Ini sering terjadi saat instance diluncurkan di subnet yang salah — subnet privat alih-alih subnet publik.
aws ec2 describe-route-tables \
--filters Name=association.subnet-id,Values=subnet-0123456789abcdef0 \
--query 'RouteTables[*].Routes' \
--output json \
--region us-east-1
Cari entry dengan DestinationCidrBlock: 0.0.0.0/0 dan GatewayId yang diawali dengan igw-. Jika tidak ada, subnet tersebut adalah subnet privat dan instance tidak bisa diakses langsung dari internet.
Langkah 5: Konfirmasi Instance Status Checks Lulus
Jika semua konfigurasi jaringan sudah benar tapi SSH masih gagal, ada kemungkinan instance mengalami masalah di level OS atau hardware. Instance status checks yang gagal bisa menyebabkan SSH daemon tidak berjalan meskipun instance terlihat 'running' di console.
aws ec2 describe-instance-status \
--instance-ids i-0123456789abcdef0 \
--query 'InstanceStatuses[*].{InstanceStatus:InstanceStatus.Status,SystemStatus:SystemStatus.Status}' \
--output table \
--region us-east-1
Kedua kolom harus menunjukkan ok. Jika SystemStatus menunjukkan impaired, ini adalah masalah infrastruktur AWS — coba stop dan start instance (bukan reboot) untuk memindahkannya ke host fisik yang berbeda.
dan public IP"] S1 --> Q1{"Instance running
dan punya public IP?"} Q1 -- "Tidak" --> Fix1["Start instance atau
assign Elastic IP"] Q1 -- "Ya" --> S2["Langkah 2: Cek Security Group
inbound port 22"] S2 --> Q2{"Ada rule TCP 22
dari IP kamu?"} Q2 -- "Tidak" --> Fix2["Tambah inbound rule
TCP port 22"] Q2 -- "Ya" --> S3["Langkah 3: Cek Network ACL
subnet"] S3 --> Q3{"NACL allow inbound 22
dan outbound 1024-65535?"} Q3 -- "Tidak" --> Fix3["Update NACL rules
inbound dan outbound"] Q3 -- "Ya" --> S4["Langkah 4: Cek Route Table
subnet"] S4 --> Q4{"Ada route 0.0.0.0/0
ke igw-xxx?"} Q4 -- "Tidak" --> Fix4["Pindah ke subnet publik
atau gunakan bastion"] Q4 -- "Ya" --> S5["Langkah 5: Cek instance
status checks"] S5 --> Q5{"System dan instance
status: ok?"} Q5 -- "Tidak" --> Fix5["Stop dan start instance
untuk pindah host fisik"] Q5 -- "Ya" --> Done["Cek SSH key pair
dan username AMI"] style Fix1 fill:#2ecc71,color:#fff style Fix2 fill:#2ecc71,color:#fff style Fix3 fill:#2ecc71,color:#fff style Fix4 fill:#2ecc71,color:#fff style Fix5 fill:#2ecc71,color:#fff style Done fill:#3498db,color:#fff
- Mulai dari verifikasi status instance — tidak ada gunanya debug jaringan jika instance belum siap.
- Security Group adalah penyebab paling umum — periksa lebih dulu sebelum lapisan lain.
- Jika Security Group sudah benar, NACL adalah lapisan berikutnya yang sering terlewat.
- Route table menentukan apakah subnet bersifat publik atau privat.
- Jika semua jaringan sudah benar, periksa kondisi instance itu sendiri.
Kasus Nyata: Misdiagnosis yang Sering Terjadi
Skenario yang sering terjadi: engineer menambahkan inbound rule SSH ke Security Group, mencoba koneksi lagi, masih timeout. Kesimpulan awal: 'Security Group-nya belum aktif' atau 'perlu waktu propagasi'. Keduanya salah — perubahan Security Group berlaku hampir seketika.
Penyebab sebenarnya dalam kasus ini hampir selalu adalah instance diluncurkan di subnet privat yang tidak memiliki route ke Internet Gateway. Public IP memang ter-assign ke instance, tapi tidak ada jalur routing yang valid dari internet ke subnet tersebut. Perintah di Langkah 4 akan langsung mengungkap ini — tidak ada igw- di route table.
Perbaikannya: pindahkan instance ke subnet publik (launch ulang), atau jika arsitektur memang mengharuskan instance di subnet privat, akses via bastion host di subnet publik atau gunakan AWS Systems Manager Session Manager yang tidak memerlukan port 22 sama sekali.
Konfigurasi Security Group yang Direkomendasikan
Berikut adalah contoh IAM policy minimal yang dibutuhkan jika kamu mengelola Security Group rules via CLI atau otomasi:
🔽 Klik untuk melihat IAM Policy untuk mengelola Security Group
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DescribeSecurityGroups",
"Effect": "Allow",
"Action": [
"ec2:DescribeSecurityGroups",
"ec2:DescribeInstances",
"ec2:DescribeNetworkAcls",
"ec2:DescribeRouteTables",
"ec2:DescribeInstanceStatus"
],
"Resource": "*"
},
{
"Sid": "ModifySecurityGroupIngress",
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress"
],
"Resource": "arn:aws:ec2:us-east-1:123456789012:security-group/sg-0123456789abcdef0"
}
]
}
Perhatikan bahwa action Describe memerlukan Resource: * karena tidak mendukung resource-level permission. Action Modify bisa dibatasi ke ARN Security Group spesifik sesuai prinsip least privilege.
Alternatif: Akses Instance Tanpa Membuka Port 22
Jika kamu tidak ingin mengekspos port 22 ke internet sama sekali — yang merupakan praktik yang lebih aman di lingkungan produksi — AWS Systems Manager Session Manager adalah alternatif yang solid. Session Manager tidak memerlukan inbound rule apapun di Security Group, tidak memerlukan public IP, dan semua sesi ter-log ke CloudTrail dan opsional ke S3 atau CloudWatch Logs.
Syaratnya: instance harus menjalankan SSM Agent (sudah pre-installed di Amazon Linux 2, Amazon Linux 2023, dan beberapa AMI lain), dan instance profile harus memiliki policy AmazonSSMManagedInstanceCore.
Wrap-Up: Checklist EC2 SSH Connection Timeout
Ketika menghadapi EC2 SSH connection timeout, urutan diagnosis yang efisien adalah: status instance → Security Group inbound port 22 → Network ACL → Route Table → instance status checks. Mayoritas kasus selesai di langkah kedua atau ketiga.
Untuk lingkungan produksi, pertimbangkan untuk tidak membuka port 22 sama sekali dan beralih ke Session Manager — ini menghilangkan seluruh kelas masalah ini sekaligus meningkatkan postur keamanan.
Referensi resmi: AWS EC2 Troubleshooting SSH Connections dan AWS Systems Manager Session Manager.
Glosarium
| Istilah | Penjelasan |
|---|---|
| Security Group | Stateful firewall virtual di level instance EC2. Deny semua inbound secara default; allow outbound secara default. |
| Network ACL (NACL) | Stateless firewall di level subnet. Inbound dan outbound harus dikonfigurasi eksplisit. |
| Internet Gateway (IGW) | Komponen VPC yang memungkinkan komunikasi antara instance di VPC dan internet. |
| Ephemeral Ports | Port sementara (1024-65535) yang digunakan OS klien untuk response traffic pada koneksi TCP. |
| Session Manager | Fitur AWS Systems Manager untuk akses shell ke instance tanpa membuka port SSH atau menggunakan bastion host. |
Komentar
Posting Komentar