4 điểm bởi GN⁺ 2024-06-24 | 1 bình luận | Chia sẻ qua WhatsApp

Mục tiêu

  • Chỉ cho phép người dùng có quyền thực thi lệnh với quyền root
  • Không sử dụng leo thang đặc quyền

Triển khai

  • Tạo khóa SSH chuyên dụng để dùng cho xác thực root

    mkdir /root/.ssh/
    echo ssh-ed25519 AAAAC3Nza... > /root/.ssh/local_keys
    
  • Chạy một instance máy chủ sshd được bind vào Unix domain socket

    mkdir /run/sshd/
    chown root:wheel /run/sshd/
    chmod 750 /run/sshd/
    s6-ipcserver /run/sshd/sshd.sock sshd -ie -o AuthorizedKeysFile=/root/.ssh/local_keys -o PermitRootLogin=yes
    
  • Khóa tài khoản root và cấu hình để không thể đăng nhập bằng mật khẩu

    # thay đổi mật khẩu root trong tệp /etc/passwd
    
  • Sử dụng tùy chọn ProxyCommand để kết nối tới instance sshd cục bộ

    ssh -o ProxyCommand='socat STDIO UNIX-CONNECT:/run/sshd/sshd.sock' \
        -i .ssh/root-key.pub \
        -t \
        root@root \
        "cd $(pwd); '$SHELL' --login"
    
  • Viết script dùng tùy chọn ProxyUseFdpass để chuyển file descriptor của socket

    #!/usr/bin/env python3
    import sys
    import socket
    import array
    
    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    s.connect("/run/sshd/sshd.sock")
    
    fds = array.array("i", [s.fileno()])
    ancdata = [(socket.SOL_SOCKET, socket.SCM_RIGHTS, fds)]
    socket.socket(fileno=1).sendmsg([b'\0'], ancdata)
    
  • Cuối cùng, chạy lệnh ssh

    ssh -o ProxyCommand='/home/hugo/tmp/passfd.py' \
        -i .ssh/root-key.pub \
        -o ProxyUseFdpass=yes \
        -t \
        root@root \
        "cd $(pwd); '$SHELL' --login"
    

Kết luận

  • Kỹ thuật này dùng OpenSSH để xử lý các chi tiết bảo mật
  • Hỗ trợ nhiều phương thức xác thực, bao gồm khóa SSH dựa trên phần cứng
  • Quá trình thiết lập trên host mới không phức tạp
  • Script passfd.py chỉ là giải pháp tạm thời để thử nghiệm; nếu dùng hằng ngày thì nên viết thành một tệp thực thi nhỏ

Ý kiến của GN⁺

  • Cách làm này có thể tăng cường bảo mật như một lựa chọn thay thế cho sudo hoặc doas
  • Cách tiếp cận dùng SSH để tăng cường xác thực hỗ trợ nhiều phương thức xác thực, bao gồm cả xác thực dựa trên phần cứng
  • Cấu hình hệ thống tương đối đơn giản nên cả kỹ sư mới vào nghề cũng có thể dễ dàng làm theo
  • Nếu biến script passfd.py thành một tệp thực thi nhỏ và đặt vào /usr/local/bin thì sẽ tiện hơn khi sử dụng
  • Phương pháp này chỉ hoạt động cục bộ, không phơi bày ra mạng, nên có độ an toàn cao

1 bình luận

 
GN⁺ 2024-06-24
Ý kiến trên Hacker News
  • Vấn đề phức tạp bổ sung: Thay vì một binary suid duy nhất như trước, sẽ cần hai binary dùng socket UNIX, trong đó một binary chạy dưới quyền root. Điều này làm tăng độ phức tạp, bao gồm cả các thao tác mật mã bất đối xứng.

  • Bảo mật hệ thống: Nếu giới hạn binary sudo cho một nhóm cụ thể (wheel) và điều chỉnh quyền phù hợp, vẫn có thể duy trì mức độ bảo mật tương tự cách tiếp cận sshd. Nếu trình quản lý gói của hệ thống làm hỏng quyền của sudo, cũng có thể dùng cron để sửa định kỳ hoặc tự cài sudo từ mã nguồn.

  • run0 của systemd: Công cụ run0 của systemd hoạt động tương tự sudo nhưng không dùng SUID. Thay vào đó, nó yêu cầu trình quản lý dịch vụ chạy lệnh. Cách này có hành vi giống ssh hơn.

  • So sánh sshsudo: Có nghi vấn liệu đăng nhập root qua ssh có thực sự an toàn hơn sudo hay không. Cần bàn thêm về cách chặn truy cập người dùng từ xa tới sshd. So với các giới hạn của sudo, cách tiếp cận bằng ssh có thể dễ tổn thương hơn.

  • Vấn đề dịch vụ mạng: Nếu ssh không khởi động khi boot, thì cả đăng nhập console cũng trở nên bất khả thi. Điều này có thể gây ra nhiều vấn đề hơn so với sudo hay su.

  • Cách tiếp cận tương tự systemd run0: Có một cách tiếp cận tương tự công cụ run0 của systemd.

  • Khả năng kiểm soát chi tiết của sudo: sudo cho phép kiểm soát chi tiết lệnh, đối số, việc tạo shell con và nhiều thứ khác. Cách tiếp cận mới sẽ làm mất đi mức kiểm soát này, đồng thời việc quản lý khóa tin cậy cũng khó hơn.

  • Thiết lập console SSH: Có thể dùng một console SSH chuyên dụng để quản lý truy cập root. Bảo mật được tăng cường bằng Yubikey và cấu hình tường lửa.

  • Giới hạn của giao thức SSH: SSH không coi việc tạo tiến trình là một phần của giao thức, và cũng không thể truyền tài nguyên cục bộ vào tiến trình con. Muốn dùng nó để thay thế sudo thì sẽ cần một phần mở rộng tương tự POSIX spawn.

  • Quản lý người dùng: Điều quan trọng là không đối xử với người dùng như trẻ con, mà đặt ra các mặc định hợp lý để tránh những rắc rối tiềm ẩn. Nếu cần truy cập root thì nên đăng nhập qua console.

  • Vấn đề chế độ một người dùng: Nếu không thể đăng nhập root ở chế độ một người dùng thì việc khôi phục hệ thống sẽ trở nên khó khăn. Điều này cần thiết để xử lý các sự cố có thể phát sinh trong quá trình nâng cấp hệ thống.