はじめに

RDSに接続する際、こんな経験はありませんか?

「AWSのCA証明書?ダウンロードしたことないけど、普通に接続できてるし…」
「特に証明書設定もしていないし…平文通信になっているんじゃ…?」

実は私もそう思っていました。しかし、通信はちゃんと暗号化されていたのです。

ここで疑問が浮かびます。

暗号化されているなら、それで十分安全なのでは?
わざわざCA証明書をダウンロードして設定する必要があるの?

この答えは、「暗号化」と「認証」の違いにありました。

本記事では、RDS接続における暗号化の仕組みと、本番環境で適切なセキュリティレベルを選択する方法を、具体例を交えて解説します。
※この記事はRDS PostgreSQLを中心に説明しており、Amazon Aurora PostgreSQLにも適用できる内容です。

暗号化 vs 認証

ここで重要な概念の区別が必要です。

1. 暗号化

データを暗号化して、途中で誰かに傍受されても内容を見られないようにすることです。

例: 手紙を暗号文で書くようなものです。途中で誰かに盗まれても、何が書いてあるか分かりません。

2. 認証

自分が接続しようとしているサーバーが本当にそのサーバーであることを確認することです。

例: 手紙を受け取る人が本当にその人であることを、マイナンバーカードで確認するようなものです。

重要な気づき

RDSにはサーバー証明書が用意されているため、暗号化通信自体はCA証明書がなくても(サーバー証明書だけでも)可能です

つまり、通信は暗号化されますが、接続先のRDSが本物かどうかを確認する認証は行えない、ということになります。

RDSで実際に起きていること

PostgreSQL 15以降のデフォルト動作

RDS PostgreSQL 15以降のバージョンでは、デフォルトでSSL接続を要求します。私が何も設定せずに接続したときも

psql "host=my-rds.amazonaws.com port=5432 user=postgres (sslmode=prefer)"

このようにシンプルに接続しても、自動的にSSL暗号化通信が行われます。(PostgreSQLサーバに証明証が設定されていれば)
sslmode=preferというオプションがデフォルトでついています。

ルートCA証明書とは?

サーバー証明書の発行元が本物であることを保証する「信頼の起点」となる証明書です。
RDSではAWSが独自のルートCAを用意しており、RDSインスタンスのサーバー証明書はこのルートCAを基点とした証明書チェーンで発行されています。

クライアント側にこのルートCAをインストールしておくことで、接続先が本当にAWSのRDSであるかを検証できるようになります。

Root CA証明書のダウンロード方法

AWS公式サイトからリージョン別にまとめられたRDS CA証明書バンドルをダウンロード可能です。
RDS CA証明書バンドル一覧

使用例(sslmodeと組み合わせた接続コマンド)

# psqlでCA証明書を指定する例
psql "host=my-rds.amazonaws.com \
      port=5432 \
      dbname=dbname \
      user=user \
      sslmode=verify-full \
      sslrootcert=/path/to/ca-bundle.pem"

証明書ローテーションについて

  • RDSでは定期的にサーバー証明書のローテーションが行われます。

  • ルート証明書は有効期限が切れた場合、手動で更新する必要があります。

 

ルートCA証明書がない場合の通信の流れ

この方式は通信内容を暗号化しますが、接続したサーバーが本当にRDSなのかを最後まで確認しません。

接続プロセスと問題点

ステップ1:クライアント → サーバー

クライアント:「こんにちは。接続したいのですが、暗号化通信しましょう」

ステップ2:サーバー → クライアント

サーバー:「いいですよ。私の身分証(サーバー証明書)がこちらです。ここに書かれた公開鍵を使って、暗号を作りましょう」

このサーバー証明書には

  • サーバーのアドレス(例:my-rds.amazonaws.com
  • 暗号化に使用する公開鍵
  • 発行機関(CA)の情報

が含まれています。

ステップ3:クライアントの(不完全な)処理

クライアント:(サーバーから渡された証明書を受け取る) 「この証明書で暗号化チャネルを作ろう」
ただし、この証明書が本物かどうかは確認しない→通信したいRDSであるか確認ができない。

ルートCA証明書が存在しない場合のリスクは以下を考えられます。

  • 中間者攻撃(MITM: Man-In-The-Middle)の危険性
    攻撃者がDNSの書き換えやIPの乗っ取りを行い、偽のサーバーに接続させることで、暗号化された通信内容を中継・改ざんできる可能性があります。

  • データ漏えいのリスク
    偽サーバーにパスワードや認証情報を送信してしまうことで、認証情報が盗まれる危険があります。

  • 通信先の信頼性の欠如
    クライアントは「暗号化されている」ことしか保証できず、「正しい相手と通信している」ことは保証できません。

 

ステップ4:暗号化通信の開始

クライアント ↔ サーバー:暗号化通信開始 

 ルートCA証明書がある場合の通信の流れ

この方式は通信の暗号化はもちろん、接続したサーバーがRDSサーバーであることを「証明書チェーン」を通じて検証します。

接続プロセス

ステップ1:クライアント → サーバー

クライアント:「こんにちは。接続したいのですが、暗号化通信しましょう。ちなみに、Amazon RDSのルートCA証明書を持っています。」

ステップ2:サーバー → クライアント

サーバー:「いいですよ。これがサーバー証明書です。Amazon RDS CAから発行されています。」

ステップ3:クライアントの徹底的な検証 

ここでクライアントは受け取ったサーバー証明書を検証します

クライアント:「ちょっと待って、この証明書、本物かどうか確認しないと…」

① CA署名の検証

質問:「このサーバー証明書に押されたAmazon RDS CAの署名は本物か?」

方法:自分が持っているルートCA証明書に含まれる公開鍵でサーバー証明書のデジタル署名を検証

結果:✅ 署名一致 → この証明書は本物のAmazonが発行したもの

 

② 有効期限の確認

質問:「この証明書は有効期限切れになっていないか?」

確認:現在の日付が証明書の有効期間内にあるか

結果:✅ 2024-01-01 ~ 2025-12-31の間 → 有効

 

③ ホスト名の一致確認(sslmode=verify-fullの場合)

質問:「証明書に書かれたアドレスが、自分が接続しようとしているアドレスと一致しているか?」

比較:

  • 接続しようとしているアドレス:my-rds.amazonaws.com
  • 証明書に記載されたアドレス(CN/SAN):my-rds.amazonaws.com

結果:✅ 一致 → 自分が望むまさにそのサーバーで正しい

ステップ4:検証完了後の接続

クライアント:「よし!すべての検証をパスした。 このサーバーはAWSが運営する信頼できる本物のRDSサーバーだ」
クライアント ↔ サーバー:ようやく安全に暗号化通信を開始

これで以下のリスクを防ぐことができます!

  • 中間者攻撃(MITM攻撃)の危険性

  • データ漏えいのリスク

  • 通信先の信頼性の欠如

sslmodeオプションの詳細比較

PostgreSQLはsslmodeパラメータでセキュリティレベルを調整できます。

sslmodeオプション表

オプション 説明
disable SSL を使わない
prefer(デフォルト) 可能なら SSL、無理なら非SSL
require SSL 必須、証明書は確認しない
verify-ca SSL 必須、CA 証明書を確認
verify-full SSL 必須、CA とホスト名も確認

prefer vs require

prefer 

  • 「SSLがあれば使用、なければ平文接続」

  • SSL接続を試みるが、失敗すると暗号化なしで接続
  • サーバーがSSL対応 → ✅ 暗号化接続
    サーバーがSSL非対応 → ⚠️ 平文接続

  • ※RDSを利用する場合は基本的に内蔵証明書を持っているため、preferでも自動的に暗号化接続されます。

require

「SSL接続のみ許可、ダメなら接続拒否」

  • SSL接続が必須だが、CA証明書の検証はしない
  • サーバーがSSL対応 → ✅ 暗号化接続
    サーバーがSSL非対応 → ❌ 接続拒否
    偽の証明書 → ⚠️ 接続許可

    verify-ca vs verify-full

    ここではSSL証明書検証の2つの方式の違いについて説明します。

    CA検証について

    通常、正常にアクセスできる場合は、verify-caとverify-fullのどちらでも安全にアクセスできます。しかし攻撃を受けた場合、その動作に違いが現れます。

    攻撃シナリオ

    自分のRDSにアクセスしようとします。

    • ホスト名:my-rds.amazonaws.com

    悪意を持つ者が以下のことを実行したとします。

    1. 同じCAから署名を受けた別のRDS(unsafe-rds.amazonaws.com)を作成
    2. あなたのローカルネットワークのDNS設定を改ざん
      1.  my-rds.amazonaws.com→ unsafe-rds.amazonaws.comのIPアドレスに割り当て

      verify-ca(CAのみ検証)

      「証明書発行機関のみ確認」

      • 証明書がAmazon RDSなどの信頼できるCAから署名されているかのみ確認、ホスト名の検証は行わない
      • 接続アドレス: my-rds.amazonaws.com
        証明書アドレス: unsafe-rds.amazonaws.com

         

        1.サーバーがSSL対応 → ✅ 暗号化接続

        2.CA信頼確認  →⚠️接続許可 

         

        問題点:DNSスプーフィング攻撃で接続先アドレスが改ざんされても、CA署名が有効である限り接続を許可してしまいます。
        その結果、攻撃者の偽のRDSに接続されてしまう危険があります。

      verify-full(CA + ホスト名を検証)

      「発行機関 + アドレス一致を両方確認」

      1. CA信頼性の確認、接続アドレスと証明書のアドレスが一致しているか確認

      接続アドレス: my-rds.amazonaws.com
      証明書アドレス: unsafe-rds.amazonaws.com 

       

      1.サーバーがSSL対応 → ✅ 暗号化接続

      2.CA信頼確認  → ⚠️接続許可

      3.ホスト名一致確認  → ❌接続拒否

       

      セキュリティ効果 :DNS操作されても、攻撃者が用意した偽のRDSの証明書では正しいホスト名が含まれていないため、接続がブロックされます。

      注意点

      verify-full は最も安全ですが、データベースの前段にNLBやRDS Proxyを置く場合は使用できません。
      この場合、プロキシのホスト名と証明書のホスト名が一致せず、接続が拒否されてしまうためです。

      比較表

      検証項目 prefer require verify-ca verify-full
      SSL暗号化 ⚠️  ✅  ✅  ✅ 
      CA検証
      ホスト名検証
      セキュリティ ⚠️
      本番推奨 ⚠️ ✅ 

      公式ドキュメントによるとすべてのSSLオプションは暗号化と鍵交換のオーバーヘッドが発生するため、セキュリティとパフォーマンスの間でバランスを取る必要があるそうです。
      (各モード間の具体的なパフォーマンス差異を示す定量的な指標データは見つかりませんでした。)
      また、Connection Poolを使用して初期接続コストを分散することができると思います。

      まとめ

      RDSへの接続において、CA証明書なしでも暗号化通信は可能ですが、それは「暗号化」と「認証」が別物だからです。

      重要なポイント

      暗号化: データの内容を保護 → CA証明書なしでも可能

      認証: 接続先サーバーの身元を保証 → CA証明書が必要

      本番環境での推奨設定

      sslmode=verify-full + ルートCA証明書

      安全なデータベース接続を実現するために、verify-full モードの利用が推奨されます。
      RDSを利用することで、証明書の設定や管理が自動化されるため、セキュリティ対策を手軽に実装できます。

      参考資料