คนที่อยู่กับ Linux หรือ Unix เวลาที่ต้องทำงานด้วย ช่องทางหลักที่จะเชื่อมต่อก็น่าจะเป็น protocol SSH ซึ่งเป็นช่องทางที่รองรับการทำงานที่ตอนโจทย์คนทำงานที่หลากหลาย ไม่ใช่เฉพาะ Remote Access ยังรองรับการทำงานที่เป็น Port Forward ช่วยให้ผู้ใช้งานเชื่อมต่อไปยังระบบต่าง ๆ ภายในผ่าน server ตัวนั้นได้
ในการเริ่มต้นเชื่อมต่อไปยัง SSH Server ผู้ใช้งานจำเป็นต้องพิสูจน์ตัวตนก่อน โดยท่ามาตรฐานที่สุดคงเป็น Password Authentication ผู้ใช้จะใช้ username & password ในการพิสูจน์ตัวตน ส่วนอีกวิธีก็เป็นที่รู้จักกันอย่างแพร่หลาย Public key-based authentication วิธีการนี้ ผู้ใช้จะสร้าง Key Pair ขึ้นมา จากนั้นนำข้อมูล public key ที่สร้างขึ้น ไปเก็บไว้ที่ $HOME/.ssh/authorized_keys ที่ SSH Server
โจทย์ที่เอ่ยมาเครื่องมือพวก Automation แนว ๆ Infrastructure as Code ก็คงตอบโจทย์ได้ไม่ยากนัก แต่ถ้าอยู่ในสถานการณ์นี้
- มี Linux Server ที่ต้องทำงานด้วย 50 เครื่อง
- มี outsource ที่ทำงาน project a ระยะเวลาโครงการ 3 เดือน จำนวน 5 คน
- มีทีม service & support ที่จะมาทำ preventive maintenance วันนี้วันเดียว
- มีน้องพนักงาน temporary ที่มีสัญญาจ้าง 1 ปี แต่ละคนเริ่มงานไม่พร้อมกัน
- มี outsource ที่ทำงาน project b ระเวลาโครงการ 6 เดือน จำนวน 2 คน และยังมีโครงการใหม่เพิ่มขึ้นอีกจำนวนมากในยุค digital transformation
ทีม admin ที่ดูแลคงต้องการปฎิทิน งาน process ในการจัดการ user เหล่านี้ เพื่อถึงเวลาที่จบโครงการ แต่ละคนคงต้องถูกลบออกจากระบบเพื่อลดความเสี่ยงของระบบลง
ตัวอย่างการเชื่อมต่อไปยัง SSH Server ด้วยวิธีการ Public key-based authentication
ส่วนใหญ่ใน instance บน Cloud Computing มักจะกำหนด PasswordAuthentication no
ทำให้ไม่สามารถใช้ username & password ในการ login ไปได้ มีผลทำให้ไม่สามารถใช้คำสั่ง ssh-copy-id ได้ ดังนั้นขั้นตอนการเขียนไฟล์ authorized_keys จะมีหลายขั้นตอน
d8k-a2m2 ssh > ssh-keygen -t ed25519 -N "" -C "user1" -f user1
Generating public/private ed25519 key pair.
Your identification has been saved in user1
Your public key has been saved in user1.pub
The key fingerprint is:
SHA256:hAiG62N7b14vwn2+gaecw6FeQSuibTUqp3lZ0NQ53PI user1
The key's randomart image is:
+--[ED25519 256]--+
| .o o o |
|.. . o B . |
| . + ..= |
|. . ....E |
|. ..+ oS |
| +o +.o.o |
|.oo=+ ++.o |
| .*+ =+==.. |
| oo =+.+=+. |
+----[SHA256]-----+
d8k-a2m2 ssh > ssh root@server1.d8k.io -C "mkdir /home/user1/.ssh"
d8k-a2m2 ssh > ssh root@server1.d8k.io -C "chown user1.user1 /home/user1/.ssh"
d8k-a2m2 ssh > rsync -av user1.pub root@server1.d8k.io:/home/user1/.ssh/authorized_keys
building file list ... done
user1.pub
sent 211 bytes received 42 bytes 101.20 bytes/sec
total size is 87 speedup is 0.34
d8k-a2m2 ssh > ssh root@server1.d8k.io -C "chown user1.user1 /home/user1/.ssh/authorized_keys"
d8k-a2m2 ssh > ssh -i user1 user1@server1.d8k.io
Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-50-generic x86_64)
[... truncated output ...]
Last login: Mon Jan 23 08:15:17 2023 from 49.229.230.42
$
ขอแนะนำอีกทางเลือกในการพิสูจน์ตัวตนกับ SSH Server - Signed SSH Certificates
วิธีการนี้เป็นการใช้ Key Pair ในการพิสูจน์ตัวตนเช่นกัน เพียงแต่ว่า public key ที่ใช้ ต้องถูก signed ด้วย Certificate Authority ด้วยวิธีการนี้ไม่จำเป็นต้องนำข้อมูล public key ที่สร้างขึ้น ไปเก็บไว้ที่ $HOME/.ssh/authorized_keys ที่ SSH Server แต่ว่า ต้องแก้ไข configuration ของ SSH Server ให้ trust ตัว Key ของ Certificate Authority
Signed SSH Certificates #0 - ข้อมูลเบื้องต้น
- เครื่อง Client ที่ใช้ในการทดสอบชื่อเครื่อง
d8k-a2m2
ระบบปฏิบัติการเป็น macOS 13.1 - เครื่อง SSH Server ที่ใช้ในการทดสอบชื่อเครื่อง
server1.d8k.io
ระบบปฏิบัติการเป็น Ubuntu 22.04 LTS เป็น Droplet ใน Digital Ocean
Signed SSH Certificates #1 - สร้าง Key Pair สำหรับใช้เป็น Certificate Authority
d8k-a2m2 ssh > ssh-keygen -t ed25519 -N "" -C "Certificate Authority" -f ca
Generating public/private ed25519 key pair.
Your identification has been saved in ca
Your public key has been saved in ca.pub
The key fingerprint is:
SHA256:hkHGfmtC4ElViJ/mAZMedpd3S8eQi0Bap+mHews7gnI Certificate Authority
The key's randomart image is:
+--[ED25519 256]--+
| =+++.. .+ |
| Xo+o++. + o |
| = Xoooo + + |
| + B+... o |
| +.oS.. |
| o.oo |
| . oo . |
| . E . .+ . |
| o .... |
+----[SHA256]-----+
d8k-a2m2 ssh > ls -la ca*
-rw-------@ 1 drs staff 411 Jan 23 14:28 ca
-rw-r--r--@ 1 drs staff 103 Jan 23 14:28 ca.pub
Signed SSH Certificates #2 - SSH Server Configuration
ในขั้นตอนนี้ต้อง remote access ไปยัง SSH Server ที่ต้องการ และจำเป็นต้องใช้สิทธิ์ root ในการแก้ไข /etc/ssh/sshd_config
และ restart sshd service
d8k-a2m2 ssh > rsync -av ca.pub root@server1.d8k.io:/etc/ssh/ca.pub
building file list ... done
ca.pub
sent 224 bytes received 42 bytes 177.33 bytes/sec
total size is 103 speedup is 0.39
d8k-a2m2 ssh > ssh root@server1.d8k.io
[... truncated output ...]
root@server1:~# echo "TrustedUserCAKeys /etc/ssh/ca.pub" >> /etc/ssh/sshd_config
root@server1:~# systemctl restart sshd
root@server1:~# useradd -m user1
Signed SSH Certificates #3 - สร้าง และ signed สำหร้บเชื่อมต่อไปยัง SSH Server
สร้าง key pair สำหรับ user1 ด้วยคำสั่ง ssh-keygen จะได้ไฟล์ user1 และ user1.pub จากนั้นใช้คำสั่ง ssh-keygen ตัวเดิมทำการ signed ด้วย CA key ที่ชื่อว่า ca กำหนดให้สามารถใช้งานได้เพียง 5 นาที
ผลที่จะได้ จะทำให้ user1 ที่ใช้ key ตัวนี้สามารถ login ได้ภายในเวลา 5 นาทีเท่านั้น ถ้าเลยเวลา key ตัวนี้ก็ไม่สามารถ loging ได้แล้ว
d8k-a2m2 ssh > ssh-keygen -t ed25519 -N "" -C "user1" -f user1
Generating public/private ed25519 key pair.
Your identification has been saved in user1
Your public key has been saved in user1.pub
The key fingerprint is:
SHA256:hAiG62N7b14vwn2+gaecw6FeQSuibTUqp3lZ0NQ53PI user1
The key's randomart image is:
+--[ED25519 256]--+
| .o o o |
|.. . o B . |
| . + ..= |
|. . ....E |
|. ..+ oS |
| +o +.o.o |
|.oo=+ ++.o |
| .*+ =+==.. |
| oo =+.+=+. |
+----[SHA256]-----+
d8k-a2m2 ssh > ssh-keygen -s ca -I user1 -n user1 -V +5m -z 1 user1.pub
Signed user key user1-cert.pub: id "user1" serial 1 for user1 valid from 2023-01-23T15:13:00 to 2023-01-23T15:19:14
d8k-a2m2 ssh > ssh-keygen -Lf user1-cert.pub
user1-cert.pub:
Type: ssh-ed25519-cert-v01@openssh.com user certificate
Public key: ED25519-CERT SHA256:hAiG62N7b14vwn2+gaecw6FeQSuibTUqp3lZ0NQ53PI
Signing CA: ED25519 SHA256:hkHGfmtC4ElViJ/mAZMedpd3S8eQi0Bap+mHews7gnI (using ssh-ed25519)
Key ID: "user1"
Serial: 1
Valid: from 2023-01-23T15:13:00 to 2023-01-23T15:19:14
Principals:
user1
Critical Options: (none)
Extensions:
permit-X11-forwarding
permit-agent-forwarding
permit-port-forwarding
permit-pty
permit-user-rc
Signed SSH Certificates #4 - ทดสอบ login ด้วย signed certificate
ทดสอบ login ด้วย user1 ไปยัง server1.d8k.io จะเห็นได้ว่า ไม่มีการเขียนไฟล์ authorized_keys ไว้ที่ server
d8k-a2m2 ssh > ssh -i user1 user1@server1.d8k.io
Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-50-generic x86_64)
[... truncated output ...]
$ hostnamectl
Static hostname: server1
Icon name: computer-vm
Chassis: vm
Machine ID: 6365466097a407991fcb15b663ce395c
Boot ID: 13044d98648e417f89e3ae0074635f30
Virtualization: kvm
Operating System: Ubuntu 22.04.1 LTS
Kernel: Linux 5.15.0-50-generic
Architecture: x86-64
Hardware Vendor: DigitalOcean
Hardware Model: Droplet
$
Signed SSH Certificates #5 - ทดสอบ login ด้วย signed certificate หลังจากเลยระยะเวลาที่กำหนดไว้ในขั้นตอน signed
d8k-a2m2 ssh > ssh -i user1 user1@server1.d8k.io
user1@server1.d8k.io: Permission denied (publickey).
ข้อสังเกตุ
จะเห็นว่า ขั้นตอนการ signed ที่ต้องการทำขั้นตอนนี้เป็นประจำ จำเป็นต้องใช้ Key ของ CA ซึ่งจะทำให้ขั้นตอนนี้ไม่สะดวกในมุมของการทำ Daily Operation ในตอนที่ 2 จะมองหาตัวช่วย HashiCorp Vault มาช่วยจัดการเรื่องนี้ให้สามารถทำงานได้สะดวกขึ้น
อ้างอิง: https://www.lorier.net/docs/ssh-ca.html