
ทำไมต้องเปลี่ยนจาก Password เป็น SSH Key?
Password Authentication มีข้อจำกัดหลายอย่าง โดยเฉพาะเรื่อง Security ถ้าคุณยังใช้ Password SSH อยู่ในปี 2026 ถือว่าเสี่ยงมาก เพราะ Brute Force Attack พัฒนาขึ้นเรื่อย ๆ และ Password ถูก Crack ได้ง่ายกว่าที่คิด
Password vs SSH Key Authentication
| เกณฑ์ | Password Auth | SSH Key Auth |
|---|---|---|
| Brute Force | เสี่ยงสูง ถูกเดาได้ | แทบเป็นไปไม่ได้ (2048/4096-bit) |
| ความสะดวก | ต้องพิมพ์ทุกครั้ง | ไม่ต้องพิมพ์ (SSH Agent) |
| Automation | ต้อง Hard-code Password (อันตราย) | ใช้ Key ได้เลย ปลอดภัย |
| Phishing | เสี่ยง Password ถูกขโมย | ไม่มี Password ให้ขโมย |
| Key Rotation | เปลี่ยน Password ทุก Server | Deploy Key ใหม่ได้ง่าย |
| Multi-Factor | ยากที่จะเพิ่ม MFA | ใช้ Key + Passphrase = MFA |
| Audit | รู้แค่ User ที่ Login | รู้ว่า Key ไหน Login (Comment/Fingerprint) |
SSH Key คืออะไร? หลักการทำงาน
SSH Key ใช้หลัก Asymmetric Cryptography (Public-Key Cryptography) ซึ่งประกอบด้วย Key 2 ตัว:
# SSH Key Pair
#
# Private Key (id_ed25519):
# - เก็บไว้บนเครื่อง Client ของคุณ
# - ห้ามแชร์ให้ใคร!
# - เหมือน "กุญแจ" ที่ใช้ไขล็อก
#
# Public Key (id_ed25519.pub):
# - ใส่ไว้บน Server (authorized_keys)
# - แชร์ได้ ไม่มีอันตราย
# - เหมือน "ล็อก" ที่ติดอยู่บนประตู
#
# วิธีทำงาน:
# 1. Client ส่ง Public Key ไป Server
# 2. Server ตรวจว่า Public Key อยู่ใน authorized_keys
# 3. Server ส่ง Challenge (Random Data) มา
# 4. Client ใช้ Private Key ลงนาม Challenge
# 5. Server ตรวจ Signature ด้วย Public Key
# 6. ตรง = Login สำเร็จ!
#
# ทั้งหมดนี้เกิดใน 0.1 วินาที!
สร้าง SSH Key (ssh-keygen)
Ed25519 vs RSA
| เกณฑ์ | Ed25519 | RSA-4096 |
|---|---|---|
| Algorithm | EdDSA (Curve25519) | RSA |
| Key Size | 256-bit | 4096-bit |
| Security Level | ~128-bit security | ~128-bit security |
| Performance | เร็วกว่ามาก | ช้ากว่า |
| Key File Size | เล็กกว่า (~400 bytes) | ใหญ่กว่า (~3,000 bytes) |
| Compatibility | OpenSSH 6.5+ (2014) | ทุก Version |
| แนะนำ 2026 | แนะนำ (Default) | สำหรับ Legacy System เท่านั้น |
# สร้าง SSH Key - Ed25519 (แนะนำ)
ssh-keygen -t ed25519 -C "[email protected]"
# ผลลัพธ์:
# Generating public/private ed25519 key pair.
# Enter file in which to save the key (/home/user/.ssh/id_ed25519): [Enter]
# Enter passphrase (empty for no passphrase): [ใส่ Passphrase]
# Enter same passphrase again: [ยืนยัน]
#
# สร้าง 2 ไฟล์:
# ~/.ssh/id_ed25519 → Private Key (ห้ามแชร์!)
# ~/.ssh/id_ed25519.pub → Public Key (ใส่บน Server)
# สร้าง SSH Key - RSA-4096 (สำหรับ Legacy)
ssh-keygen -t rsa -b 4096 -C "[email protected]"
# สร้าง Key สำหรับงานเฉพาะ (Custom Filename)
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ansible
ส่ง Public Key ไป Server (ssh-copy-id)
# วิธีที่ 1: ssh-copy-id (ง่ายที่สุด)
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server-ip
# ถ้า SSH Port ไม่ใช่ 22:
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2222 user@server-ip
# วิธีที่ 2: Manual (ถ้าไม่มี ssh-copy-id)
cat ~/.ssh/id_ed25519.pub | ssh user@server-ip "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
# วิธีที่ 3: Copy-Paste
# 1. ดู Public Key:
cat ~/.ssh/id_ed25519.pub
# 2. SSH เข้า Server:
ssh user@server-ip
# 3. เพิ่มใน authorized_keys:
echo "ssh-ed25519 AAAA...key... [email protected]" >> ~/.ssh/authorized_keys
# ทดสอบ Login ด้วย Key:
ssh -i ~/.ssh/id_ed25519 user@server-ip
# ถ้าไม่ถาม Password = สำเร็จ!
authorized_keys — จัดการ Key บน Server
# ไฟล์ ~/.ssh/authorized_keys
# แต่ละบรรทัด = 1 Public Key = 1 คนที่ Login ได้
# ดู Key ทั้งหมดที่อนุญาต:
cat ~/.ssh/authorized_keys
# ตัวอย่างเนื้อหา:
# ssh-ed25519 AAAA...key1... admin@office-pc
# ssh-ed25519 AAAA...key2... admin@laptop
# ssh-rsa AAAA...key3... ansible-automation
# ลบ Key ที่ไม่ต้องการ:
# แก้ไขไฟล์ ลบบรรทัดที่ไม่ต้องการ
nano ~/.ssh/authorized_keys
# Permissions ที่ถูกต้อง (สำคัญมาก!):
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R $USER:$USER ~/.ssh
# ถ้า Permissions ผิด SSH จะปฏิเสธ Key Auth!
# ปัญหานี้เจอบ่อยที่สุด!
authorized_keys Options (Advanced)
# จำกัดสิทธิ์ต่อ Key:
# บังคับ Command (ใช้ได้แค่ Command เดียว):
command="rsync --server --sender -logDtprze.iLsfxCIvu . /backup" ssh-ed25519 AAAA...
# จำกัด IP ที่ Login ได้:
from="192.168.1.0/24,10.0.0.0/8" ssh-ed25519 AAAA...
# ห้าม Port Forwarding:
no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA...
# รวมหลาย Options:
from="192.168.1.100",command="/usr/local/bin/backup.sh",no-port-forwarding ssh-ed25519 AAAA... backup-script
SSH Agent — ไม่ต้องพิมพ์ Passphrase ซ้ำ
# SSH Agent เก็บ Private Key ไว้ใน Memory
# พิมพ์ Passphrase ครั้งเดียว ใช้ได้จนปิดเครื่อง
# เริ่ม SSH Agent:
eval "$(ssh-agent -s)"
# เพิ่ม Key เข้า Agent:
ssh-add ~/.ssh/id_ed25519
# Enter passphrase for /home/user/.ssh/id_ed25519: [พิมพ์ 1 ครั้ง]
# Identity added: /home/user/.ssh/id_ed25519
# ดู Key ที่อยู่ใน Agent:
ssh-add -l
# ลบ Key ออกจาก Agent:
ssh-add -d ~/.ssh/id_ed25519
# ลบทั้งหมด:
ssh-add -D
# ตั้ง Timeout (Key หมดอายุใน Agent):
ssh-add -t 3600 ~/.ssh/id_ed25519
# → Key จะถูกลบจาก Agent หลัง 1 ชั่วโมง
# Auto-start SSH Agent (ใส่ใน ~/.bashrc):
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)" > /dev/null
ssh-add ~/.ssh/id_ed25519 2>/dev/null
fi
SSH Config File (~/.ssh/config)
SSH Config ช่วยให้จัดการ SSH Connection หลาย Server ได้ง่าย ไม่ต้องจำ IP, Port, User, Key
# ~/.ssh/config
# Web Server
Host web
HostName 192.168.1.100
User admin
Port 22
IdentityFile ~/.ssh/id_ed25519
# Database Server
Host db
HostName 192.168.1.200
User dbadmin
Port 2222
IdentityFile ~/.ssh/id_db
# Jump Host (Bastion)
Host bastion
HostName bastion.mycompany.com
User jump-user
Port 22
IdentityFile ~/.ssh/id_bastion
# Internal Server (ผ่าน Bastion)
Host internal
HostName 10.0.0.50
User admin
ProxyJump bastion
# GitHub
Host github.com
IdentityFile ~/.ssh/id_github
User git
# Default สำหรับทุก Host
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
AddKeysToAgent yes
IdentitiesOnly yes
# ใช้งาน:
# ssh web → เท่ากับ ssh -p 22 -i ~/.ssh/id_ed25519 [email protected]
# ssh db → เท่ากับ ssh -p 2222 -i ~/.ssh/id_db [email protected]
# ssh internal → SSH ผ่าน Bastion อัตโนมัติ
ปิด Password Auth (sshd_config)
หลังจากตั้ง SSH Key Auth แล้ว ต้อง ปิด Password Auth บน Server เพื่อป้องกัน Brute Force
# แก้ไข /etc/ssh/sshd_config:
sudo nano /etc/ssh/sshd_config
# เปลี่ยนค่าเหล่านี้:
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
PubkeyAuthentication yes
# (ทำเลือก) เพิ่มความปลอดภัย:
PermitRootLogin prohibit-password # Root login ด้วย Key เท่านั้น
# หรือ
PermitRootLogin no # ห้าม Root login เลย (แนะนำ)
MaxAuthTries 3 # จำกัดจำนวน Login ที่ลองได้
LoginGraceTime 30 # Timeout 30 วินาที
AllowUsers admin deploy # อนุญาตเฉพาะ User ที่ระบุ
# ⚠️ ก่อนปิด Password Auth:
# 1. ทดสอบ Key Auth ให้แน่ใจว่าใช้ได้
# 2. เปิด Terminal ใหม่ ทดสอบ SSH ด้วย Key
# 3. อย่าปิด Terminal เก่าจนกว่าจะแน่ใจ!
# 4. ถ้า Key ใช้ไม่ได้ + ปิด Password Auth = ถูกล็อกนอก Server!
# Restart SSH:
sudo systemctl restart sshd
# ทดสอบ (Terminal ใหม่):
ssh -v user@server-ip
# ดูว่า "Authentications that can continue: publickey"
# ไม่มี "password" = สำเร็จ!
SSH Key สำหรับ Automation
Ansible
# Ansible ใช้ SSH Key เป็น Default
# สร้าง Key สำหรับ Ansible:
ssh-keygen -t ed25519 -C "ansible-controller" -f ~/.ssh/id_ansible -N ""
# Deploy Key ไปทุก Server:
for host in web1 web2 db1; do
ssh-copy-id -i ~/.ssh/id_ansible.pub admin@$host
done
# ansible.cfg:
# [defaults]
# private_key_file = ~/.ssh/id_ansible
# remote_user = admin
CI/CD (GitHub Actions, GitLab CI)
# 1. สร้าง Deploy Key (ไม่มี Passphrase):
ssh-keygen -t ed25519 -C "deploy-cicd" -f deploy_key -N ""
# 2. เพิ่ม Public Key บน Server:
# ใส่ใน authorized_keys พร้อม Restrictions:
command="/usr/local/bin/deploy.sh",no-port-forwarding ssh-ed25519 AAAA... deploy-cicd
# 3. เพิ่ม Private Key ใน CI/CD:
# GitHub: Settings → Secrets → SSH_PRIVATE_KEY
# GitLab: Settings → CI/CD → Variables → SSH_PRIVATE_KEY
# 4. ใน CI/CD Pipeline:
# - name: Deploy
# run: |
# mkdir -p ~/.ssh
# echo "$SSH_PRIVATE_KEY" > ~/.ssh/deploy_key
# chmod 600 ~/.ssh/deploy_key
# ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no admin@server "deploy.sh"
SSH Key Rotation — เปลี่ยน Key เป็นประจำ
# SSH Key Rotation Procedure:
#
# 1. สร้าง Key ใหม่:
ssh-keygen -t ed25519 -C "[email protected]$(date +%Y%m)" -f ~/.ssh/id_ed25519_new
# 2. Deploy Key ใหม่ไปทุก Server:
for host in web1 web2 db1 bastion; do
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub admin@$host
done
# 3. ทดสอบ Key ใหม่:
ssh -i ~/.ssh/id_ed25519_new admin@web1
# 4. เปลี่ยนใช้ Key ใหม่:
mv ~/.ssh/id_ed25519 ~/.ssh/id_ed25519_old
mv ~/.ssh/id_ed25519_new ~/.ssh/id_ed25519
mv ~/.ssh/id_ed25519_new.pub ~/.ssh/id_ed25519.pub
# 5. ลบ Key เก่าจากทุก Server:
for host in web1 web2 db1 bastion; do
ssh admin@$host "sed -i '/old-key-comment/d' ~/.ssh/authorized_keys"
done
# 6. ลบ Key เก่าจาก Local:
rm ~/.ssh/id_ed25519_old
# แนะนำ: Rotate ทุก 6-12 เดือน
# หรือทันทีเมื่อ:
# - พนักงานลาออก
# - เครื่อง Laptop หาย/ถูกขโมย
# - สงสัยว่า Key ถูก Compromised
SSH Hardening Beyond Keys
| มาตรการ | วิธีตั้งค่า | ผลลัพธ์ |
|---|---|---|
| เปลี่ยน Port | Port 2222 ใน sshd_config |
ลด Bot Scan (ไม่ใช่ Security จริง แต่ลด Noise) |
| Fail2Ban | apt install fail2ban |
Ban IP ที่ Login ผิดซ้ำ |
| AllowUsers | AllowUsers admin deploy |
จำกัด User ที่ Login ได้ |
| AllowGroups | AllowGroups ssh-users |
จำกัด Group ที่ Login ได้ |
| TCP Wrappers | /etc/hosts.allow |
จำกัด IP ที่เข้าถึง SSH |
| 2FA (TOTP) | Google Authenticator PAM | Key + OTP = Security สูงสุด |
| SSH CA | Certificate Authority | จัดการ Key ขนาดใหญ่ ไม่ต้องใช้ authorized_keys |
# Fail2Ban Config สำหรับ SSH:
sudo apt install fail2ban
# /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# ดู IP ที่ถูก Ban:
sudo fail2ban-client status sshd
Troubleshooting SSH Key Issues
| ปัญหา | สาเหตุ | วิธีแก้ |
|---|---|---|
| Permission denied (publickey) | Key ไม่ตรง, Permissions ผิด | ตรวจ Key + Permissions (700, 600) |
| ยังถาม Password | Key ไม่ได้ส่ง, sshd_config ยังเปิด Password | ใช้ ssh -v ดู Log |
| Agent forwarding ไม่ทำงาน | Agent ไม่ได้ Start, AllowAgentForwarding off | ตรวจ Agent + sshd_config |
| Connection refused | sshd ไม่ทำงาน, Port ผิด, Firewall | ตรวจ sshd status + Firewall |
| Too many auth failures | Agent มี Key เยอะเกินไป | ใช้ IdentitiesOnly yes ใน config |
# Debug SSH Connection:
ssh -vvv user@server-ip 2>&1 | grep -i "auth\|key\|identity"
# ดูว่า Server รองรับ Auth อะไร:
ssh -o PreferredAuthentications=none user@server-ip
# ตรวจ Permissions บน Server:
ls -la ~/.ssh/
# drwx------ .ssh/
# -rw------- authorized_keys
# ตรวจ sshd_config:
sudo sshd -T | grep -i "pubkey\|password\|permit"
# ดู sshd Log:
sudo journalctl -u sshd -f
# หรือ
sudo tail -f /var/log/auth.log
สรุป: SSH Key Authentication Checklist
| ลำดับ | งาน | Command |
|---|---|---|
| 1 | สร้าง Ed25519 Key Pair | ssh-keygen -t ed25519 |
| 2 | ส่ง Public Key ไป Server | ssh-copy-id user@server |
| 3 | ทดสอบ Key Auth | ssh user@server |
| 4 | ตั้งค่า SSH Agent | ssh-add ~/.ssh/id_ed25519 |
| 5 | สร้าง SSH Config | แก้ ~/.ssh/config |
| 6 | ปิด Password Auth | แก้ sshd_config |
| 7 | ติดตั้ง Fail2Ban | apt install fail2ban |
| 8 | วาง Schedule Key Rotation | ทุก 6-12 เดือน |
SSH Key Authentication เป็นพื้นฐานที่ Linux Admin ทุกคนต้องทำให้เป็น ไม่ว่าจะมี Server กี่ตัว ไม่ว่าจะใช้ Cloud หรือ On-Premise เปลี่ยนจาก Password มาใช้ SSH Key วันนี้ แล้วคุณจะมี Security ที่ดีขึ้นมากพร้อมความสะดวกที่มากขึ้นด้วย