パスワードをスクリプトに埋め込むなんてありえない!Tableau ServerのTSMコマンド用スクリプトへ移行する方法

はじめに

Tableau Server のVersion 2018.02以降、管理コマンド tabadmin が廃止され、代わりにTSMコマンドを利用しなければなりません。TSMコマンドはリモートから実行できる代わりにユーザ名とパスワードによる認証が必要になりました。バックアップ取得やログクリーンナップのために、TSMコマンドを実行するスクリプトを運用する必要があります。本日はユーザ名やパスワードをTSMコマンドを実行するスクリプト内に記入することなく、セキュリティ的に安全にTMSへユーザ名/パスワードを渡す方法を紹介します。

セキュリティ的に安全にユーザ名/パスワードを渡す方法

AWSエンジニアであればAWS KMSによる暗号化SSMのパラメータストアといったアプローチが考えられますが、今回は、Windows PowerShellのDPAPI(Data Protection Application Programming Interface)を用いて、暗号化された認証情報ファイルを使って、スクリプト内部からユーザ名/パスワードをTSMへ渡す方法で認証します。

手順1.パスワードを暗号化して保存する

最初にユーザー名とパスワードを暗号化したファイルを作成して保存します。&Credential.Passwordを実行すると、ユーザー名とパスワードを入力するダイアログが表示され、その結果をSecureStringに渡してファイル出力します。

サンプル:createCredential.ps1

$FilePath = "C:\Users\Administrator\.tableau\cred.sec"
$Credential = Get-Credential
$Credential.Password | ConvertFrom-SecureString | Set-Content $FilePath

上記のスクリプトを実行すると以下のようなダイアログが表示されますので、ユーザー名とパスワードを入力してください。実行すると$FilePathにファイルとして保存されます。

手順2.パスワードを含む暗号化したファイルを用いてコマンド実行する

ユーザー名とパスワードを暗号化したファイルを読み込み、SecureStringとしてパスワードを取り出します。クレデンシャル(PsCredential)を生成します。最後に認証情報($cred)をTSMコマンドに渡して実行します。下記のスクリプトはサービスの稼働状況を取得します。

サンプル:getServiceStatusAfterReadCredentialFile.ps1

$FilePath = "C:\Users\Administrator\.tableau\cred.sec"
$Username = "Administrator"

# ユーザー名とパスワードを暗号化したファイルを読み込み
$encryptedCred = Get-Content $FilePath | ConvertTo-SecureString

# クレデンシャル(PsCredential)を生成
$cred = New-Object System.management.Automation.PsCredential($Username, $encryptedCred)

# 認証情報をTSMコマンドに渡して、サービスの稼働状況を取得する
$ret = & echo $cred.GetNetworkCredential().Password | tsm status

試した環境のパスワードに&が含まれていたのでハマりましたが、下記のコードの通り、$cred.GetNetworkCredential().Passwordをパイプで渡すことでエスケープを回避しています。

tabadminコマンドからTMSコマンドにスクリプトをマイグレーションする

今回は、以下のブログで紹介したディスクフル対策のログクリーナップスクリプトをマイグレーションします。

Tableau Server のディスクフル対策

移行前:tabadminコマンドによる実装

現在の状態を確認して、サービス起動中であれば、ログのクリーナップを実行するという仕様です。

サンプル:tabhotcleanup_tabadmin.ps1

$tabadmin = "D:\Tableau\Tableau Server\10.1\bin\tabadmin.exe"

$ret = & $tabadmin "status"
if ( $ret -eq 'Status: RUNNING') {
  & $tabadmin "cleanup"
}

移行後:TSMコマンドによる実装

先程のスクリプトをマイグレーションします。クレデンシャル(PsCredential)を生成した後は、コマンドをtabadminからtsmに変更するのみです。下の4行はほぼ一緒です。

サンプル:tabhotcleanup_tsm.ps1

$FilePath = "C:\Users\Administrator\.tableau\cred.sec"
$Username = "Administrator"
$encryptedCred = Get-Content $FilePath | ConvertTo-SecureString
$cred = New-Object System.management.Automation.PsCredential($Username, $encryptedCred)

$ret = & echo $cred.GetNetworkCredential().Password | tsm status
if ( $ret -eq 'Status: RUNNING') {
  & echo $cred.GetNetworkCredential().Password | tsm cleanup
}

最後に

tabadminコマンドはバージョンディレクトリの下に保存されるため、バージョンアップのたびに呼び出すパスを変更していました。先入観があったTSMコマンドですが、パスが通っているためバージョンアップのたびにパスを変更することを意識する必要がないことは嬉しい誤算でした。この2つのコマンドは同じ機能をサポートしているわけではないので、スクリプトのマイグレーションの際には以下のドキュメントを参考にしてください。

参考