Warning: preg_match(): Compilation failed: unrecognized character follows \ at offset 1 in /home/r5652521/public_html/soma-engineering.com/wp-content/themes/affinger/functions.php on line 1548
Warning: preg_match(): Compilation failed: unrecognized character follows \ at offset 1 in /home/r5652521/public_html/soma-engineering.com/wp-content/themes/affinger/functions.php on line 1548
Warning: preg_match(): Compilation failed: unrecognized character follows \ at offset 1 in /home/r5652521/public_html/soma-engineering.com/wp-content/themes/affinger/functions.php on line 1548
Warning: preg_match(): Compilation failed: unrecognized character follows \ at offset 1 in /home/r5652521/public_html/soma-engineering.com/wp-content/themes/affinger/functions.php on line 1548
Warning: preg_match(): Compilation failed: unrecognized character follows \ at offset 1 in /home/r5652521/public_html/soma-engineering.com/wp-content/themes/affinger/functions.php on line 1548
こんにちは!SE ブログの相馬です。
今回は、PowerShell のスクリプトに署名を付けて、特定のスクリプトのみ動作する方法について書きました。
PowerShell の実行ポリシーについて
まず、PowerShell には実行ポリシーというものがあります。
実は、PowerShell ではどんなスクリプトでも実行ができるわけではありません。
PowerShell のデフォルト設定では、Restricted という状態になっておりこれではいかなるスクリプトでも実行する事が許可されていません。
理由としては、スクリプトによってコンピューターを攻撃したりする事ができてしまう為です。
そこで、PowerShell は実行ポリシーという機能を付ける事で、環境に合わせて実行ができるスクリプトをレベル別に許可するように設定されています。
という事で、実行ポリシーを Restricted から変更する場合ですが、いくつか種類があります。以下の記事に詳しく書いてありますので見て頂ければと思います。
https://soma-engineering.com/coding/powershell/change-executinpolicy-powershell/2018/04/27/
PowerShell の実行ポリシーを変更する
実行ポリシーが Restricted になっている状態で、PowerShell を実行すると、以下の画像のように「スクリプトの実行が無効になっているため...」という内容が表示され、スクリプトが実行できません。
ですので、これをどの実行ポリシーに変更するか、考えなくてはなりませんが、ここでは AllSigned に変更します。
AllSigned の内容は上の記事から引用すると以下のとおりです。
スクリプトは実行できますが、デジタル署名が付いてなければなりません。
(そのスクリプトをローカル PC で書いても同じです。)
未署名のスクリプトを実行すると、実行を許可するか拒否するか確認ダイアログが表示されます。
(ユーザーが許可を選べば実行します。)
という事で、デジタル署名が付いているスクリプトのみ実行ができます。では、どうやってデジタル署名を付けるのかをこの記事で説明します。
デジタル署名
ではどうやってデジタル署名を作るのかみてゆきましょう。検証目的で自己証明書を作るには New-SelfSignedCertificate コマンドレットを使います。
New-SelfSignedCertificate | Microsoft Developer Network
補足:この記事は検証目的で自己証明書を作っています。本番環境では証明書は企業のルート証明書で署名するのが一般的かもしれません。
1 2 3 |
$mycert = New-SelfSignedCertificate -Subject "CN=PS CodeSigning" ` -KeyAlgorithm RSA -KeyLength 2048 -Type CodeSigningCert ` -CertStoreLocation Cert:\LocalMachine\My\ |
では、$mycert を実行して、証明書が生成されたか確認します。
1 2 3 4 5 6 7 8 9 10 |
$mycert # 実行結果 PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\My Thumbprint Subject ---------- ------- C06ECB6E4FDEA841CC7133DBBA11CB4C6F3C5EF2 CN=PS CodeSigning |
自己証明書を以下の Move-Item コマンドレットでルート証明書に移動します。
1 |
Move-Item "Cert:\LocalMachine\My\$($mycert.Thumbprint)" Cert:\LocalMachine\Root |
スクリプトに署名するには、thumbprint が代入されている変数を以下のように書けば簡単にできます。
1 |
$myrootcert = "Cert:\LocalMachine\Root\$($mycert.Thumbprint)" |
これで以下の方法で スクリプトに署名ができるようになりました。
1 2 3 4 5 6 7 8 9 10 |
set-AuthenticodeSignature \Users\Stuart\Desktop\test.ps1 $mycert # 実行結果 ディレクトリ: C:\scripts SignerCertificate Status Path ----------------- ------ ---- C06ECB6E4FDEA841CC7133DBBA11CB4C6F3C5EF2 Valid hello.ps1 |
これでスクリプトが正しく署名されました。但し、ここで署名したのは信頼できる証明書プロバイダではなく、あくまでも自己証明書です。
それでは、署名されたスクリプトが AllSigned の実行ポリシーでも動くかどうか、確認しましょう。その前に実行ポリシーを AllSigned に変更しておきます。
1 |
PS C:\WINDOWS\system32> Set-ExecutionPolicy AllSigned |
では署名されたスクリプトを実行してみましょう。実行すると以下のようなメッセージが表示されますので、[一度だけ実行する] をクリックします。
1 2 |
PS C:\WINDOWS\system32> C:\scripts\hello.ps1 Hello World! |
やっと問題なく実行ができましたね。そこで署名されたスクリプトファイルの中身ってどうなんでしょう。
署名されたスクリプトファイルの中身
実行はこんなかんじで、ものすごい多くの文字列が書いてあります。これが署名になっています。
実際、ファイルの中身を変更して実行してみましたところ、セキュリティエラーが発生して実行できませんでした。
1 2 3 4 5 6 7 8 |
PS C:\WINDOWS\system32> C:\scripts\hello.ps1 C:\scripts\hello.ps1 : ファイル C:\scripts\hello.ps1 を読み込めません。ファイル C:\scripts\hello.ps1 の内容は、承認されていないユーザーまたはプロセスによって変更された可能性があります。ファイルのハッシュが、デジタル署名に保存されているハッシュと一致しません。このスクリプトは指定されたシステムでは実行できません。詳細については、Get-He lp about_Signing を実行してください。。 発生場所 行:1 文字:1 + C:\scripts\hello.ps1 + ~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : セキュリティ エラー: (: ) []、PSSecurityException + FullyQualifiedErrorId : UnauthorizedAccess |
以上になります。いかがでしょうか。
署名されたスクリプトのみ実行する環境でなければ特に必要はないですが、どのような方法で署名して実行されるのかが、ここで把握できました。
また、今回は検証環境での方法で自己証明書を使ってやりましたが、実際は企業のルート証明書などを使用するかもしれません。
では最後までお読みいただきありがとうございました!