4P by neo 3달전 | favorite | 댓글 1개

목표

  • 권한이 있는 사용자만 root 권한으로 명령어 실행 가능하게 함
  • 권한 상승을 사용하지 않음

구현

  • 전용 SSH 키를 생성하여 root 인증에 사용함

    mkdir /root/.ssh/
    echo ssh-ed25519 AAAAC3Nza... > /root/.ssh/local_keys
    
  • Unix 도메인 소켓에 바인딩된 sshd 서버 인스턴스를 실행함

    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
    
  • root 계정을 잠그고 비밀번호로 로그인 불가하게 설정함

    # /etc/passwd 파일에서 root 비밀번호를 변경
    
  • 로컬 sshd 인스턴스에 연결하기 위해 ProxyCommand 옵션을 사용함

    ssh -o ProxyCommand='socat STDIO UNIX-CONNECT:/run/sshd/sshd.sock' \
        -i .ssh/root-key.pub \
        -t \
        root@root \
        "cd $(pwd); '$SHELL' --login"
    
  • ProxyUseFdpass 옵션을 사용하여 소켓 파일 디스크립터를 전달하는 스크립트를 작성함

    #!/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)
    
  • 최종적으로 ssh 명령어를 실행함

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

결론

  • 이 기술은 OpenSSH를 사용하여 보안 세부 사항을 처리함
  • 하드웨어 기반 SSH 키를 포함한 다양한 인증 방법을 지원함
  • 새로운 호스트에 설정하는 과정이 복잡하지 않음
  • passfd.py 스크립트는 실험을 위한 임시 방편이며, 일상적으로 사용하려면 작은 실행 파일로 작성하는 것이 좋음

GN⁺의 의견

  • 이 방법은 sudodoas의 대안으로 보안성을 높일 수 있음
  • SSH를 사용하여 인증을 강화하는 접근 방식은 하드웨어 기반 인증을 포함해 다양한 인증 방법을 지원함
  • 시스템 설정이 비교적 간단하여 초급 엔지니어도 쉽게 따라할 수 있음
  • passfd.py 스크립트를 작은 실행 파일로 만들어 /usr/local/bin에 배치하면 더 편리하게 사용할 수 있음
  • 이 방법은 네트워크 노출 없이 로컬에서만 동작하므로 보안성이 높음
Hacker News 의견
  • 추가 복잡성 문제: 기존의 단일 suid 바이너리 대신 루트로 실행되는 바이너리와 UNIX 소켓을 사용하는 두 개의 바이너리가 필요해짐. 이는 비대칭 암호화 작업을 포함하여 복잡성을 증가시킴.

  • 시스템 보안: sudo 바이너리를 특정 그룹(wheel)으로 제한하고 권한을 조정하면, sshd 접근 방식과 유사한 보안 수준을 유지할 수 있음. 시스템 패키지 관리자가 sudo 권한을 망칠 경우, cron을 사용해 주기적으로 수정하거나 sudo를 직접 소스에서 설치하는 방법도 있음.

  • systemd의 run0: systemd의 "run0" 도구는 sudo와 유사하게 작동하지만 SUID가 아님. 대신 서비스 관리자가 명령을 실행하도록 요청함. 이는 ssh와 더 유사한 동작을 보임.

  • ssh와 sudo 비교: ssh를 통해 루트로 로그인하는 것이 sudo보다 더 안전한지 의문. sshd의 원격 사용자 접근을 막는 방법에 대한 논의가 필요함. sudo의 제한 사항과 비교했을 때, ssh 접근 방식이 더 취약할 수 있음.

  • 네트워크 서비스 문제: ssh가 부팅 시 시작되지 않으면 콘솔 로그인도 불가능해짐. 이는 sudo나 su보다 더 많은 문제를 야기할 수 있음.

  • systemd run0와 유사한 접근: systemd의 run0 도구와 유사한 접근 방식이 있음.

  • sudo의 세부 제어: sudo는 명령어와 인수, 하위 셸 생성 등을 세부적으로 제어할 수 있음. 새로운 접근 방식은 이러한 세부 제어를 잃게 되며, 신뢰할 수 있는 키 관리가 더 어려움.

  • SSH 콘솔 설정: 전용 SSH 콘솔을 사용해 루트 접근을 관리하는 방법. Yubikey와 방화벽 설정을 통해 보안을 강화함.

  • SSH 프로토콜의 한계: SSH는 프로세스 생성이 프로토콜의 일부가 아니며, 로컬 리소스를 자식 프로세스로 전달할 수 없음. sudo 대체로 사용하려면 POSIX 스폰과 유사한 확장이 필요함.

  • 사용자 관리: 사용자를 어린아이처럼 대하지 않고, 합리적인 기본값을 설정해 잠재적인 문제를 피하는 것이 중요함. 루트 접근이 필요하면 콘솔을 통해 로그인하는 것이 바람직함.

  • 단일 사용자 모드 문제: 단일 사용자 모드에서 루트로 로그인할 수 없으면 시스템 복구가 어려워짐. 이는 시스템 업그레이드 중 발생할 수 있는 문제를 해결하는 데 필요함.