블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

쿠버네티스 #19

보안 4/4 - Pod Security Policy

조대협 (http://bcho.tistory.com)



SecurityContext가 컨테이너나 Pod의 보안 기능을 정의 하는 것이라면, Pod Security Policy (이하 PSP)는 보안 기능에 대한 정책을 정의 하는 것이다.

예를 들어, 정책으로 Pod를 생성할때는 반드시 root 사용자를 사용하지 못하도록 강제한다던지, Privileged 모드를 사용못하도록 강제할 수 있다. 현재는 (2018년9월1일) 베타 상태이기 때문에 다소의 기능 변경이 있을 수 있음을 염두하고 사용하도록 하자.

개념

개념이 복잡하기 때문에 먼저 기본적인 개념을 이해한 후에, 각 상세를 살펴보도록 하자.

먼저 아래 그림을 보자 PSP는 생성후에, 사용자에게 지정이 된다.

그리고 Pod를 생성할때, Pod의 보안 요건을 SecurityContext를 이용해서 Pod 설정에 정의한다.

Pod를 생성하려고 할때, 생성자(사용자)의 PSP를 레퍼런스 하는데, Pod의 보안 요건이 사용자에게 정의되어 있는 PSP 요건을 만족하면, Pod가 생성된다.



반대로, Pod를 생성할때, Pod의 보안 요건 (SecurityContext)가 Pod를 생성하고자하는 사용자의 PSP요건을 만족하지 않으면, Pod 생성이 거부된다. 아래 그림은 사용자의 PSP에서 Privileged 모드를 사용할 수 없도록 설정하였으나, Pod를 생성할때 Privileged 모드를 Pod 가 사용할 수 있도록 설정하였기 때문에, Pod를 생성에 실패하는 흐름이다.




Pod Security Policy

Pod Security Policy는 Security Context와 달리 클러스터 리소스 (Cluster Resource)이다.

즉 적용하는 순간 클러스터 전체에 적용이 된다는 이야기이다.


정책 종류

Pod Security Policy를 통해서 통제할 수 있는 정책은 다음과 같다.

(출처 https://kubernetes.io/docs/concepts/policy/pod-security-policy/) 자세한 내용은 원본 출처를 참고하기 바란다.


Control Aspect

Field Names

Running of privileged containers

privileged

Usage of host namespaces

hostPID, hostIPC

Usage of host networking and ports

hostNetwork, hostPorts

Usage of volume types

volumes

Usage of the host filesystem

allowedHostPaths

White list of Flexvolume drivers

allowedFlexVolumes

Allocating an FSGroup that owns the pod’s volumes

fsGroup

Requiring the use of a read only root file system

readOnlyRootFilesystem

The user and group IDs of the container

runAsUser, supplementalGroups

Restricting escalation to root privileges

allowPrivilegeEscalation, defaultAllowPrivilegeEscalation

Linux capabilities

defaultAddCapabilities, requiredDropCapabilities, allowedCapabilities

The SELinux context of the container

seLinux

The AppArmor profile used by containers

annotations

The seccomp profile used by containers

annotations

The sysctl profile used by containers

annotations



포맷

PSP의 포맷을 이해하기 위해서 아래 예제를 보자

apiVersion: extensions/v1beta1

kind: PodSecurityPolicy

metadata:

 name: nonroot-psp

spec:

 seLinux:

   rule: RunAsAny

 supplementalGroups:

   rule: RunAsAny

 runAsUser:

   rule: MustRunAsNonRoot

 fsGroup:

   rule: RunAsAny

 volumes:

 - '*'


nonroot-psp 라는 이름으로 PSP를 정의하였고, seLinux,supplementalGroup,fsGroup과 volumes(디스크)에 대한 권한은 모두 허용하였다. runAsUser에 rule (규칙)을 MustRunAsNonRoot로 지정해서, 이 정책을 적용 받은 사용자는 Pod를 생성할때 Pod가 반드시 root 사용자가 아닌 다른 사용자를 지정하도록 정의했다.

PSP 사용자 적용

PSP 를 정의하고 실행한다고 해도, 실제로 적용되지 않는다. PSP를 적용하기 위해서는 생성한 PSP를 RBAC을 이용하여 ClusterRole을 만들고, 이 ClusterRole을 사용자에게 부여해야 실제로 정책이 적용되기 시작한다. 사용자에게 PSP를 적용하는 부분은 뒤의 예제에서 살펴보자

이때 주의할점은 사용자의 정의인데, 쉽게 생각하면 사용자를 사람으로만 생각할 수 있는데, 쿠버네티스의 사용자는 사람이 될 수 도 있지만 서비스 어카운트 (Service account)가 될 수 도 있다.

쿠버네티스에서 Pod를 생성하는 주체는 사용자가 kubectl 등으로 Pod를 직접생성할 경우, 사람이 사용자가 되지만, 대부분의 경우 Pod의 생성과 관리는 Deployment나 ReplicaSet과 같은 컨트롤러를 이용하기 때문에, 이 경우에는 컨트롤러들이 사용하는 서비스 어카운트가 사용자가 되는 경우가 많다.

그래서, PSP를 적용하는 대상은 일반 사용자가 될 수 도 있지만 서비스 어카운트에 PSP를 적용해야 하는 경우가 많다는 것을 반드시 기억해야 한다.

PSP 활성화

PSP는 쿠버네티스 클러스터에 디폴트로는 비활성화 되어 있다. PSP 기능을 사용하기 위해서는 이를 활성화 해야 하는데, PSP는 admission controller에 의해서 컨트롤 된다.

구글 클라우드

구글 클라우드에서 PSP를 활성화 하는 방법은 아래와 같이 gcloud 명령을 이용하면 된다.


%gcloud beta container clusters update {쿠버네티스 클러스터 이름} --enable-pod-security-policy --zone={클러스터가 생성된 구글 클라우드 존}


만약에 활성화된 PSP 기능을 비활성화 하고 싶으면 아래와 같이 gcloud 에서 --no-enable-pod-security-policy  옵션을 사용하면 된다.


gcloud beta container clusters update {쿠버네티스 클러스터 이름}  --no-enable-pod-security-policy --zone={클러스터가 생성된 구글 클라우드 존}

Minikube

minikube start --extra-config=apiserver.GenericServerRunOptions.AdmissionControl=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds,PodSecurityPolicy


주의할점은 PSP 기능이 활성화된후에, PSP가 적용되지 않은 사용자(사람과, 서비스어카운트 모두)의 경우에는 Pod를 생성할 수 없기 때문에, 기존에 잘 생성되던 Pod가 갑자기 생성되지 않는 경우가 많기 때문에, 반드시 기능을 활성화하기 전에 반드시, 사용자마다 적절한 PSP를 생성해서 적용하기 바란다. (PSP기능을 활성화하지 않더라도 기본적으로 PSP 정의및, PSP를 사용자에게 적용하는 것은 가능하다.)

예제

개념에 대한 이해가 끝났으면 이제 실제 예제를 통해서 어떻게 PSP를 생성 및 적용하는지를 알아보도록 하자. 예제는 다음 순서로 진행하도록 한다.

  1. PSP 정의 : Root 권한을 사용이 불가능한 PSP를 생성한다.

  2. 서비스 어카운트 생성 : PSP를 생성할 서비스 어카운트를 생성한다. Pod를 바로 생성하는 것이 아니라 Deployment를 통해서 생성할것이기 때문에 Deployment에서 이 서비스 어카운트를 사용할것이다.

  3. ClusterRole 생성 : 다음 1에서 만든 PSP를 2에서 만든 서비스 어카운트에 적용하기 위해서, PSP를 가지고 있는 ClusterRole을 생성한다.

  4. ClusterRoleBinding을 이용하여 서비스 어카운트에 PSP 적용 : 3에서 만든 ClusterRole을 2에서 만든 서비스 어카운트에 적용한다.

  5. Admission controller 활성화 : PSP를 사용하기 위해서 Admission controller를 활성화 한다.

  6. Pod 정의 및 생성 : 2에서 만든 서비스 어카운트를 이용하여 Deployment 를 정의한다.

  7. 테스트 : 테스트를 위해서, root user를 사용하는 deployment와, root user를 사용하지 않는 deployment 두개를 각각 생성해서 psp 가 제대로 적용되는지를 확인한다.

PSP 정의

PSP를 정의해보자. 아래와 같이 nonroot-psp.yaml 을 작성한다. 이 PSP는 runAsUser에서 MustRunAsNotRoot 규칙을 추가해서, Root 권한으로 컨테이너가 돌지 않도록 하는 정책이다.


# nonroot-psp.yaml

apiVersion: extensions/v1beta1

kind: PodSecurityPolicy

metadata:

 name: nonroot-psp

spec:

 seLinux:

   rule: RunAsAny

 supplementalGroups:

   rule: RunAsAny

 runAsUser:

   rule: MustRunAsNonRoot

 fsGroup:

   rule: RunAsAny

 volumes:

 - '*'


파일을 nonroot-psp.yaml 파일로 저장한후에,

%kubectl create -f nonroot-psp.yaml

명령어를 이용하여 PSP를 생성한후에,

%kubectl get psp

명령을 이용하여, PSP가 생성된것을 확인하자




서비스 어카운트 생성

서비스 어카운트 생성을 위해서 아래 yaml 파일을 작성하고, 서비스 어카운트를 생성하여 확인하자


#nonroot-sa.yaml

apiVersion: v1

kind: ServiceAccount

metadata:

 name: nonroot-sa



ClusterRole 생성 및 적용

서비스 어카운트를 생성하였으면, 앞에 만든 PSP nonroot-psp 를 사용하는 ClusterRole nonroot-clusterrole을 생성하고, 이 롤을 nonroot-clusterrole-bindings를 이용하여, 앞서 만든 서비스 어카운트 nonroot-sa 에 연결한다.


아래와 같이 ClusterRole을 생성하는데, resouces 타입을 podsecuritypolicies 로 정의하고, 리소스 이름은 앞에서 생성한 PSP인 nonroot-psp로 지정한다. 그리고, 이 psp를 사용하기 위해서 verb는 “use”로 지정한다

#nonroot-clusterbinding.yaml

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

 name: nonroot-clusterrole

rules:

- apiGroups:

 - policy

 resources:

 - podsecuritypolicies

 resourceNames:

 - nonroot-psp

 verbs:

 - use


%kubectl create -f nonroot-clusterrole.yaml

명령어를 이용하여 위의 ClusterRole을 생성한후에, 이 ClusterRole을 서비스 어카운트 nonroot-sa 에 적용하자.

아래와 같이 nonroot-clusterrolebinding.yaml 를 생성한후,


#nonroot-clusterrolebinding.yaml

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding

metadata:

 name: nonroot-clusterrole-bindings

subjects:

- kind: ServiceAccount

 name: sa-nonroot

 namespace: default

roleRef:

 apiGroup: rbac.authorization.k8s.io

 kind: ClusterRole

 name: nonroot-clusterrole


%kubectl create -f nonroot-clusterrolebinding.yaml

명령어를 이용하여 ClusterRole nonroot-clusterrole을 서비스 어카운트 sa-nonroot에 적용한다.

도커 컨테이너 생성

이제 PSP가 생성되었고, 이 PSP를 사용하는 서비스 어카운트 nonroot-sa 가 완성되었으면, 이를 실제로 배포에 적용해보자. 배포에 앞서서 컨테이너 이미지를 만든다.

아래는 Docker 파일인데, 앞의 보안 컨텍스트 설명때 사용한 컨테이너와 동일하다.


#Dockerfile

FROM node:carbon

EXPOSE 8080

RUN groupadd -r -g 2001 appuser && useradd -r -u 1001 -g appuser appuser

RUN mkdir /home/appuser && chown appuser /home/appuser

USER appuser

WORKDIR /home/appuser

COPY --chown=appuser:appuser server.js .

CMD node server.js > /home/appuser/log.out

생성된 도커이미지를 gcr.io/terrycho-sandbox/nonroot-containe:v1 이름으로 docker push 명령을 이용해서  컨테이너 레지스트리에 등록한다.

PSP 기능 활성화

이미지까지 준비가 되었으면, 이제 Pod를 생성할 모든 준비가 되었는데, PSP를 사용하려면, 쿠버네티스 클러스터에서 PSP 기능을 활성화 해야 한다.

다음 명령어를 이용해서 PSP를 활성화한다.

%gcloud beta container clusters update {쿠버네티스 클러스터 이름} --enable-pod-security-policy --zone={클러스터가 생성된 구글 클라우드 존}


아래 그림과 같이 PSP 기능이 활성화 되는 것을 확인한다.


Deployment 생성

기능 활성화가 끝났으면, 이제 Pod를 deploy해보자.

아래는 nonroot-deploy.yaml 파일이다.


#nonroot-deploy.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

 name: nonroot-deploy

spec:

 replicas: 3

 selector:

   matchLabels:

     app: nonroot

 template:

   metadata:

     name: nonroot-pod

     labels:

       app: nonroot

   spec:

     serviceAccountName: nonroot-sa

     securityContext:

       runAsUser: 1001

       fsGroup: 2001

     containers:

     - name: nonroot

       image: gcr.io/terrycho-sandbox/security-context:v1

       imagePullPolicy: Always

       ports:

       - containerPort: 8080


우리가 nonroot-psp를 사용하기 위해서, 이 psp가 정의된 서비스 어카운트 nonroot-sa를 사용하도록 하였다. 그래고 nonroot-psp에 정의한데로, 컨테이너가 root 권한으로 돌지 않도록 securityContext에 사용자 ID를 1001번으로 지정하였다.

%kubectl create -f nonroot-deploy.yaml

을 실행한후,

%kubectl get deploy 명령어를 실행해보면 아래와 같이 3개의 Pod가 생성된것을 확인할 수 있다.


보안 정책에 위배되는 Deployment 생성

이번에는 PSP 위반으로, Pod 가 생성되지 않는 테스트를 해보자.

아래와 같이 root-deploy.yaml 이라는 이름으로, Deployment 스크립트를 작성하자.


#root-deploy.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

 name: root-deploy

spec:

 replicas: 3

 selector:

   matchLabels:

     app: root

 template:

   metadata:

     name: root-pod

     labels:

       app: root

   spec:

     serviceAccountName: nonroot-sa

     containers:

     - name: root

       image: gcr.io/terrycho-sandbox/nonroot-containe:v1

       imagePullPolicy: Always

       ports:

       - containerPort: 8080


이 스크립트는 앞에서 작성한 nonroot-deploy.yaml 과 거의 유사하지만 Security Context에서 사용자 ID를 지정하는 부분이 없기 때문에, 디폴트로 root로 컨테이너가 기동된다. 그래서 PSP에 위반되게된다.


%kubectl create -f root-deploy.yaml

을 실행하면 결과가 아래와 같다.



맨 아래 root-deploy-7895f57f4를 보면, Current 가 0으로 Pod가 하나도 기동되지 않았음을 확인할 수 있다.

원인을 파악하기 위해서 Pod를 만드는 ReplicaSet을 찾아보자

%kubectl get rs

명령을 아래와 같이 ReplicaSet 리스트를 얻을 수 있다.

%kubectl describe rs root-deploy-7895f57f4

명령을 실행해서 ReplicaSet의 디테일과 로그를 확인해보면 다음과 같다.



그림과 같이 Pod 생성이 정책 위반으로 인해서 실패한것을 확인할 수 있다.



쿠버네티스 #18

보안 3/4 - Security Context

조대협 (http://bcho.tistory.com)

보안 컨택스트

보안 컨택스트 (Security context)는 쿠버네티스의 Pod나 컨테이너에 대한 접근 제어 설정(Access Control Setting)이나, 특수 권한 (Privilege)를 설정하는 기능을 제공한다. 단어가 추상적이기 때문에 바로 이해하기 약간 어려울 수 있는데, 몇가지 예를 들어보면, 컨테이너 내에서 동작하는 프로세스의 사용자 ID (UID)나, 그룹 ID (GID)를 설정하거나, 프로세스에 커널에 대한 접근 권한을 부여하는 것과 같은 기능을 수행할 수 있다.


구체적으로 보안 컨택스트가 지원하는 기능은 다음과 같다. 예제와 병행해서 살펴보도록 하자

예제에 사용된 코드는 https://github.com/bwcho75/kube101/tree/master/10.security/4.securityContext 에 있다.

프로세스 사용자 ID와 그룹 ID 지정

Pod나 컨테이너에서 구동되는 프로세스의 사용자 ID와 그룹 ID를 지정한다.

디폴트로 컨테이너에서 구동되는 모든 프로세스는 root 권한으로 실행이 된다. 이 경우 컨테이너 이미지가 오염되어, 악성적인 코드를 가지고 있을 경우에는 root 권한으로 컨테이너의 모든 기능을 장악할 수 있기 때문에, 이를 방지하기 위해서는 컨테이너 내에서 구동되는 사용자 애플리케이션 프로세스의 사용자 ID와 그룹 ID를 지정하여, 특정 자원 (파일이나 디렉토리)에 대한 액세스만을 허용하게 할 필요가 있다.

또한 프로세스의 사용자 ID와 그룹 ID를 지정하면, 생성되는 파일 역시 지정된 사용자 ID와 그룹 ID 를 통해서 생성된다.


간단한 예제를 하나 보자.  우리가 계속 사용해왔던 server.js 로 node.js 서버를 하나 올리는 예제이다.

이 예제를 변경하여, 사용자 ID를 1000으로, 그리고 그룹 ID를 1000으로 지정해서 Pod를 올려보도록 하자.


몇가지 수정이 필요한데, 먼저 기존에 아래와 같이 사용했던 Dockerfile을

FROM node:carbon

EXPOSE 8080

COPY server.js .

CMD node server.js > log.out


log.out 파일 경로를 /log.out에서 아래와 같이 /home/node/log.out 으로 변경한다.

기존의 예제들의 경우에는 컨테이너와 Pod를 root 권한으로 수행했지만 이 예제에서는 runAs를 이용하여 사용자 ID가 1000인 사용자로 돌리기 때문에, 루트 (“/”) 디렉토리에 파일을 생성하려면 권한 에러가 난다.

사용자 ID 1000은 node:carbon 이미지에서 정의되어 있는 node 라는 사용자로, 디폴트로 /home/node 라는 사용자 디렉토리를 가지고 있기 때문에, 이 디렉토리에 파일을 쓰도록 아래와 같이 변경한다.


FROM node:carbon

EXPOSE 8080

COPY server.js .

CMD node server.js > /home/node/log.out


다음 yaml 파일을 작성한다. (1.runas.yaml)

apiVersion: v1

kind: Pod

metadata:

 name: runas

spec:

 securityContext:

   runAsUser: 1000

   fsGroup: 1000

 volumes:

 - name: mydisk

   emptyDir: {}

 containers:

 - name: runas

   image: gcr.io/terrycho-sandbox/security-context:v1

   imagePullPolicy: Always

   volumeMounts:

   - name: mydisk

     mountPath: /mydisk

   ports:

   - containerPort: 8080


위와 같이 securityContext에 runAsUser에 사용자 ID 1000을 그리고 fsGroup에 그룹 ID 1000을 지정하여 Pod를 생성한다. 그리고, mydisk 디스크 볼륨을 생성하여, /mydisk 디렉토리에 마운트 하였다.

생성후 결과를 보자.


생성된 Pod에

%kubectl exec -it runas /bin/bash

명령을 이용하여 로그인 한후 다음 그림과 같이 권한을 체크해본다.




먼저 ps -ef로 생성된 컨테이너들의 사용자 ID를 보면 위와 같이 node (사용자 ID가 1000임)으로 생성되어 있는것을 볼 수 있다.

다음 ls -al /home/node 디렉토리를 보면 컨테이너 생성시 지정한 로그 파일이 생성이 되었고 마찬가지로 사용자 ID와 그룹 ID가 node로 지정된것을 확인할 수 있다.

다음 마운트된 디스크의 디렉토리인 /mydisk 에 myfile이란 파일을 생성해도 파일의 사용자 ID와 그룹 ID가 node로 설정되는것을 확인할 수 있다.


앞의 예제의 경우에는 사용자를 이미지에서 미리 정해진 사용자(node)를 사용하였는데, 만약에 미리 정해진 사용자가 없다면 어떻게 해야 할까?

여러가지 방법이 있겠지만, 도커 이미지를 생성하는 단계에서 사용자를 생성하면 된다. 아래는 사용자를 생성하는 도커 파일 예제이다.


FROM node:carbon

EXPOSE 8080

RUN groupadd -r -g 2001 appuser && useradd -r -u 1001 -g appuser appuser

RUN mkdir /home/appuser && chown appuser /home/appuser

USER appuser

WORKDIR /home/appuser

COPY --chown=appuser:appuser server.js .

CMD node server.js > /home/appuser/log.out


RUN 명령을 이용하여 useradd와 groupadd로 사용자를 생성하고, mkdir로 사용자 홈디렉토리 생성을 한후, 해당 디렉토리의 사용자를 생성한 사용자로 변경한다

그 후에 명령을 실행하기 위해서 명령어를 실행하는 사용자를 변경해야 하는데, USER 명령을 이용하면 사용자를 변경할 수 있다. 이후 부터 생성되는 사용자는 USER에 의해서 지정된 사용자로 실행이 된다.

그 다음은 디렉토리를 WORKDIR을 이용해서 홈디렉토리로 들어가서 COPY와 CMD 명령을 순차로 실행한다.


실행 결과 디렉토리를 확인해보면



와 같이 모든 파일이 앞에서 생성한 appuser 라는 사용자 ID로 생성이 되어 있고, 그룹 역시 appuser로 지정되어 있는 것을 확인할 수 있다.


프로세스를 확인해보면 아래와 같이 앞에서 생성한 appuser라는 사용자로 프로세스가 기동됨을 확인할 수 있다.




SecurityContext for Pod & Container

보안 컨택스트의 적용 범위는 Pod 에 적용해서 Pod 전체 컨테이너에 적용되게 할 수 도 있고, 개발 컨테이너만 적용하게 할 수 도 있다.


아래 예제의 경우에는 컨테이너에 보안 컨택스트를 적용한 예이고,

pods/security/security-context-4.yaml  

apiVersion: v1

kind: Pod

metadata:

 name: security-context-demo-4

spec:

 containers:

 - name: sec-ctx-4

   image: gcr.io/google-samples/node-hello:1.0

   securityContext:

     capabilities:

       add: ["NET_ADMIN", "SYS_TIME"]


아래 예제는 Pod 전체의 컨테이너에 적용한 예이다.

apiVersion: v1

kind: Pod

metadata:

 name: runas

spec:

 securityContext:

   runAsUser: 1000

   fsGroup: 1000

 volumes:

 - name: mydisk

   emptyDir: {}

 containers:

 - name: runas

   image: gcr.io/terrycho-sandbox/security-context:v1

   imagePullPolicy: Always

   volumeMounts:

   - name: mydisk

         : (중략)


노드 커널에 대한 억세스 권한을 제어

쿠버네티스에서 동작하는 컨테이너는 호스트 OS와 가상적으로 분리된 상태에서 기동된다. 그래서, 호스트 커널에 대한 접근이 제한이 된다. 예를 들어 물리머신에 붙어 있는 디바이스를 접근하거나 또는 네트워크 인터페이스에 대한 모든 권한을 원하거나 호스트 머신의 시스템 타임을 바꾸는 것과 같이 호스트 머신에 대한 직접 억세스가 필요한 경우가 있는데, 컨테이너는 이런 기능에 대한 접근을 막고 있다. 그래서 쿠버네티스는 이런 기능에 대한 접근을 허용하기 위해서 privilege 모드라는 것을 가지고 있다.

도커 컨테이너에 대한 privilege 모드 권한은 https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities 문서를 참고하기 바란다.

NFS 디스크 마운트나 FUSE를 이용한 디스크 마운트나, 로우 레벨 네트워크 모니터링이나 통제가 필요할때 사용할 수 있다.

privilege 모드를 true로 하면 커널의 모든 권한을 사용할 수 있는데,

아래 예제는 https://github.com/kubernetes/examples/blob/master/staging/volumes/nfs/nfs-server-rc.yaml 의 일부로 NFS 볼륨을 마운트 하는 리소스 컨트롤러 설정의 일부이다. NFS로 마운트를 하기 위해서 컨테이너의 privileged: true 로 설정하여 privileged 모드로 컨테이너가 실행하게 한것을 확인할 수 있다.


containers:

- name: nfs-server

 image: k8s.gcr.io/volume-nfs:0.8

 ports:

   - name: nfs

     containerPort: 2049

   - name: mountd

     containerPort: 20048

   - name: rpcbind

     containerPort: 111

 securityContext:

   privileged: true


Privileged 모드가 커널의 모든 기능을 부여한다면, 꼭 필요한 기능만 부여할 수 있게 세밀한 컨트롤이 가능하다. 이를 위해서 Linux capability 라는 기능이 있는데, 이 기능을 이용하면 커널의 기능을 선별적으로 허용할 수 있다. 자세한 설명은 https://linux-audit.com/linux-capabilities-hardening-linux-binaries-by-removing-setuid/ 문서를 참고하기 바란다.


아래 예제는 https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container 중의 일부로, 컨테이너 생성시에, NET_ADMIN과 SYS_TIME 권한 만을 컨테이너에 부여한 내용이다.


pods/security/security-context-4.yaml  

apiVersion: v1

kind: Pod

metadata:

 name: security-context-demo-4

spec:

 containers:

 - name: sec-ctx-4

   image: gcr.io/google-samples/node-hello:1.0

   securityContext:

     capabilities:

       add: ["NET_ADMIN", "SYS_TIME"]

기타

Security context는 이 이외에도 다양한 보안 관련 기능과 리소스에 대한 접근 제어가 가능하다.


  • AppAmor
    는 리눅스 커널의 기능중의 하나로 애플리케이션의 리소스에 대한 접근 권한을 프로필안에 정의하여 적용함으로써, 애플리케이션이 시스템에 접근할 수 있는 권한을 명시적으로 정의 및 제한 할 수 있다.
    (https://wiki.ubuntu.com/AppArmor)

  • Seccomp
    Security computing mode 의 약자로, 애플리케이션의 프로세스가 사용할 수 있는 시스템 콜의 종류를 제한할 수 있다. (https://en.wikipedia.org/wiki/Seccomp)

SELinux
보안 리눅스 기능으로 AppAmor와 유사한 기능을 제공하는데, 리소스에 대한 접근 권한을 정책으로 정의해서 제공한다.


쿠버네티스 #17

보안 2/4 - 네트워크 정책

조대협 (http://bcho.tistory.com)

네트워크 정책 (Network Policy)

쿠버네티스의 보안 기능중의 하나가 네트워크 정책을 정의함으로써 Pod로 부터 들어오거나 나가는 트래픽을 통제할 수 있다. Network Policy라는 기능인데, 일종의 Pod용 방화벽정도의 개념으로 이해하면 된다.

특정 IP나 포트로 부터만 트래픽이 들어오게 하거나 반대로, 특정 IP나 포트로만 트래픽을 내보내게할 수 있는 등의 설정이 가능한데, 이 외에도 다음과 같은 방법으로 Pod에 대한 Network Policy를 설정할 수 있다.

Ingress 트래픽 컨트롤 정의

어디서 들어오는 트래픽을 허용할것인지를 정의하는 방법은 여러가지가 있다.

  • ipBlock
    CIDR IP 대역으로, 특정 IP 대역에서만 트래픽이 들어오도록 지정할 수 있다.

  • podSelector
    label을 이용하여, 특정 label을 가지고 있는 Pod들에서 들어오는 트래픽만 받을 수 있다. 예를 들어 DB Pod의 경우에는 apiserver 로 부터 들어오는 트래픽만 받는것과 같은 정책 정의가 가능하다.

  • namespaceSelector
    재미있는 기능중 하나인데, 특정 namespace로 부터 들어오는 트래픽만을 받을 수 있다. 운영 로깅 서버의 경우에는 운영 환경 namespace에서만 들어오는 트래픽을 받거나, 특정 서비스 컴포넌트의 namespace에서의 트래픽만 들어오게 컨트롤이 가능하다. 내부적으로 새로운 서비스 컴포넌트를 오픈했을때, 베타 서비스를 위해서 특정 서비스나 팀에게만 서비스를 오픈하고자 할때 유용하게 사용할 수 있다.

  • Protocol & Port
    받을 수 있는 프로토콜과 허용되는 포트를 정의할 수 있다.

Egress 트래픽 컨트롤 정의

Egress 트래픽 컨트롤은 ipBlock과 Protocol & Port 두가지만을 지원한다.

  • ipBlock
    트래픽이 나갈 수 있는 IP 대역을 정의한다. 지정된 IP 대역으로만 outbound 호출을할 수 있다.

  • Protocol & Port
    트래픽을 내보낼 수 있는 프로토콜과, 포트를 정의한다.

예제

예제를 살펴보자. 아래 네트워크 정책은 app:apiserver 라는 라벨을 가지고 있는 Pod들의 ingress 네트워크 정책을 정의하는 설정파일로, 5000번 포트만을 통해서 트래픽을 받을 수 있으며, role:monitoring이라는 라벨을 가지고 있는 Pod에서 들어오는 트래픽만 허용한다.


kind: NetworkPolicy

apiVersion: networking.k8s.io/v1

metadata:

 name: api-allow-5000

spec:

 podSelector:

   matchLabels:

     app: apiserver

 ingress:

 - ports:

   - port: 5000

   from:

   - podSelector:

       matchLabels:

         role: monitoring




네트워크 정책을 정의하기 위한 전체 스키마는 다음과 같다.

apiVersion: networking.k8s.io/v1

kind: NetworkPolicy

metadata:

 name: test-network-policy

 namespace: default

spec:

 podSelector:

   matchLabels:

     role: db

 policyTypes:

 - Ingress

 - Egress

 ingress:

 - from:

   - ipBlock:

       cidr: 172.17.0.0/16

       except:

       - 172.17.1.0/24

   - namespaceSelector:

       matchLabels:

         project: myproject

   - podSelector:

       matchLabels:

         role: frontend

   ports:

   - protocol: TCP

     port: 6379

 egress:

 - to:

   - ipBlock:

       cidr: 10.0.0.0/24

   ports:

   - protocol: TCP

     port: 5978


자 그럼, 간단하게 네트워크 정책을 정의해서 적용하는 테스트를 해보자

app:shell 이라는 라벨을 가지는 pod와 app:apiserver 라는 라벨을 가지는 pod 를 만든후에, app:shell pod에서 app:apiserver pod로 HTTP 호출을 하는 것을 테스트 한다.

다음 app:apiserver pod에 label이 app:loadbalancer 인 Pod만 호출을 받을 수 있도록 네트워크 정책을 적용한 후에, app:shell pod에서 app:apiserver로 호출이 되지 않는 것을 확인해보도록 하겠다.


테스트 환경은 구글 클라우드 쿠버네티스 엔진 ( GKE : Google cloud Kubernetes engine) 를 사용하였다.

GKE의 경우에는 NetworkPolicy가 Default로 Disable 상태이기 때문에, GKE 클러스터를 만들때 또는 만든 후에, 이 기능을 Enabled 로 활성화 해줘야 한다.

아래는 GKE 클러스터 생성시, 이 기능을 활성화 하는 부분이다.


클러스터 설정이 끝났으면, 이제 테스트에 사용할 Pod 를 준비해보자.

apiserver는 아래와 같이 server.js 의 node.js 파일을 가지고 8080 포트를 통해서 서비스하는 pod가 된다.

var os = require('os');


var http = require('http');

var handleRequest = function(request, response) {

 response.writeHead(200);

 response.end("Hello World! I'm API Server  "+os.hostname() +" \n");


 //log

 console.log("["+

Date(Date.now()).toLocaleString()+

"] "+os.hostname());

}

var www = http.createServer(handleRequest);

www.listen(8080);

이 서버로 컨테이너 이미지를 만들어서 등록한후에, 그 이미지로 아래와 같이 app:apiserver 라벨을 가지는

Pod를 생성해보자.


apiVersion: v1

kind: Pod

metadata:

 name: apiserver

 labels:

   app: apiserver

spec:

 containers:

 - name: apiserver

   image: gcr.io/terrycho-sandbox/apiserver:v1

   ports:

   - containerPort: 8080

마찬가지로, app:shell 라벨을 가진 Pod도 같은  server.js 파일로 생성한다.

app:apiserver와 app:shell 라벨을 가진 pod를 생성하기 위한 코드와 yaml 파일은 https://github.com/bwcho75/kube101/tree/master/10.security/3.%20networkpolicy 를 참고하기 바란다.


두 개의 Pod를 생성하였으면 shell pod 에 kubectl exec -it {shell pod 명} -- /bin/bash를 이용해서 로그인한후에

apiserver의 URL인 10.20.3.4:8080으로 curl 로 요청을 보내보면 아래와 같이 호출되는 것을 확인할 수 있다.



이번에는 네트워크 정책을 정의하여, app:apiserver pod에 대해서 app:secure-shell 라벨을 가진 pod로 부터만 접근이 가능하도록 정책을 정해서 정의해보자


아래는 네트워크 정책을 정의한 accept-secureshell.yaml 파일이다.

kind: NetworkPolicy

apiVersion: networking.k8s.io/v1

metadata:

 name: accept-secureshell

spec:

 policyTypes:

 - Ingress

 podSelector:

   matchLabels:

     app: apiserver

 ingress:

 - from:

   - podSelector:

       matchLabels:

         app: secureshell


이 설덩은 app:apiserver 라벨이 설정된 Pod로의 트래픽은 라벨이 app:secureshell에서 보내는 트래픽만 받도록 설정한 정책이다.

%kubectl create -f accept-secureshell.yaml

명령어를 이용해서 앞에서 만든 정책을 적용한후에, 앞에서와 같이 app:shell → app:apiserver로 curl 호출을 실행하면 다음과 같이 연결이 막히는 것을 확인할 수 있다.



이외에도 다양한 정책으로, 트래픽을 컨트롤할 수 있는데, 이에 대한 레시피는 https://github.com/ahmetb/kubernetes-network-policy-recipes 문서를 참고하면 좋다.

OAuth 2.0 노트

아키텍쳐 /Security & IDM | 2014.08.11 17:05 | Posted by 조대협

OAuth 용어 정리

Resource Owner (사용자)

Authorization Server (인증서버

Resource Server (REST API)



 

OAuth 2.0 grant flow

Authorization code grant flow

주로 Web Application에서 사용됨

Implicit grant flow

자바스크립트 애플리케이션에서 많이 사용됨. 스크립트 단에서는 credential 등이 노출 될 수 있으니, 주로 Read only 용도로 많이 사용함. accessToken이 노출될것을 전제로 함.

모바일 애플리케이션도 많이 사용하는걸로 나오네??

Ÿ   Used in public clients

Ÿ   It's is a redirection-based flow (similar to the one in the authorization code grant)

Ÿ   The access token is received as a parameter of the redirection endpoint upon successful completion of the request, similar to the authorization code parameter in the authorization request response in the authorization code grant



Flow

     The first step is initiation of the flow. The client redirects the User agent to the Authorization server by using the authorization endpoint, the client identifier, and the redirection endpoint that will be used for the response.

     The Authorization server authenticates the Resource owner and requests his decision whether to authorize or deny the request.

     If the Resource owner authorizes the request (which is assumed), he is redirected back with response information, using the supplied redirection endpoint that was provided with the initial request. The response information is contained in the URL fragment that contains the access token and other parameters (we'll see the difference between a regular URL parameter and one found in a URL fragment in the detailed overview).

     Now that the User agent (the browser) is redirected back, the access token included in the response is passed to the Client application.

Client Server Application Case

Mobile App Case

(웹이 아니기 때문에, Redirect 처리를 어떻게 해야 할지 고민해야 함.

Samsung Account와 같이 전용 APK를 넣는 방식이나, 웹 페이지 Scrapping 방식등이 있음)

 

Resource owner password credential grant flow

직접 ID,PASSWORD를 보내는 방식으로, 1st level 파트너나 자사 시스템에 많이 사용.

기존의 HTTP BASIC이나 HTTP Digest 인증 방식을 migration하기가 용이함



     The resource owner (for example, the user) supplies the Client application with his username and password.

     The client application makes a request to the Authorization server, including the user's credentials and also his own identifier and secret.

     The Authorization server authenticates the client based on his identifier and secret, checks whether it is authorized for making this request, and checks the resource owner credentials and other parameters supplied. If all checks pass successfully, the Authorization server returns an access token in response.

Client credential grant flow

Userless 상태에서 많이 사용됨. (API 키와 유사한 방식)

 

 

'아키텍쳐  > Security & IDM' 카테고리의 다른 글

서버와 APNS(애플푸쉬서버)와의 보안 메커니즘  (3) 2014.10.07
OAuth 2.0 노트  (0) 2014.08.11
OAuth 2.0 based API 인증 메모  (0) 2014.06.05
Digital Signing의 개념  (0) 2014.05.21
Java keystore file  (0) 2013.09.27
SSL/TLS 관련 개념 링크  (1) 2013.09.24

괜찮은 책들 정리




Security Patterns in Practice

저자
Fernandez-Buglioni, Eduardo 지음
출판사
John Wiley & Sons (Asia) Pte. | 2013-06-25 출간
카테고리
과학/기술
책소개
Learn to combine security theory an...
가격비교

Security 전반에 걸쳐, 인증, 암호화, 인가등 다양한 시나리오에 대해서 패턴 중심으로 설명, 개념 잡기 아주 좋음



OAuth 2.0에 대해서 이해가 잘되게 설명된 책. 이거 보고 개념 잡았음



Beyond Software Archiecture

저자
Hohmann 지음
출판사
Addison Wesley | 2003-01-01 출간
카테고리
과학/기술
책소개
Successfully managing the relations...
가격비교

읽어야지 하면서 아직 못본책, 아키텍쳐 설계와 특히 라이센스 관리에 대한 디자인이 들어 있는 책




Vert.x를 보면서, HTTP단이야 HTTPS로 Security 보장이 된다지만, TCP/IP Server는 어떻게 하는가가 의문이었는데, 이부분도 이미 다 준비되어 있다. Configuration 몇줄 만으로 TLS가 지원 된다.


http://vertx.io/core_manual_java.html#ssl-servers

NetServer server = vertx.createNetServer()
               .setSSL(true)
               .setKeyStorePath("/path/to/your/keystore/server-keystore.jks")
               .setKeyStorePassword("password");


아무리 봐도 잘만들었어...


암호화 알고리즘 속도 비교 (대칭키)

아키텍쳐 | 2013.07.17 01:19 | Posted by 조대협

http://www.javamex.com/tutorials/cryptography/ciphers.shtml



Comparison of ciphers

Java supports a number of encryption algorithms out of the box. Which encryption algorithm to use can depend on a number of criteria:

  • how secure the algorithm is currently judged to be in the cryptographic literature;
  • the performance characteristics of the algorithm (e.g. the "raw speed" of the algorithm, and whether it supports parallel encryption);
  • how politically safe a decision it is to use a particular algorithm (paradoxically, this doesn't necessarily depend directly on the algorithm's security);
  • whether you have to interact with a legacy system.

Summary of algorithms

We compare measured speed of encryption with various algorithms available as standard in Sun's JDK, and then give a summary of various other characteristics of those algorithms. The encryption algorithms we consider here are AES (with 128 and 256-bit keys), DES, Triple DES, RC4 (with a 256-bit key) and Blowfish (with a 256-bit key).

Performance

First, the easy bit. Figure 1 shows the time taken to encrypt various numbers of 16-byte blocks of data using the algorithms mentioned.

Figure 1: Comparison of encryption times for various common
symmetric encryption algorithms provided as standard in Java 6.

It's important to note right from the beginning that beyond some ridiculous point, it's not worth sacrificing speed for security. However, the measurements will still help us make certain decisions.

Characteristics

Table 1 gives a summary of the main features of each encryption algorithm, with what I believe is a fair overview of the algorithm's current security status.

AlgorithmKey size(s)SpeedSpeed depends on key size?Security / comments
RC440-1024Very fastNoOf questionable security; may be secure for moderate numbers of encrypted sessions of moderate length. RC4 has the redeeming feature of being fast. However, it has various weaknesses in the random number sequence that it uses: see Klein (2008)1.
Blowfish128-448FastNo

Believed secure, but with less attempted cryptanalysis than other algorithms. Attempts to cryptanalyse Blowfish soon after publication are promising (Schneier, 19952 & 19963). But, unlike AES, it doesn't appear to have received much attention recently in the cryptographic literature. Blowfish has been superseded by Twofish, but the latter is not supported as standard in Java (at least, not in Sun's JDK).

AES128, 192, 256FastYes

Secure, though with some reservations from the crypto community. It has the advantage of allowing a 256-bit key size, which should protect against certain future attacks (collision attacks and potential quantum computing algorithms) that would have 264 complexity with a 128-bit key and could become viable in the lifetime of your data.

DES56Slow

Insecure: A $10,000 Copacobana machine can find a DES key in an average of a week, as (probably) could a botnet with thousands of machines.

The simple answer is: "Don't use it– it's not safe". (RFC 4772).

Triple DES112/168, but equivalent security of 80/112Very slowNo

Moderately secure, especially for small data sizes. The 168-bit variant estimated by NIST (2006) to keep data secure until 20304.

Triple DES performs three DES operations (encrypt-decrypt-encrypt), using either two or three different keys. The 168-bit (three-key) variant of Triple DES is generally considered to offer "112 bits of security", due to a so-called meet-in-the-middle attackAES offers a higher level of security for lower CPU cost.

Table 1: Characteristics of commonly used encryption algorithms included in Java 6.

Remarks on AES

AES stands for Advanced Encryption Standard and is actually an algorithm that was originally called Rijndael, after its inventors Rijmen & Daemen. It is the algorithm that most people will end up using unless they have a strong reason to use anything else:

  • it is a politically safe decision: the encryption standard of the US National Institute of Standards and Technology (NIST), and the US government reportedly approves AES with 192 or 256-bit keys for encrypting top secret documents (or put another way, your boss won't sack you for choosing AES...);
  • it is largely considered secure, though with some reservations:
    • nobody yet has (publicly) a full attack on AES, or a partial attack that is practical (though some impractical partial attacks exist5);
    • however, AES is algebraically simpler than other block ciphers: effectively, it can be written as a series of mathematical equations, and there is a worry that somebody could demonstrate a way to solve those equations (see Ferguson & Schneier, Practical Cryptography, pp. 57-58);
    • the NSA may have chosen Rijndael as they secretly know how to break it, or secretly estimated that they could develop a way to break it.
  • it is fast (Ferguson & Schneier (op cit), p. 59, argue that this is the reason it was picked over Serpent as the AES standard).

Key sizes

On the next page, we look at the issue of choosing and setting key sizes for encryption in Java.

'아키텍쳐' 카테고리의 다른 글

Technical Debt  (2) 2013.10.30
License Key Management  (0) 2013.08.01
암호화 알고리즘 속도 비교 (대칭키)  (0) 2013.07.17
API platform  (0) 2013.07.17
API design for client which support limited HTTP method  (0) 2013.07.10
아키텍트의 종류와 역할  (3) 2012.09.06

Authentication (인증 방식)

일반적인 id,passwd 기반의 인증 방식

사용자 정보와 사용자 credential (id/passwd)를 데이타베이스에 저장해놓고, 사용자로 부터 id/passwd를 입력받아, 이를 비교하여 인증하는 방식.

일반적은 중소 규모 사이트 개발에는 RDBMS를 사용하는 것이 일반적이며,조직 구조, 여러가지 Role, 권한등을 저장할때는 LDAP등을 사용한다. 근래에는 대규모 사용자를 저장하기 위해서 Cassandra와 같은 NoSQL을 저장하는 경우도 많다.

이러한 저장소에 비밀 번호를 저장할때 평문으로 저장하는것 보다, 암호화된 형태로 저장하는 것이 좋다. 그래서 MD5 SHA1같은 Hash로 변경해서 저장한다. 이렇게 하면, Hacker에 의해서 데이타 베이스가 탈취되더라도 데이타 베이스내의 passwd Hash 값만 저장되어 있기 때문에, 원본 passwd는 알아낼 수 가 없다.

hash = sha1-256(passwd)

그렇다면 원본 passwd를 알아낼 수 없다면, 인증은 어떻게 할까? 답은 쉽다. 사용자가 입력한 passwd를 같은 알고리즘으로 Hash값을 계산한 후에, 데이타 베이스에 저장된 Hash 값과 일치하는지를 체크하면 된다.

이런 Hash 알고리즘도 요즘은 어느정도는 복호화가 가능하다. asdf1234MD5 hash 값은 1adbb3178591fd5bb0c248518f39bf6d http://www.md5decrypt.org/를 통해서 테스트 해보면, MD5 Hash를 쉽게 디코딩 할 수 있다 비밀번호나 스트링등을 MD5로 변환한 dictionary를 가지고 있다가, dictionary를 기반으로 하여 search를 하면, Hash 전의 값을 찾아내는 방법이다.

이를 보안상의 헛점을 극복하는 방법이 SALT라는 기법인데, passwordhash로 변경하기 전에 password 끝에 random string을 붙여서 Hash로 변경하면, dictionary 기반의 attack에서는 random string이 끝에 붙어 있기 때문에, dictionary에 저장되어 있을 가능성이 상대적으로 낮게 되고, 이로 인해서 이러한 dictionary attack을 회피할 수 있다.

hash = sha1-256( strcat(passwd,salt) )

이때 salt도 데이타 베이스에 hash 값과 함께 저장한다.

Salt의 길이를 늘리고, random화 하면, 보안 수준도 같이 올라간다.

여기에 조금 더, 복잡도를 높이는 방식은, salt에 의해서 계산된 hash값을 다시 같은 salt를 더해서 N번 재 hash하는 방식이 있다.(보통 1000번 이상의 루프를 추천합니다.)

hash = sha1-256( strcat(passwd,salt) )

hash = sha1-256( strcat(hash,salt) )

:

:

X.509 기반 인증

X.509 PKI 기반의 인증서를 이용하여 서버가 클라이언트를 인증하는 방식으로, 쉽게 이야기 해서, 클라이언트를 인증할때, id,passwd를 이용하는 방식이 아닌 인증서를 사용하는 방식이다. 인터넷 뱅킹의 공인 인증서등을 생각하면 되며, 양방향 SSL을 사용하면, 이 방식의 인증을 구현할 수 있다.

특히 서버간의 통신에 대해서, 강한 인증이 필요한 경우, 양방향 SSL을 사용하게 되면, 서버간의 인증을 쉽게 구현할 수 있다.

Claim based Authentication (CBA)

아키텍쳐 /Security & IDM | 2013.06.07 22:58 | Posted by 조대협


CBA Claim based authentication


ADFS 2.0 등 MS 진영에서 주로 사용함

- Claim : Subject를 identitify 할 수 있는 name, group 등 (쉽게 말해서 attribute)

- Token : Claim을 transpport하기 위한 packet ( 1개 이사으이 claim이 packaging되며, digitial signature로 packaging됨) ex) SAML packaging도 하나의 Token의 예

- Issuer: Token을 만드는 대상 (Idp가 주로 Issuer가 되는 경우가 많음)

- Secure Token Server (STS) : The central issuing authority. (In most case STS works as Idp) - 인증하고 Token 만들어주는 서버. (ADFS 2.0 )

- Replying party - Claim based authentication 을 사용하는 Sp (Service Provider)


Process

전체적인 흐름 자체는 SAML과 유사함.

사용자가 resource를 요청하면 STS (Idp)서버로 redirect해서 login 한후,  token 발급 받아서, 그 token으로, resource에 가서 인증하고 log in 하는 시나리오


1. User attempts to access an application.

2. User is redirected to the STS.

3. User authenticates to the STS.

4. The STS pulls claim information from the appropriate store and uses the information to create a token.

5. The token is sent back to the user.

6. Token is submitted to application.


3.7.2.1.1. Passive Client Flow


1. User attempts to access resource.

2. Resource redirects browser to STS URL.

3. Browser redirects to STS URL.

4. User authenticates to STS.

5. STS issues token to client.

6. Token is passed to resource.

7. User is granted access to resource.



3.7.2.2.1. Active Client Flow


1. Username used to request CBA token.

2. STS authenticates user.

3. CBA token issues to application.

4. Call made to web service using token.

5. WIF validates security token.

6. Response returned.



3.7.3. Cross-Realm Federation with CBA

As we’ve seen, each application must be configured with an issuer. This issuer is the one that creates the tokens that will be trusted by the application. So what happens when an application trusts one issuer but a user logs into a different issuer? How can the user still use the application? The answer is cross-realm federation.

Cross-realm federation allows you to log into one STS and access applications that are configured for another STS. There are many situations where this might be the case. You might have a situation where you have an application that is accessed by customers or partners, but you don’t want to manage user accounts for those users. You can have the users log into a separate IdP but still allow them access to your application. You may also have a situation where your organization has acquired a new company. This company already had their own IdP. If you need to provide these users access to your company’s applications, you don’t have to wait until you port all the users over to your IdP. They can still log into their own IdP and have access to your company’s applications.

You can set up a federation trust between two issuers. In addition to configuring the trust, you have to configure a token translation. With a token translation, you configure the incoming claim and what the outbound claim should be changed to.

1. User attempts to access application.

2. User is redirected to issuer1 configured on application.

3. User selects issuer2 for authentication.

4. User authenticates to issuer2 and receives token.

5. User presents token to issuer1.

6. Issuer1 converts token to one that can be used by applications and send that token to user.

7. User presents new token to application.


MS 문서 https://www.google.co.kr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&sqi=2&ved=0CDQQFjAA&url=http%3A%2F%2Fdownload.microsoft.com%2Fdownload%2F7%2Fd%2F0%2F7d0b5166-6a8a-418a-addd-95ee9b046994%2FGeneva_Beta1_DataSheet.pdf&ei=XuSxUYuUAYWbigeJiYGIAg&usg=AFQjCNGbmhiqxvwNx-T4OKxVL5gVApVAZA&sig2=QPNpHxknVD6NHYHVVHCeBw&bvm=bv.47534661,d.aGc 
에 설명 엄청 잘되어 있음


MS에서는 WIF (Windows Identity Foundation) - .NET Framework과 ADFS 2.0(서버)를 이용해서 구현


Identity Management System (IDM) Overview

Terry.Cho (http://bcho.tistory.com)


1. Background

 

IDM (Identity Management system) is one of most important and complex component in common IT system. 

Pain Point

Here is sample pain point in Identity management scenario when it comes from identity management area commonly.

 

Federation.

1)        Enterprise build their IT system with very simple & isolated identity management feature. All of each system has own IT management features.

2)        Number of the IT system has been grown, and it has own identity management system.

3)        End user starts complain to log in with different id for each system.

Lifecycle management & Provisioning

1)        After employee leaves company, Enterprise it admin needs to delete all of identity across the system.

2)        After new employee has been joined, his identity need to be created in email, ERP, CRM etc. Some identity creation needs to be approved by manager

 

Without common Identity management platform, identity management is being very painful. 

B2B vs B2C

There are two main category that uses identity management. One is B2B and the other one is B2C.

B2B is enterprise IT. It is designed for manage internal user or restricted number of end client.

The characteristic of B2B system is,

-       It has very complex scenario to support their business

-       It has a lot of package based legacy system like ERP,CRM etc.

-       It needs very elaborate authorization control.

-       It has many types of roles (admin, manager, end user, org admin etc).

So the product which supports B2B scenario,  focuses legacy system integration (provisioning, connector, standard support - WS-Security, SAML, XACML etc ) , work flow support etc.

This area is mainly driven by enterprise vendor like Oracle,CA,IBM etc.

 

In contrast, B2C area has different requirement.

In B2C area , it provides service to customer like SNS.

-       It supports huge # of end user (+million)

-       Role type and authorization control is very simple compare to B2B scenario.

-       Open standard based federation model (OAuth 2.0, Open ID etc)

-       Global deployment 

Trend & Implementation options

To build up IDM system there are 3 different approach.

1)       Option A. build with open source framework

build IDM system from scratch or reuse open source frame work.

To support just single silo system, big identity management system is not required. In this case, user just build the IDM system from scratch. For small to medium # of user, RDBMS backend preferred.  For medium to big number of user, LDAP or Microsoft Active Directory is preferred.

 

To provided more platformanized (or well defined) IDM, open source frame work can be used.

Spring Security is one of major player in this area. It is more focused on web based application.

Apache Shiro is also one of the other major player. It can support web and others (REST API based security control etc).   

2)       Option B. build with niche vendor solution  

If IT has to support more complex scenario. It that case it can consider solution. There are a lot of solutions which are optimized to specific scenario.

For example, Centrify is well optimized to support Active Directory based single sign on in B2B scenario. PingIdentity is good for user account federation scenario.

3)       Option C. Full package from enterprise vendor

If the company has a lot of package based legacy system and it needs sophisticated role based authorization control, long running work flow for authorization approval, audit etc, full packaged IDM is recommended.

These kind of IDM product is delivered by enterprise vendor like Oracle,IBM,CA etc.



Figure 1. IDM gartner magic quadrent 2010

Trend is,

For B2C, commonly it uses Option A and if there is more complex requirement it uses (or moves from Option A to ) Option B. Big B2C company like Facebook, Google builds up their own IDM system with Option A approach.

 

For B2B, for small & isolated system it uses Option A. For restricted scenario, Option B. For enterprise wide it uses Option C. Commonly enterprise IT system has its own LDAP server internally and they provides minimum single sign on with solutions (Option B).

 Commonly they has SSO, Provisioning only, not support authorization and other stuff.  The authorization supports requires a lot of customization both in IDM and service application side. And full package vendor solution is very expensive, complex and hard to manage. 

2. IDM System common features

Here is common feature which is provided by traditional IDM systems.

1)       User Management

It managed user identity during full life cycle. It created, update and delete the user identity information.

Ÿ   Lifecycle management

This feature manages whole life cycle of user identity management from creation to remove. Depends on requirement, user identity can be expired based on pre-defined logic. It also can manage password expiration date etc.

Ÿ   Work flow

Some user identity creation or new authorization permission guarantee needs a approval. For example in case of banking account creation, it needs to check user identity. This kinds of approval required long running process.

It is implemented by using work flow engine (eg. BPM etc)

Ÿ   Provisioning

When user identity has been created or modified, it need to be replicated another system. For example new email has been created in email system, new account in sales system need to be created. In that case the user profile should be replicated (provisioned). It is one of very important feature in centralized IDM.

Ÿ   Delegated Admin

To manage user identity , single IDM admin is not enough. If the company has a lot of organization and authorization control is requires, single IDM admin cannot cover whole of the requests. So in that case restricted admin authority need to be delegated to someone (ex. managers in the organization ). This feature is delegated admin.

One more thing for this feature, if the delegated admin has been leaved the company the delegated authority should be propagated to another user in the IDM.

Ÿ   Identification management

In specific system, user identity which prove "Who is the user?" is very important.

In Banking, Stock Trading system, user identity proven is very important issue. To support them IDM manages additional information like user certification, finger print and user biometric data 

2)       Access Management

Access management defines "Can user access specific resource?". It allows system to provide restricted access

Ÿ   Authentication

Authentication is the process of determining whether someone or something is, in fact, who or what it is declared to be. This is commonly done by comparing user identity & credentials (id & password)

Ÿ   Authorization (ACL , Entitlement)

This is process of granting or denying access to resource.

In other term, it is controlled by "ACL (Access Control List)". It describes "Who can access what resource".

In authorization scenario, there are 3 types of access control

       RBAC (Resource Based Access Control)

Resource access is controlled by user role. Individual user can have number of role. For example a user can be "Partner" ,"Admin" ,"End User". Resource control is granted by pre defined access control based on each role.

RBAC is one of most broadly used authorization method.

       DAC (Discretionary Access Control)

It is more flexible compare to RBAC. DAC manages authority based on user identity (user id or it's associated group)

       MAC (Mandatory Access Control)
User are given permission to resources by system administrator. Only the admin can grant permission to resource.

Ÿ   Federation (SSO)

If there are number of systems and user logged once in one system, it doesn't need to log into other system anymore. This is Single Sign On.

There are standards to support SSO like SAML, CAS, Kerberos etc.  

3)       Repository

Repository persists user identity & profile.

User identity has user id and password for log in. ACL (Access Control List) and user profile which contains user related data for example - name, address , email etc.

This repository is read intensive. And it needs to support tree like structure because, user identity combines user organization structure too. In this reason LDAP is common solution for repository.

If system have to support global roll out, it should also consider regulation issue. Some user information cannot be stored outside their country. When it designs user profile scheme, legal check is required.

And to support the global roll out, data replication across data center should be supported.  

4)       Audit & Reporting

Audit means, "who did what to which resource?". It can enables admin to track resource usage, denial resource access etc. In some system , the access log can be used to track user pattern. Web access log analysis scenario is one of the example. In addition the resource access log can be used to metering service usage. (cloud computing scenario etc)

For denial access, it need to support notification message to admin and reporting. To prevent denied access, it also need to support "black list".

This area is consists of logging, gathering, analysis, reporting and achieving. Now days, it is implemented by using big data technology. (logging framework etc)  

5)       Integrations

Integration feature is integrate multiple identity management system.

There are many perspectives. Replicate user profile from one to other systems is covered by "provisioning". Authentication across number of system can be covered by Single Sign On. Authorization over number of system can be covered by XACML based authorization system.

To simplify integration, we can have 3 perspective like below

Ÿ   Open standard support

Integration support is old problem in Identity management area. So there are already open standard to support the integration issue.

In B2C area, Open ID and OAuth are major player that support authentication.

In B2B area, there are a lot of standard like

-        SAML,WS-Security: support SSO & Federation

-        XACML: support authorization

-        LDAP or Microsoft Active Directory : repository integration

-        WS-Trust : API Security

Ÿ   Internal service integration

In enterprise, there are a lot of internal system. Especially legacy enterprise system (ERP,CRM) has very complex user profile scheme, organization structure and sometimes it doesn't support open standard.  So it needs special integration connector to support the integration (provisioning, authorization etc).

The Connector support is main feature of internal service integration

Ÿ   External service integration

It covers identity integration covers external system which resides in outside of company.  

-        B2C integration - There are already well know B2C service system like google, Windows Live accout, Face book, Twitter account. B2C integration scenario is usually implemented with open standard (OAuth, OpenID, Active Directory etc)

-        B2B integration - This area can have various scenario depends on requirement. If company A provides service B's from company B with white-label. They need to support SSO. In this case company A,B need to integrate their authentication by using SSO. In this scenario, if company B charge the service, user identity need to be provisioned from company A to company B to measure their usage.

B2B integration is occurred by ad-hoc way. There are no common approach in this area. Best way is clarify gap between two different identity management system and make integration scenario case by case. This approach is similar to EAI (Enterprise Application Integration).

-        B2B (Cloud) integration - There are already cloud enterprise cloud service like SalesForce.com, Microsoft Office 365. This service needs to integrate with company wide IDM system. 

3. IDM deployment model

To understand IDM deployment model, we have to understand IDM term first

Ÿ   IdP (Identity Provider) : This is IDM. It persists user identity, authenticate & authorize incoming request.

Ÿ   SP (Service Provider) : It provides service to end user. It has resource. Access to the resources are restricted by Idp. Example. Web Site etc.

Ÿ   Token : User credentials (id & password, or log in token - which is used for authentication)

There are 3 types of deployment models

Isolated IDM Model

Each service provider has it's own IdP. End user has to log in for each service provider with different identity.



Centralized IDM Model

Each services shares single IdP. This is most ideal model. End user can log in and access with single user identity.

All of access controls in all Service Provides are controlled by single ACL. It is consistent.

But it is hard to meet in real world. Product (open source or solution) already has it own Idp internally. If all of Service Providers are built from scratch, it can support this model.



Federated IDM Model

End user perspective, it is same to centralized IDM model. End user logs in Service Provider with single user identity. But each Service Provider has different IdP in backend.

This is common use case in IDM area. Authentication is integrated by SSO (Federation) and Authorization is covered by Entitlement (XACML etc)




Here is reference architecture of federation model



User management system create & update user profile. The profile is propagated to each IdP servers thru provisioning components. Service Provider has recent version of user profile.

End user logs in Service provider. It is federated by using SSO.


 

Bouncy Castle

프로그래밍/LIBS | 2013.03.15 17:00 | Posted by 조대협

http://www.bouncycastle.org/java.html


Java 기반의 암호화 라이브러리

'프로그래밍 > LIBS' 카테고리의 다른 글

Bouncy Castle  (0) 2013.03.15
Fuse 관련  (0) 2011.08.02
XDoclet 간단 예제..  (0) 2007.09.11
무료 차트 API  (0) 2007.08.10