1.13. 보안
서비스 메시 애플리케이션이 복잡한 마이크로 서비스를 사용하여 구성된 경우 Red Hat OpenShift Service Mesh를 사용하여 해당 서비스 간 통신 보안을 사용자 지정할 수 있습니다.
사전 준비 사항
샘플 애플리케이션은 보안 개념을 설명하는 데 도움이 됩니다.
1.13.1.
일부 프로토콜(IKE, SSH)에서는 기본 인증 모드이며, 다른 프로토콜(TLS)에서는 선택적입니다. TLS는 서비스 메시 인프라와 두 사이드카 프록시 사이에서 전적으로 처리됩니다.
기본적으로 Red Hat OpenShift Service Mesh의 mTLS가 활성화되고 허용 모드로 설정됩니다. 여기서 서비스 메시의 사이드카는 일반 텍스트 트래픽과 mTLS를 사용하여 암호화된 연결을 모두 허용합니다. 메시의 서비스가 메시 외부 서비스와 통신하는 경우 엄격한 mTLS가 해당 서비스 간의 통신을 중단할 수 있습니다. 워크로드를 서비스 메시로 마이그레이션하는 동안 허용 모드를 사용합니다. 그러면 메시, 네임스페이스 또는 애플리케이션 전반에서 엄격한 mTLS를 활성화할 수 있습니다.
ServiceMeshControlPlane
리소스의 데이터 플레인 수준에서 메시의 네임스페이스를 보호할 수 있습니다. 트래픽 암호화 연결을 사용자 지정하려면 PeerAuthentication
및 DestinationRule
리소스를 사용하여 애플리케이션 수준에서 네임스페이스를 구성합니다.
1.13.1.1. 서비스 메시에서 엄격한 mTLS 활성화
워크로드가 외부 서비스와 통신하지 않으면 통신 중단 없이 메시 전체에서 mTLS를 빠르게 활성화할 수 있습니다. ServiceMeshControlPlane
리소스에서 spec.security.dataPlane.mtls
를 true
로 설정하여 활성화할 수 있습니다. Operator는 필요한 리소스를 생성합니다.
apiVersion: maistra.io/v2 kind: ServiceMeshControlPlane spec: version: v2.3 security: dataPlane: mtls: true
절차
- 웹 콘솔에 로그인합니다.
-
Operators
설치된 Operators를 클릭합니다. - 제공된 API에서 Service Mesh Control Plane을 클릭합니다.
-
ServiceMeshControlPlane
리소스의 이름(예:production
)을 클릭합니다. - 세부 정보 페이지에서 데이터 플레인 보안의 보안 섹션에서 토글을 클릭합니다.
1.13.1.1.1. 특정 서비스의 수신 연결에 대해 사이드카 구성
정책을 생성하여 개별 서비스 또는 네임스페이스에 대해 mTLS를 구성할 수도 있습니다.
절차
다음 예제를 사용하여 YAML 파일을 생성합니다.
PeerAuthentication 정책 예 policy.yaml
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: <namespace> spec: mtls: mode: STRICT
-
<namespace>를
서비스가 있는 네임스페이스로 바꿉니다.
-
다음 명령을 실행하여 서비스가 있는 네임스페이스에 리소스를 생성합니다. 방금 생성한 정책 리소스의
namespace
필드와 일치해야 합니다.$ oc create -n <namespace> -f <policy.yaml>
자동 mTLS를 사용하지 않고 PeerAuthentication
을 STRICT으로 설정하는 경우 서비스에 대한 DestinationRule
리소스를 생성해야 합니다.
1.13.1.1.2. 발신 연결에 대한 사이드카 구성
메시에서 다른 서비스로 요청을 보낼 때 mTLS를 사용하도록 서비스 메시를 구성하는 대상 규칙을 생성합니다.
절차
다음 예제를 사용하여 YAML 파일을 생성합니다.
DestinationRule 예제 destination-rule.yaml
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: default namespace: <namespace> spec: host: "*.<namespace>.svc.cluster.local" trafficPolicy: tls: mode: ISTIO_MUTUAL
-
<namespace>
를 서비스가 있는 네임스페이스로 바꿉니다.
-
다음 명령을 실행하여 서비스가 있는 네임스페이스에 리소스를 생성합니다. 방금 생성한
DestinationRule
리소스의namespace
필드와 일치해야 합니다.$ oc create -n <namespace> -f <destination-rule.yaml>
1.13.1.1.3. 최소 및 최대 프로토콜 버전 설정
사용자 환경에 서비스 메시의 암호화된 트래픽에 대한 특정 요구 사항이 있는 경우 ServiceMeshControlPlane
리소스에 spec.security.controlPlane.tls.minProtocolVersion
또는 spec.security.controlPlane.tls.maxProtocolVersion
을 설정하여 허용되는 암호화 기능을 제어할 수 있습니다.
기본값은 TLS_AUTO
이며 TLS 버전을 지정하지 않습니다.
값 | 설명 |
---|---|
| default |
| TLS 버전 1.0 |
| TLS 버전 1.1 |
| TLS 버전 1.2 |
| TLS 버전 1.3 |
절차
- 웹 콘솔에 로그인합니다.
-
Operators
설치된 Operators를 클릭합니다. - 제공된 API에서 Service Mesh Control Plane을 클릭합니다.
-
ServiceMeshControlPlane
리소스의 이름(예:production
)을 클릭합니다. - YAML 탭을 클릭합니다.
YAML 편집기에 다음 코드 조각을 삽입합니다.
minProtocolVersion
의 값을 TLS 버전 값으로 바꿉니다. 이 예에서 최소 TLS 버전은TLSv1_2
로 설정됩니다.ServiceMeshControlPlane 스니펫
kind: ServiceMeshControlPlane spec: security: controlPlane: tls: minProtocolVersion: TLSv1_2
- 저장을 클릭합니다.
- 새로 고침을 클릭하여 변경 사항이 올바르게 업데이트되었는지 확인합니다.
1.13.1.2.
그림 1.5.
[D]
그림 1.6.
[D]
그림 1.7.
[D]
1.13.2. 역할 기반 액세스 제어(RBAC) 구성
RBAC(역할 기반 액세스 제어) 오브젝트에 따라 사용자 또는 서비스가 프로젝트 내에서 지정된 작업을 수행할 수 있는지가 결정됩니다. 메시의 워크로드에 대해 메시, 네임스페이스, 워크로드 전체 액세스 제어를 정의할 수 있습니다.
RBAC를 구성하려면 액세스를 구성하는 네임스페이스에 AuthorizationPolicy
리소스를 생성합니다.
예를 들어 RBAC를 사용하면 다음과 같은 정책을 생성할 수 있습니다.
- 프로젝트 내 통신을 구성합니다.
- 기본 네임스페이스의 모든 워크로드에 대한 전체 액세스를 허용하거나 거부합니다.
- 수신 게이트웨이 액세스를 허용 또는 거부합니다.
- 액세스 하려면 토큰이 필요합니다.
권한 부여 정책에는 선택기, 작업 및 규칙 목록이 포함됩니다.
-
selector
필드는 정책의 대상을 지정합니다. -
action
필드는 요청을 허용하거나 거부할지 여부를 지정합니다. rules
필드는 작업을 트리거할 시기를 지정합니다.-
from
필드는 요청 원본에 대한 제약 조건을 지정합니다. -
to
필드는 요청 대상 및 매개변수에 대한 제약 조건을 지정합니다. -
when
필드는 규칙을 적용하기 위한 추가 조건을 지정합니다.
-
프로세스
AuthorizationPolicy
리소스를 생성합니다. 다음 예제는 IP 주소가 수신 게이트웨이에 액세스하는 것을 거부하도록 ingress-policyAuthorizationPolicy
를 업데이트하는 리소스를 보여줍니다.apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: ingress-policy namespace: istio-system spec: selector: matchLabels: app: istio-ingressgateway action: DENY rules: - from: - source: ipBlocks: ["1.2.3.4"]
리소스를 작성한 후 다음 명령어를 실행하여 네임스페이스에 리소스를 만듭니다. 네임스페이스는
AuthorizationPolicy
리소스의metadata.namespace
필드와 일치해야 합니다.$ oc create -n istio-system -f <filename>
다음 단계
다른 일반적인 구성에 대해서는 다음 예제를 고려하십시오.
1.13.2.1. 프로젝트 내 통신 구성
1.13.2.1.1. 네임스페이스 외부 서비스에 대한 액세스 제한
다음 AuthorizationPolicy
리소스 예제를 사용하여 bookinfo
네임스페이스에 없는 모든 소스의 요청을 거부할 수 있습니다.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: httpbin-deny namespace: bookinfo spec: selector: matchLabels: app: httpbin version: v1 action: DENY rules: - from: - source: notNamespaces: ["bookinfo"]
1.13.2.1.2. 권한 부여 모두 허용 및 권한 부여 모두 거부(기본) 정책 만들기
다음 예제에서는 bookinfo
네임스페이스의 모든 워크로드에 액세스할 수 있는 권한 부여 모두 허용 정책을 보여줍니다.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-all namespace: bookinfo spec: action: ALLOW rules: - {}
다음 예제에서는 bookinfo
네임스페이스의 모든 워크로드에 대한 액세스를 거부하는 정책을 보여줍니다.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: bookinfo spec: {}
1.13.2.2. 수신 게이트웨이에 대한 액세스 허용 또는 거부
IP 주소를 기반으로 허용 또는 거부 목록을 추가하도록 권한 부여 정책을 설정할 수 있습니다.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: ingress-policy namespace: istio-system spec: selector: matchLabels: app: istio-ingressgateway action: ALLOW rules: - from: - source: ipBlocks: ["1.2.3.4", "5.6.7.0/24"]
1.13.2.3. JSON 웹 토큰으로 액세스 제한
JSON 웹 토큰(JWT)으로 메시에 액세스하는 항목을 제한할 수 있습니다. 인증 후 사용자 또는 서비스는 해당 토큰과 연결된 경로, 서비스에 액세스할 수 있습니다.
워크로드에서 지원하는 인증 방법을 정의하는 RequestAuthentication
리소스를 생성합니다. 다음 예제에서는 http://localhost:8080/auth/realms/master
에서 발행한 JWT를 수락합니다.
apiVersion: "security.istio.io/v1beta1" kind: "RequestAuthentication" metadata: name: "jwt-example" namespace: bookinfo spec: selector: matchLabels: app: httpbin jwtRules: - issuer: "http://localhost:8080/auth/realms/master" jwksUri: "http://keycloak.default.svc:8080/auth/realms/master/protocol/openid-connect/certs"
그런 다음, 동일한 네임스페이스에 AuthorizationPolicy
리소스를 생성하여, 사용자가 생성한 RequestAuthentication
리소스와 함께 작업할 수 있습니다. 다음 예제에서는 httpbin
워크로드에 요청을 보낼 때 Authorization
헤더에 JWT가 있어야 합니다.
apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "frontend-ingress" namespace: bookinfo spec: selector: matchLabels: app: httpbin action: DENY rules: - from: - source: notRequestPrincipals: ["*"]
1.13.3. 암호화 제품군 및 ECDH 곡선 구성
암호화 제품군 및 ECDH(Elliptic-curve Diffie–Hellman) 곡선은 서비스 메시를 보호하는 데 도움이 될 수 있습니다. 이러한 속성 중 하나가 비어 있으면 기본값이 사용됩니다.
서비스 메시에서 TLS 1.2 또는 이전 버전을 사용하는 경우 cipherSuites
설정이 적용됩니다. TLS 1.3을 사용할 때는 효과가 없습니다.
우선순위에 따라 암호화 제품군을 쉼표로 구분된 목록으로 설정합니다. 예를 들어 ecdhCurves: CurveP256, CurveP384
는 CurveP256
을 CurveP384
보다 높은 우선순위로 설정합니다.
암호화 제품군을 구성할 때 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
또는 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
을 포함해야 합니다. HTTP/2 지원에는 이러한 암호화 제품군 중 하나 이상이 필요합니다.
지원되는 암호화 제품군은 다음과 같습니다.
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
- TLS_RSA_WITH_AES_128_GCM_SHA256
- TLS_RSA_WITH_AES_256_GCM_SHA384
- TLS_RSA_WITH_AES_128_CBC_SHA256
- TLS_RSA_WITH_AES_128_CBC_SHA
- TLS_RSA_WITH_AES_256_CBC_SHA
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
- TLS_RSA_WITH_3DES_EDE_CBC_SHA
지원되는 ECDH 곡선은 다음과 같습니다.
- CurveP256
- CurveP384
- CurveP521
- X25519
1.13.4. 외부 인증 기관 키 및 인증서 추가
기본적으로 Red Hat OpenShift Service Mesh는 자체 서명된 루트 인증서와 키를 생성하고 이를 사용하여 워크로드 인증서에 서명합니다. 사용자 정의 인증서 및 키를 사용하여 사용자 정의 루트 인증서로 워크로드 인증서에 서명할 수도 있습니다. 이 작업은 인증서와 키를 서비스 메시에 연결하는 예제를 보여줍니다.
사전 요구 사항
- 인증서를 구성하려면 상호 TLS가 활성화된 Red Hat OpenShift Service Mesh를 설치합니다.
- 프로덕션의 경우 인증 기관의 자체 인증서를 사용합니다.
- 이러한 지침으로 결과를 확인하려면 Bookinfo 샘플 애플리케이션을 배포합니다.
1.13.4.1. 기존 인증서 및 키 추가
기존 서명(CA) 인증서 및 키를 사용하려면 CA 인증서, 키, 루트 인증서가 포함된 신뢰 파일 체인을 생성해야 합니다. 해당 인증서 각각에 대해 다음과 같은 정확한 파일 이름을 사용해야 합니다. CA 인증서를 ca-cert.pem
, 키는 ca-key.pem
이라고 합니다. ca-cert.pem
을 서명하는 루트 인증서는 root-cert.pem
이라고 합니다. 워크로드에서 중개 인증서를 사용하는 경우 cert-chain.pem
파일에 인증서를 지정해야 합니다.
$ oc create secret generic cacerts -n istio-system --from-file=<path>/ca-cert.pem \ --from-file=<path>/ca-key.pem --from-file=<path>/root-cert.pem \ --from-file=<path>/cert-chain.pem
기본
rootCADir
는/etc/cacerts
입니다. 키와 인증서가 기본 위치에 마운트된 경우privateKey
를 설정할 필요가 없습니다. 서비스 메시는 secret-mount 파일에서 인증서와 키를 읽습니다.apiVersion: maistra.io/v2 kind: ServiceMeshControlPlane spec: security: dataPlane: mtls: true certificateAuthority: type: Istiod istiod: type: PrivateKey privateKey: rootCADir: /etc/cacerts
$ oc -n istio-system delete pods -l 'app in (istiod,istio-ingressgateway, istio-egressgateway)'
$ oc -n bookinfo delete pods --all
출력은 다음과 유사합니다.
pod "details-v1-6cd699df8c-j54nh" deleted pod "productpage-v1-5ddcb4b84f-mtmf2" deleted pod "ratings-v1-bdbcc68bc-kmng4" deleted pod "reviews-v1-754ddd7b6f-lqhsv" deleted pod "reviews-v2-675679877f-q67r2" deleted pod "reviews-v3-79d7549c7-c2gjs" deleted
$ oc get pods -n bookinfo
1.13.4.2. 인증서 확인
$ sleep 60 $ oc -n bookinfo exec "$(oc -n bookinfo get pod -l app=productpage -o jsonpath={.items..metadata.name})" -c istio-proxy -- openssl s_client -showcerts -connect details:9080 > bookinfo-proxy-cert.txt $ sed -n '/-----BEGIN CERTIFICATE-----/{:start /-----END CERTIFICATE-----/!{N;b start};/.*/p}' bookinfo-proxy-cert.txt > certs.pem $ awk 'BEGIN {counter=0;} /BEGIN CERT/{counter++} { print > "proxy-cert-" counter ".pem"}' < certs.pem
<path>
를 인증서 경로로 교체합니다.$ openssl x509 -in <path>/root-cert.pem -text -noout > /tmp/root-cert.crt.txt
$ openssl x509 -in ./proxy-cert-3.pem -text -noout > /tmp/pod-root-cert.crt.txt
$ diff -s /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt
<path>
를 인증서 경로로 교체합니다.$ openssl x509 -in <path>/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt
$ openssl x509 -in ./proxy-cert-2.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt
$ diff -s /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt
루트 인증서에서 워크로드 인증서로의 인증서 체인을 확인합니다.
<path>
를 인증서 경로로 교체합니다.$ openssl verify -CAfile <(cat <path>/ca-cert.pem <path>/root-cert.pem) ./proxy-cert-1.pem
1.13.4.3. 인증서 제거
추가한 인증서를 제거하려면 다음 단계를 따르십시오.
시크릿
cacerts
를 제거합니다.$ oc delete secret cacerts -n istio-system
ServiceMeshControlPlane
리소스에서 자체 서명된 루트 인증서로 서비스 메시를 재배포합니다.apiVersion: maistra.io/v2 kind: ServiceMeshControlPlane spec: security: dataPlane: mtls: true