web-dev-qa-db-ja.com

ログイン後にSSHユーザーを定義済みのコマンドセットに制限する方法

これはセキュリティのアイデアです。従業員は、Linuxサーバー上の一部のコマンドにアクセスできますが、すべてではありません。彼らは例えばログファイル(less logfile)にアクセスしたり、別のコマンド(shutdown.sh/run.sh)を開始したりできます。

背景情報:

すべての従業員は同じユーザー名でサーバーにアクセスします。当社の製品は「通常の」ユーザー権限で実行され、「インストール」は必要ありません。ユーザーディレクトリに解凍して実行してください。アプリケーションが「インストール」されている複数のサーバーを管理します。すべてのマシンにユーザーjohndoeがいます。従業員は、ログファイルにアクセスして確認したり、手動でアプリケーションを再起動したりするために、コマンドラインでアプリケーションにアクセスする必要がある場合があります。一部のユーザーのみがコマンドラインに完全にアクセスできます。

サーバーでppk認証を使用しています。

Employee1がログファイルにのみアクセスでき、employee2もXなどを実行できる場合は素晴らしいことです...

解決策:解決策として、accepted回答に記載されているcommandオプションを使用します。 some従業員に対して実行できる唯一のファイルとなる、独自の小さなシェルスクリプトを作成します。このスクリプトは、実行可能ないくつかのコマンドを提供しますが、他のコマンドは提供しません。述べられているようにauthorized_keysで以下のパラメーターを使用します here

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

これは私たちにとって十分なセキュリティです。コミュニティに感謝します!

78
Marcel

また、キーを許可されたコマンド(authorized_keysファイル内)に制限することもできます。

つまりユーザーはsshを介してログインせず、コマンドの制限されたセットを持ちますが、sshを介してそれらのコマンドの実行のみが許可されます(例:「ssh somehost bin/showlogfile」)

63
HD.

sshは、パスワードファイルからユーザーのシェルプログラムを使用してコマンドを実行することにより、rshの伝統に従います。

これは、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スタイルの呼び出しを受け取り、コマンド全体を1つの引数として、/bin/shが受け取るのとまったく同じ方法で呼び出します。

ご覧のとおり、ここでできることは、-c引数で呼び出された場合を認識し、文字列を解析する(パターンマッチングなどにより)スクリプトをさらに開発することです。許可された文字列は、/bin/bash -c <string>を再帰的に呼び出すことにより、実際のシェルに渡すことができます。リジェクトケースは、エラーメッセージを出力して終了します(-cが欠落している場合を含む)。

これを書く方法に注意する必要があります。非常に具体的なことのみを許可し、他のすべてを禁止する肯定的な一致のみを作成することをお勧めします。

注:rootである場合、su -s /bin/bash fooのように、suコマンドでシェルをオーバーライドすることにより、このアカウントにログインできます。 (代替シェルの選択。)非ルートはこれを行うことができません。

スクリプトの例を次に示します。ユーザーは、/gitの下のリポジトリへのsshアクセスに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プログラムgit-upload-packおよびgit-receive-packには、ユーザーがシステムにアクセスできるようにする穴やエスケープハッチがないことを信頼しています。

これは、この種の制限スキームに固有のものです。ユーザーは特定のセキュリティドメインでコードを実行するために認証されており、そのドメインをサブドメインに制限するための制限に固執しています。たとえば、ユーザーが特定のファイルに対してvimコマンドを実行して編集できるようにすると、ユーザーは:!sh[Enter]のシェルを取得できます。

29
Kaz

探しているのは Restricted Shell です。 Bashは、ユーザーが自分のホームディレクトリにあるコマンドのみを実行できる(そして他のディレクトリに移動できない)モードを提供します。

このスレッド は、少し古くなっていれば、非常にわかりやすいものであることがわかりました。

14
Vinko Vrsalovic

制限されたシェルである `rssh 'を取得する必要があります

上記の制限ガイドに従うことができますが、それらはすべて自明であり、従うのは簡単です。 「chroot jail」という用語、およびsshd/terminal構成を効果的に実装する方法などを理解してください。

ほとんどのユーザーはsshd経由で端末にアクセスするため、SSHデーモン構成ファイルであるsshd_conifgも調べて、SSH経由で特定の制限を適用する必要があります。ただし、注意してください。間違った設定の影響はおそらく恐ろしいため、実装しようとするものを適切に理解してください。

4
Chuah

独自のログインシェルを作成してみませんか?このために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でテストできます。

注意、コマンド全体と一致することを確認し、ワイルドカードに注意してください! ;&&&||$、およびバックティックなどのBashシンボルを確実に除外してください。

ユーザーに与える自由度にもよりますが、これほど安全になることはありません。いくつかの関連コマンドのみにアクセスできるユーザーを作成するだけでよく、その場合はこれが本当に優れたソリューションであることがわかりました。しかし、より多くの自由を与えたいですか、刑務所と許可がより適切かもしれません。間違いは簡単に起こり、すでに手遅れになったときにのみ気づきます。

3
Yeti

jail の設定を検討することをお勧めします。

1
tmeisenh

[開示:下記の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コマンドのファイアウォールまたはホワイトリストコントロールのようなものです。

また、さまざまなユーザーに許可されるさまざまなコマンドをサポートします。

0
raf

これを見るもう1つの方法は、POSIX ACLを使用することです。ファイルシステムでサポートする必要がありますが、Windowsで同じコントロールを使用するのと同じ方法でLinuxのすべてのコマンドをきめ細かく調整することができます(UIを改良する必要はありません) )。 リンク

もう1つ調べる必要があるのは、 PolicyKit です。

現時点ではLinuxの強みではないので、すべてを機能させるにはかなりのグーグルをする必要があります。

0
Bryan Rehbein