web-dev-qa-db-ja.com

SSHを使用してLinuxでrootとして自動コマンド実行を許可する

SSHを使用してroot特権を持つリモートサーバーでコマンドまたはスクリプトを自動実行できる適切な設定とは何ですか?

私は次のオプションを知っています(漠然と一部のオプションについてのみ)。

  • rootPermitRootLogin )による直接ログインを許可します(およびおそらくキー認証を強制します)。
  • パスワードを必要としないようにSudoを構成する(_ NOPASSWDsudoersフラグ)およびTTY(requirettyフラグ)。
  • 特定の秘密鍵で認証されたときに、特定のコマンド/スクリプトの実行を許可するようにSudoを構成します。
  • スクリプトの所有者をrootとして設定し、 setuid権限 を設定します。

しかし、最初に、これらがセキュリティに及ぼす影響が何かはわかりません。たとえば、rootログインを許可することは好ましくないことを知っています。しかし、それが時代遅れの観点ではないのかどうかはわかりません。私が理解したことから、パスワード認証は危険であるように見えます。公開鍵認証を使用すると、直接rootログインが可能になる場合があります。また、一部のオプション、特にSudoについては、必要な構成についてもわかりません。私はそれらすべてをググることはできますが、見逃してしまうセキュリティ上の考慮事項があるかもしれません。そのため、私は専門家の意見を求めています。

server-side設定を求めていることに注意してください。実行はsshのようなツールではなくプログラムによってトリガーされるため、自動client認証などを探していません。


背景:アクティブになる Stack Overflowのsshタグ は、頻繁に出てくる質問の1つです。さまざまなプログラミング言語(C#、Java)を使用してrootアカウントを使用し、リモートのUnix/LinuxサーバーサーバーでSSHを介してコマンド/スクリプト(またはSFTPサーバー)を実行しようとする人々が試みるさまざまなハッキングについて、VB.NET、Pythonなど)およびSSHライブラリ(SSH.NET、JSch、Paramikoなど)。

人々が試みる実装は、通常suまたはSudoを使用してみます。次に、パスワードの入力を求めます。そのため、実装はパスワードをコマンド入力にフィードしようとします。 suおよびSudoは、パスワードプロンプトに ターミナルエミュレーション を必要とすることが多いため、実装にはPTYが必要です。端末エミュレーションとのセッションは ANSIエスケープコード 、ページネーションなどのインタラクティブ機能を使用することが多いため、これはさらに問題を引き起こします。これらすべてにより、削除または解釈さえしようとする、さらに信頼性の低いハッキングが大量に発生します。 ANSIエスケープコードまたはページネーションを回避するのに十分な大きさのターミナルをシミュレートします。

多くのうちいくつかの例:

私は通常、これらのハックの実装に関するヘルプを提供できますが、Sudo/suを自動化するよりも優れた方法があるという提案も通常追加します。しかし、私は実際には「より良い方法」とされるものの詳細を提供することに自信がありません。

それで、私はスーパーユーザーの観点からcanonical回答を探しています。これは、スタックオーバーフローの目的で参照および適応できます。

8
Martin Prikryl

一般的な考慮事項

  • SSHを使用する場合は常に、パスワード認証を使用しないでください。つまり、/ etc/ssh/sshd_configファイルに次の行を含める必要があります。

    PermitRootLogin no
    PasswordAuthentication no
    
  • ただし、何らかの理由でpassword authenticationを使用する必要がある場合は、 sshpass のような確立された、よく知られテストされたツールを使用する必要があります。自分でパスワードをパイプで回し始めないでください。

  • pubkey authenticationを使用する場合、パスフレーズが設定ファイル内などに保存されていると、秘密鍵をパスフレーズで保護する意味がありません。攻撃者がファイルシステムの読み取りアクセス権を取得して秘密鍵ファイルを盗むことができる場合、攻撃者は設定ファイルも盗むことができます。

  • ser特権で実行できるすべてのコマンドは、root特権ではなくserで実行する必要があります。

  • セキュリティに関しては、Pythonのsubprocess.call、JavaのJava.lang.Runtime.exec、またはシェルスクリプト内のサブシェル環境に違いがないため、使用されているプログラミング言語はこの回答では考慮されません。

  • ファイアウォールを構成したり、IDS/IPSシステムを配置したりすることにより、外部の攻撃者に対するリモートホストをさらに強化することも、範囲外であるため考慮されません。

とはいえ、さまざまなシナリオを考えてみましょう。

Finite Subsetにroot権限が必要なコマンドの実行

別のユーザーを使用する必要があります(adduser --Shell /bin/rbash --disabled-password remcmdexecは制限されたシェルを持つユーザーを作成し、ローカルログインはできませんがリモートログインのみが可能です。man adduserman rbashを参照してください)。 sudoersこのユーザーが必要な有限のコマンドセットのみをリモートホストでrootman sudoersを参照)として実行できるようにするファイル:

# /etc/sudoers

remcmdexec ALL = (root:root) NOPASSWD: /usr/bin/systemctl reload some.service

これらのコマンドをSudoで実行するためにパスワードを要求することは意味がありません。ローカルログインが無効になり(--disabled-passwordパラメータ)、キーファイルを盗むことができた攻撃者も、必要なパスワード(回答の最初のセクションを参照)。

authorized_keysファイルには、たとえば、ポート転送、man sshdを参照:

restrict ssh-rsa <BASE64-PUBKEY-REPRESENTATION> remcmdexec

さらに、SSH制限の削除を防ぐために、rootによって所有され、読み取り可能ですが、remcmdexecユーザーによる書き込みはできません。

$ ls -l /home/remcmdexec/.ssh/authorized_keys
-rw-r--r-- 1 root root 739 Sep  18 22:47 /home/remcmdexec/.ssh/authorized_keys

呼び出すssh remcmdexec@remhost Sudo /usr/bin/systemctl reload some.serviceroot特権を必要とするコマンドの場合。他のすべてのコマンドについては、Sudoをスキップします。

非有限だが適切なサブセットのroot権限が必要なコマンドの実行

回答の前のセクションで示したものと同じ設定を使用できますが、sudoersファイルを調整する必要があります。

remcmdexec ALL = (ALL:ALL) NOPASSWD: ALL

これはremcmdexecが最終的にroot特権を取得する必要があるためです。 remcmdexecとしてログインできる攻撃者が、リモートホストに設定されているすべての制限を削除できるようになったことを理解してください。複雑な方法でroot =特権が設計されました。したがって、これらの制限はすべてsecurity(意欲的な攻撃者)に関しては無駄です。ただし、安全性(システム障害)に関しては無駄ではありません。

Nonfinite Setのコマンドの実行Allルート権限が必要

Sudoを使用しても意味がありません。代わりに、コマンドを実行するためにroot特権を持つユーザーとしてログインします:ssh root@remhost /usr/bin/somecmd

したがって、次の行が/ etc/ssh/sshd_configファイルに存在する必要があります。

PermitRootLogin prohibit-password

ただし、いくつかの基本的な安全性を保持するために、制限をauthorized_keysファイル内に保持します。

1
dirdi

単純なケースの大部分(つまり、Puppet/Chef/CfEngine/Ansibleのようなフレームワークが過剰である場合)には適切な解決策があると思いますが、リモートシステムの高レベルの制御が必要です。

(a)鍵ベースの認証を要求する(b)SSHが使用できる場所をロックダウンする-特にrootユーザーが使用できるIPアドレスをロックダウンする(c)この信頼関係を持つマシンが適切に保護されていることを確認する.

私は「rootとしてログインすると不快に感じる」とは思いません。「root権限を必要としないことを実行するためにrootとしてログインする」と不快に思うほどです。推測可能なパスワードを使用すると、アカウントがブルートフォースで攻撃される可能性があります。これは、競合する問題であり、rootとしてログインできるようにすることで、より広い範囲で愚かなエラーを発生させ、不審なことを非表示にすることができます悪意のある活動-アーキテクチャによっては、これは実際には意味がない場合があります。

この XKCD commic は、環境によっては、rootアカウントが侵害されても実際には問題にならない可能性があることを指摘しています。

おそらく、一般的な場合の最もシンプルで最も効果的な解決策は、適切なAllowUsersを指定してキーを制御することにより、rootとしてログインできるユーザーを正確に制限することです。 /etc/ssh/sshd.confの行。通常のユーザーを許可し、rootアクセスをロックする適切な行は次のようになります。

  AllowUsers normaluser1 normaluser2 [email protected]

もちろん、パスワードベースのログインが許可されていないこと、またはrootアカウントにパスワードがない(つまり、パスワードファイルのパスワードフィールドに「!」または「*」がある)ことが重要です。

仮定したように、実行する必要があるプログラムが1つ(または少数)の場合は、キーベースの認証を使用して特定のユーザーを設定し、必要なコマンドへの適切なSudoアクセスを許可することをお勧めします。

もちろん、データの値に応じて、アクセスをさらに「ロックダウン」するために実行できる多くのことがあります-selinux、リモートロギング、制限されたシェル、時刻制約、ログイン直後の通知、fail2banのようなアクティブなログの監視(オプションであると私が考えるネットワークの制限に加えて)はすべてソリューションの一部になります。とはいえ、吹き飛ばして簡単に再作成できるシステムを単純に制御している場合、これの多くはやりすぎです。

セキュリティはレイヤーで構築されていることに注意してください。ルートアクセスを取得できるようにするには、アカウントがいくつかのレイヤーを通過する必要があります。アクセスのロックダウン、SSH秘密鍵、ファイアウォール、時間制限[および最小限のアクセスの原則、つまり必要なものへのアクセスのみを提供し、それ以上のロギング、バックアップ]はすべて、優れたセキュリティの一部として一緒に機能する必要があります。

追加-Sudoアクセス

Sudoは、通常のユーザーが管理者特権で特定のコマンドを実行できるようにするメカニズムであり、範囲が非常に柔軟で多様です。 Sudoの概要はここでは適切ではありませんが(ほとんどのディストリビューションでman Sudoと入力すると十分に文書化されます)、適切な手順は次のようになります-

  1. / etc/sudoersの編集-Linuxのほとんどのバリアントには、「visudo」と呼ばれる特別なプログラムがあり、rootとして実行する必要があります。システムエディターを使用して/ etc/sudoersを編集するのとほぼ同じです(これは別の方法です)これ-おそらくあちこちにありますが)

  2. 適切な行を追加/変更して、特定のユーザーが特定のことを行えるようにします。たとえば、パスワードを入力せずにディレクトリをマウントできるようにしたい場合は、次のような行を入力します。

    username    ALL=/sbin/mount NOPASSWD: ALL
    

次に、このコマンドを実行するには、適切なユーザーが次のようなものを実行します

  Sudo mount /dev/xxx /path/to/mount

複数のコマンドに対して複数の行をリストし、使用するのではなくグループを使用できます-sudoersはかなり柔軟なサブシステムです。多くのディストリビューションでは、/ etc/sudoers.dのようなサブディレクトリにコマンド付きのファイルを追加することも可能です。

3
davidgo

以下はUnix Stackexchangeの投稿からの回答です
パスワードなしでsshコマンドをSudoコマンドでリモート実行する方法

この方法を使用すると、サーバーの管理者は、パスワードを指定せずに、アカウントで1つのコマンドをSudoとして実行できます。コマンドはおそらくスクリプトの呼び出しであり、アカウントで実行した場合にのみ許可されます。許可されたコマンドは引数を含めて完全に指定されているので、この方法はかなり安全だと思います。

sudoにコマンドのパスワードをスキップするように指示できます。

例えば/etc/sudoers

archemar  ALL = (www-data) NOPASSWD: /bin/rm -rf /var/www/log/upload.*

これにより、

Sudo -u www-data /bin/rm -rf /var/www/log/upload.*

パスワードなしのアーキマーとして。

ご了承ください

Sudo -u www-data rm -rf /var/www/log/upload.*

rm/bin/rmと異なるため、機能しません(パスワードを要求します)。

必ずvisudoコマンドを使用して/etc/sudoersを編集してください。

上級レベルに達したら、/etc/sudoers.dに独自のSudoファイルを作成することができます。

2
harrymc

同様の状況での私のセットアップは/home/blesseduser/.ssh/authorized_keysです。

no-port-forwarding,command="/usr/local/bin/audited-command" ssh-rsa AAAAB...

そのスクリプト内で、SSH_ORIGINAL_COMMAND変数のサニタイズ(およびいくつかの監査)を実行し、ユーザーが実行したいコマンドを抽出します。すべての許可されたコマンドは、/home/blesseduser/binへのシンボリックリンクとしてユーザー/usr/local/bin/Sudo-runnerにあります。

#!/bin/bash -e
Sudo /usr/local/bin/$(basename $0) "$@"

シンボリックリンクは、sudoersファイルからスクリプトによって生成されます。コマンドが存在しない場合は、彼のbinディレクトリの内容がリストされます。ポート転送を制限しないと、悪いことが起こります。

1
brablc

セキュリティに関する考慮事項についての回答を以下に示します。他の回答では対応されていないと思います。

SSHを使用してroot権限を持つリモートサーバーでコマンドまたはスクリプトを自動実行できる適切な設定とは何ですか?

これには複数の部分があります。昇格された特権(root)で単一のスクリプトまたはコマンドの実行を許可し、SSHを使用します。これらは必ずしも依存しているわけではありません。

  • ルート(PermitRootLogin)による直接ログインを許可します(キー認証を強制することもできます)。

これにより、誰でも完全なroot権限を持つことができます(単一のコマンド/スクリプトに限定されません)。また、パスワードなどを使用して、誰でもリモートからシステムに侵入しようとすることもできます。

  • パスワード(sudoerのNOPASSWDフラグ)およびTTY(requirettyフラグ)を必要としないようにSudoを構成する。

これにより、ログインしている限り、すべてのユーザーが完全なroot権限を持つことができます。他のユーザーアカウントに侵入する自動化された試みは少なくなりますが、セキュリティの観点からは、rootログインを許可するよりもはるかに優れています。

  • 特定の秘密鍵で認証されたときに、特定のコマンド/スクリプトの実行を許可するようにSudoを構成します。

これがどのように実装されるかわかりません-SudoはSSHキーについて何も知りません。少なくとも私が知っているSudoの亜種は知りません。

特定のコマンド/スクリプトの実行のみを許可するようにSudoを構成することは、セキュリティの観点からはるかに優れています(より制限的であるため)。

  • スクリプト/コマンドの所有者をrootとして設定し、setuid権限を設定します。

これにより、すべてのユーザーがこのスクリプトをrootとして実行できるようになります。これを特定のユーザーに制限することはできません。setuidビットには、潜在的なセキュリティ上の弱点があります。


結局のところ、単一のcanonical回答があるとは思いません。最善の解決策は、状況や要件によって異なります。したがって、すべてのセキュリティ関連の場合と同様に、最初に座って要件を詳しく説明します。どの程度寛容で柔軟になりたいですか。実際のユースケースは何ですか?システムをどのくらい緊密に拘束する必要がありますか?等。

とはいえ、あなたが言及していない非常に制限的な代替手段を追加しましょう:

その特定のスクリプト/コマンドを実行するためだけに使用される特定のユーザーアカウントを作成します。このユーザーへのSSHログインを、キーペアでのみ許可します(パスワードを無効にします)。このユーザーがrootとして特定の/ scriptコマンドを実行できるようにSudoを構成します。

これには、次のセキュリティ上の影響があります。

  • 外部のハッカーは、ブルートフォースを使用して特定のアカウントのパスワードを解読することはできません。

  • このアカウントへのアクセス権を取得したユーザーは、単一のスクリプト/コマンドのみを実行できます。

  • 他のユーザーは、この構築を通じて昇格された特権を取得しません。

  • Setuidの弱点はありません。

1
dirkt

Ansible は、自動化およびリモートホストでの最適なツールです。 Ansibleの使用可能なメソッドを使用すると、リモートマシンでスーパーユーザー(root)としてコマンドを実行できます--become & --become_methodは、sudoのenable permit rootログインとNOPASSWDなしでSudo経由でrootに切り替えます。

さらに、クライアントホストにインストールする必要はありません—唯一の要件は、リモートホストがPython> = 2.7。

AFAIK Ansibleには、SSHとParamikoを使用する2つの方法があります。

0
Das D