VMConAWS: „Sichere“ S3 Content Library

Basierend auf den Blog Artikeln Create a vCenter Content Library using AWS S3 – Part 2 von Gilles Chekroun und Creating a vSphere Content Library directly on Amazon S3 von William Lam, auf die ich hier nicht weiter im Detail eingehen werde, möchte ich in diesem Beitrag den Fokus darauf legen, wie man die in Amazon S3 erzeugte Content Library absichern kann und sie nicht für jedermann public verfügbar macht.

Leider unterstützt die vom vCenter losgelöste Content Library die native Authentifizierung über Passwort nicht. Eine Alternative dazu lässt sich jedoch mit Hilfe von AWS Bordmitteln/Policies umsetzen. Außerdem soll der Zugriff auf die Content Library von einem VMware Cloud on AWS SDDC aus über das Elastic Network Interface (ENI) und somit ohne anfallende Outbound Data Transfer Kosten erfolgen, anstelle über das Internet Gateway.

Ausgangssituation

Bucket: vmw-contentlibs in N. Virginia (us-east-1)
SDDC: Singe Host in N. Virginia (us-east-1)
On-Premises: vSphere 7.0 Update 1 Home Lab
Workstation: Ubuntu Server 20.04 LTS

Anmerkung:
Um über das ENI auf die Content Library zugreifen zu können, müssen sich S3 Bucket und SDDC in der selben Region befinden, da hierfür ein VPC Gateway Endpoint benötigt wird und Gateway Endpoints nur innerhalb derselben Region unterstützt werden.

Zielkonfiguration

– S3 Content Library in N. Virginia (us-east-1)
– Zugriff nur vom On-Premises vCenter und dem SDDC vCenter in N. Virginia (us-east-1) erlaubt
– Zugriff vom SDDC aus über das Elastic Network Interface

Erstellen der S3 Content Library

Folgende Dateien wurden bereits in das Bucket hochgeladen und in einer „Ordnerstruktur“ (prefixes) organisiert.

vmw-contentlibs Inhalt (erstellt mit s3-tree von William Klier):

vmw-contentlibs
└── vmc
    ├── ISOs
    │   └── VeeamBackup&Replication_11.0.0.837_20210507.iso
    ├── Ubuntu_Server_20.04_LTS
    │   ├── Ubuntu_Server_20.04_LTS-1.vmdk
    │   ├── Ubuntu_Server_20.04_LTS-2.nvram
    │   ├── Ubuntu_Server_20.04_LTS.mf
    │   └── Ubuntu_Server_20.04_LTS.ovf
    └── Windows_Server_2019_Datacenter_EN
        ├── Windows_Server_2019_Datacenter_EN-1.vmdk
        ├── Windows_Server_2019_Datacenter_EN-2.nvram
        ├── Windows_Server_2019_Datacenter_EN.mf
        └── Windows_Server_2019_Datacenter_EN.ovf

Hinweis:
Sollte man beim Upload der Dateien über die AWS Console Probleme haben, so kann man diese auch über die AWS CLI durchführen. Bei abgebrochenen Multipart-Uploads bietet es sich an eine Lifecycle Rule einzurichten (s. auch hier). Außerdem werden nur OVFs unterstützt, keine OVAs.

Zur eigentlichen Erstellung der Content Library kommt nun die Ubuntu Server VM zum Einsatz. Dort installiert man die AWS CLI nach folgender Anleitung.

Zusammengefasst:

sudo apt install unzip python3-boto3
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version
aws configure

Anschließend lädt man das Skript von William Lam herunter und führt es aus:

wget https://vdc-download.vmware.com/sampleExchange/v1/downloads/4388 -O make_vcsp_2018.py
python3 make_vcsp_2018.py -n "VMC S3" -t s3 -p vmw-contentlibs/vmc

Nachdem das Skript erfolgreich ausgeführt wurde, sollte der Inhalt des vmw-contentlibs Buckets nun so aussehen:

vmw-contentlibs
└── vmc
    ├── ISOs
    │   ├── VeeamBackup&Replication_11.0.0.837_20210507
    │   │   └── item.json
    │   └── VeeamBackup&Replication_11.0.0.837_20210507.iso
    ├── items.json
    ├── lib.json
    ├── Ubuntu_Server_20.04_LTS
    │   ├── item.json
    │   ├── Ubuntu_Server_20.04_LTS-1.vmdk
    │   ├── Ubuntu_Server_20.04_LTS-2.nvram
    │   ├── Ubuntu_Server_20.04_LTS.mf
    │   └── Ubuntu_Server_20.04_LTS.ovf
    └── Windows_Server_2019_Datacenter_EN
        ├── item.json
        ├── Windows_Server_2019_Datacenter_EN-1.vmdk
        ├── Windows_Server_2019_Datacenter_EN-2.nvram
        ├── Windows_Server_2019_Datacenter_EN.mf
        └── Windows_Server_2019_Datacenter_EN.ovf

Jedes mal wenn zusätzliche ISOs oder OVFs hinzukommen muss das Skript natürlich erneut ausgeführt werden.

Erstellen eines S3 VPC Gateway Endpoints

Standardmäßig ist für das Connected VPC der S3 Service Access Enabled.

Das bedeutet der Zugriff auf den Amazon S3 Service innerhalb der gleichen Region erfolgt „private“ über das ENI über private IPv4 Adressen, statt „public“ über das Internet Gateway (IGW) mit öffentlichen IPv4 Adressen. Hierfür wird auf AWS Seite im Connected VPC allerdings zuerst noch ein Endpoint benötigt.

In der AWS Console wählt man den VPC Service aus, vergewissert sich, dass man sich in der richtigen Region befindet und klickt anschließend auf Endpoints.

Mit einem Klick auf Create Endpoints gelangt man zur Konfigurationsseite. Hier wählt man unter Service Category AWS services aus, fügt unter Service Name am besten einen Filter „s3“ hinzu und wählt com.amazonaws.us-east-1.s3 mit Type Gateway aus. Unter VPC wählt man das mit dem SDDC verbundene „connected“ VPC aus und setzt unter Configure route tables den Haken bei der Main route table.

Unter Policy hat man die Wahl zwischen Full Access oder Custom. Mit Full Access kann jeder User und Service innerhalb des VPCs auf alle Amazon S3 Ressourcen in der gleichen Region, auch in anderen Accounts, über private IPv4 Adressen zugreifen. Dies lässt sich mit der Option Custom entsprechend anpassen bzw. einschränken (s. auch hier).

Mit nachfolgender Policy ist der Zugriff über den VPC Endpoint, also auch vom SDDC aus, nur noch auf den Bucket-Folder, der die Content Library enthält und ein weiteres Bucket namens example-bucket mit den S3 Aktionen ListBucket, GetObject und PutObject erlaubt. Dies gilt für alle User und Services innerhalb des VPCs.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::vmw-contentlibs/vmc/*",
                "arn:aws:s3:::example-bucket",
                "arn:aws:s3:::example-bucket/*"
            ]
        }
    ]
}

Anmerkung:
Wie bereits erwähnt schränkt man hiermit allerdings nur den Zugriff auf S3 Ressourcen innerhalb der gleichen Region ein. Auf Buckets in anderen Regions greift man nach wie vor über das IGW zu und somit hat die VPC Endpoint Policy darauf keinen Einfluss. Die eigentliche „Absicherung“ des Buckets erfolgt über die Bucket Policy (s. nächster Abschnitt).

Abschließend erstellt man den Endpoint über Create endpoint.

Zurück in der Endpoints Übersicht findet man den gerade erstellten Endpoint und seine ID. Diese wird im nächsten Schritt für das Erstellen der Bucket Policy benötigt.

Konfiguration des Buckets

Nun wechselt man zur S3 Console, wählt das vmw-contentlibs Bucket aus und klickt auf Permissions. Unter Block public access (bucket settings) klickt man auf Edit, entfernt das Häkchen bei Block all public access und somit gleichzeitig auch alle anderen Häkchen, klickt auf Save changes und bestätigt die Änderung im sich daraufhin öffnenden Dialog-Fenster.

Im Anschluss wählt man unter Bucket policy Edit, kopiert nachfolgende Policy hinein, passt die On-Premises SourceIP und die VPC Endpoint ID an und klickt auf Save changes.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::vmw-contentlibs/vmc/*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": "XXX.XXX.XXX.XXX/32"
                },
                "StringNotEquals": {
                    "aws:SourceVpce": "vpce-XXXXXXXXXXXXXXXXX"
                }
            }
        }
    ]
}

Als nächstes wechselt man in den vmc Folder, wählt alle Objekte und Ordner aus und klickt unter Actions auf Make public.

Damit ist die Einrichtung des Buckets und der Content Library abgeschlossen.

Einbinden der Content Library

Im vCenter bindet man die Content Library nun wie gewohnt ein.

Menu -> Content Libraries -> + Create

Die Subscription URL erhält man über die S3 Console mit einem Klick auf die lib.json Datei im vmc Folder.

Anmerkung:
Um nicht unnötig vSAN Speicherplatz zu belegen, sollte man unter Download content die Option when needed wählen.

Nicht in der Bucket Policy angegebene IPs bzw. VPC Endpoints erhalten beim Versuch die Content Library einzubinden folgende Fehlermeldung:

Somit haben nur noch On-Premises vCenter und das mit dem VPC verbundene SDDC vCenter Zugriff auf die Content Library.

Fazit

Die S3 Content Library lässt sich nun sowohl von der angegebenen On-Premises IP aus einbinden als auch vom mit dem VPC verbundenen SDDC. Der Zugriff von anderen IPs ist nicht mehr möglich. Anzumerken ist hierbei noch, dass der Zugriff vom SDDC über das ENI „private“ erfolgt und somit keine Kosten verursacht. Das On-Premises vCenter greift jedoch „public“ auf die Content Library zu und sobald Daten geladen werden, fallen AWS Outbound Data Transfer Gebühren an.

Share this

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.