Blog
AWS Secure Shell (SSH) Einrichtung mit EC2 und CloudFormation

Bei binx.io schaffen wir unveränderliche Infrastrukturen. Mit Hilfe der Automatisierung und der gewünschten Statuskonfiguration nutzen wir CloudFormation für die Erstellung der Infrastruktur. Es ist jedoch nicht möglich, mit CloudFormation Amazon EC2-Instanzen zu erstellen, die mit einem Public/Private Key-Paar bereitgestellt werden. Aus diesem Grund hat Mark van Holsteijn, CTO
RSA und SSH
RSA-Schlüssel werden bei der Verschlüsselung mit öffentlichen Schlüsseln verwendet. Der Algorithmus verwendet einen privaten Schlüssel und einen abgeleiteten öffentlichen Schlüssel. Der private Schlüssel sollte geheim gehalten werden, aber der öffentliche Schlüssel kann mit anderen geteilt werden. RSA-Schlüssel werden bei der Einrichtung von Secure Shell oder 'SSH' verwendet. Bei Secure Shell wird der öffentliche Schlüssel auf dem Server gespeichert, um einen Client zu identifizieren. Denn bei RSA gibt es eine Eins-zu-Eins-Beziehung zwischen dem öffentlichen und dem privaten Schlüssel. Der Grund dafür ist, dass die öffentlichen Schlüssel von einem einzigen privaten Schlüssel abgeleitet werden. Der private Schlüssel wird vom Client verwendet, um sich beim Server anzumelden. Die Verbindung mit dem Server wird vom Client initiiert. Der Client verschlüsselt die SSH-Verbindung mit dem privaten Schlüssel. Der Server kann die Verbindung mit dem öffentlichen Schlüssel entschlüsseln. Die Sicherheit ist einfach: Nur der öffentliche Schlüssel kann eine mit dem privaten Schlüssel initiierte Verbindung entschlüsseln. Wenn die Entschlüsselung erfolgreich ist, weiß der Server automatisch, dass die Verbindung vertrauenswürdig ist.
Geheimnisse generieren
Der Secret Provider kann RSA-Schlüssel generieren. Der private Schlüssel wird im AWS-Parameterspeicher gespeichert. Der öffentliche Schlüssel ist verfügbar, wenn Sie den benutzerdefinierten Anbieter fragen. Ich habe den öffentlichen Schlüssel mit einer CloudFormation-Ausgabe exportiert. Der geheime Anbieter kann die RSA-Schlüssel auch als EC2 KeyPair speichern. Unten sehen Sie, wie Sie eine solche Konfiguration einrichten.
PrivateKey:
Type: Custom::RSAKey
Properties:
Name: /bastion/default/private-key
RefreshOnUpdate: false
ServiceToken: !GetAtt CFNSecretProvider.Arn
KeyPair:
Type: Custom::KeyPair
DependsOn: PrivateKey
Properties:
Name: BastionKeyPair
PublicKeyMaterial: !GetAtt 'PrivateKey.PublicKey'
ServiceToken: !GetAtt CFNSecretProvider.Arn
Der geheime Anbieter ist eine benutzerdefinierte Ressource von CloudFormation. Die Implementierung ist ein Lambda und muss in Ihrer AWS-Umgebung bereitgestellt werden.
CFNSecretProvider:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Sub 'binxio-public-${AWS::Region}'
S3Key: lambdas/cfn-secret-provider-0.13.2.zip
Handler: secrets.handler
MemorySize: 128
Role: !GetAtt 'CFNSecretProviderRole.Arn'
Runtime: python3.6
Timeout: 300
CFNSecretProviderLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub '/aws/lambda/${CFNSecretProvider}'
RetentionInDays: 30
Das Lambda braucht die entsprechenden Berechtigungen, um die Schlüssel zu erzeugen und zu speichern.
CFNSecretProviderRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Condition: {}
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: CFNCustomSecretProviderPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- iam:CreateAccessKey
- iam:UpdateAccessKey
- iam:DeleteAccessKey
- ssm:PutParameter
- ssm:GetParameter
- ssm:DeleteParameter
- ec2:ImportKeyPair
- ec2:DeleteKeyPair
Resource:
- '*'
- Effect: Allow
Action:
- kms:Encrypt
- kms:Decrypt
Resource:
- '*'
Eine EC2-Instanz kann mit dem KeyPair konfiguriert werden, das vom benutzerdefinierten Anbieter erstellt wurde.
BastionHost:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap ['NatAMI', 'eu-west-1', 'ami']
KeyName: BastionKeyPair
InstanceType: 't3.micro'
SourceDestCheck: false
SubnetId: !Ref PublicSubnet
SecurityGroupIds:
- !Ref BastionHostSecurityGroup
IamInstanceProfile: !Ref BastionInstanceProfile
BlockDeviceMappings:
- DeviceName: /dev/xvdcz
Ebs:
VolumeType: gp2
VolumeSize: 10
DeleteOnTermination: true
Encrypted: true
UserData:
Fn::Base64: !Sub |
#!/bin/bash
export AWS_DEFAULT_REGION=eu-west-1
yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
BastionInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref BastionRole
BastionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: /
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM'
- 'arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser'
Policies:
- PolicyName: gitlab-runner
PolicyDocument:
Statement:
- Effect: Allow
Action:
- ssm:GetParameter
Resource:
- !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/bastion/default/*'
BastionHostSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
Groupcontent: 'Security group for the bastion host'
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: '-1'
CidrIp: '0.0.0.0/0'
SecurityGroupEgress:
- IpProtocol: '-1'
CidrIp: '0.0.0.0/0'
Zugriff auf den privaten Schlüssel
Der private Schlüssel kann mit Hilfe der AWS CLI heruntergeladen werden. Sie benötigen den privaten Schlüssel, um eine SSH-Verbindung von Ihrem Computer zur EC2-Instanz zu initiieren.
# print the private key
aws ssm get-parameter --name /bastion/default/private-key --with-decryption | jq -r '.Parameter.Value'
# copy the private key to the clipboard
aws ssm get-parameter --name /bastion/default/private-key --with-decryption | jq -r '.Parameter.Value' | pbcopy
# writing the private key to 'bastion.pem'
aws ssm get-parameter --name /bastion/default/private-key --with-decryption | jq -r '.Parameter.Value' > bastion.pem
SSH einrichten
Um eine SSH-Verbindung aufzubauen, benötigen Sie Zugriff auf den privaten Schlüssel. Die Datei mit dem privaten Schlüssel benötigt die Berechtigung 0600. Geben Sie zum Anmelden make create && make ssh oder ein:
DNSNAME=`sceptre --output json describe-stack-outputs example vpc | jq -r '.[] | select(.OutputKey=="BastionHostPublicDnsName") | .OutputValue'`
ssh -i bastion.pem ec2-user@$DNSNAME
Beispiel
Das Beispielprojekt zeigt, wie Sie ein Projekt zur Erstellung von KeyPairs konfigurieren und wie Sie eine EC2-Instanz mit einem KeyPair mit CloudFormation konfigurieren. Das Beispiel kann mit make ssh ein.
Fazit
Mit dem binxio/cfn-secret-provider ist es möglich, mit AWS CloudFormation Geheimnisse zu erzeugen. In diesem Blog haben wir gesehen, wie RSA-Schlüssel erstellt werden, wie EC2-Schlüsselpaare erstellt werden und wie eine EC2-Instanz für die Verwendung dieses Schlüsselpaars konfiguriert wird. Wir haben auch gesehen, wie Sie Zugriff auf den privaten Schlüssel erhalten und wie Sie diesen Schlüssel verwenden, um eine SSH-Verbindung mit der EC2-Instanz herzustellen.
Verfasst von
Dennis Vriend
Unsere Ideen
Weitere Blogs
Contact



