これは、アドベントカレンダー11日目の記事です。
時空のゆがみ。
さて、前回まででシンプルなコンフィグレーションをプッシュで反映させる方法を見てきました。
今回は、センシティブな情報。そう、パスワードをどうやってリモート先に安全に伝搬するかです。
センシティブな情報とは
PowerShell DSCの中では、[PSCredential]です。つまり、パスワードなどの機密情報です。
PowerShellには[PSCredential]という型があるので、これがセンシティブな情報となります。
$Passwordのような平文、$Passwordのようなやり方はベストプラクティスからは大きくずれます。やってる人はすぐやめましょう。というレベルで本当に今すぐやめてください。当然DSCでもそれらは非推奨です。当然です。
どうやって暗号化するの
暗号化は、公開鍵暗号を用います。ざっくりとした詳細はこちらに。
さくっと流れを抑えましょう。
ノード
DSCサーバーから取得したMOFファイルの暗号化データを自分の秘密鍵でデコードします。
- 秘密鍵(*.pfx) を、Cert:\LocalMachine\My** にインポート
- この秘密鍵から公開鍵(***.cer)をエキスポート
- この鍵のThumbPrintをノードのLCMにてCertificateIdに指定
DSCサーバー
ノードでエキスポートした公開鍵を使って対称させます。
- DSCサーバーの任意のパスに公開鍵ファイル(****.cer)を設置
- DSCサーバーの Cert:\LocalMachine\My に公開鍵をインポート
- インポートした公開鍵のThumbprintを取得
あとは、DSCサーバーの公開鍵をコンフィグレーション実行時に指定するだけです。
- コンフィグレーションに
PSCredentialでセンシティブ情報を渡す - コンフィグレーションの実行時に、
コンフィグレーションデータで、公開鍵ファイルパスとThumbPrintを渡す
今回はわかりやすいようにローカルマシンで、ノード、DSCサーバー共に動かします。
暗号化をしない
暗号化しないやり方はBest Practiceではありません
先に、暗号化をしないでコンフィグレーションを扱ってみましょう。
さらっと書いてみます。
コンフィグレーションNoEncryptionの実行時にエラーで停止します。
ConvertTo-MOFInstance : 型 'User' のプロパティ 'Password' の処理中に System.InvalidOperationException エラーが発生しました: 暗号化されたパスワ ードを変換してプレーンテキストとして格納することが許可されるのは、PSDscAllowPlainTextPassword が true に設定されている場合だけです。 At line:8 char:5 + User 発生場所 行:164 文字:16 + $aliasId = ConvertTo-MOFInstance $keywordName $canonicalizedValue + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [Write-Error]、InvalidOperationException + FullyQualifiedErrorId : FailToProcessProperty,ConvertTo-MOFInstance 構成 'NoEncryption' を処理中にエラーが発生しました。 発生場所 C:\Windows\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration .psm1:2088 文字:5 + throw $errorRecord + ~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (NoEncryption:String) []、InvalidOperationException + FullyQualifiedErrorId : FailToProcessConfiguration
コンフィグレーションデータを渡す
コンフィグレーションデータを使って、コンフィグレーションデータにコンフィグレーションデータを渡して実行します。コンフィグレーションデータが何か忘れた人は8日目をどうぞ。
コンフィグレーションデータを指定して書きなおします。
MOFが出力されましたね。
ディレクトリ: C:\test Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 2014/12/16 4:09 1382 localhost.mof
MOF を見てみよう
生成されたMOFを見てみます。
あら、パスワードが丸見えですね。困ったものです。そう、Passw0rdsというのが今回指定したパスワードでした。
このままStart-DSCConfigurationを実行してみましょう。
設定されました。
詳細: パラメーター ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName ' = root/Microsoft/Windows/DesiredStateConfiguration' を使用して操作 'CimMethod の呼び出し' を実行します。 詳細: コンピューター DSCSERVER、ユーザー SID S-1-5-21-2427780029-983018638-525960072-500 から LCM メソッドが呼び出されました。 詳細: [DSCSERVER]: LCM: [ 開始 設定 ] 詳細: [DSCSERVER]: LCM: [ 開始 リソース ] [[User]NoEncryption] 詳細: [DSCSERVER]: LCM: [ 開始 テスト ] [[User]NoEncryption] 詳細: [DSCSERVER]: [[User]NoEncryption] test という名前のユーザーが存在しません。 詳細: [DSCSERVER]: LCM: [ 終了 テスト ] [[User]NoEncryption] 2.2810 秒かかりました。 詳細: [DSCSERVER]: LCM: [ 開始 設定 ] [[User]NoEncryption] 詳細: [DSCSERVER]: [[User]NoEncryption] ユーザー test の構成が開始されました。 詳細: [DSCSERVER]: [[User]NoEncryption] ユーザー test が正常に作成されました。 詳細: [DSCSERVER]: [[User]NoEncryption] ユーザー test の構成が正常に完了しました。 詳細: [DSCSERVER]: LCM: [ 終了 設定 ] [[User]NoEncryption] 2.2820 秒かかりました。 詳細: [DSCSERVER]: LCM: [ 終了 リソース ] [[User]NoEncryption] 詳細: [DSCSERVER]: LCM: [ 終了 設定 ] 詳細: [DSCSERVER]: LCM: [ 終了 設定 ] (4.5790 秒)。 詳細: 操作 'CimMethod の呼び出し' が完了しました。 詳細: 構成ジョブが完了するまでにかかった時間は 4.619 秒です
公開鍵暗号を行う
では証明書を使った公開鍵暗号を試しましょう。今回は、自己証明書でやりましょう。
手段はいろいろあります。好きな方法でどうぞ。
- mkcert
New-SelfSignedCertificate- Active Directoryの証明書機関
- GEO証明書
コンフィグレーションを書く
さて細かくいっても仕方ないでしょう。コンフィグレーションデータとコンフィグレーションはこんな感じです。
ここまで読んできた方にはもう簡単ではないでしょうか。コンフィグレーションデータ内部で以下を行っています。
PSDscAllowPlainTextPasswordにPSDscAllowPlainTextPasswordを指定CertificateFileに公開鍵CertificateFileファイルへのパスを指定Thumbprintに、公開鍵のThumbprintを指定
PSDscAllowPlainTextPassword = $false CertificateFile = "c:\test.cer" Thumbprint = (ls Cert:\LocalMachine\My | where Subject -eq "CN=test").Thumbprint
もう一点は、LCMを事前に設定していなかった前提として、コンフィグレーションのLocalConfigurationManagerセクションで、LocalConfigurationManagerにConfiguraionDataで指定したThumbprintを渡しています。事前にLCMへLocalConfigurationManagerを指定してあれば、当然コンフィグレーションで一々指定する必要はなく省略してokです。むしろ事前にLCM設定しておきましょう。
LocalConfigurationManager
{
CertificateId = $AllNodes.ThumbPrint
}
MOF の生成
さて、MOFを生成しましょう。当然ですが、コンフィグレーション実行時にコンフィグレーションデータを渡してください。
LCM用の、.meta.mofとコンフィグレーション実態の.meta.mofが生成されましたね。
ディレクトリ: C:\test Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 2014/12/16 4:25 2128 localhost.mof -a--- 2014/12/16 4:25 892 localhost.meta.mof
MOFを見てみよう
先ほど暗号化しなかったMOFには、パスワードが生でかかれていて怖気が走りましたね。今回は暗号化されているでしょうか。
問題ありませんね。無事暗号化されています。
では、これを適用してみましょう。
LCMを設定していなかった場合
今回のように事前にLCMを設定していなかった人は、コンフィグレーション設定前に対象ノードのLCMを設定します。久々にみたSet-DSCLocalConfigurationManagerですね。
ちなみに、.meta.mofの中身は.meta.mofの設定だけです。
コンフィグレーションの適用
では、ノードをPUSHであるべき状態にしましょう。
詳細: パラメーター ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName ' = root/Microsoft/Windows/DesiredStateConfiguration' を使用して操作 'CimMethod の呼び出し' を実行します。 詳細: コンピューター GREENDSCSERVER、ユーザー SID S-1-5-21-2427780029-983018638-525960072-500 から LCM メソッドが呼び出されました。 詳細: [DSCSERVER]: LCM: [ 開始 設定 ] 詳細: [DSCSERVER]: LCM: [ 開始 リソース ] [[User]Encryption] 詳細: [DSCSERVER]: LCM: [ 開始 テスト ] [[User]Encryption] 詳細: [DSCSERVER]: [[User]Encryption] test という名前のユーザーが存在しません。 詳細: [DSCSERVER]: LCM: [ 終了 テスト ] [[User]Encryption] 2.3750 秒かかりました。 詳細: [DSCSERVER]: LCM: [ 開始 設定 ] [[User]Encryption] 詳細: [DSCSERVER]: [[User]Encryption] ユーザー test の構成が開始されました。 詳細: [DSCSERVER]: [[User]Encryption] ユーザー test が正常に作成されました。 詳細: [DSCSERVER]: [[User]Encryption] ユーザー test の構成が正常に完了しました。 詳細: [DSCSERVER]: LCM: [ 終了 設定 ] [[User]Encryption] 2.3130 秒かかりました。 詳細: [DSCSERVER]: LCM: [ 終了 リソース ] [[User]Encryption] 詳細: [DSCSERVER]: LCM: [ 終了 設定 ] 詳細: [DSCSERVER]: LCM: [ 終了 設定 ] (4.7190 秒)。 詳細: 操作 'CimMethod の呼び出し' が完了しました。 詳細: 構成ジョブが完了するまでにかかった時間は 4.722 秒です
完了です。
まとめ
公開鍵暗号は、Windowsでデファクトスタンダードのようにそこかしこで使われています。 MOFを毎回処分することは困難でしょうから、LANだとしてもきっちり処理したいですね。