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 공개 인증서로 검증하기

  1. 인스턴스에 연결합니다.
  2. 인스턴스 메타데이터에서 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
  1. 리전의 DSA 공개 인증서를 "인스턴스 ID 문서 서명용 AWS 공개 인증서"에서 찾아 그 내용을 certificate라는 새 파일에 추가합니다.
  2. OpenSSL smime 명령으로 서명을 검증합니다. -verify 옵션은 서명을 검증해야 함을, -noverify 옵션은 인증서를 검증할 필요가 없음을 나타냅니다.
$ openssl smime -verify -in pkcs7 -inform PEM -certfile certificate -noverify | tee document
  1. 서명이 유효하면 Verification successful 메시지가 나타납니다.
  2. 이 명령은 인스턴스 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
  1. 서명을 검증할 수 없으면 AWS Support에 연락하세요.

사전 요건 — 이 절차는 System.Security Microsoft .NET Core 클래스를 필요로 해요. PowerShell 세션에 클래스를 추가하려면 다음 명령을 실행합니다.

PS C:\> Add-Type -AssemblyName System.Security

참고 — 이 명령은 현재 PowerShell 세션에만 클래스를 추가해요. 새 세션을 시작하면 명령을 다시 실행해야 합니다.

PKCS7 서명과 AWS DSA 공개 인증서로 검증하기 (PowerShell)

  1. 인스턴스에 연결합니다.
  2. 인스턴스 메타데이터에서 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)
  1. 인스턴스 메타데이터에서 일반 텍스트 인스턴스 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)
  1. 리전의 DSA 공개 인증서를 찾아 내용을 certificate.pem 파일에 추가합니다.
  2. 인증서 파일에서 인증서를 추출해 $Store 변수에 저장합니다.
PS C:\> $Store = [Security.Cryptography.X509Certificates.X509Certificate2Collection]::new([Security.Cryptography.X509Certificates.X509Certificate2]::new((Resolve-Path certificate.pem)))
  1. 서명을 검증합니다.
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 공개 인증서로 검증하기

  1. 인스턴스에 연결합니다.
  2. 인스턴스 메타데이터에서 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
  1. 인스턴스 메타데이터에서 일반 텍스트 인스턴스 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
  1. 리전의 RSA 공개 인증서를 찾아 내용을 certificate 파일에 추가합니다.
  2. AWS RSA 공개 인증서에서 공개 키를 추출해 key 파일에 저장합니다.
$ openssl x509 -pubkey -noout -in certificate >> key
  1. OpenSSL dgst 명령으로 인스턴스 ID 문서를 검증합니다.
$ openssl dgst -sha256 -verify key -signature signature document
  1. 서명이 유효하면 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
  1. 서명을 검증할 수 없으면 AWS Support에 연락하세요.

base64 인코딩 서명과 AWS RSA 공개 인증서로 검증하기 (PowerShell)

  1. 인스턴스에 연결합니다.
  2. 인스턴스 메타데이터에서 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)
  1. 인스턴스 메타데이터에서 일반 텍스트 인스턴스 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)
  1. 리전의 RSA 공개 인증서를 찾아 내용을 certificate.pem 파일에 추가합니다.
  2. 인스턴스 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 공개 인증서로 검증하기

  1. 인스턴스에 연결합니다.
  2. 인스턴스 메타데이터에서 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
  1. 리전의 RSA-2048 공개 인증서를 찾아 내용을 certificate 파일에 추가합니다.
  2. OpenSSL smime 명령으로 서명을 검증합니다. -verify 옵션은 서명 검증, -noverify 옵션은 인증서 불검증을 나타냅니다.
$ openssl smime -verify -in rsa2048 -inform PEM -certfile certificate -noverify | tee document
  1. 서명이 유효하면 Verification successful 메시지가 나타납니다. 검증할 수 없으면 AWS Support에 연락하세요.

사전 요건 — 이 절차는 System.Security Microsoft .NET Core 클래스가 필요해요. PowerShell 세션에 추가하려면 아래 명령을 실행합니다.

PS C:\> Add-Type -AssemblyName System.Security

참고 — 이 명령은 현재 PowerShell 세션에만 클래스를 추가해요. 새 세션에서는 다시 실행해야 합니다.

RSA-2048 서명과 AWS RSA-2048 공개 인증서로 검증하기 (PowerShell)

  1. 인스턴스에 연결합니다.
  2. 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)
  1. 일반 텍스트 인스턴스 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)
  1. 리전의 RSA-2048 공개 인증서를 찾아 내용을 certificate.pem 파일에 추가합니다.
  2. 인증서 파일에서 인증서를 추출해 $Store 변수에 저장합니다.
PS C:\> $Store = [Security.Cryptography.X509Certificates.X509Certificate2Collection]::new([Security.Cryptography.X509Certificates.X509Certificate2]::new((Resolve-Path certificate.pem)))
  1. 서명을 검증합니다.
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에 연락하세요.

더 알아보기 (Learn more)