要するに:
- cftotalcontrolは、他のインフラストラクチャノードへのSSHアクセスを使用して特別なアカウント環境を作成し、大量のルーチンタスクを並行して実行するためのモジュールです。
- インフラストラクチャへの安全で制御されたアクセスを組織化する理論、実装から抽象化。
- 特定のソリューションの実際のアプリケーションについて説明します。
テーマサイクル:
- パートI:ネットワークおよびネットワークフィルター(cfnetwork + cffirehol)
- パートII:アクセスと標準環境(cfauth + cfsystem)
- パートIII:Puppet Server(cfpuppetserver)のインストール
- パートIV:集中管理(cftotalcontrol)
- パートV:データベース(cfdb)
- パートVI:現在のブラックリストと保護されたノッキング
インフラストラクチャへのアクセスを整理する概念
もちろん、この記事は網羅的なガイドではありません。 それでも、わかりやすくするために、サーバーへの管理者アクセスの典型的な例を考えてみましょう。各管理者は自分の秘密鍵を持ち、管理しているサーバーに直接アクセスします。
このアプローチにはいくつかの欠点があります。
- 各サーバーの各管理者の公開鍵を登録する必要。
- Puppetを介して新しいキーを処方することは問題ではありませんが、利用可能なすべてのシステムで実際の構成変更が必要です。
- 管理者の任意の場所から各システムへのエンドツーエンドアクセスを整理する必要性。
- 多くの場合、SSHエージェント転送はこれに対して危険です。
- DNATを使用して、完全に柔軟性のないソリューションに出くわすこともあります。
- 各システムをノックしてすべての管理IPおよび/またはポートを開くことも、やや疑わしい決定です。
- 各管理者は、共通のまたは独自のSSH構成とルーチンタスク用の一連のスクリプトを手動で維持し、時間通りに更新する必要があります。 これにより、エラーが発生することが保証されます。
- システムの数が増えると、インフラストラクチャ内のアクセス組織の監査は重要なタスクに変わります。
- 直接的な集中管理(実施)は決定されていません。
- もちろん、イベントモデルに基づいたさまざまなソリューションがありますが、その安全性には疑問が生じます。 Puppet自体には、このためのMCollectiveがあります。
比較のために、ドメイングループ形式の条件付きインフラストラクチャ管理者によるアクセスを検討してください。
このアプローチの呼び方は異なりますが、何らかの形で、統合された商用ソリューションに長い間存在していました。 通常、これは特権ユーザーのドメイングループを通じて実装され、インフラストラクチャシステムのすべてまたは一部にアクセスできます。 このアプローチには、前の方法のいくつかの欠点(2、3、および5)に加えて明らかなニュアンスがあります-認証および許可サービスの常時可用性の必要性(もちろん、キャッシュなしではありません)。 ところで、PAMとLDAPを使用して似たようなものを整理することはそれほど難しくありません。
そのため、 cftotalcontrol
実装されたアクセス概念の最下部にすぐにcftotalcontrol
。
本質的に、このアプローチは以前の2つの方法を組み合わせたものです。
- アクセスには、追加のサービスなしでSSHのみが使用されます。 Puppetは、認証キーが配布される場合にのみ使用されます。
- 管理ユーザーが導入されます-管理者が接続されているインフラストラクチャの特に安全なノード上の特別なアカウント。 抽象的には、そのようなアカウントは管理者のグループです。
- システム自体が、管理ユーザーの中間ノードとSSHクライアントを構成します。 認証キーの最小数はシステムに登録されており、ノードの数と管理者の数の両方の増加に応じて適切に拡張されます。
- 管理者の職場では、管理アカウントへの接続を除き、構成は必要ありません。
- 完全に制御されたアカウントにより、ジャーナリングで管理者のアクションを簡単に監査できます。 特に特権の低いグループに役立ちます。
- 多数のシステムを実行するための既製のソリューションがあります。
- 使用可能なすべてのノードでコマンドを実行できます。
- PuppetDBでの要求に応じて、静的または動的にグループ内のノードを定義できます。
- 対話モードでコマンドを順番に実行できます。
- 並列接続の最大数を制限してコマンドを並行して実行し、完了時にコマンドの出力を受け取ることができます。
- ルーチンタスクの場合、各ノード、ノードのグループ、およびすべてのノードに対してテンプレートコマンドが作成されます。 標準コマンドのリストは次のとおりです。
- Puppetの強制展開。
- パッケージリポジトリからメタ情報を更新します。
- システム更新。
- 古い未使用パッケージの削除。
- 構成で指定された任意のコマンド。
- 特権「合計」制御( Total Control Users )の代わりに、低特権制御ユーザー( Scoped Control Users )を作成することができます。
- このようなユーザーは、この領域に属していると明示的にマークされているシステム( Control Scope )のみにアクセスできます。
設置
インフラストラクチャは、 cfnetwork
、 cfauth
およびcfpuppetserver
モジュール上に構築されますが、 cftotalcontrol
は競合せずに混在環境で完全に動作することがcftotalcontrol
されています。
まず、平和にスリープするには、少なくとも1つのSSHキーを保持することをおcfauth
ます。このキーは、 cfauth
モジュールを通じてすべてのシステムに登録されますが、「家庭」のニーズには使用されません。 もちろん、緊急時にIPMIを介してハードウェアにアクセスし、シリアル/ GUIコンソールを介して仮想マシンにアクセスすることを忘れないでください。
次に、 例を見てください:
-
cftotalcontrol
モジュールをcftotalcontrol
追加します
mod 'codingfuture/cftotalcontrol'
- すべてのノードの
classes
リスト(common.yaml
ファイル)
classes: # , "" - cftotalcontrol::auth
- 管理ユーザーがいるノード(以下、「管理ノード」と呼びます)の構成の
classes
リストへ
classes: # - cftotalcontrol
- Puppetデプロイメント(
/opt/puppetlabs/bin/puppet agent --test
)を次の順序で実行する必要があります。
- 管理ノードにPuppetをデプロイします-管理ユーザーとその環境を作成します。
- 他のすべてのノードにPuppetをデプロイします-これにより、管理ユーザー設定の自動生成のためにPuppetDBにシステムが登録されます。
- 管理ユーザーの下に移動し、秘密キーを生成します(自動的に提供されます)。 生成後、Puppetのデプロイメントが自動的に呼び出され、公開キーがPuppetDBにエクスポートされます。
- すべてのシステムにPuppetをもう一度展開します-管理ユーザーの公開キーはどこにでも登録され、ユーザーはすべてのノードにアクセスできる構成を作成します。
- この一連のアクションは、初期インストール時にのみ必要です。 さらに、新しいキーを生成するときにキーの更新が自動化されます。
これらの簡単な操作の後、特別にcftotalcontrol
れたBash環境とクライアントSSH構成を持つcftotalcontrol
ユーザーが、 cftotalcontrol
クラスを持つノード上に作成されます。 cftotalcontrol::control_user
て、ユーザー名を非標準に変更することを強くお勧めしcftotalcontrol::control_user
。
cfauth
すべての標準管理キーもこのユーザーに登録されますが、イデオロギー的に正しいアクセスを整理するには、 cftotalcontrol::ssh_auth_keys
のみ管理キーを登録する必要があります。 もちろん、まずすべてが機能し、すべてのサーバーがアクセスできることを確認する必要があります。
SSHプロキシアクセス
大規模なインフラストラクチャでは、ほとんどの場合、システムのごく一部のみが外の世界を覗き込み、それらを通して他のシステムへのアクセスを整理する必要があります。
SSHクライアントでは、これは値ssh -W target:port proxyhost
したProxyCommand
オプションを使用して簡単に実装できます。 この方法は、リモートシステムで管理者の秘密鍵を盗むことができるSSHエージェント転送を使用するよりも安全です。 原則として、これらの技術的詳細の知識は、 cftotalcontrol
モジュールを使用するために必要ではありません。 必要なすべての構成は、 cftotalcontrol::pool_proxy
基づいて生成されcftotalcontrol::pool_proxy
。
もちろん、各ターゲットノードのプロキシノードをリストするのは非効率的であるだけでなく、新しいシステムを追加するときに頻繁にエラーが発生することにもなります。 代わりに、前のパートで説明したファクトcf_location
およびcf_location_pool
が「ナビゲーション」に使用されます。 通常、これらのファクトは、 cf_gen_puppet_client_init
クライアント初期化スクリプトの初期インストール中に設定されますが、 cfsystem
モジュールのパラメーターを使用して変更できます。
SSHクライアント構成を生成するとき、プロキシノードは次の順序で検索されます。
-
$cftotalcontrol::pool_proxy["$cf_location/$cf_location_pool"]
-
$cftotalcontrol::pool_proxy["$cf_location"]
-
$cftotalcontrol::pool_proxy["$certname"]
-はい、例外的なケースでは、ターゲットノードのフルネームに基づいてプロキシノードを示すための抜け穴が残っていました。
もちろん、このすべてがcfnetwork
統合されており、不必要なジェスチャーをすることなく、必要なものすべてをネットワークフィルター構成に追加します。
ノードグループ
通常、同じタイプの特定のタスクは、特定の属性(OS、サービスのセット、ロールなど)を持つノードでのみ実行する必要があります。 ノードの分離によって庭をブロックしないようにするには、 cftotalcontrol::host_groups
してこれを簡単に実行cftotalcontrol::host_groups
。これは、連想配列です。 puppetdbqueryモジュールの説明を読むことができます。
例:
cftotalcontrol::host_groups: puppetserver: "Package['puppetserver']" infra: "cf_location_pool = 'infra'" custom: - 'web.example.com' - 'db.example.com'
標準ルーチンコマンド
それ以上の説明なしで明確にする必要があります
cftotalcontrol::standard_commands: helloworld: 'echo "Hello world!"' gethostname: 'hostname --fqdn'
中央管理環境の紹介
これは、仮想管理者の投稿が始まる場所です。 最初のエントリで、システムは秘密キーを生成することを親切に提供し、その後、SSHエージェントを起動して秘密キーを追加し、同時にパスワードを要求します。
しかし、人生が蜜に思えないように、システムはcftotalcontrol::ssh_old_key_days = 180
日よりも古い秘密キーを更新するようにcftotalcontrol::ssh_old_key_days = 180
ます。 入らない場合でも、cronは同じことを行い、怒って毎日の手紙を送ります。 cftc_gen_key
コマンドを使用して新しいキーを生成できます。このコマンドは、他のアクションを必要とせずに、すべての監視対象ノードに自動的にインストールします。 何か問題が発生した場合、古いキーは、新しいキーが生成された時点で、秒単位のUNIXタイムスタンプの形式で、拡張子が~/.ssh/
常にあり~/.ssh/
。 これは、接続エラー、Puppet設定、または些細なオフライン制御システムが原因で発生する可能性があります。
一般に、内部では次のことが発生します。
-
~/.bash_aliases
接続がある行が必要です~/.cftotalcontrol_aliases
-
~/.cftotalcontrol_aliases
-Bash環境のすべての魔法 -
~/.ssh/cftotalcontrol_config
正しいユーザー、ポート、およびProxyCommand
持つ特別なSSHProxyCommand
。 言うまでもなく、データもPuppetDBから取得されます。 -
~/.ssh/cftchostsall
すべての制御対象ノードのリスト。 -
~/.ssh/cftchosts_${grp}
-特定のグループの制御されたノードのリスト。 -
~/.ssh/cftc_id_${ssh_key_type}
-現在の秘密鍵。 -
~/.ssh/cftc_id_${ssh_key_type}.${backup_timestamp}
-通常の場合、どこにも登録されていない古い秘密鍵。
ユーティリティBash環境コマンド:
-
cftc_ssh
必要なすべてのパラメーターを使用したSSHの正しい起動。 -
cftc_scp
すべての必要なパラメーターを使用したSCPの正しい起動。 -
cftc_gen_key
秘密キーの手動再生成(キーがない場合に入力すると自動的に呼び出されます)。 -
cftc_add_key
-SSHエージェントを起動し、秘密鍵を追加します(入力時に自動的に呼び出されます)。 -
cftc_check_old_key
古いキーの手動検証(入力時に自動的に呼び出され、cronによって毎日呼び出されます)。
ノードの直接作業:
-
ssh_${hostname} [$cmd]
-特定のホストに移動するか、対話モードで任意のコマンドを実行します。 注:${hostname}
でピリオドはアンダースコアに置き換えられます -
ssh_${hostname}_{stdcmd} [args]
-特定のノードで標準コマンドの1つを実行します。 -
ssh_masscmd {cmd}
-すべてのノードで対話モードで{cmd}
順番に実行します。 -
ssh_mass_{stdcmd} [args]
-すべてのノードで標準モードのいずれかを対話モードで順番に実行します。 -
pssh_masscmd {cmd}
-すべてのノードで並行して{cmd}
を実行します。 -
pssh_mass_{stdcmd} [args]
-すべてのノードで標準コマンドの1つを並行して実行します。 -
sshgrp_{group}_*
およびpsshgrp_{group}_*
は、以前の「バルク」のものと同じですが、ノードの限定された名前付きグループ用です。
重要な環境変数:
-
PSSH_COUNT=$cftotalcontrol::parallel
並列呼び出しの最大数。 大きな負荷がプロキシノードに送られ、MaxStartupsオプションによって接続がハッキングされる可能性があることを覚えておく価値があります。 残念ながら、ControlMasterを使用したアプローチは、多数の接続で成果を上げません。 多重化はかなり平凡に機能します-連続通話の高速化に適しています。 -
PSSH_OPTS=-i
-parallel-ssh
追加パラメーター(pssh) -
SSH_OPTS=
追加パラメーター -
SCP_OPTS=
追加パラメーター
標準コマンドは、パスワードなしでsudo
経由で呼び出すためにcfauth
に追加されたコマンドと同じです。
-
aptupdate
-sudo /usr/bin/apt-get update
-
aptdistupgrade
-sudo DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get dist-upgrade -o Dpkg::Options::="--force-confold" -qf
-
aptautoremove
-sudo DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get autoremove
-
puppetdeploy
-sudo /opt/puppetlabs/puppet/bin/puppet agent --test
- 使用例:
pssh_mass_aptupdate
、psshgrp_grpname_aptdistupgrade -sy
、ssh_host_example_com_puppetdeploy
制限付き管理者を作成する
遅かれ早かれ、特定の管理者権限を人々に与える必要があります。 その責任範囲はインフラストラクチャ全体の管理ではありません。 これには、DevOps、DBA、リリースマネージャーなどが含まれます。 一部のクラスタリングツールは、仲間のノードへのSSHアクセスにも依存しています。これは、パスワードなしで秘密キーを自動生成するなど、同じモジュールで簡単に構成できます。
つまり、特権のない管理者を作成する標準的な方法は、 cftotalcontrol::extra_users
。このcftotalcontrol::extra_users
、 cftotalcontrol::admin
ようなリソースを正しく作成します。 「トータル」コントロールのユーザーとの特別な違い:
- ユーザー名は、対応する管理領域の名前です。
- 「_proxy」という接尾辞を持つ同じ名前のユーザーがすべての中間ノード上に作成され、接続とPuppetの強制展開(キーの更新時に使用)のみにアクセスできます。
残っているのは、ターゲットノードを指定する方法の問題です。 これは、 cftotalcontrol::auth::control_scope
。 複数の球体を同じノードに一度に掛けることができます。 例:
cftotalcontrol::auth::control_scope: - web - devops
cftotalcontrol
モジュールのcftotalcontrol
クラスcftotalcontrol
-
pool_proxy = {}
。 ペアキー=> "name.proxy.node"。 キー形式:
- 「$ {cf_location} / $ {cf_location_pool}」
- 「$ {cf_location}」
- 「$ {certname}」
-
control_user = 'cftcuser'
は、制御ユーザーの名前です。 -
control_home = undef
ホームフォルダー。 デフォルト:/home/$control_user
。 -
host_groups = {}
-タイプ(p)sshgrp_*
コマンドのhost_groups = {}
グループの定義。 キーはグループの名前です。 値:
- 配列-グループ内のノードによる静的リスト
- 文字列-動的リストのPuppet DBクエリ
-
parallel = 10
同時SSH呼び出しの数。 -
standard_commands = {}
-リストに追加する標準のルーチンコマンド。 -
ssh_key_type = 'rsa'
秘密鍵のタイプ。 新しいタイプの「ed25519」にも注意を払う価値があります。 -
ssh_key_bits = 4096
秘密キーの長さ、ed25519では無視されます。 -
autogen_ssh_key = false
パスワードなしで秘密鍵を自動的に生成します(「完全な」制御には価値がありません)。 -
ssh_old_key_days = 180
アカウントの入力時にシステムがcronで泣き出すまでの秘密鍵の年齢。 -
ssh_auth_keys = undef
-cfauth
指定されたもの以外のユーザーへの追加アクセスキー -
extra_users = undef
インフラストラクチャへのアクセスが制限されている追加ユーザー=> cftotalcontrol::admin
クラスcftotalcontrol::auth
-
control_scope = []
-このシステムに適用される制限付きアクセスゾーンの名前を持つ文字列または文字列の配列
タイプcftotalcontrol::admin
通常、 cftotalcontrol::extra_users
介して初期化されます。 extra_users
自体を除き、すべてのパラメーターはcftotalcontrol
と同じです。
-
control_scope = undef
該当する場合、制限区域の名前。extra_users
を介して作成された場合、ユーザー名extra_users
一致します。 指定しない場合、無制限のアクセス権を持つユーザーが作成されます。