Amazon EC2 인스턴스의 인스턴스 ID 문서(instance identity document) 검증하기
Amazon EC2 인스턴스의 인스턴스 ID 문서(instance identity document) 검증하기
인스턴스 ID 문서의 내용을 중요한 목적으로 사용하려 한다면, 사용하기 전에 그 내용과 진위를 검증해야 해요. 일반 텍스트 인스턴스 ID 문서에는 세 가지 해시·암호화 서명이 함께 제공됩니다. 이 서명들로 인스턴스 ID 문서와 그 내용의 출처·진위를 검증할 수 있어요.
출처: 문서
본문
다음 서명이 제공됩니다.
- Base64 인코딩 서명 — RSA 키 페어로 암호화된 인스턴스 ID 문서의 base64 인코딩 SHA256 해시입니다.
- PKCS7 서명 — DSA 키 페어로 암호화된 인스턴스 ID 문서의 SHA1 해시입니다.
- RSA-2048 서명 — RSA-2048 키 페어로 암호화된 인스턴스 ID 문서의 SHA256 해시입니다.
각 서명은 인스턴스 메타데이터의 서로 다른 엔드포인트에서 사용할 수 있어요. 해싱·암호화 요구에 따라 이 중 하나를 사용할 수 있습니다. 서명을 검증하려면 해당하는 AWS 공개 인증서를 사용해야 합니다.
옵션 1: PKCS7 서명으로 인스턴스 ID 문서 검증
이 주제에서는 PKCS7 서명과 AWS DSA 공개 인증서로 인스턴스 ID 문서를 검증하는 방법을 설명해요.
PKCS7 서명과 AWS DSA 공개 인증서로 검증하기
- 인스턴스에 연결합니다.
- 인스턴스 메타데이터에서 PKCS7 서명을 가져와 필수 헤더와 푸터와 함께
pkcs7이라는 새 파일에 추가합니다. 인스턴스가 사용하는 IMDS 버전에 따라 다음 명령 중 하나를 사용합니다.- IMDSv2
$ echo "-----BEGIN PKCS7-----" >> pkcs7 \
&& TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/pkcs7 >> pkcs7 \
&& echo "" >> pkcs7 \
&& echo "-----END PKCS7-----" >> pkcs7
- IMDSv1
$ echo "-----BEGIN PKCS7-----" >> pkcs7 \
&& curl -s http://169.254.169.254/latest/dynamic/instance-identity/pkcs7 >> pkcs7 \
&& echo "" >> pkcs7 \
&& echo "-----END PKCS7-----" >> pkcs7
- 리전의 DSA 공개 인증서를 "인스턴스 ID 문서 서명용 AWS 공개 인증서"에서 찾아 그 내용을
certificate라는 새 파일에 추가합니다. - OpenSSL
smime명령으로 서명을 검증합니다.-verify옵션은 서명을 검증해야 함을,-noverify옵션은 인증서를 검증할 필요가 없음을 나타냅니다.
$ openssl smime -verify -in pkcs7 -inform PEM -certfile certificate -noverify | tee document
- 서명이 유효하면
Verification successful메시지가 나타납니다. - 이 명령은 인스턴스 ID 문서의 내용도
document라는 새 파일에 기록합니다. 인스턴스 메타데이터의 인스턴스 ID 문서 내용과 이 파일의 내용을 다음 명령으로 비교할 수 있어요.
$ openssl dgst -sha256 < document
$ curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/document | openssl dgst -sha256
- 서명을 검증할 수 없으면 AWS Support에 연락하세요.
사전 요건 — 이 절차는 System.Security Microsoft .NET Core 클래스를 필요로 해요. PowerShell 세션에 클래스를 추가하려면 다음 명령을 실행합니다.
PS C:\> Add-Type -AssemblyName System.Security
참고 — 이 명령은 현재 PowerShell 세션에만 클래스를 추가해요. 새 세션을 시작하면 명령을 다시 실행해야 합니다.
PKCS7 서명과 AWS DSA 공개 인증서로 검증하기 (PowerShell)
- 인스턴스에 연결합니다.
- 인스턴스 메타데이터에서 PKCS7 서명을 가져와 바이트 배열로 변환하고
$Signature변수에 추가합니다.- IMDSv2
PS C:\> [string]$token = (Invoke-WebRequest -Method Put -Headers @{'X-aws-ec2-metadata-token-ttl-seconds' = '21600'} -Uri http://169.254.169.254/latest/api/token).Content
PS C:\> $Signature = [Convert]::FromBase64String((Invoke-WebRequest -Headers @{'X-aws-ec2-metadata-token' = $Token} -Uri http://169.254.169.254/latest/dynamic/instance-identity/pkcs7).Content)
- IMDSv1
PS C:\> $Signature = [Convert]::FromBase64String((Invoke-WebRequest -Uri http://169.254.169.254/latest/dynamic/instance-identity/pkcs7).Content)
- 인스턴스 메타데이터에서 일반 텍스트 인스턴스 ID 문서를 가져와 바이트 배열로 변환하고
$Document변수에 추가합니다.- IMDSv2
PS C:\> $Document = [Text.Encoding]::UTF8.GetBytes((Invoke-WebRequest -Headers @{'X-aws-ec2-metadata-token' = $Token} -Uri http://169.254.169.254/latest/dynamic/instance-identity/document).Content)
- IMDSv1
PS C:\> $Document = [Text.Encoding]::UTF8.GetBytes((Invoke-WebRequest http://169.254.169.254/latest/dynamic/instance-identity/document).Content)
- 리전의 DSA 공개 인증서를 찾아 내용을
certificate.pem파일에 추가합니다. - 인증서 파일에서 인증서를 추출해
$Store변수에 저장합니다.
PS C:\> $Store = [Security.Cryptography.X509Certificates.X509Certificate2Collection]::new([Security.Cryptography.X509Certificates.X509Certificate2]::new((Resolve-Path certificate.pem)))
- 서명을 검증합니다.
PS C:\> $SignatureDocument = [Security.Cryptography.Pkcs.SignedCms]::new()
PS C:\> $SignatureDocument.Decode($Signature)
PS C:\> $SignatureDocument.CheckSignature($Store, $true)
서명이 유효하면 명령이 출력 없이 반환됩니다. 검증할 수 없으면 Exception calling "CheckSignature" with "2" argument(s): "Cannot find the original signer가 반환됩니다. 검증할 수 없으면 AWS Support에 연락하세요.
7. 인스턴스 ID 문서의 내용을 검증합니다.
PS C:\> [Linq.Enumerable]::SequenceEqual($SignatureDocument.ContentInfo.Content, $Document)
내용이 유효하면 True가 반환됩니다. 검증할 수 없으면 AWS Support에 연락하세요.
옵션 2: base64 인코딩 서명으로 인스턴스 ID 문서 검증
이 주제에서는 base64 인코딩 서명과 AWS RSA 공개 인증서로 인스턴스 ID 문서를 검증하는 방법을 설명해요.
base64 인코딩 서명과 AWS RSA 공개 인증서로 검증하기
- 인스턴스에 연결합니다.
- 인스턴스 메타데이터에서 base64 인코딩 서명을 가져와 이진(binary)으로 변환하고
signature파일에 추가합니다.- IMDSv2
$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/signature | base64 -d >> signature
- IMDSv1
$ curl -s http://169.254.169.254/latest/dynamic/instance-identity/signature | base64 -d >> signature
- 인스턴스 메타데이터에서 일반 텍스트 인스턴스 ID 문서를 가져와
document파일에 추가합니다.- IMDSv2
$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/document >> document
- IMDSv1
$ curl -s http://169.254.169.254/latest/dynamic/instance-identity/document >> document
- 리전의 RSA 공개 인증서를 찾아 내용을
certificate파일에 추가합니다. - AWS RSA 공개 인증서에서 공개 키를 추출해
key파일에 저장합니다.
$ openssl x509 -pubkey -noout -in certificate >> key
- OpenSSL
dgst명령으로 인스턴스 ID 문서를 검증합니다.
$ openssl dgst -sha256 -verify key -signature signature document
- 서명이 유효하면
Verification successful메시지가 나타납니다. 이 명령은 인스턴스 ID 문서 내용도document파일에 기록하므로, 메타데이터의 문서와 다음 명령으로 비교할 수 있어요.
$ openssl dgst -sha256 < document
$ curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/document | openssl dgst -sha256
- 서명을 검증할 수 없으면 AWS Support에 연락하세요.
base64 인코딩 서명과 AWS RSA 공개 인증서로 검증하기 (PowerShell)
- 인스턴스에 연결합니다.
- 인스턴스 메타데이터에서 base64 인코딩 서명을 가져와 바이트 배열로 변환하고
$Signature변수에 추가합니다.- IMDSv2
PS C:\> [string]$token = (Invoke-WebRequest -Method Put -Headers @{'X-aws-ec2-metadata-token-ttl-seconds' = '21600'} http://169.254.169.254/latest/api/token).Content
PS C:\> $Signature = [Convert]::FromBase64String((Invoke-WebRequest -Headers @{'X-aws-ec2-metadata-token' = $Token} http://169.254.169.254/latest/dynamic/instance-identity/signature).Content)
- IMDSv1
PS C:\> $Signature = [Convert]::FromBase64String((Invoke-WebRequest http://169.254.169.254/latest/dynamic/instance-identity/signature).Content)
- 인스턴스 메타데이터에서 일반 텍스트 인스턴스 ID 문서를 가져와 바이트 배열로 변환하고
$Document변수에 추가합니다.- IMDSv2
PS C:\> $Document = [Text.Encoding]::UTF8.GetBytes((Invoke-WebRequest -Headers @{'X-aws-ec2-metadata-token' = $Token} http://169.254.169.254/latest/dynamic/instance-identity/document).Content)
- IMDSv1
PS C:\> $Document = [Text.Encoding]::UTF8.GetBytes((Invoke-WebRequest http://169.254.169.254/latest/dynamic/instance-identity/document).Content)
- 리전의 RSA 공개 인증서를 찾아 내용을
certificate.pem파일에 추가합니다. - 인스턴스 ID 문서를 검증합니다.
PS C:\> [Security.Cryptography.X509Certificates.X509Certificate2]::new((Resolve-Path certificate.pem)).PublicKey.Key.VerifyData($Document, 'SHA256', $Signature)
서명이 유효하면 True가 반환됩니다. 검증할 수 없으면 AWS Support에 연락하세요.
옵션 3: RSA-2048 서명으로 인스턴스 ID 문서 검증
이 주제에서는 RSA-2048 서명과 AWS RSA-2048 공개 인증서로 인스턴스 ID 문서를 검증하는 방법을 설명해요.
RSA-2048 서명과 AWS RSA-2048 공개 인증서로 검증하기
- 인스턴스에 연결합니다.
- 인스턴스 메타데이터에서 RSA-2048 서명을 가져와 필수 헤더·푸터와 함께
rsa2048파일에 추가합니다.- IMDSv2
$ echo "-----BEGIN PKCS7-----" >> rsa2048 \
&& TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/rsa2048 >> rsa2048 \
&& echo "" >> rsa2048 \
&& echo "-----END PKCS7-----" >> rsa2048
- IMDSv1
$ echo "-----BEGIN PKCS7-----" >> rsa2048 \
&& curl -s http://169.254.169.254/latest/dynamic/instance-identity/rsa2048 >> rsa2048 \
&& echo "" >> rsa2048 \
&& echo "-----END PKCS7-----" >> rsa2048
- 리전의 RSA-2048 공개 인증서를 찾아 내용을
certificate파일에 추가합니다. - OpenSSL
smime명령으로 서명을 검증합니다.-verify옵션은 서명 검증,-noverify옵션은 인증서 불검증을 나타냅니다.
$ openssl smime -verify -in rsa2048 -inform PEM -certfile certificate -noverify | tee document
- 서명이 유효하면
Verification successful메시지가 나타납니다. 검증할 수 없으면 AWS Support에 연락하세요.
사전 요건 — 이 절차는 System.Security Microsoft .NET Core 클래스가 필요해요. PowerShell 세션에 추가하려면 아래 명령을 실행합니다.
PS C:\> Add-Type -AssemblyName System.Security
참고 — 이 명령은 현재 PowerShell 세션에만 클래스를 추가해요. 새 세션에서는 다시 실행해야 합니다.
RSA-2048 서명과 AWS RSA-2048 공개 인증서로 검증하기 (PowerShell)
- 인스턴스에 연결합니다.
- RSA-2048 서명을 가져와 바이트 배열로 변환하고
$Signature변수에 추가합니다.- IMDSv2
PS C:\> [string]$token = (Invoke-WebRequest -Method Put -Headers @{'X-aws-ec2-metadata-token-ttl-seconds' = '21600'} http://169.254.169.254/latest/api/token).Content
PS C:\> $Signature = [Convert]::FromBase64String((Invoke-WebRequest -Headers @{'X-aws-ec2-metadata-token' = $Token} http://169.254.169.254/latest/dynamic/instance-identity/rsa2048).Content)
- IMDSv1
PS C:\> $Signature = [Convert]::FromBase64String((Invoke-WebRequest http://169.254.169.254/latest/dynamic/instance-identity/rsa2048).Content)
- 일반 텍스트 인스턴스 ID 문서를 가져와 바이트 배열로 변환하고
$Document변수에 추가합니다.- IMDSv2
PS C:\> $Document = [Text.Encoding]::UTF8.GetBytes((Invoke-WebRequest -Headers @{'X-aws-ec2-metadata-token' = $Token} http://169.254.169.254/latest/dynamic/instance-identity/document).Content)
- IMDSv1
PS C:\> $Document = [Text.Encoding]::UTF8.GetBytes((Invoke-WebRequest http://169.254.169.254/latest/dynamic/instance-identity/document).Content)
- 리전의 RSA-2048 공개 인증서를 찾아 내용을
certificate.pem파일에 추가합니다. - 인증서 파일에서 인증서를 추출해
$Store변수에 저장합니다.
PS C:\> $Store = [Security.Cryptography.X509Certificates.X509Certificate2Collection]::new([Security.Cryptography.X509Certificates.X509Certificate2]::new((Resolve-Path certificate.pem)))
- 서명을 검증합니다.
PS C:\> $SignatureDocument = [Security.Cryptography.Pkcs.SignedCms]::new()
PS C:\> $SignatureDocument.Decode($Signature)
PS C:\> $SignatureDocument.CheckSignature($Store, $true)
서명이 유효하면 출력 없이 반환됩니다. 검증할 수 없으면 Exception calling "CheckSignature" ... "Cannot find the original signer가 반환되며, 이 경우 AWS Support에 연락하세요.
7. 인스턴스 ID 문서 내용을 검증합니다.
PS C:\> [Linq.Enumerable]::SequenceEqual($SignatureDocument.ContentInfo.Content, $Document)
내용이 유효하면 True가 반환됩니다. 검증할 수 없으면 AWS Support에 연락하세요.