IT

로그인 후 SSH 사용자를 사전 정의 된 명령 세트로 제한하는 방법은 무엇입니까?

lottoking 2020. 10. 10. 10:27

로그인 후 SSH 사용자를 사전 정의 된 명령 세트로 제한하는 방법은 무엇입니까?


이 보안을위한 아이디어입니다. 우리 직원은 리눅스 서버의 일부 명령에 액세스 할 수 있고 전부는 아닙니다. 예를 들어 로그 파일 ( less logfile) 에 액세스 하거나 다른 명령 ( shutdown.sh/ run.sh)을 시작할 수 있어야합니다 .

배경 정보 :

모든 직원은 동일한 사용자 이름으로 서버에 액세스합니다. 당사 제품은 "일반"사용자 권한으로 실행 완료 "설치"가 필요하지 않습니다. 사용자 디렉토리에 압축을 풀고 실행하십시오. 애플리케이션이 "설치된"서버를 관리합니다. 모든 컴퓨터에는 사용자가 johndoe있습니다. 직원들은 로그 파일에 액세스하여 확인하거나 수동으로 애플리케이션을 다시 시작하기 위해 명령 줄에서 애플리케이션에 액세스해야합니다. 일부 사용자 만 전체 명령 줄 액세스 권한을 갖습니다.

우리는 서버에서 ppk 인증을 사용하고 있습니다.

employee1이 로그 파일에만 액세스 할 수 있고 employee2도 X 등을 수행 할 수있는 권한 좋을 것입니다.

해결책 : 해결책으로 나는 수락 된 답변에 command명시된 옵션을 사용할 을 구석으로입니다. 일부 직원을 위해 실행할 수있는 유일한 파일이 될 저만의 작은 쉘 펼쳐를 만들을 구석으로 입니다. 펼쳐지는 수있는 여러 명령을 제공하지만 다른 명령은 제공하지 않습니다. 여기에 다음 에서 사용하는 다음 변수를 사용합니다 .authorized_keys

command="/bin/myscript.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty
ssh-dss AAAAB3....o9M9qz4xqGCqGXoJw= user@host

이것은 우리에게 충분한 보안입니다. 감사합니다, 커뮤니티!


또한 키를 허용 가능한 명령으로 제한 할 수 있습니다 (authorized_keys 파일에서).

즉, 사용자는 ssh를 통해 로그인하지 않고 명령 세트를 가지지 만 오히려 ssh (예 : "ssh somehost bin / showlogfile")를 통해서만 해당 명령을 수 있습니다.


sshrsh파일에서 사용자의 셸 프로그램을 사용하여 명령을 실행하고 전통을 사용 셸 암호 .

이것은 ssh어떤 식 으로든 구성을 포함 하지 않고 있음을 의미합니다 .

사용자가 쉘 액세스 권한을 갖지 못하도록 해당 사용자의 쉘을 펼쳐 바꾸십시오. 들여다 보면 각 /etc/passwd사용자에게 쉘 명령 인터프리터를 할당하는 필드가 있음을 알 수 있습니다. 펼쳐지는 대화식 로그인 ssh user@host과 명령 모두에 대해 쉘로 사용 ssh user@host command arg ...합니다.

여기에 예가 있습니다. foo쉘이 펼쳐 인 사용자 만들었습니다 . 펼쳐지 는 메시지 my arguments are:와 인수 (각각 별도의 행과 우리 만 괄호로 묶음)를 인쇄하고 종료합니다. 로그에는 인수가 없습니다. 다음은 발생합니다.

webserver:~# ssh foo@localhost
foo@localhost's password:
Linux webserver [ snip ]
[ snip ]
my arguments are:
Connection to localhost closed.

사용자가 명령을 실행하려고합니다.

webserver:~# ssh foo@localhost cat /etc/passwd
foo@localhost's password:
my arguments are:
<-c>
<cat /etc/passwd>

우리의 "쉘" -c은 전체 명령을 하나의 인수로 사용하여 스타일 호출 /bin/sh을받습니다.

보시다시피, 이제 우리가 할 수있는 일은 펼쳐질 추가로 개발하여 -c인수 로 호출 된 경우를 인식 하여 다음 업그레이드를 구문 분석하는 것입니다 (예 : 패턴 일치). 허용되는 디렉토리는 재귀 적으로 호출하여 실제 쉘로 많은 수 있습니다 /bin/bash -c <string>. 거부 사례는 오류 메시지를 인쇄하고 종료 할 수 있습니다 ( -c누락 된 사례 포함 ).

이 글을 작성하는 방법에주의해야합니다. 나는 모든 것이 허용하지 않는 긍정적 인 일치 만 작성하는 것이 좋습니다.

참고 : 인 경우 다음 과 같이 명령 에서 root을 재정의하고 계정에 로그인 할 수 있습니다 . (선택한 대체 쉘.) 비 루트는이를 수행 할 수 없습니다.susu -s /bin/bash foo

다음은 예제 펼쳐입니다. 사용자를 에서 저장소에 ssh대한 git액세스 용으로 만 사용 하도록 제한합니다 /git.

#!/bin/sh

if [ $# -ne 2 ] || [ "$1" != "-c" ] ; then
  printf "interactive login not permitted\n"
  exit 1
fi

set -- $2

if [ $# != 2 ] ; then
  printf "wrong number of arguments\n"
  exit 1
fi

case "$1" in
  ( git-upload-pack | git-receive-pack )
    ;; # continue execution
  ( * )
    printf "command not allowed\n"
    exit 1
    ;;
esac

# Canonicalize the path name: we don't want escape out of
# git via ../ path components.

gitpath=$(readlink -f "$2")  # GNU Coreutils specific

case "$gitpath" in
  ( /git/* )
     ;; # continue execution
  ( * )
    printf "access denied outside of /git\n"
    exit 1
    ;;
esac

if ! [ -e "$gitpath" ] ; then
   printf "that git repo doesn't exist\n"
   exit 1
fi

"$1" "$gitpath"

물론, 우리는이 망할 놈의 프로그램 신뢰하는 git-upload-pack과가 git-receive-pack구멍이 나 사용자에게 시스템에 대한 액세스를 제공합니다 해치를 탈출하지.

그것은 단지 종류의 제한 계획에 내재되어 있습니다. 사용자는 특정 보안 도메인에서 코드를 실행하도록 인증을 소유하고 해당 도메인을 하위 도메인으로 제한하는 제한을 두었습니다. 예를 들어 사용자가 vim특정 파일에 대해 명령 을 실행하여 편집 할 수 있도록 허용하면 사용자 :!sh[Enter].


찾고있는 것은 Restricted Shell 이라고 합니다. Bash는 사용자가 자신의 홈에있는 명령 만 있고 수 있고 다른 디렉토리로 설치된 수없는 모드를 제공 할 수 있습니다.

이 예시 는 약간의 날짜가있는 경우 매우 예시 적인 것이 있습니다.


거의 쉘인`rssh를 붙여야합니다.

한 제한 가이드를 따를 수 있고, 모두 이해하기 따를 감시하고 있습니다. `chroot jail '이라는 용어를 이해하고 shd / 터미널 구성을 구현하는 방법 등을 이해합니다.

대부분의 사용자가 sshd를 통해 터미널에 액세스하는 SSH를 통해 특정 제한을 적용 대상 SSH 데몬 구성 파일 인 sshd_conifg도 살펴볼 수 있습니다. 조심하십시오. 잘못된 구성의 결과는 아마도 다소 심각 할 수 있으므로 구현하는 것을 이해하십시오.


자신만의 로그인 쉘을 작성하지 않는 이유는 무엇입니까? Bash를 사용하는 것은 매우 간단하지만 모든 언어를 사용할 수 있습니다.

Bash의 예

사용하는 편집기를 사용하는 파일을 만듭니다 /root/rbash.sh(이름 또는 경로가 될 수 있습니다. chown root:root되어야 함 chmod 700)

#!/bin/bash

commands=("man" "pwd" "ls" "whoami")
timestamp(){ date +'%Y-%m-%s %H:%M:%S'; }
log(){ echo -e "$(timestamp)\t$1\t$(whoami)\t$2" > /var/log/rbash.log; }
trycmd()
{
    # Provide an option to exit the shell
    if [[ "$ln" == "exit" ]] || [[ "$ln" == "q" ]]
    then
        exit

    # You can do exact string matching for some alias:
    elif [[ "$ln" == "help" ]]
    then
        echo "Type exit or q to quit."
        echo "Commands you can use:"
        echo "  help"
        echo "  echo"
        echo "${commands[@]}" | tr ' ' '\n' | awk '{print "  " $0}'

    # You can use custom regular expression matching:
    elif [[ "$ln" =~ ^echo\ .*$ ]]
    then
        ln="${ln:5}"
        echo "$ln" # Beware, these double quotes are important to prevent malicious injection

        # For example, optionally you can log this command
        log COMMAND "echo $ln"

    # Or you could even check an array of commands:
    else
        ok=false
        for cmd in "${commands[@]}"
        do
            if [[ "$cmd" == "$ln" ]]
            then
                ok=true
            fi
        done
        if $ok
        then
            $ln
        else
            log DENIED "$cmd"
        fi
    fi
}

# Optionally show a friendly welcome-message with instructions since it is a custom shell
echo "$(timestamp) Welcome, $(whoami). Type 'help' for information."

# Optionally log the login
log LOGIN "$@"

# Optionally log the logout
trap "trap=\"\";log LOGOUT;exit" EXIT

# Optionally check for '-c custom_command' arguments passed directly to shell
# Then you can also use ssh user@host custom_command, which will execute /root/rbash.sh
if [[ "$1" == "-c" ]]
then
    shift
    trycmd "$@"
else
    while echo -n "> " && read ln
    do
        trycmd "$ln"
    done
fi

이 실행 파일을 로그인 쉘로 설정하기 만하면됩니다. 예를 들어, 편집하여 /etc/passwd파일을 해당 사용자의 현재 로그인 쉘 교체 /bin/bash와를 /root/rbash.sh.

이것은 단순한 예일 뿐이지 만 원하는만큼 발전시킬 수 있습니다. 아이디어가 있습니다. 자신과 유일한 사용자의 로그인 셸을 변경하여 자신을 잠그지 않도록주의하십시오. 그리고 항상 이상한 기호와 명령을 테스트하여 실제로 안전한지 확인하십시오.

다음을 사용하여 테스트 할 수 있습니다 su -s /root/rbash.sh..

주의 하고 전체 명령과 일치하는지 확인하고 와일드 카드에주의하십시오! 더 나은 같은 배쉬 - 문자 제외 ;, &, &&, ||, $, 및 역 따옴표 확신 할 수 있습니다.

사용자에게주는 자유에 따라 이보다 훨씬 더 안전하지 않습니다. 몇 가지 관련 명령에만 액세스 할 수있는 사용자를 만들기 만하면되는 경우가 많았으며이 경우 이것이 정말 더 나은 솔루션입니다. 그러나 더 많은 자유를 원하십니까, 감옥과 권한이 더 적절할 수 있습니다. 실수는 쉽게 만들어지며 이미 너무 늦었을 때만 알아 차립니다.


감옥 을 설정하는 것을 볼 수 있습니다 .


이를 확인하는 또 다른 방법은 POSIX ACL을 사용하는 것입니다. 파일 시스템에서 지원해야하지만 Windows에서 동일한 제어 권한을 갖는 것과 동일한 방식으로 Linux에서 모든 명령을 세밀하게 조정할 수 있습니다 (더 좋은 UI없이 ). 링크

살펴볼 또 다른 사항은 PolicyKit 입니다.

현재로서는 확실히 Linux의 강점이 아니기 때문에 모든 것이 작동하도록하려면 꽤 많은 인터넷 검색을해야합니다.


[공개 : 아래에 설명 된 sshdo를 작성했습니다.]

로그인이 대화식이되도록하려면 제한된 셸을 설정하는 것이 정답 일 것입니다. 그러나 허용하려는 실제 명령 세트가 있고 (다른 것은 없음) 이러한 명령이 ssh (예 : ssh user @ host cmd arg blah blah)를 통해 개별적으로 실행 되어도 괜찮다면 일반 명령이 ssh가 필요할 수 있습니다. 이것은 명령이 클라이언트 측에서 스크립팅되고 사용자가 실제로 ssh 명령을 입력 할 필요가 없을 때 유용합니다.

이를위한 sshdo라는 프로그램이 있습니다. 들어오는 ssh 연결을 통해 실행할 수있는 명령을 제어합니다. 다음에서 다운로드 할 수 있습니다.

http://raf.org/sshdo/ (여기에서 매뉴얼 페이지 읽기) https://github.com/raforg/sshdo/

시도 된 모든 명령을 허용하는 교육 모드와 학습 된 명령을 영구적으로 허용하는 데 필요한 구성을 생성하는 --learn 옵션이 있습니다. 그런 다음 훈련 모드를 끌 수 있으며 다른 명령은 실행되지 않습니다.

또한 시간이 지남에 따라 요구 사항이 변경 될 때 엄격한 최소 권한을 유지하기 위해 더 이상 사용되지 않는 명령의 허용을 중지하는 --unlearn 옵션이 있습니다.

그것이 허용하는 것에 대해 매우 까다 롭습니다. 인수가있는 명령은 허용되지 않습니다. 완전한 쉘 명령 만 허용 될 수 있습니다.

그러나 명령 줄에 나타나는 숫자 (예 : 시퀀스 번호 또는 날짜 / 시간 스탬프)에서만 다른 유사한 명령을 나타내는 간단한 패턴을 지원합니다.

ssh 명령에 대한 방화벽 또는 화이트리스트 제어와 같습니다.

그리고 다른 사용자에게 허용되는 다른 명령을 지원합니다.


GNU Rush 는이를 수행하는 가장 유연하고 안전한 방법 일 수 있습니다.

GNU Rush는 제한된 사용자 셸로, svn 또는 git 저장소, scp 등과 같은 리소스에 대한 제한된 원격 액세스를 제공하는 사이트를 위해 설계되었습니다. GNU Rush는 정교한 구성 파일을 사용하여 사용자가 실행하는 명령 줄은 물론 가상 메모리, CPU 시간 등과 같은 시스템 리소스 사용에 대한 완전한 제어를 제공합니다.

참고 URL : https://stackoverflow.com/questions/402615/how-to-restrict-ssh-users-to-a-predefined-set-of-commands-after-login