1 คะแนน โดย GN⁺ 4 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • git pull ของ GitHub บนโน้ตบุ๊กที่ไม่ได้เปลี่ยนแปลงอะไรอยู่ ๆ ก็ล้มเหลว แต่เมื่อ สร้างไฟล์ .pub ที่ตรงกับ private key ก็ยืนยันตัวตนได้อีกครั้ง
  • ถ้ามีไฟล์ .pub อยู่ OpenSSH จะส่ง public key ไปก่อนเพื่อขอการยอมรับ แล้วจึงเซ็นชื่อ แต่ถ้าไม่มี จะ ส่งคำขอยืนยันตัวตนที่เซ็นแล้วทันที
  • ทั้งสองกระบวนการ เป็นไปตาม RFC 4252 และ sshd ทั่วไปก็ยอมรับได้ แต่ดูเหมือนว่า GitHub SSH frontend ในตอนนั้นจะไม่รับคำขอที่เซ็นตรงแบบนี้
  • ในการทดสอบแบบควบคุม 12 ครั้ง ทั้ง 6 ครั้งที่ไม่มีไฟล์ .pub ถูกปฏิเสธทั้งหมด และทั้ง 6 ครั้งที่มีไฟล์ก็สำเร็จทั้งหมด
  • จากการเปลี่ยนแปลงของ server banner พอจะคาดเดาได้ว่า อาจมีการเปลี่ยนซอฟต์แวร์ฝั่งเซิร์ฟเวอร์ แต่ยังยืนยันสาเหตุที่แท้จริงไม่ได้ จึงปลอดภัยกว่าหากเก็บไฟล์ public key ที่คู่กันไว้ด้วย

การยืนยันตัวตนล้มเหลวแบบกะทันหันและวิธีแก้

  • git pull บนโน้ตบุ๊กหลักหยุดทำงานพร้อมข้อผิดพลาด Permission denied (publickey)
    • คีย์ดังกล่าวยังคงลงทะเบียนอยู่ใน GitHub
    • บนโน้ตบุ๊กอีกเครื่องที่ใช้คีย์อื่นยังดึง repository เดียวกันได้ตามปกติ
  • ไม่พบความผิดปกติในคีย์และการตั้งค่าไคลเอนต์
    • openssl rsa -check คืนค่า RSA key ok
    • ใช้อัลกอริทึมลายเซ็นรุ่นใหม่ rsa-sha2-512
    • ไม่มีปัญหาใน ~/.ssh/config และหน้าสถานะของ GitHub ก็ปกติ
  • หลังติดตั้งใหม่ ไฟล์ public key ที่ตรงกับ ~/.ssh/github_rsa ได้หายไป และเมื่อสร้างด้วยคำสั่งต่อไปนี้ก็ยืนยันตัวตนสำเร็จ
ssh-keygen -y -f ~/.ssh/github_rsa > ~/.ssh/github_rsa.pub
  • ในการทดสอบแบบควบคุม ทั้ง 6 ครั้งที่ไม่มีไฟล์ .pub ล้มเหลวทั้งหมด และทั้ง 6 ครั้งที่มีไฟล์สำเร็จทั้งหมด

ขั้นตอนยืนยันตัวตนที่ต่างกันตามไฟล์ .pub

  • OpenSSH ใช้ ขั้นตอนการยืนยันตัวตนด้วย public key ที่ต่างกันตามการมีอยู่ของไฟล์ .pub
    • ถ้ามีไฟล์ จะส่ง public key ไปก่อนและรอให้เซิร์ฟเวอร์อนุมัติ แล้วจึงเซ็นชื่อ
    • ถ้ามีแค่ private key จะข้ามการตรวจสอบล่วงหน้าและส่งคำขอยืนยันตัวตนที่เซ็นสมบูรณ์แล้วทันที
  • ทั้งสองวิธีเป็นสิ่งที่ RFC 4252 อนุญาต และ sshd ทั่วไปก็รับได้ทั้งคู่
  • ในตอนนั้น GitHub ปฏิเสธคำขอ public key ที่เซ็นตรง แต่ยังยืนยันไม่ได้ว่ามีการเปลี่ยนแปลงจริงจากฝั่ง GitHub หรือไม่
    • server banner ใน debug log ไม่ได้เป็นรูปแบบ babeld-<hash> แบบเดิม แต่แสดงเป็น 6a2c000
    • จึงพอคาดเดาได้ว่าเซิร์ฟเวอร์ซอฟต์แวร์ตัวใหม่อาจปฏิเสธคำขอที่เซ็นตรง แต่ยังเป็นเพียงข้อสันนิษฐาน
  • เพื่อหลีกเลี่ยงปัญหาเดียวกัน ควรเก็บไฟล์ .pub ที่ตรงกับ private key ไว้ด้วย

1 ความคิดเห็น

 
GN⁺ 4 시간 전
ความเห็นจาก Lobste.rs
  • ตลอด 4 ชั่วโมงที่ผ่านมาก็เจอปัญหาเดียวกัน และมีการลงทะเบียนไว้แล้วที่ https://www.githubstatus.com/incidents/g40zcbvchny4

  • เมื่อไม่กี่สัปดาห์ก่อนตอนเปลี่ยน SSH key ผมไม่ได้ลบไฟล์ .pub เดิมที่ Git มองข้ามอยู่ พอลองเชื่อมต่อด้วยคีย์ใหม่ก็ยังล้มเหลวต่อไป
    กว่าจะรู้ว่า SSH client กำลังส่ง fingerprint เก่าอยู่ก็ต้องเปิดตัวเลือกดีบักหลายอัน และก่อนหน้านี้ก็ไม่รู้เลยว่า OpenSSH อ่านไฟล์ .pub ด้วย คิดมาตลอดว่าเป็นไฟล์ที่ไม่จำเป็นโดยสิ้นเชิง

  • วันนี้เซิร์ฟเวอร์ CI ก็เจอ อาการขัดข้องเดียวกัน แบบกะทันหันเหมือนกัน ดูเหมือนจะเชื่อมต่อกับ github.com ไม่ได้
    พอเปลี่ยนคีย์เป็น ed25519 key ที่ถูกต้องก็กลับมาใช้งานได้อีกครั้ง แต่คีย์นี้ก็ไม่มีไฟล์ `.pub`` คู่กันเหมือนกัน เลยไม่รู้ว่าทำไมถึงแก้ได้

    • คีย์อยู่ ๆ ใช้งานไม่ได้จนตอนแรกนึกว่าโดนเจาะระบบ แต่ตอนนี้ดูเหมือน GitHub กำลังรับมือเองอยู่ก็โล่งใจ
  • วันนี้ก็เจอปัญหาเดียวกัน และเท่าที่รู้ GitHub ไม่เคยประกาศว่าจะมี การเปลี่ยนพฤติกรรมของการยืนยันตัวตนผ่าน SSH

    • ไม่น่าจะเป็นการเปลี่ยนแปลงที่วางแผนไว้
  • เพราะทำทั้งรหัสผ่านและ recovery key หายหมด เลยต้องเข้าสู่กระบวนการ กู้คืนบัญชีด้วย SSH key แต่ GitHub กลับทำให้ SSH key นั้นหมดอายุ เลยสูญเสียสิทธิ์เข้าถึงบัญชีไปทั้งหมด

  • ตลอด 7~8 ปีที่ผ่านมาเหมือนไม่เคยเก็บไฟล์ .pub ไว้เลย หวังว่าก่อนจะใช้ GitHub ครั้งหน้าปัญหานี้จะถูกแก้แล้ว

    • ไฟล์ public key สร้างใหม่ได้ง่าย ๆ และมีคำสั่งนั้นอยู่ใน บทความต้นฉบับ แล้ว
  • ถ้าทั้งสอง flow ของการยืนยันตัวตนถูกต้องตามหลัก ทำไมถึงต้องมี flow การค้นหาคีย์ อยู่ด้วย
    มันดูเหมือนจะก่อแต่พฤติกรรมประหลาดแบบนี้ และถ้าสร้าง public key จาก private key ได้อยู่แล้ว ก็น่าจะให้ SSH จัดการอัตโนมัติไปเลย

    • มันเป็นฟีเจอร์สำหรับกรณีที่ private key ถูกเข้ารหัสไว้ หรือเก็บอยู่ใน hardware security token จนยังใช้งานได้ทันทีไม่ได้
      SSH จะตรวจดูก่อนว่าคีย์ไหนมีโอกาสใช้กับเซิร์ฟเวอร์นั้นได้ เพื่อไม่ให้ผู้ใช้ต้องถอดรหัสคีย์ที่ยังไงก็ยืนยันตัวตนไม่ผ่านโดยไม่จำเป็น
      พฤติกรรมนี้ยังมีผลข้างเคียงแปลก ๆ อย่าง https://github.com/FiloSottile/whoami.filippo.io ด้วย ดังนั้นก็ควรอนุญาตให้มีวิธีที่เซิร์ฟเวอร์ต้องรู้ public key ของไคลเอนต์ล่วงหน้าก่อน จึงจะลองยืนยันตัวตนได้ เผื่อกรณีผู้ใช้เผลอเชื่อมต่อไปยังเซิร์ฟเวอร์ผิดเครื่อง
  • บัญชี Office 365 สำหรับงานของผมก็จู่ ๆ ใช้งานไม่ได้เป็นครั้งแรกในรอบ 5 ปีเหมือนกันวันนี้
    เลยสงสัยว่า Microsoft โดนเจาะจนต้องใส่ salt ใหม่ให้ทุกค่า หรือเป็นเรื่องที่เกิดเฉพาะผู้ใช้ยุโรปเพราะการลงมติ Chat Control 1.0 ล่าสุด

    • บริการ ตัดการเชื่อมต่อ ของ GitHub กับการยืนยันตัวตนของบัญชี M365 ไม่ได้เกี่ยวข้องกันเลย และผมมั่นใจ 99.999% ว่าเป็นเรื่องบังเอิญ
      ผมพูดแบบนี้ได้เต็มปาก เพราะเป็น 1 ใน 2 คนที่ผมรู้จักซึ่งเคยทำงานทั้งฝั่ง Git Systems ของ GitHub และฝั่งผลิตภัณฑ์ Office/M365 ของ Microsoft
      ต่อให้สาเหตุมาจากการเปลี่ยนนโยบายหรือเทคโนโลยีเดียวกันที่มีผลกับทั้งสองบริการจริง ๆ ก็ยังเป็นระบบที่แยกขาดจากกัน โอกาสที่จะปล่อยใช้งานในวันเดียวกันมีต่ำมาก