6 điểm bởi GN⁺ 18 ngày trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Chứng chỉ SSH giải quyết sự phiền toái của cơ chế xác thực SSH dựa trên khóa công khai truyền thống và cung cấp độ tin cậy tự động giữa client và server
  • Được hỗ trợ từ OpenSSH 5.4, CA (tổ chức chứng thực) ký khóa người dùng và khóa host để có thể xác thực mà không cần sửa authorized_keys
  • Chứng chỉ có thể bao gồm thời hạn hiệu lực, người dùng được phép (principal), IP truy cập, lệnh bắt buộc (force-command) v.v. để hỗ trợ kiểm soát truy cập chi tiết
  • Loại bỏ quy trình TOFU (Trust on First Use), cho phép kết nối an toàn khi khóa host thay đổi mà không xuất hiện cảnh báo
  • Nếu tận dụng máy chủ hoặc công cụ ký tự động, có thể tự động hóa quản lý SSH trong môi trường máy chủ quy mô lớn và nâng cao bảo mật

Tổng quan về chứng chỉ SSH và giới hạn của xác thực SSH dựa trên khóa truyền thống

  • Khi kết nối SSH, cần kiểm tra dấu vân tay khóa host (fingerprint) của server truy cập lần đầu; nhưng đa số người dùng không xác minh mà chỉ nhập ‘yes’, tức sử dụng mô hình TOFU (Trust on First Use)
    • Quản trị viên có thể tự kiểm tra dấu vân tay của server hoặc xác minh bằng lệnh ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key
  • Xác thực dựa trên khóa công khai cho phép đăng nhập không cần mật khẩu, nhưng phải phân phối khóa công khai vào file authorized_keys của từng server
  • Dùng SSH agent (ssh-agent) có thể lưu khóa riêng trong bộ nhớ để xác thực nhiều lần mà không cần nhập lặp lại
  • Giới hạn của cách làm cũ
    • Cần sao chép khóa công khai lên server cho từng người dùng
    • Khi khóa host thay đổi, phía client sẽ xuất hiện thông báo cảnh báo
    • Việc quản lý độ tin cậy bất tiện do TOFU

Chứng chỉ SSH và tổ chức chứng thực (CA)

  • Chứng chỉ SSH (Certificate) được hỗ trợ từ OpenSSH 5.4 (tháng 3 năm 2010), là cấu trúc mở rộng của định dạng khóa SSH hiện có
  • SSH CA được tạo thành từ một cặp khóa SSH, trong đó khóa công khai đóng vai trò gốc tin cậy
  • Các ưu điểm chính
    • Không cần sửa file authorized_keys trên server
    • Không có cảnh báo khi thay khóa host
    • Loại bỏ quy trình TOFU để hiện thực độ tin cậy tự động
    • Có thể đưa vào chứng chỉ người dùng được phép (principal), IP được phép, thời hạn hiệu lực, lệnh bắt buộc (force-command) v.v.
    • Tự động chặn truy cập khi chứng chỉ hết hạn

Quy trình thiết lập SSH CA và ký

  • Trên hệ thống CA, tạo cặp khóa CA bằng thuật toán ECDSA
    • ssh-keygen -t ecdsa -C "SSH CA" -f CA/ssh-ca
  • Người dùng gửi khóa công khai của mình (*.pub) cho CA, sau đó CA ký (sign) khóa đó để phát hành chứng chỉ (*-cert.pub)
    • Ví dụ: ssh-keygen -s CA/ssh-ca -I "Jane Jolie" -n jane -z 001 -V +1w jane.pub
  • Cấu hình server
    • Lưu khóa công khai CA vào /etc/ssh/ssh-ca.pub và thêm thiết lập TrustedUserCAKeys
    • Ký khóa host của server bằng CA (ssh-keygen -h -s CA/ssh-ca ...) rồi đăng ký trong mục HostCertificate
  • Cấu hình client
    • Thêm một dòng @cert-authority vào file known_hosts
    • Ví dụ: @cert-authority *.example.com $(cat CA/ssh-ca.pub)

Kết nối và xác minh dựa trên chứng chỉ SSH

  • Người dùng đăng nhập bằng chứng chỉ đã ký cùng với khóa riêng (ssh -i jane -l jane alice.example.com)
  • Trong log của server sẽ ghi lại ID, số sê-ri (serial), dấu vân tay CA của chứng chỉ
  • Có thể thêm nhiều hostname hoặc IP làm principal trong chứng chỉ
  • Nếu cố đăng nhập bằng người dùng không nằm trong principal được chỉ định của chứng chỉ, sẽ xuất hiện lỗi “Certificate invalid: name is not a listed principal”
  • Có thể thiết lập lệnh bắt buộc (force-command) hoặc IP được phép (source-address) trong chứng chỉ để kiểm soát truy cập chi tiết

Danh sách kiểm tra và xử lý sự cố

  • Các mục cần kiểm tra phía server

    • Thiết lập TrustedUserCAKeys và sự tồn tại của khóa công khai CA
    • Khóa host đã được ký và HostCertificate đã được chỉ định
    • Cần khởi động lại sshd
  • Các mục cần kiểm tra phía client

    • Khóa người dùng phải được CA ký
    • Mục @cert-authority trong known_hosts phải khớp với principal
    • Khi chứng chỉ hết hạn sẽ hiện thông báo “Certificate invalid: expired”
    • Nếu điều kiện ràng buộc của chứng chỉ không khớp, hệ thống sẽ yêu cầu nhập mật khẩu
    • Khi thêm chứng chỉ vào SSH agent thì cả khóa và chứng chỉ đều được đăng ký (ssh-add jane)
    • Có thể dùng tùy chọn (-O) khi ký để điều khiển chức năng
    • Ví dụ: dùng -O clear để xóa mọi quyền, sau đó chỉ cho phép permit-agent-forwarding, permit-port-forwarding

Tự động hóa chứng chỉ khóa host

  • Dùng module Python sshkey-tools và BottlePy để triển khai máy chủ ký tự động (hkbot)
    • Chạy hkbot.py trên server CA, sau đó tự động ký khi tải khóa công khai host lên qua HTTP request
    • Trên client, có thể tự động cài đặt bằng lệnh curl -F hostkey=@/etc/ssh/ssh_host_ed25519_key.pub http://CA:8870 | sh
    • Chỉnh sửa /etc/ssh/sshd_config, kiểm tra rồi áp dụng bằng systemctl restart sshd
  • Sau đó khi kết nối SSH, có thể tự động tin cậy và đăng nhập dựa trên chứng chỉ

Tóm tắt ưu điểm của chứng chỉ SSH

  • Không cần TOFU, có độ tin cậy tự động giữa client và server
  • Có thể cấp chứng chỉ ngắn hạn để kiểm soát truy cập tạm thời
  • Tự động chặn truy cập khi chứng chỉ hết hạn, không cần dọn authorized_keys
  • Có thể thiết lập chính sách chi tiết như lệnh bắt buộc, giới hạn PTY, kiểm soát IP truy cập
  • Có thể đơn giản hóa quản lý môi trường máy chủ quy mô lớn bằng công cụ tự động hóa
  • Giới thiệu dự án liên quan: Smallstep SSH

Tài liệu tham khảo thêm

Cập nhật

  • SSH CA đặc biệt hữu ích trong môi trường sở hữu server riêng và có quyền root
  • Trong hệ thống nhiều người dùng, cách dùng known_hostsauthorized_keys truyền thống vẫn cần thiết
  • Bản thảo chuẩn hóa định dạng chứng chỉ SSH: draft-miller-ssh-cert-06

1 bình luận

 
Ý kiến trên Hacker News
  • Thật ngạc nhiên là mọi người vẫn còn dùng mật khẩu SSH
    Đặc biệt trong môi trường doanh nghiệp lớn, nhiều chính sách mật khẩu chồng chéo khiến ngay cả việc chỉ đăng nhập vào máy chủ cũng mất nhiều thời gian
    Vì thế dù có bảo họ dùng khóa bằng ssh-keygen, đa số vẫn chỉ nghĩ “để lúc nào đó làm” rồi cuối cùng không làm

    • Khóa hữu ích khi cá nhân hoặc công ty có hệ thống quản lý tập trung
      Nhưng ngoài thực tế, rất dễ rơi vào tình trạng quản lý hỗn loạn như dùng một khóa chung cho nhiều máy chủ hoặc chia sẻ khóa cho nhau
      Mật khẩu ít nhất có ưu điểm là đơn giản
    • Tôi đã quản lý khóa SSH bằng HSM dựa trên Yubikey suốt nhiều năm
      Không có mật khẩu, nhưng khi đăng nhập phải chạm Yubikey vật lý
    • Việc dùng khóa phân tán như ssh-copy-id khiến hacker dễ di chuyển ngang trong mạng hơn, nên nhiều tổ chức chặn cách này
  • Cứ vài tháng lại có người “khám phá” lại chứng chỉ SSH rồi viết blog về nó
    Tôi cũng từng viết một bài liên quan từ 15 năm trước, nhưng giờ nhìn lại thì còn thiếu sót

    • Nhiều người nhầm lẫn giữa khóa và chứng chỉ
      Ngay cả kỹ sư bảo mật đôi khi cũng quên rằng họ đang dùng xác thực bằng khóa chứ không phải chứng chỉ SSH
    • Chứng chỉ SSH hữu ích vì có thể cấp quyền truy cập cho một người dùng cụ thể với thời hạn và quyền hạn giới hạn
    • Tôi cũng biết về chứng chỉ SSH từ lâu, nhưng vẫn chưa chuyển khỏi cách làm dựa trên khóa
      Việc quản lý thủ công khóa trên nhiều máy chủ quá phiền phức
      Giờ tôi đang cân nhắc liệu chuyển đổi lúc này có còn đáng giá không
    • Khi công ty cũ của tôi dựng SSH CA cách đây 10 năm, họ đã tham khảo bài blog ở trên
  • Cách TOFU(Trust On First Use) đơn giản nhưng đi khá xa
    Với các máy chủ của tôi, chỉ cần tự xác minh khóa máy chủ một lần là đủ
    Trong môi trường doanh nghiệp lớn, chỉ cần đăng danh sách khóa công khai của các máy chủ nội bộ lên một website nội bộ được ký SSL
    Nhưng trong môi trường có quá nhiều máy chủ hoặc thay đổi thường xuyên thì chứng chỉ tốt hơn hẳn, và TOFU có giới hạn ở nhiều mặt
    Tôi cũng ước trình duyệt có chức năng thông báo khi khóa TLS của máy chủ thay đổi

    • Tôi đã dùng SSH từ năm 1996 nhưng chưa từng thấy ai thật sự tự xác minh khóa công khai
      Hầu hết chỉ gõ “yes” rồi bỏ qua
  • Ở công ty, chúng tôi lãng phí cực nhiều thời gian và tiền bạc vì kiểm tra SSL của Zscaler
    Mỗi khi hiện lỗi “self-signed certificate in certificate chain” là lại đau đầu

    • Tôi từng phân tích Zscaler cài trên Windows 11 của công ty bạn mình, và nó gần như ở mức phần mềm độc hại
      Nó cài chứng chỉ gốc riêng, khóa cứng cấu hình trình duyệt để không thể dùng proxy
      Dù sửa file cấu hình của Firefox hay Chrome, nó cũng lập tức ghi đè lại
      Thậm chí muốn tắt trong GUI còn phải có mật khẩu của IT
      Chỉ khá hơn antivirus Cybereason một chút
    • Cisco Umbrella ở công ty chúng tôi cũng y như vậy
      Nó phá hỏng toàn bộ các giao thức dựa trên HTTP
      Hàng loạt công cụ như Git, RubyGems, go mod, Nix đều bị lỗi
      Nhà cung cấp thì bảo là “minh bạch”, nhưng thực tế hoàn toàn không phải vậy
      Chẩn đoán vấn đề mất hàng giờ, và đa số quản trị viên không biết mức độ phá hoại của nó
    • Nhân tiện, chứng chỉ SSH khác với chứng chỉ X.509
  • Bài viết chỉ nói đến ưu điểm của chứng chỉ CA, nhưng rõ ràng cũng có nhược điểm
    Tôi chưa từng gặp vấn đề bảo mật nào do TOFU gây ra

    • Kiểu lập luận “chưa từng có sự cố nên là an toàn” cũng giống như nói không cần thắt dây an toàn
      Nếu chứng chỉ SSH có nhược điểm thì tôi muốn biết cụ thể là gì
    • TOFU tiện lợi nhưng không bắt buộc
      Nếu muốn tăng bảo mật thì có thể trao đổi khóa công khai qua kênh an toàn như USB
      Dù dùng chứng chỉ thì cuối cùng vẫn phải trải qua quy trình tương tự, chỉ là chủ thể quản lý được chuyển từ người dùng sang quản trị viên
      Với tổ chức quy mô lớn, chứng chỉ có thể hữu ích, nhưng mức độ bảo mật nói chung là như nhau
    • Nếu có thể cấu hình CA từ trước thì có thể tránh TOFU
      Chỉ cần đưa vào script cài đặt hoặc image triển khai là được
      TOFU chỉ có ý nghĩa khi truy cập vào một máy đã được thiết lập sẵn
    • Câu “đến giờ vẫn chưa có sự cố bảo mật do TOFU” chỉ có nghĩa là đến giờ vẫn chưa có
  • Trong môi trường dev/stg của chúng tôi, mỗi ngày cài lại một nửa số máy
    Nhờ chứng chỉ máy chủ SSH, việc không phải xóa known_hosts hay giữ nguyên khóa trở nên tiện hơn rất nhiều

  • Tôi đang làm một dự án cá nhân tên là Sshifu
    Đây là công cụ giúp đăng nhập bằng chứng chỉ SSH và SSO một cách dễ dàng
    Cài sshifu-server trên máy chủ để dùng như CA, rồi cấu hình để từng máy chủ SSH tin CA này
    Người dùng chỉ cần đăng nhập bằng lệnh npx sshifu là xong
    Xem kho GitHub

  • Trong môi trường vận hành thực tế, truy cập dựa trên chứng chỉ dẫn tới các vấn đề quản lý phức tạp
    Nhiều vấn đề phát sinh như chứng chỉ hết hạn, xóa người dùng, hay đăng nhập khi máy chủ gặp sự cố
    Userify đã xử lý các vấn đề kiểu này suốt 15 năm, và việc xây dựng hạ tầng xác thực SSH ổn định chưa bao giờ là đơn giản

    • Nhưng tôi nghĩ mô hình SaaS lại là lựa chọn tệ nhất
  • Tôi đã thêm hỗ trợ chứng chỉ SSH vào pico.sh, và nó rất hữu ích vì có thể triển khai kiểm soát truy cập kiểu RBAC
    Xem tài liệu

  • Trong production, chứng chỉ SSH lại tập trung hóa độ phức tạp và khiến vấn đề lớn hơn
    Một CA duy nhất phải luôn sẵn sàng, và nếu gặp sự cố thì toàn bộ truy cập sẽ bị chặn
    Còn có nhiều vấn đề thực tế khác như điều chỉnh TTL, quản lý root of trust, khó debug
    Cuối cùng mọi người lại đưa cache hoặc agent trở lại
    Ngược lại, chúng tôi để mỗi node đồng bộ thông tin người dùng qua HTTPS vào authorized_keys cục bộ
    Cách này vẫn giữ được kiểm soát tập trung nhưng sự cố được khoanh vùng cục bộ
    Userify hiện dùng cách này, và xử lý không chỉ xác thực mà cả quản lý quyền hạn
    Chỉ riêng chứng chỉ thì không giải quyết được các vấn đề như tạo người dùng, vai trò sudo, hay dọn dẹp thư mục home

    • Có người hỏi là vậy giải quyết TOFU thế nào