目次
はじめに
私は現在アジャイル推進UでIoTデータ解析のプラットフォーム構築に携わっています。 先日、ローカルからAWS EC2インスタンスを経由して、API Gatewayへデータを転送できるか検証しました。 EC2インスタンスへのセッション確立およびポートフォワーディングのためにAWS SSMを使用しましたが、TLS/SSL negotiation failedエラーが発生しました。 これからnegotiation failedを解決するためにTLS/SSL規格について学んだ結果として、以下の2点について書いていきます。 - エラーの原因として考えられること。 - 解決するためにどのような対処を行ったか。
結論
ローカル側でアクセスしようとしているドメイン名とEC2インスタンスからフォワーディングしようとしているドメイン名が異なっていることが問題だと考えられました。 ローカルのhostsファイルにエントリを追加し、127.0.0.1をAPI Gatewayのエンドポイント名で名前解決できるようにすることで解決しました。
⚠️ 注意:本記事で紹介する解決方法はあくまで一次対応(暫定対応)です。hostsファイルの編集による名前解決の上書きは、環境依存や管理上の問題を招く可能性があるため、恒久対応として使用すべきではありません。恒久対応としては、カスタムドメインの設定やDNSレコードの適切な管理など、インフラ側での対応を検討してください。
AWS SSM(Systems Manager)とは何か
AWS公式ドキュメントでは以下のように説明されています。
「AWS Systems Manager では、オンプレミスでもマルチクラウド環境でも、AWS 内のノードを広範囲にわたって一元的に表示、管理、および運用できます。統合コンソールエクスペリエンスのリリースにより、Systems Manager では AWS アカウントとリージョン全体にわたってよく使用するノードタスクを完了できるさまざまなツールが統合されています。」
参考:AWS Systems Manager ユーザーガイド
つまりAWSの各サービス、ノード、インスタンスを簡単に管理することができるサービスです。
私が取り組んだこと
今回私はこのSSMを用いて以下の構成図の通り、Linux EC2にセッションを繋いで、それを踏み台にAPI Gatewayへポートフォワーディングを行い、APIを呼び出しました。 ※本記事の内容は検証環境での検証結果です。

aws ssm start-session --target "{Linux EC2インスタンスID}" --document-name "AWS-StartPortForwardingSessionToRemoteHost" --parameters '{"host":["{API Gatewayのエンドポイント名}"],"portNumber":["{使用するEC2インスタンスのポート番号}"],"localPortNumber":["{使用するローカルのポート番号}"]}'
このコマンドを実行すれば、localhostに向けてcurlコマンドを実行することでAPIを呼び出すことができる想定でした。しかしTLS/SSL negotiation failedというエラーが発生してしまいました。その解決にとても苦労しました。
問題の切り分け
- CloudWatchのログを確認しました。
- ログを確認した結果、そもそもAPI Gatewayにcurlコマンドが届いていないことが分かりました。そのため、EC2インスタンスからAPI Gatewayへのポートフォワーディングの段階で何らかの問題が発生していることが判明しました。
自力ではこれ以上解決方法を見つけることができませんでした。チームメンバーの有識者と相談しながら作業を進めることで解決しました。
原因と解決策
問題が起きた原因

ローカルからアクセスしようとしているホストが「localhost」であるのに対し、API Gateway側が所有しているサーバー証明書のホストが「API Gatewayのエンドポイント名」であり、両者が一致していないことが原因だと考えられます。
解決のために実施したこと
ローカルのhostsファイルを以下の通りに編集しました。
※この操作を行う際には、hostsファイルのバックアップを取ることを推奨します。
127.0.0.1 {API Gatewayのエンドポイント名}

この操作をすることで、ローカルからアクセスしようとするホストが「API Gatewayのエンドポイント名」に置き換わり、サーバー証明書のホストと一致するようになったため、TLS/SSL negotiation failedを回避することができました。
⚠️ 本対応の位置づけについて
本記事で紹介したhostsファイルの編集による解決方法は、一次対応(暫定対応) としてのものです。以下の理由から、恒久対応として使用すべきではありません。
- hostsファイルの変更はローカル環境に依存するため、他の開発者やCI/CD環境では同じ設定を手動で行う必要があり、再現性・保守性に欠けます。
- hostsファイルの変更を戻し忘れた場合、通常のDNS解決が上書きされたままとなり、意図しない通信先への接続が発生する恐れがあります。
- TLS/SSLの証明書検証を正しく通過させるための本質的な解決にはなっていません。
恒久対応としては、以下のようなインフラ側での対応を検討してください。 - API Gatewayにカスタムドメインを設定し、適切なDNSレコードを管理する。 - プライベートDNSを利用して名前解決を行う。 - VPCエンドポイント経由でのアクセスを検討する。
まとめ
- SSMを用いたポートフォワーディングをするときの思わぬ落とし穴として、ホスト名が一致しない問題がありました。
- その解決としてhostsファイルを編集して、localhostをAPI Gatewayのエンドポイント名で名前解決できるようにしました。
- ただし、この方法はあくまで一次対応であり、恒久対応としてはインフラ側での適切な対応を検討する必要があります。
- これを通してTLS/SSLプロトコルを調べる良い機会になりました。