새소식

Storage

[MinIO Study 3주차] MinIO 접근 제어 (feat. LDAP)

  • -

CoudNet@ 팀의 가시다님께서 리딩하시는 MinIO Study 3주차 스터디 내용 정리

 

이번 주차에는 MinIO 스터디의 마지막 주차로 스토리지 접근 제어PBAC, LDAP 연동 그리고 SDK 를 활용한 MinIO 접근에 대해서 공부했습니다.

 

실습 환경 구성은 앞의 글을 참고 바랍니다.




1. LDAP

 

LDAP (Lightweight Directory Access Protocol)사용자, 그룹, 권한 정보를 계층적으로 보관하는 '주소록/조직도' 를 의미합니다.



1.1. LDAP 구성

 

 

LDAP 은 다음과 같은 구성으로 이루어집니다.

 

1. LDAP 서버
- 사용자, 그룹, 권한 정보를 디렉토리 라는 구조로 보관하는 중앙 관리소

 

2. 디렉토리 구조
- 아래와 같은 계층적 주소로 정보를 저장

 

dc - company
ou - 부서
cn - 사용자

 

3. 클라이언트
- 누군가 시스템에 로그인하려고 할 때, 시스템이 LDAP 에 질의한 후 허용 여부를 결정

 

4. 인증(Authentication)
- 시스템이 LDAP 서버에 아이디와 비밀번호 전송하여 확인

 

5. 권한부여(Authorization)
- LDAP 서버가 그룹 정보나 역할을 반환하면, 시스템이 그 정보에 따라 권한 부여

 



1.2. OpenLDAP

 

LDAP 을 오픈소스로 활용할 수 있게 만든 도구입니다.
LDAP 실습은 OpenLDAP 을 통해 진행할 예정입니다.

 

OpenLDAP 배포를 위한 조직 설정 파일 생성

 

LDAP 은 조직도, 구성도인 만큼 생성 전에 조직도 초기 설정 파일을 만들어 줘야 합니다.
다음과 같이 조직도를 구성할 예정입니다.

# 전체 그림
## Users OU는 아직 사용자가 안 들어가 있지만 컨테이너만 생성
## Groups OU 안에 Admins/ Maintainers 그룹이 있고 사용자 DN이 멤버로 들어감
dc=minio,dc=io
├── cn=developer (사용자)
├── cn=maintainer (사용자)
├── cn=admin_root (사용자)
├── ou=Users (OU)
└── ou=Groups
    ├── cn=Admins (groupOfUniqueNames, member=admin_root)
    └── cn=Maintainers (groupOfUniqueNames, member=maintainer,developer)


# 사용자 엔트리들
dn: cn=developer,dc=minio,dc=io  # dn: 엔트리의 Distinguished Name(LDAP 경로)
changetype: add                  # changetype: add : 새 엔트리를 추가
objectclass: inetOrgPerson       # 속성(attribute)을 나열
cn: developer
givenname: developer
sn: Developer
displayname: Developer User
mail: developer@minio.io
userpassword: developer_pass

dn: cn=maintainer,dc=minio,dc=io
changetype: add
objectclass: inetOrgPerson       # LDAP에서 사람을 나타낼 때 쓰는 표준 객체 클래스
cn: maintainer                   # cn : Common Name (로그인 ID 같은 것)
givenname: maintainer
sn: Maintainer
displayname: Maintainer User     # displayname : LDAP UI 등에서 보여줄 이름
mail: maintainer@minio.io
userpassword: maintainer_pass    # userpassword : 사용자 비밀번호
...


# 조직 단위(OU) 생성
dn: ou=Groups,dc=minio,dc=io     # ou=Groups : 그룹들을 담는 컨테이너(Organizational Unit)
changetype: add
objectclass: organizationalUnit
ou: Groups

dn: ou=Users,dc=minio,dc=io      # ou=Users : 사용자를 담는 컨테이너
changetype: add
objectclass: organizationalUnit
ou: Users                        # 사용자들이 dc=minio,dc=io에 직접 만들어졌지만, 별도 OU로도 구분 가능


# 그룹 엔트리들
dn: cn=Admins,ou=Groups,dc=minio,dc=io
changetype: add
cn: Admins                       # cn=Admins 라는 그룹을 만들고
objectclass: groupOfUniqueNames  # objectclass: groupOfUniqueNames : 고유 멤버 DN을 갖는 그룹
uniqueMember: cn=admin_root,dc=minio,dc=io  # uniqueMember: 로 admin_root 사용자를 그룹 멤버로 추가

dn: cn=Maintainers,ou=Groups,dc=minio,dc=io
changetype: add
cn: Maintainers                  # Maintainers라는 그룹을 만들고
objectclass: groupOfUniqueNames
uniqueMember: cn=maintainer,dc=minio,dc=io # maintainer와 developer 두 명을 멤버로 지정
uniqueMember: cn=developer,dc=minio,dc=io

 

LDIF Configmap 작성

 

실제 위의 정보를 K8S 에 배포하기 위해 Configmap 을 생성합니다.

 

#
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: openldap-admin-secret
type: Opaque
stringData:
  admin-password: "admin123"
EOF

#
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: openldap-bootstrap
  namespace: default
data:
  bootstrap.ldif: |
    dn: cn=developer,dc=minio,dc=io
    changetype: add
    objectclass: inetOrgPerson
    cn: developer
    givenname: developer
    sn: Developer
    displayname: Developer User
    mail: developer@minio.io
    userpassword: developer_pass

    dn: cn=maintainer,dc=minio,dc=io
    changetype: add
    objectclass: inetOrgPerson
    cn: maintainer
    givenname: maintainer
    sn: Maintainer
    displayname: Maintainer User
    mail: maintainer@minio.io
    userpassword: maintainer_pass

    dn: cn=admin_root,dc=minio,dc=io
    changetype: add
    objectclass: inetOrgPerson
    cn: admin_root
    givenname: admin_root
    sn: AdminRoot
    displayname: Admin User
    mail: admin_root@minio.io
    userpassword: admin_pass

    dn: ou=Groups,dc=minio,dc=io
    changetype: add
    objectclass: organizationalUnit
    ou: Groups

    dn: ou=Users,dc=minio,dc=io
    changetype: add
    objectclass: organizationalUnit
    ou: Users

    dn: cn=Admins,ou=Groups,dc=minio,dc=io
    changetype: add
    cn: Admins
    objectclass: groupOfUniqueNames
    uniqueMember: cn=admin_root,dc=minio,dc=io

    dn: cn=Maintainers,ou=Groups,dc=minio,dc=io
    changetype: add
    cn: Maintainers
    objectclass: groupOfUniqueNames
    uniqueMember: cn=maintainer,dc=minio,dc=io
    uniqueMember: cn=developer,dc=minio,dc=io
EOF

 

OpenLDAP k8s 배포

 

cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: openldap
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: openldap
  template:
    metadata:
      labels:
        app: openldap
    spec:
      initContainers:
        - name: copy-bootstrap
          image: busybox
          command: ['sh', '-c', 'cp /config/bootstrap.ldif /ldif/bootstrap.ldif']
          volumeMounts:
            - name: configmap-ldif
              mountPath: /config
            - name: writable-ldif
              mountPath: /ldif
      containers:
        - name: openldap
          image: osixia/openldap:1.5.0
          env:
            - name: LDAP_ORGANISATION
              value: "MinIO"
            - name: LDAP_DOMAIN
              value: "minio.io"
            - name: LDAP_ADMIN_PASSWORD
              value: "admin123"
            - name: LDAP_REMOVE_CONFIG_AFTER_SETUP
              value: "false"
          ports:
            - containerPort: 389
            - containerPort: 636
          volumeMounts:
            - name: writable-ldif
              mountPath: /container/service/slapd/assets/config/bootstrap/ldif/custom
        - name: phpldapadmin
          image: osixia/phpldapadmin:0.9.0
          env:
            - name: PHPLDAPADMIN_LDAP_HOSTS
              value: "localhost"
            - name: PHPLDAPADMIN_HTTPS
              value: "false" # 기본 HTTP로 사용, HTTPS 쓰려면 true
          ports:
            - containerPort: 80
      volumes:
        - name: configmap-ldif
          configMap:
            name: openldap-bootstrap
        - name: writable-ldif
          emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: openldap
  namespace: default
spec:
  selector:
    app: openldap
  ports:
    - name: ldap
      port: 389
      targetPort: 389
    - name: ldaps
      port: 636
      targetPort: 636
    - name: http
      port: 80
      targetPort: 80
EOF

 

배포 확인

 

kubectl get deploy,pod,svc,ep,cm,secret



1.3. LDAP 액세스 관리

 

MinIO 는 사용자 ID 의 외부 관리를 위해 AD(Active Directory) 또는 LDAP 서비스 구성을 지원합니다.
AD/LDAP 외부 ID 관리를 활성화하면 MinIO 내부 IDP 는 비활성화 됩니다.
외부 공급자 ID 의 경우, MinIO 는 해당 ID 사용자들을 MinIO 가 보유한 기존 정책에 매핑하려고 시도합니다.




2. LDAP 실습



2.1. LDAP 연동

 

OpenLDAP 이 성공적으로 배포되었다면 아래와 같이 LDAP 을 연동합니다.

 

 

입력 정보는 아래와 같습니다.

Server Insecure : **Enabled**
Server Address : `openldap.default.svc.cluster.local:389`
Lookup Bind DN* : `cn=admin,dc=**minio**,dc=io`
Lookup Bind Password* : **`admin123`**
User DN Search Base* : **`dc**=minio,dc=io`
User DN Search Filter* : `(cn=%s)`

 

 

그 후 MinIO 를 재시작해야합니다.

 

LDAP 연동 화면

 

 

LDAP 이 연동되면 기존 Identity 에 있던 User 와 Group 은 사라지게 됩니다.



2.2. LDAP 활용

 

LDAP 을 통해서 사용자에게 정책을 설정하고 확인해보겠습니다.
정책을 부여할 사용자는 admin_root 입니다.

 

# 전체 그림
dc=minio,dc=io
├── cn=developer (사용자)
├── cn=maintainer (사용자)
├── cn=admin_root (사용자)
├── ou=Users (OU)
└── ou=Groups
    ├── cn=Admins (groupOfUniqueNames, member=admin_root)
    └── cn=Maintainers (groupOfUniqueNames, member=maintainer,developer)

 

LDAP 도 MinIO cli 를 통해 조회할 수 있습니다.

 

# LDAP 정보 조회
mc idp ldap info $MYALIAS --insecure

# DN (admin_root) 에 consoleAdmin 정책 부여
mc idp ldap policy attach $MYALIAS consoleAdmin --user='cn=admin_root,dc=minio,dc=io' --insecure

# user 확인
mc admin user list $MYALIAS --insecure --json

 

 

LDAP 사용자로 로그인

 

위에서 정책을 부여한 admin_root 사용자로 로그인해보겠습니다.
아래 접근 정보로 로그인 합니다.

ID: admin_root, PW: admin_pass

 

접속이 되는 것을 확인할 수 있습니다.

 



2.3. LDAP 그룹 활용

 

앞서 LDAP 초기 연동 설정에서는 그룹 검색은 설정하지 않았습니다.
LDAP 에서 그룹을 활용하는 방법에 대해서 알아보겠습니다.

 

다음과 같이 CLI 로 그룹을 설정할 수 있습니다.
웹콘솔에서도 동일하게 설정가능하며, 설정 후 재시작이 필요합니다.

# 그룹 검색 추가
mc idp ldap update $MYALIAS \
  group_search_filter="(&(objectClass=groupOfUniqueNames)(uniqueMember=%d))" \
  group_search_base_dn="dc=minio,dc=io" --insecure

# MinIO 재시작
mc admin service restart $MYALIAS --insecure

# LDAP 정보 확인
mc idp ldap info $MYALIAS --insecure

 

 

웹 콘솔에서도 확인 가능합니다.

 

 

이제 그룹에 정책을 추가해보겠습니다.
정책을 추가할 그룹은 Maintainers 입니다.

 

# 전체 그림
dc=minio,dc=io
├── cn=developer (사용자)
├── cn=maintainer (사용자)
├── cn=admin_root (사용자)
├── ou=Users (OU)
└── ou=Groups
    ├── cn=Admins (groupOfUniqueNames, member=admin_root)
    └── cn=Maintainers (groupOfUniqueNames, member=maintainer,developer)

 

Maintainers 에 readwrite 권한 부여

 

# 그룹에 정책 추가
mc idp ldap policy attach $MYALIAS readwrite \
  --group="cn=Maintainers,ou=Groups,dc=minio,dc=io" --insecure

# 그룹 확인
mc admin group list $MYALIAS --insecure

 

 

이후 MinIO 에 maintainer, developer 사용자로 로그인 할 수 있는 것을 확인하였습니다.


 

 

Contents

포스팅 주소를 복사했습니다