SSHを使用してroot
特権を持つリモートサーバーでコマンドまたはスクリプトを自動実行できる適切な設定とは何ですか?
私は次のオプションを知っています(漠然と一部のオプションについてのみ)。
root
( PermitRootLogin
)による直接ログインを許可します(およびおそらくキー認証を強制します)。Sudo
を構成する(_ NOPASSWD
のsudoers
フラグ)および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回答を探しています。これは、スタックオーバーフローの目的で参照および適応できます。
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システムを配置したりすることにより、外部の攻撃者に対するリモートホストをさらに強化することも、範囲外であるため考慮されません。
とはいえ、さまざまなシナリオを考えてみましょう。
別のユーザーを使用する必要があります(adduser --Shell /bin/rbash --disabled-password remcmdexec
は制限されたシェルを持つユーザーを作成し、ローカルログインはできませんがリモートログインのみが可能です。man adduser
とman rbash
を参照してください)。 sudoersこのユーザーが必要な有限のコマンドセットのみをリモートホストでroot(man 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.service
root特権を必要とするコマンドの場合。他のすべてのコマンドについては、Sudo
をスキップします。
回答の前のセクションで示したものと同じ設定を使用できますが、sudoersファイルを調整する必要があります。
remcmdexec ALL = (ALL:ALL) NOPASSWD: ALL
これはremcmdexecが最終的にroot特権を取得する必要があるためです。 remcmdexecとしてログインできる攻撃者が、リモートホストに設定されているすべての制限を削除できるようになったことを理解してください。複雑な方法でroot =特権が設計されました。したがって、これらの制限はすべてsecurity(意欲的な攻撃者)に関しては無駄です。ただし、安全性(システム障害)に関しては無駄ではありません。
Sudo
を使用しても意味がありません。代わりに、コマンドを実行するためにroot特権を持つユーザーとしてログインします:ssh root@remhost /usr/bin/somecmd
したがって、次の行が/ etc/ssh/sshd_configファイルに存在する必要があります。
PermitRootLogin prohibit-password
ただし、いくつかの基本的な安全性を保持するために、制限をauthorized_keysファイル内に保持します。
単純なケースの大部分(つまり、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と入力すると十分に文書化されます)、適切な手順は次のようになります-
/ etc/sudoersの編集-Linuxのほとんどのバリアントには、「visudo」と呼ばれる特別なプログラムがあり、rootとして実行する必要があります。システムエディターを使用して/ etc/sudoersを編集するのとほぼ同じです(これは別の方法です)これ-おそらくあちこちにありますが)
適切な行を追加/変更して、特定のユーザーが特定のことを行えるようにします。たとえば、パスワードを入力せずにディレクトリをマウントできるようにしたい場合は、次のような行を入力します。
username ALL=/sbin/mount NOPASSWD: ALL
次に、このコマンドを実行するには、適切なユーザーが次のようなものを実行します
Sudo mount /dev/xxx /path/to/mount
複数のコマンドに対して複数の行をリストし、使用するのではなくグループを使用できます-sudoersはかなり柔軟なサブシステムです。多くのディストリビューションでは、/ etc/sudoers.dのようなサブディレクトリにコマンド付きのファイルを追加することも可能です。
以下は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
ファイルを作成することができます。
同様の状況での私のセットアップは/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
ディレクトリの内容がリストされます。ポート転送を制限しないと、悪いことが起こります。
セキュリティに関する考慮事項についての回答を以下に示します。他の回答では対応されていないと思います。
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の弱点はありません。
Ansible は、自動化およびリモートホストでの最適なツールです。 Ansibleの使用可能なメソッドを使用すると、リモートマシンでスーパーユーザー(root)としてコマンドを実行できます--become & --become_method
は、sudoのenable permit rootログインとNOPASSWDなしでSudo経由でrootに切り替えます。
さらに、クライアントホストにインストールする必要はありません—唯一の要件は、リモートホストがPython> = 2.7。
AFAIK Ansibleには、SSHとParamikoを使用する2つの方法があります。