🚴🏻♀️
REST API の相互 TLS 認証をやる。
概要
REST API の相互 TLS 認証を勉強する為の記事、API GATEWAYでのクライアント認証をやりたい。
AWS資料
ClassMethod資料
やってみる
Cloud9での環境作成
まずは環境準備
.pyenvの設定
# git clone
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
# bash_profileの編集
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
# bash_profileの読み込み
source ~/.bash_profile
# ライブラリのInstall
sudo yum -y update
sudo yum remove -y openssl-devel
sudo yum -y install gcc make patch zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel tk-devel libffi-devel xz-devel openssl11 openssl11-devel
# Install 5分程度要します
pyenv install 3.10.11
# Version切り替え
pyenv global 3.10.11
# 最新化後のVersion確認
python --version
Python仮想環境作成
# 仮想環境の作成
python -m venv .venv
# アクティベート
source .venv/bin/activate
AWS CLI最新化
# インストーラーをDownLoad
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
# 解答
unzip awscliv2.zip
# 最新化
sudo ./aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli --update
# ゴミ削除
rm -rf aws awscliv2.zip
# 最新化後のVersion確認
aws --version
AWS SAM CLI の最新化
# githubよりインストーラーをDownLoad
wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip
# 解答
unzip aws-sam-cli-linux-x86_64.zip -d sam-installation
# 最新化
sudo ./sam-installation/install --update
# ゴミ削除
rm -rf aws-sam-cli-linux-x86_64.zip sam-installation
# 最新化後のVersion確認
sam --version
AWS SAMでHelloWorld作成
API GatewayとLambda作成
SAM実行
# APPの初期化
cd ~/environment/
sam init
# 選択肢
- AWS Quick Start Templates
- Hello World Example
- N
- python3.10
- Zip
- N
- N
- rest-api-tls
# Build
cd ~/environment/rest-api-tls
sam build
# Deploy
cd ~/environment/rest-api-tls
sam deploy --guided
# 選択肢
基本デフォルト`HelloWorldFunction may not have authorization defined, Is this okay? [y/N]`だけY
# Deploy中
Deploy this changeset? [y/N]: Y
HelloWorldApiの変数設定
API_ENDPOINT="https://xxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/"
curl $API_ENDPOINT
{"message": "hello world"}という文字が出ればOK
ACM作成
前提
Route53上にドメインがあることが前提
ACMにリクエスト発行
aws acm request-certificate \
--domain-name $SUB_DOMAIN \
--validation-method DNS
ACMの画面コンソールでRoute53へレコード登録が出来る画面があるので、従う
API Gatewayでカスタムドメイン作成
# ACMのARN取得
CertificateArn=$(aws acm list-certificates \
--query "CertificateSummaryList[?DomainName==\`$SUB_DOMAIN\`].CertificateArn" \
--output text);echo $CertificateArn
# API ID取得
ApiId=$(aws apigateway get-rest-apis \
--query "items[?name==\`rest-api-tls\`].id" \
--output text);echo $ApiId
# カスタムドメイン作成
aws apigatewayv2 create-domain-name \
--domain-name $SUB_DOMAIN \
--domain-name-configurations CertificateArn=$CertificateArn
# カスタムドメインにAPIを紐づける(APIマッピング)
aws apigatewayv2 create-api-mapping \
--domain-name $SUB_DOMAIN \
--api-id $ApiId \
--stage Prod
Route53でカスタムドメインをAレコードに登録
上述のACM設定が通るまで少々時間がかかるようです。
カスタムドメインでAPI CALL
# 変数設定
SUB_DOMAIN_API_ENDPOINT=https://$SUB_DOMAIN/hello
echo $SUB_DOMAIN_API_ENDPOINT
# カスタムドメインでAPI CALL
curl $SUB_DOMAIN_API_ENDPOINT
{"message": "hello world"}という文字が出ればOK
デフォルトのApi Gateway Endpointを潰す
# 無効化
aws apigateway update-rest-api \
--rest-api-id $ApiId \
--patch-operations op=replace,path=/disableExecuteApiEndpoint,value='True'
# Deploy
aws apigateway create-deployment \
--rest-api-id $ApiId \
--stage-name Prod
# デフォルトのApi CALL
API_ENDPOINT="https://jyl2n5wj7h.execute-api.ap-northeast-1.amazonaws.com/"
curl $API_ENDPOINT
{"message":"Forbidden"} であればOK
クライアント証明書
# ルートCAの秘密鍵 を生成します
openssl genrsa -out RootCA.key 4096
# 自己署名CA証明書 を生成します
openssl req -new -x509 -days 3650 -key RootCA.key -out RootCA.pem
# クライアント証明書のプライベートキー を生成します
openssl genrsa -out my_client.key 2048
# 証明書署名要求 (CSR) を生成します
openssl req -new -key my_client.key -out my_client.csr
# CA を使用してクライアント証明書に署名します
openssl x509 -req -in my_client.csr -CA RootCA.pem -CAkey RootCA.key -set_serial 01 -out my_client.pem -days 3650 -sha256
S3にCA証明書をUp
# S3作成(S3の名前は各自で変更)
aws s3 mb s3://rest-api-tls-shigeruoda-20230520
# S3に格納
aws s3 cp RootCA.pem s3://rest-api-tls-shigeruoda-20230520
クライアント証明書による認証を有効化
aws apigatewayv2 update-domain-name \
--domain-name $SUB_DOMAIN \
--domain-name-configurations CertificateArn=$CertificateArn \
--mutual-tls-authentication TruststoreUri=s3://rest-api-tls-shigeruoda-20230520/RootCA.pem
更新まち。
ちょっと待機
カスタムドメインドメインでAPI CALL(失敗)
# カスタムドメインでAPI CALL
curl $SUB_DOMAIN_API_ENDPOINT
curl: (35) Recv failure: Connection reset by peer というエラー
カスタムドメインでAPI CALL(成功)
curl $SUB_DOMAIN_API_ENDPOINT --key my_client.key --cert my_client.pem
{"message": "hello world"}という文字が出ればOK
Discussion