ตั้ง Two-Factor Authentication (2FA) สำหรับ SSH
Password เพียงอย่างเดียวไม่เพียงพอสำหรับการป้องกัน SSH ถ้า password หลุดหรือถูก brute force ได้ VPS จะตกเป็นของผู้ไม่หวังดีทันที การเพิ่ม 2FA (Two-Factor Authentication) ด้วย TOTP (Time-based One-Time Password) ทำให้แม้ password หลุดก็เข้าไม่ได้หากไม่มี device
ติดตั้ง Google Authenticator PAM
sudo apt update
sudo apt install libpam-google-authenticator -y
# ตั้งค่า TOTP สำหรับ user ปัจจุบัน
google-authenticator
ตอบคำถามที่ถาม:
- Time-based tokens → y
- Update .google_authenticator → y
- Disallow reuse → y
- Permit 30-second clock skew → y
- Rate limiting → y
จด QR code (scan ด้วย Google Authenticator app) และ backup codes ทั้ง 5 โค้ดเก็บไว้ในที่ปลอดภัย
ตั้งค่า PAM สำหรับ SSH
sudo nano /etc/pam.d/sshd
# เพิ่มบรรทัดนี้หลัง @include common-auth
auth required pam_google_authenticator.so
sudo nano /etc/ssh/sshd_config
# แก้หรือเพิ่มบรรทัดเหล่านี้
ChallengeResponseAuthentication yes
# หรือใน SSH เวอร์ชันใหม่:
KbdInteractiveAuthentication yes
UsePAM yes
# ถ้าต้องการทั้ง SSH key และ 2FA:
AuthenticationMethods publickey,keyboard-interactive
# Restart SSH daemon
sudo systemctl restart ssh
# ทดสอบใน terminal ใหม่ (อย่าปิด session เดิม)
ssh user@YOUR_VPS_IP
ให้ SSH Key ข้ามขั้นตอน 2FA (Optional)
ถ้าต้องการให้ SSH key bypass 2FA ได้ (สะดวกกว่า แต่ security น้อยกว่า):
sudo nano /etc/pam.d/sshd
# แก้บรรทัดที่เพิ่มเป็น:
auth required pam_google_authenticator.so nullok
sudo nano /etc/ssh/sshd_config
# ตั้ง AuthenticationMethods ให้รองรับทั้งสอง mode
AuthenticationMethods publickey publickey,keyboard-interactive
Match User deploybot block ใน sshd_config เพื่อข้าม 2FA เฉพาะ user นั้น
ตรวจสอบว่า 2FA ทำงานถูกต้อง
# ตรวจ sshd config syntax
sudo sshd -t
# ตรวจสถานะ SSH service
systemctl status ssh
# ทดสอบ login ใหม่ (ต้องถามทั้ง password และ OTP code)
ssh -v user@YOUR_VPS_IP
# ตรวจว่า PAM module โหลด
grep google-authenticator /var/log/auth.log | tail -10
/etc/pam.d/sshd และ /etc/ssh/sshd_config อีกรอบ
แก้ปัญหาที่พบบ่อย
SSH ไม่ถาม Verification Code เลย
ChallengeResponseAuthentication ยังเป็น no หรือ PAM ไม่ได้ include google-authenticator:
# ตรวจ sshd_config
grep -i "ChallengeResponse\|KbdInteractive\|UsePAM" /etc/ssh/sshd_config
# ตรวจ PAM
grep -n "google-authenticator" /etc/pam.d/sshd
# อ่าน journal หลัง login
sudo journalctl -u ssh -n 30
ถูก Lock Out ทั้งที่รู้ code ถูกต้อง
เวลาของ VPS กับ phone ต่างกันเกิน 30 วินาที ต้อง sync NTP ก่อน:
# ตรวจเวลา server
date
timedatectl
# Sync NTP
sudo timedatectl set-ntp true
sudo systemctl restart systemd-timesyncd
google-authenticator file หาย หรือ reinstall phone
ไฟล์ ~/.google_authenticator เก็บ secret key ถ้าหายต้องสร้างใหม่:
# สร้างใหม่ (ต้อง scan QR code ใน app อีกรอบ)
google-authenticator
# ถ้า lock out ทั้งหมด ต้องเข้าผ่าน VPS console (KVM)
# แล้วปิด 2FA ชั่วคราวเพื่อ recovery
Backup codes ทั้งหมดถูกใช้หมดแล้ว
สร้าง backup codes ใหม่โดย regenerate google-authenticator แต่ต้อง scan QR ใน app ใหม่ด้วย:
# เปิด file แก้ backup codes โดยตรง (บรรทัดที่ขึ้นต้นด้วย 8 ตัวเลข)
nano ~/.google_authenticator
# หรือ regenerate ทั้งหมด
google-authenticator -f -t -d -r 3 -R 30 -w 3
คำถามที่พบบ่อย
2FA กับ SSH key ต่างกันอย่างไร ควรใช้อันไหน?
SSH key ป้องกัน brute force ได้ดีมากเพราะ key ยาวมาก แต่ถ้า private key หลุดออกไปก็เข้าได้เลย 2FA เพิ่มชั้นป้องกันที่ต้องมี device ด้วย ในอุดมคติควรใช้ทั้งสองอย่างพร้อมกัน: SSH key + 2FA
TOTP กับ HOTP ต่างกันอย่างไร?
TOTP (Time-based OTP) สร้าง code ใหม่ทุก 30 วินาที ใช้เวลาเป็น input HOTP (HMAC-based OTP) ใช้ counter แทน เพิ่มทีละ 1 ทุกครั้งที่ใช้ TOTP นิยมกว่าเพราะ code หมดอายุเองอัตโนมัติ
ถ้าโทรศัพท์หายจะ lock out ไหม?
ใช่ ถ้าไม่มี backup codes จะ lock out หากโทรศัพท์หาย ทางออกคือ: 1) เก็บ backup codes ไว้นอกเครื่อง 2) เปิด 2FA บน device 2 เครื่อง 3) เก็บ secret key (.google_authenticator) ไว้ใน password manager