보안 및 컴플라이언스

Red Hat OpenShift Service on AWS 4

AWS 클러스터에서 보안 컨텍스트 제약 조건 구성

Red Hat OpenShift Documentation Team

초록

이 문서에서는 보안 컨텍스트 제약 조건을 구성하는 방법을 설명합니다.

1장. 감사 로그 보기

AWS 감사의 Red Hat OpenShift Service는 시스템의 개별 사용자, 관리자 또는 기타 구성 요소가 시스템에 영향을 준 활동 순서를 문서화하는 보안 관련 레코드 집합을 제공합니다.

1.1. API 감사 로그 정보

감사는 API 서버 수준에서 작동하며 서버로 들어오는 모든 요청을 기록합니다. 각 감사 로그에는 다음 정보가 포함됩니다.

표 1.1. 감사 로그 필드

필드설명

level

이벤트가 생성된 감사 수준입니다.

auditID

각 요청에 생성되는 고유 감사 ID입니다.

stage

이 이벤트 인스턴스가 생성되었을 때의 요청 처리 단계입니다.

requestURI

클라이언트에서 서버로 보낸 요청 URI입니다.

verb

요청과 관련된 Kubernetes 동사입니다. 리소스가 아닌 요청의 경우 소문자 HTTP 메서드입니다.

user

인증된 사용자 정보입니다.

impersonatedUser

선택 사항입니다. 요청에서 다른 사용자를 가장하는 경우 가장된 사용자 정보입니다.

sourceIPs

선택 사항입니다. 요청이 발생한 소스 IP 및 중간 프록시입니다.

userAgent

선택 사항입니다. 클라이언트에서 보고한 사용자 에이전트 문자열입니다. 사용자 에이전트는 클라이언트에서 제공하며 신뢰할 수 없습니다.

objectRef

선택 사항입니다. 이 요청의 대상이 되는 오브젝트 참조입니다. 이는 List 유형의 요청 또는 리소스가 아닌 요청에는 적용되지 않습니다.

responseStatus

선택 사항입니다. ResponseObjectStatus 유형이 아닌 경우에도 채워지는 응답 상태입니다. 성공적인 응답을 위해 여기에는 코드만 포함됩니다. 상태 유형이 아닌 오류 응답의 경우 오류 메시지가 자동으로 채워집니다.

requestObject

선택 사항입니다. 요청의 API 오브젝트로, JSON 형식으로 되어 있습니다. RequestObject는 버전 변환, 기본값 설정, 승인 또는 병합 전에 요청에 있는 그대로(JSON으로 다시 인코딩될 수 있음) 기록됩니다. 외부 버전이 지정된 오브젝트 유형이며 그 자체로는 유효한 오브젝트가 아닐 수 있습니다. 리소스가 아닌 요청의 경우 생략되며 요청 수준 이상에서만 기록됩니다.

responseObject

선택 사항입니다. 응답에서 반환된 API 오브젝트로, JSON 형식으로 되어 있습니다. ResponseObject는 외부 유형으로 변환된 후 기록되고 JSON으로 직렬화됩니다. 리소스가 아닌 요청의 경우 생략되며 응답 수준에서만 기록됩니다.

requestReceivedTimestamp

요청이 API 서버에 도달한 시간입니다.

stageTimestamp

요청이 현재 감사 단계에 도달한 시간입니다.

annotations

선택 사항: 인증, 권한 부여 및 승인 플러그인을 포함하여 요청 서비스 체인에서 호출한 플러그인에 의해 설정될 수 있는 감사 이벤트와 함께 저장된 구조화되지 않은 키 값 맵입니다. 이러한 주석은 감사 이벤트용이며 제출된 오브젝트의 metadata.annotations와 일치하지 않습니다. 키는 이름 충돌을 방지하기 위해 알림 구성 요소를 고유하게 식별해야 합니다(예: podsecuritypolicy.admission.k8s.io/policy). 값은 짧아야 합니다. 주석은 메타데이터 수준에 포함됩니다.

Kubernetes API 서버의 출력 예:

{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"ad209ce1-fec7-4130-8192-c4cc63f1d8cd","stage":"ResponseComplete","requestURI":"/api/v1/namespaces/openshift-kube-controller-manager/configmaps/cert-recovery-controller-lock?timeout=35s","verb":"update","user":{"username":"system:serviceaccount:openshift-kube-controller-manager:localhost-recovery-client","uid":"dd4997e3-d565-4e37-80f8-7fc122ccd785","groups":["system:serviceaccounts","system:serviceaccounts:openshift-kube-controller-manager","system:authenticated"]},"sourceIPs":["::1"],"userAgent":"cluster-kube-controller-manager-operator/v0.0.0 (linux/amd64) kubernetes/$Format","objectRef":{"resource":"configmaps","namespace":"openshift-kube-controller-manager","name":"cert-recovery-controller-lock","uid":"5c57190b-6993-425d-8101-8337e48c7548","apiVersion":"v1","resourceVersion":"574307"},"responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2020-04-02T08:27:20.200962Z","stageTimestamp":"2020-04-02T08:27:20.206710Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by ClusterRoleBinding \"system:openshift:operator:kube-controller-manager-recovery\" of ClusterRole \"cluster-admin\" to ServiceAccount \"localhost-recovery-client/openshift-kube-controller-manager\""}}

1.2. 감사 로그 보기

각 컨트롤 플레인 노드에 대한 OpenShift API 서버, Kubernetes API 서버, OpenShift OAuth API 서버 및 OpenShift OAuth 서버의 로그를 볼 수 있습니다.

절차

감사 로그를 보려면 다음을 수행합니다.

  • OpenShift API 서버 감사 로그를 확인합니다.

    1. 각 컨트롤 플레인 노드에 사용할 수 있는 OpenShift API 서버 감사 로그를 나열합니다.

      $ oc adm node-logs --role=master --path=openshift-apiserver/

      출력 예

      ci-ln-m0wpfjb-f76d1-vnb5x-master-0 audit-2021-03-09T00-12-19.834.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-0 audit.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-1 audit-2021-03-09T00-11-49.835.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-1 audit.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-2 audit-2021-03-09T00-13-00.128.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-2 audit.log

    2. 노드 이름과 로그 이름을 제공하여 특정 OpenShift API 서버 감사 로그를 확인합니다.

      $ oc adm node-logs <node_name> --path=openshift-apiserver/<log_name>

      예를 들면 다음과 같습니다.

      $ oc adm node-logs ci-ln-m0wpfjb-f76d1-vnb5x-master-0 --path=openshift-apiserver/audit-2021-03-09T00-12-19.834.log

      출력 예

      {"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"381acf6d-5f30-4c7d-8175-c9c317ae5893","stage":"ResponseComplete","requestURI":"/metrics","verb":"get","user":{"username":"system:serviceaccount:openshift-monitoring:prometheus-k8s","uid":"825b60a0-3976-4861-a342-3b2b561e8f82","groups":["system:serviceaccounts","system:serviceaccounts:openshift-monitoring","system:authenticated"]},"sourceIPs":["10.129.2.6"],"userAgent":"Prometheus/2.23.0","responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2021-03-08T18:02:04.086545Z","stageTimestamp":"2021-03-08T18:02:04.107102Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by ClusterRoleBinding \"prometheus-k8s\" of ClusterRole \"prometheus-k8s\" to ServiceAccount \"prometheus-k8s/openshift-monitoring\""}}

  • Kubernetes API 서버 감사 로그를 확인합니다.

    1. 각 컨트롤 플레인 노드에 사용할 수 있는 Kubernetes API 서버 감사 로그를 나열합니다.

      $ oc adm node-logs --role=master --path=kube-apiserver/

      출력 예

      ci-ln-m0wpfjb-f76d1-vnb5x-master-0 audit-2021-03-09T14-07-27.129.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-0 audit.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-1 audit-2021-03-09T19-24-22.620.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-1 audit.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-2 audit-2021-03-09T18-37-07.511.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-2 audit.log

    2. 노드 이름과 로그 이름을 제공하여 특정 Kubernetes API 서버 감사 로그를 확인합니다.

      $ oc adm node-logs <node_name> --path=kube-apiserver/<log_name>

      예를 들면 다음과 같습니다.

      $ oc adm node-logs ci-ln-m0wpfjb-f76d1-vnb5x-master-0 --path=kube-apiserver/audit-2021-03-09T14-07-27.129.log

      출력 예

      {"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"cfce8a0b-b5f5-4365-8c9f-79c1227d10f9","stage":"ResponseComplete","requestURI":"/api/v1/namespaces/openshift-kube-scheduler/serviceaccounts/openshift-kube-scheduler-sa","verb":"get","user":{"username":"system:serviceaccount:openshift-kube-scheduler-operator:openshift-kube-scheduler-operator","uid":"2574b041-f3c8-44e6-a057-baef7aa81516","groups":["system:serviceaccounts","system:serviceaccounts:openshift-kube-scheduler-operator","system:authenticated"]},"sourceIPs":["10.128.0.8"],"userAgent":"cluster-kube-scheduler-operator/v0.0.0 (linux/amd64) kubernetes/$Format","objectRef":{"resource":"serviceaccounts","namespace":"openshift-kube-scheduler","name":"openshift-kube-scheduler-sa","apiVersion":"v1"},"responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2021-03-08T18:06:42.512619Z","stageTimestamp":"2021-03-08T18:06:42.516145Z","annotations":{"authentication.k8s.io/legacy-token":"system:serviceaccount:openshift-kube-scheduler-operator:openshift-kube-scheduler-operator","authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by ClusterRoleBinding \"system:openshift:operator:cluster-kube-scheduler-operator\" of ClusterRole \"cluster-admin\" to ServiceAccount \"openshift-kube-scheduler-operator/openshift-kube-scheduler-operator\""}}

  • OpenShift OAuth API 서버 감사 로그를 확인합니다.

    1. 각 컨트롤 플레인 노드에 사용할 수 있는 OpenShift OAuth API 서버 감사 로그를 나열합니다.

      $ oc adm node-logs --role=master --path=oauth-apiserver/

      출력 예

      ci-ln-m0wpfjb-f76d1-vnb5x-master-0 audit-2021-03-09T13-06-26.128.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-0 audit.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-1 audit-2021-03-09T18-23-21.619.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-1 audit.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-2 audit-2021-03-09T17-36-06.510.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-2 audit.log

    2. 노드 이름과 로그 이름을 제공하여 특정 OpenShift OAuth API 서버 감사 로그를 확인합니다.

      $ oc adm node-logs <node_name> --path=oauth-apiserver/<log_name>

      예를 들면 다음과 같습니다.

      $ oc adm node-logs ci-ln-m0wpfjb-f76d1-vnb5x-master-0 --path=oauth-apiserver/audit-2021-03-09T13-06-26.128.log

      출력 예

      {"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"dd4c44e2-3ea1-4830-9ab7-c91a5f1388d6","stage":"ResponseComplete","requestURI":"/apis/user.openshift.io/v1/users/~","verb":"get","user":{"username":"system:serviceaccount:openshift-monitoring:prometheus-k8s","groups":["system:serviceaccounts","system:serviceaccounts:openshift-monitoring","system:authenticated"]},"sourceIPs":["10.0.32.4","10.128.0.1"],"userAgent":"dockerregistry/v0.0.0 (linux/amd64) kubernetes/$Format","objectRef":{"resource":"users","name":"~","apiGroup":"user.openshift.io","apiVersion":"v1"},"responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2021-03-08T17:47:43.653187Z","stageTimestamp":"2021-03-08T17:47:43.660187Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by ClusterRoleBinding \"basic-users\" of ClusterRole \"basic-user\" to Group \"system:authenticated\""}}

  • OpenShift OAuth 서버 감사 로그를 확인합니다.

    1. 각 컨트롤 플레인 노드에 사용할 수 있는 OpenShift OAuth 서버 감사 로그를 나열합니다.

      $ oc adm node-logs --role=master --path=oauth-server/

      출력 예

      ci-ln-m0wpfjb-f76d1-vnb5x-master-0 audit-2022-05-11T18-57-32.395.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-0 audit.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-1 audit-2022-05-11T19-07-07.021.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-1 audit.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-2 audit-2022-05-11T19-06-51.844.log
      ci-ln-m0wpfjb-f76d1-vnb5x-master-2 audit.log

    2. 노드 이름과 로그 이름을 지정하여 특정 OpenShift OAuth 서버 감사 로그를 확인합니다.

      $ oc adm node-logs <node_name> --path=oauth-server/<log_name>

      예를 들면 다음과 같습니다.

      $ oc adm node-logs ci-ln-m0wpfjb-f76d1-vnb5x-master-0 --path=oauth-server/audit-2022-05-11T18-57-32.395.log

      출력 예

      {"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"13c20345-f33b-4b7d-b3b6-e7793f805621","stage":"ResponseComplete","requestURI":"/login","verb":"post","user":{"username":"system:anonymous","groups":["system:unauthenticated"]},"sourceIPs":["10.128.2.6"],"userAgent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0","responseStatus":{"metadata":{},"code":302},"requestReceivedTimestamp":"2022-05-11T17:31:16.280155Z","stageTimestamp":"2022-05-11T17:31:16.297083Z","annotations":{"authentication.openshift.io/decision":"error","authentication.openshift.io/username":"kubeadmin","authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":""}}

      authentication.openshift.io/decision 주석에 사용 가능한 값은 allow,deny 또는 error 입니다.

1.3. 감사 로그 필터링

jq 또는 다른 JSON 구문 분석 툴을 사용하여 API 서버 감사 로그를 필터링할 수 있습니다.

참고

설정된 감사 로그 정책에 의해 API 서버 감사 로그에 기록되는 정보의 양을 제어할 수 있습니다.

다음 절차에서는 jq를 사용하여 컨트롤 플레인 노드node-1.example.com에서 감사 로그를 필터링하는 예를 제공합니다. jq를 사용하는 방법에 대한 자세한 내요ㅇ은 jq 설명서를 참조하십시오.

사전 요구 사항

  • dedicated-admin 역할의 사용자로 클러스터에 액세스할 수 있습니다.
  • jq를 설치했습니다.

절차

  • 사용자가 OpenShift API 서버 감사 로그를 필터링합니다.

    $ oc adm node-logs node-1.example.com  \
      --path=openshift-apiserver/audit.log \
      | jq 'select(.user.username == "myusername")'
  • 사용자 에이전트가 OpenShift API 서버 감사 로그를 필터링합니다.

    $ oc adm node-logs node-1.example.com  \
      --path=openshift-apiserver/audit.log \
      | jq 'select(.userAgent == "cluster-version-operator/v0.0.0 (linux/amd64) kubernetes/$Format")'
  • 특정 API 버전 별로 Kubernetes API 서버 감사 로그를 필터링하고 사용자 에이전트만 출력합니다.

    $ oc adm node-logs node-1.example.com  \
      --path=kube-apiserver/audit.log \
      | jq 'select(.requestURI | startswith("/apis/apiextensions.k8s.io/v1beta1")) | .userAgent'
  • 동사 제외하여 OpenShift OAuth API 서버 감사 로그를 필터링합니다.

    $ oc adm node-logs node-1.example.com  \
      --path=oauth-apiserver/audit.log \
      | jq 'select(.verb != "get")'
  • 사용자 이름을 식별하고 오류와 함께 실패한 이벤트로 OpenShift OAuth 서버 감사 로그를 필터링합니다.

    $ oc adm node-logs node-1.example.com  \
      --path=oauth-server/audit.log \
      | jq 'select(.annotations["authentication.openshift.io/username"] != null and .annotations["authentication.openshift.io/decision"] == "error")'

1.4. 감사 로그 수집

must-gather 툴을 사용하여 클러스터 디버깅을 위한 감사 로그를 수집할 수 있으며, 이를 통해 Red Hat 지원을 검토하거나 보낼 수 있습니다.

절차

  1. -- /usr/bin/gather_audit_logs 를 사용하여 oc adm must-gather 명령을 실행합니다.

    $ oc adm must-gather -- /usr/bin/gather_audit_logs
  2. 작업 디렉토리에서 생성된 must-gather 디렉토리에서 압축 파일을 만듭니다. 예를 들어 Linux 운영 체제를 사용하는 컴퓨터에서 다음 명령을 실행합니다.

    $ tar cvaf must-gather.tar.gz must-gather.local.472290403699006248 1
    1
    must-gather-local.472290403699006248 을 실제 디렉터리 이름으로 교체합니다.
  3. 압축 파일을 Red Hat 고객 포털 고객 지원 페이지의 지원 케이스에 첨부합니다.

1.5. 추가 리소스

2장. IP 기반 AWS 역할 가정에 대한 추가 제약 조건 추가

AWS 계정에서 추가 보안 계층을 구현하여 역할 가정이 허용되지 않은 IP 주소에서 발생하지 않도록 할 수 있습니다.

2.1. ID 기반 IAM 정책 생성

요청이 Red Hat 제공 IP 이외의 IP 주소에서 시작된 경우 모든 AWS 작업에 대한 액세스를 거부하는 IAM(ID 기반 ID 및 액세스 관리) 정책을 생성할 수 있습니다.

사전 요구 사항

  • IAM 정책을 생성하고 수정하는 데 필요한 권한이 있는 AWS Management Console 에 액세스할 수 있습니다.

절차

  1. AWS 계정 인증 정보를 사용하여 AWS Management 콘솔에 로그인합니다.
  2. IAM 서비스로 이동합니다.
  3. IAM 콘솔의 왼쪽 탐색 메뉴에서 정책을 선택합니다.
  4. 정책 생성을 클릭합니다.
  5. JSON 형식을 사용하여 정책을 정의할 JSON 탭을 선택합니다.
  6. JSON 정책 문서에 입력해야 하는 IP 주소를 가져오려면 다음 명령을 실행합니다.

    $ ocm get /api/clusters_mgmt/v1/trusted_ip_addresses
    참고

    이러한 IP 주소는 영구적이지 않으며 변경될 수 있습니다. API 출력을 지속적으로 검토하고 JSON 정책 문서에서 필요한 업데이트를 수행해야 합니다.

  7. 다음 policy_document.json 파일을 복사하여 편집기에 붙여넣습니다.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Deny",
                "Action": "*",
                "Resource": "*",
                "Condition": {
                    "NotIpAddress": {
                        "aws:SourceIp": []
                    },
                    "Bool": {
                        "aws:ViaAWSService": "false"
                    }
                }
            }
        ]
    }
  8. 6단계에서 가져온 모든 IP 주소를 복사하여 policy_document.json 파일의 "aws:SourceIp": [] 배열에 붙여넣습니다.
  9. 검토 및 생성을 클릭합니다.
  10. 정책에 대한 이름 및 설명을 제공하고 정확성을 위해 세부 정보를 검토하십시오.
  11. 정책 생성 을 클릭하여 정책을 저장합니다.
참고

초기 호출에 따라 후속 호출을 성공하려면 조건 키 aws:ViaAWSService 를 false로 설정해야 합니다. 예를 들어 aws ec2 describe-instances 를 처음 호출하면 ec2 인스턴스에 연결된 EBS 볼륨에 대한 정보를 검색하기 위해 AWS API 서버 내에서 수행된 모든 후속 호출은 조건 키 aws:ViaAWSService 가 false로 설정되지 않은 경우 실패합니다. 이후 호출은 AllowList에 포함되지 않은 AWS IP 주소에서 시작되므로 실패합니다.

2.2. ID 기반 IAM 정책 연결

ID 기반 IAM 정책을 생성한 후에는 해당 엔티티에 대한 IP 기반 역할 추정을 방지하기 위해 AWS 계정의 관련 IAM 사용자, 그룹 또는 역할에 연결합니다.

절차

  1. AWS 관리 콘솔에서 IAM 콘솔로 이동합니다.
  2. 정책을 연결할 기본 IAM Managed OpenShift-Support-Role 역할을 선택합니다.

    참고

    기본 IAM ManagedOpenShift-Support-Role 역할을 변경할 수 있습니다. 역할에 대한 자세한 내용은 Red Hat 지원 액세스를 참조하십시오.

  3. 권한 탭의 권한 추가 또는 권한 추가 드롭다운 목록에서 사용 권한 추가 또는 인라인 정책 생성 을 선택합니다.
  4. 이전에 생성한 정책을 검색합니다.

    1. 정책 이름을 입력합니다.
    2. 적절한 범주별로 필터링합니다.
  5. 정책을 선택하고 Attach policy 를 클릭합니다.
중요

효과적인 IP 기반 역할 추정을 위해서는 허용 IP를 최신 상태로 유지해야 합니다. 이렇게 하지 않으면 Red Hat 사이트 안정성 엔지니어링(SRE)이 계정에 액세스할 수 없으며 SLA에 영향을 미칠 수 있습니다. 추가 질문이 있거나 도움이 필요한 경우 지원 팀에 문의하십시오.

2.3. 추가 리소스

법적 공지

Copyright © 2024 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.