ใช้ Signed SSH Certificates ไว้ login ดีกว่า สบายกว่าเยอะ ep. 1

ในการเริ่มต้นเชื่อมต่อไปยัง SSH Server ผู้ใช้งานจำเป็นต้องพิสูจน์ตัวตนก่อน

author image
drs

Technology evangelistic advocacy

Posted on 2023-01-22 08:14:30 +0700

คนที่อยู่กับ 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 ก็คงตอบโจทย์ได้ไม่ยากนัก แต่ถ้าอยู่ในสถานการณ์นี้

  1. มี Linux Server ที่ต้องทำงานด้วย 50 เครื่อง
  2. มี outsource ที่ทำงาน project a ระยะเวลาโครงการ 3 เดือน จำนวน 5 คน
  3. มีทีม service & support ที่จะมาทำ preventive maintenance วันนี้วันเดียว
  4. มีน้องพนักงาน temporary ที่มีสัญญาจ้าง 1 ปี แต่ละคนเริ่มงานไม่พร้อมกัน
  5. มี 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

ssh signed cert

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

Made by มูลค่าความสุข

Share on

Tags

Human knowledge belongs to the world

a line from the movie "Antitrust"