RDS for SQL Serverで透過的データ暗号化(TDE)を試してみた

2022.01.06

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

しばたです。

SQL Serverにはデータ(データファイル)レベルでの暗号化機能である透過的データ暗号化(Transparent Data Encryption, TDE)と呼ばれる機能がありRDS for SQL Serverでもサポートされています。

本記事ではRDS for SQL ServerでのTDEの設定手順を解説します。

透過的データ暗号化(TDE)とは?

TDEの詳細についてはこちらのDocsのドキュメントをご覧ください。

TDEはデータファイルのページ単位で内容を暗号化し保存します。
ユーザーがデータを更新・参照する際は自動で暗号・復号を行うため「透過的」とされています。

そしてTDEではインスタンスレベルの「Service Master Key」とデータベースレベルの「Database Master Key」の二種類の鍵と専用の証明書を使用します。
細かい話は端折りますが、基本的にはDatabase Master Keyを使い暗号化したいデータベース単位でTDEを有効にする設定を施す形になります。

RDS for SQL ServerにおけるTDEサポート

RDS for SQL ServerにおけるTDEサポートについてはこちらのドキュメントを参照してください。

RDS for SQL Serverでは以下のバージョン・エディションでTDEがサポートされています。

  • SQL Server 2019 Standard and Enterprise Editions
  • SQL Server 2017 Enterprise Edition
  • SQL Server 2016 Enterprise Edition
  • SQL Server 2014 Enterprise Edition
  • SQL Server 2012 Enterprise Edition

基本的にはSQL Serverとしてサポートしているエディションと同じですが、RDSではSQL Server 2019のWeb Editionだけ非サポートになっている点が異なります。

そしてRDS for SQL ServerでTDEを利用するにはオプショングループ(TRANSPARENT_DATA_ENCRYPTION)の指定が必要です。 オプショングループ指定のうえ所定のSQLを実行することで機能を有効にできます。

制限事項

RDS for SQL ServerでのTDE利用においては暗号化で使う証明書のインポートおよびエクスポートが出来ない制限があります。
これによりRDSでTDEで暗号化されたネイティブバックアップはRDS外部の環境でリストアできませんし、逆にオンプレ環境等で暗号化されたバックアップもRDSにリストアできないのでご留意ください。

リソース暗号化との併用

RDSは標準でEBSストレージ全体の暗号化(リソース暗号化)をサポートしておりTDEと併用する事が可能ですが、以下の記載の様にパフォーマンスに若干の影響を与えます。

Amazon RDS は、Transparent Data Encryption (TDE) による Oracle または SQL Server の DB インスタンスの暗号化もサポートします。TDE は、保管時の暗号化とともに使用できますが、TDE と保管時の暗号化を同時に使用すると、データベースのパフォーマンスに若干影響する可能性があります。

利用するシステムに求められる要件に応じてリソース暗号化、TDEの採用、両者の併用を検討すると良いでしょう。

やってみた

それでは早速試してみます。

私の検証用AWSアカウントの東京リージョンでRDS for SQL Server(SQL Server 2019 Standard Edtion)を作成します。
VPCなどは事前準備済の状態です。

1. RDSインスタンスの作成

まずはオプショングループを作成します。
名前はsql-server-2019-tde-ogとし、SQL Server 2019 Standard Edtion用とします。

このオプショングループにオプションを追加します。

追加するオプションはTRANSPARENT_DATA_ENCRYPTIONです。

追加後はこんな感じ。

あとはサブネットグループ、パラメーターグループを環境に合わせて用意しRDSインスタンスを作成します。
オプショングループをsql-server-2019-tde-ogにし、その他細かい設定は環境に応じて決めてください。

作成後はこんな感じです。

2. TDEの有効化

あとはドキュメントに従って各データベースでTDEを有効にしてやるだけです。

今回は別途用意したWindows ServerからSSMSで接続しています。

RDSでTDEを有効にするとmasterデータベースに自動で証明書が登録されますので、その名前を取得します。

-- まずは master データベースにあるRDS向けの証明書を確認
USE [master]
GO
SELECT name FROM sys.certificates WHERE name LIKE 'RDSTDECertificate%'
GO

結果こんな感じでRDSTDECertificate[作成時刻]な名前の証明書が生成されていることがわかります。

name
RDSTDECertificate20220105T112011

この証明書は次の手順で使います。
続けて暗号化したいデータベース上でCREATE DATABASE ENCRYPTION KEY文を実行し暗号化キーを生成し、ALTER DATABASE文で暗号化を有効にします。

-- 暗号化したいデータベースに接続 : 今回は mydb データベースを事前に準備済み
USE [mydb]
GO

-- 暗号化キー (Database Master Key) を生成
-- アルゴリズムは [AES_128 | AES_192 | AES_256] から選択
-- ここで使用する証明書を指定する
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_128
ENCRYPTION BY SERVER CERTIFICATE [RDSTDECertificate20220105T112011]
GO

-- データベースを暗号化する
ALTER DATABASE [mydb]
SET ENCRYPTION ON
GO

各SQLがエラー無く完了すればOKです。
SQLは直ちに終了し裏で暗号化処理が進みます。

暗号化の状況は以下のSQLで確認できます。

-- 暗号化状態の確認
USE [master]
GO
-- 暗号化されているデータベースを取得
SELECT name FROM sys.databases WHERE is_encrypted = 1
GO
-- 暗号化の詳細を取得
SELECT db_name(database_id) as DatabaseName, * FROM sys.dm_database_encryption_keys
GO

sys.dm_database_encryption_keysシステムビューのencryption_state列が暗号化の状況で、上図であれば3 = 暗号化となります。

なお、なんらかのデータベースを暗号化した場合tempdbも自動で暗号化されます。

(optional) 暗号化の解除

暗号化の解除を行う場合は基本的に逆順の作業を行います。

まずはALTER DATABASE文で暗号化を解除します。

-- 暗号化を解除したいデータベースに接続 : 今回は mydb データベースを事前に準備済み
USE [mydb]
GO

-- 暗号化を解除
ALTER DATABASE [mydb]
SET ENCRYPTION OFF
GO

これで暗号化の解除処理が開始されます。

暗号化の解除が完了したかどうかはsys.dm_database_encryption_keysシステムビューで確認します。
encryption_state列が1 = 暗号化されていないになっていればOKです。

-- 当該データベースの encryption_state 列が 1 になるのを確認 (それまで待つ)
SELECT db_name(database_id) as DatabaseName, * FROM sys.dm_database_encryption_keys
GO

解除後暗号化キーを削除します。

基本的にはこれで完了ですがRDSのドキュメントでは加えてデータベースの復旧モデルを「単純」に変えることで暗号化済みのトランザクションログを切り捨てる処理も実施しています。
こちらについては必要に応じて行えば良いと思います。

-- 暗号化キーを削除
USE [mydb]
GO
DROP DATABASE ENCRYPTION KEY
GO

-- 復旧モデルを「単純」に変えることで暗号化済みのトランザクションログを切り捨て
-- ※筆者個人としてはこれは"必要ならやる"くらいの扱いで良い気がします...
--   トランザクションログを切り捨てたあとは復旧モデルを元に戻しておきましょう
USE [master]
GO
ALTER DATABASE [mydb] SET RECOVERY SIMPLE
GO

ちなみにtempdbについては他のすべてのデータベースの暗号化を解除したあとでインスタンスを再起動するまで暗号化は解除されない様です。

最後に

以上となります。
TDEは基本的にEnterprise Editionの機能なのであまり使うことは無いかもしれませんがRDSでもサポートされていますので要件に応じてご利用ください。