AWS IAM + LDAP + SAML testing (2017.5)

AWS 관련 문서

SAML 2.0 연동하여 AWS 콘솔에 액세스하는 방법은 AWS 문서 참고.

한글 : SAML 2.0 연동 사용자가 AWS Management Console에 액세스할 수 있게 하기

영문 : Enabling SAML 2.0 Federated Users to Access the AWS Management Console

임시 보안 자격 증명 요청하기

IAM 전체 문서 : http://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/iam-ug-ko_kr.pdf


 AWS 연동을 처리할 타사 SAML 2.0 자격 증명 공급자 솔루션 종류 : https://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/id_roles_providers_saml_3rd-party.html

https://aws.amazon.com/ko/iam/partners/ 문서도 참고할 수 있음.

Single Sign-On: Integrating AWS, OpenLDAP, and Shibboleth

지금 작성하는 문서는 Single Sign-On: Integrating AWS, OpenLDAP, and Shibboleth A Step-by-Step Walkthrough 의 내용을 가지고 정리를 하였습니다.

 

이 자료의 출처는 https://blogs.aws.amazon.com/security/post/TxMPIN2JKCL9NT/New-Whitepaper-Single-Sign-On-Integrating-AWS-OpenLDAP-and-Shibboleth 임. 

 

OpenLDAP + Shibboleth 를 이용하여 AWS와 통합을 해서 SSO를 구현하는 예제를 자세히 설명 하고 있다.

 

shibboleth 소개

http://shibboleth.net/about/ :  Shibboleth is a standards based, open source software package for web single sign-on across or within organizational boundaries. It allows sites to make informed authorization decisions for individual access of protected online resources in a privacy-preserving manner.

현재 shibboleth 최신 버전은 v3 이며 테스팅에 사용을 한것은 v2.4.0 이었음.

Abstract

롤 기반의 접근 제어(RBAC)와 SAML 2.0을 이용하여 IAM 과 LDAP을 연동을 해서 온프라미스 환경 및 클라우드 환경에서 identity 와 권한 관리를 편리하게 할 수 있다.

Introduction

Shibboleth를 IdP(identity provider)로 이용하여 LDAP 의 사용자로 AWS에 로그인을 할 수 있다. 이 문서에서는 openldap을 이용하여 설정을 하는 방법을 알려준다.

openldap 의 예제를 이용하여 테스팅을 할 경우에는 원래의 문서를 더 자세하게 읽어 보아야 함. LDAP Schema와 Role 등에 대한 설명이 있음.


예제에서 사용하는 소프트웨어

OS : Ubuntu 14.04 LTS. 실제 테스팅을 했을 때는 Ubuntu 16.04 에서 하였음.

JVM : Openjdk 7 or Openjdk 8. 

Web server : Apache Tomcat 7.0.x

Idneity provider : shibolleth IdpP 2.4

Dirctory : openldap 2.4.x. 자체 ldap 서버가 있는 경우 따로 구축을 할 필요는 없으며 직접 테스팅이 필요한 경우에는 openldap을 함께 올리는 것이 편하다.


Step 1: Prepare the Operating System

Ubuntu OS 준비

/etc/hosts 에 example.com(ldap 서버), idp.example.com(idp ip) 추가.  실제 사용하려는 도메인을 이용하면 됨.

사전에 필요한 디렉토리를 만듬. 이 문서의 예제에서는 /home/ubuntu 디렉토리에 tomcat, idp를 설치하고 있다. 설치 디렉토리는 실제 필요한 디렉토리로 변경을 하면 된다. 아래 일부 내용은 원래의 문서에서 수정을 하였다.

cd /home/ubuntu/
mkdir –p /home/ubuntu/server/tomcat/conf/Catalina/localhost
mkdir -p /home/ubuntu/server/tomcat/endorsed
mkdir -p /home/ubuntu/server/shibidp
mkdir -p /home/ubuntu/installers/shibidp

Step 2: Install and Configure OpenLDAP

openldap 설치. 현재 있는 IDC의 LDAP 서버를 이용해서도 테스팅을 할 수 있다.

LDAP에 대한 간략한 소개를 하고 있음.

ldap, tomcat, shibboleth 각종 설정 예제 파일을 제공하며 이 파일에 미리 정의된 내용이 있어서 수정을 하여 사용하는 것이 편리하다. 

LDAP 및 각종 예제 파일 : https://s3.amazonaws.com/awsiammedia/public/sample/OpenLDAPandShibboleth/examples.tar.gz

Step 3: Install Tomcat and Shibboleth IdP

tomcat 설치

먼저 jdk 를 설치하고 .bashrc 에서 JAVA_HOME 설정을 해 주어야 함.  tomcat은 /home/ubuntu/server/tomcat 에 설치를 함. 문서에는 jdk-7 을 설치했지만 jdk-8로 테스팅을 하였음.

sudo apt install -y openjdk-8-jre-headless
egrep "JAVA_HOME" ~/.bashrc || echo "export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/"  >> ~/.bashrc
source ~/.bashrc

tomcat_version="7.0.72"
wget -c http://www.us.apache.org/dist/tomcat/tomcat-7/v${tomcat_version}/bin/apache-tomcat-${tomcat_version}.tar.gz
tar -xzf apache-tomcat-${tomcat_version}.tar.gz -C server/tomcat/ --strip-components=1
shibboleth Idp 설치

예제에서는 2.4.0 설치를 함. 압축파일을 /home/ubuntu/installers/shibidp 디렉토리에 풀고 설치 스크립트를 실행을 함.  

설치디렉토리는  /home/ubuntu/server/shibidp 지정, fqdn hostname은 idp.example.com 으로 설정을 함.

keystore 은 SAML assertions을 sign 하는데 사용하는 key pair를 보호하기 위해서 사용을 한다고 한다. tomcat의 conf/server.xml  파일의 keystorePass 에도 이 패스워드를 지정한다. 

wget -c http://shibboleth.net/downloads/identity-provider/2.4.0/shibboleth-identityprovider-2.4.0-bin.tar.gz
tar -xzf shibboleth-identityprovider-2.4.0-bin.tar.gz -C installers/shibidp --strip-components=1
cd installers/shibidp/
./install.sh 
Buildfile: src/installer/resources/build.xml

install:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Be sure you have read the installation/upgrade instructions on the Shibboleth website before proceeding.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Where should the Shibboleth Identity Provider software be installed? [/opt/shibboleth-idp]
/home/ubuntu/server/shibidp
The directory '/home/ubuntu/server/shibidp' already exists.  Would you like to overwrite this Shibboleth configuration? (yes, [no])
yes
What is the fully qualified hostname of the Shibboleth Identity Provider server? [idp.example.org]
idp.example.com
A keystore is about to be generated for you. Please enter a password that will be used to protect it.
password
Updating property file: /home/ubuntu/installers/shibidp/src/installer/resources/install.properties
Created dir: /home/ubuntu/server/shibidp/bin
....
 
cd -
tomcat 설정

https 포트 설정, . shibboleth Idp 관련한 몇가지 설정을 함. 웹UI 비밀번호 설정 등. tomcat 서비스 시작함. https://idp.example.com 열어서 확인.

tomcat/conf/server.xml 파일에서 tomcat port 변경을 한다. 8080 port에 대해서는 주석 처리를 하고 8443 port를 443 으로 변경을 한다. examples 예제 파일에 tomcat 설정 및 shibboleth 설정이 되어 있으므로 복사를 해서 사용하는 것이 편리하다.  keystorePass 는 shibboleth 설치할 때 사용했던 값으로 설정을 하면 된다.

    <!--
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
....
    <Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
               keystoreFile="/home/ubuntu/server/shibidp/credentials/idp.jks"
               keystorePass="password" />
/home/ubuntu/server/tomcat/conf/Catalina/localhost/idp.xml 파일을 생성하고 다음과 같이 저장을 한다. This tells Tomcat where Shibboleth’s files are and how to use them. 
$ cat /home/ubuntu/server/tomcat/conf/Catalina/localhost/idp.xml
<Context docBase="/home/ubuntu/server/shibidp/war/idp.war"
     privileged="true"
     antiResourceLocking="false"
     antiJARLocking="false"
     unpackWAR="false"
     swallowOutput="true" />

다음의 명령을 실행한다. Shibboleth library 파일을 tomcat 에서 실행할 수 있도록 해주는 것 같다.  This command tells Tomcat that it can run the Shibboleth library files by copying the contents of Shibboleth's endorsed directory to Tomcat's endorsed directory. 

$ ls installers/shibidp/endorsed/
serializer-2.10.0.jar  xalan-2.7.1.jar  xercesImpl-2.10.0.jar  xml-apis-2.10.0.jar  xml-resolver-1.2.jar
$ cp -v ~/installers/shibidp/endorsed/* ~/server/tomcat/endorsed

/home/ubuntu/server/tomcat/conf/tomcat-users.xml 파일에 관리자 웹UI을 이용하기 위한 아이디와 패스워드를 추가한다. 보안상 관리자 웹UI를 사용하지 않을 것이라면 설정을 하지 않아도 될 것이다. 

 <user username="root" password="password" roles="manager-gui" />

tomcat 을 실행하고 tomcat이 정상적으로 뜨는지 로그를 확인한다.

sudo /home/ubuntu/server/tomcat/bin/startup.sh
tail -f /home/ubuntu/server/tomcat/logs/catalina.out

tomcat 과 shibboleth 가 정상적으로 작동을 하는지 확인을 하기 위해서 https://idp.example.com 으로 확인을 한다. Manageer App에서는 tomcat-users.xml 에 지정한 아이디와 패스워드로 인증을 하고 들어가서 shibboleth 가 작동을 하는지 확인한다.

Step 4: Configure IAM

Shibboleth 를 IdP로 설정을 했으면 AWS IAM 을 SAML service provider로 작동하도록 설정을 해야 한다. 먼저 Shibboleth IdP를 지정한 IAM SAML provider를 생성하고 두번째로는 IAM role을 만들어서 federated user가 AWS 리소스(AWS 관리 콘솔)에 접근할 수 있는 임시 security credentials를 사용할 수있도록 한다. 

IAM SAML Provider 생성하기

외부 IdP에서 SAML identity federation 을 지원하기 위해서는 IAM 에서 provider에 대한 신뢰관계를 만들어야 한다. 이렇게 하기 우해서 IAM SAML provider를 만든다. SAML 2.0 에서는 metadata document 에 두 엔티티간에 통신을 하고 신뢰를 하는데 필요한 모든 정보를 담고 있다. shibboleth 에 요청을 하여 metadata document 를 생성할 수 있다. 

다음의 url에서 metadata document 를 다운로드 받을 수 있다. 이 내용을 idp.example.com.xml 로 저장한다.

https://idp.example.com/idp/profile/Metadata/SAML

AWS 관리자 콘솔 로그인  - IAM console - Identity Providers - Create Provider 선택하면 Create Provider 위자드가 실행된다.

provider type 으로 SAML 을 선택한다. name으로는 예제에서는 ShibDemo로 되어 있는데 원하는 이름을 선택한다.

앞에서 만들었선 shibboleth 의 metadata document 를 업로드한다. 


Next Step을 클릭 한 후 Provider Name 과 Provider type을 확인 한 후 생성을 한다.

IAM Roles 생성하기

다음에는 federated users 가 사용할 수 있는 IAM roles를 생성한다. 

IAM console - Roles - Create New Role - role name 입력 - role type 으로 Grant Web Single Sign-On (WebSSO) access to SAML providers 선택.  

위자드에서는 기본으로 앞에서 설정을 했던 SAML provider를 선택하며 Value 필드는 https://signin.aws.amazon.com/sam 설정을 한다. 


Next Step을 클릭하면 role trust 에서 자동으로 다음과 같이 나온다.  000000000000 부분은 실제 사용하는 AWS account number 로 변경을 해야 한다. 정책을 확인했으면 Next Step 으로 넘어간다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRoleWithSAML",
      "Principal": {
        "Federated": "arn:aws:iam::000000000000:saml-provider/ShibDemo"
      },
      "Condition": {
        "StringEquals": {
          "SAML:aud": "https://signin.aws.amazon.com/saml"
        }
      }
    }
  ]
}

Attach Policy step 에서 필요한 권한을 설정하면 되며 다음 단계로 넘어가면 새로 생성하는 role에 대한 리뷰를 하면 된다. Role ARN(arn:aws:iam::0000000000000:role/BIO 등) 를 기록해둔다.  


필요한 role을 추가로 생성한다. 

Role 을 만들 때 Verify Role Trust 단계에서 다음과 같이 지정을 할 수도 있다. 이경우에는 SAML:eduPersonPrimaryOrgUnitDN 라는 값을 IAM 에서 체크를 하여 조건을 추가 할 수 있다. 

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::000000000000:saml-provider/ShibDemo"
      },
      "Action": "sts:AssumeRoleWithSAML",
      "Condition": {
        "ForAnyValue:StringEquals": {
          "SAML:eduPersonPrimaryOrgUnitDN": "ou=hr,dc=example,dc=com"
        },
        "StringEquals": {
          "SAML:iss": "https://idp.example.com/idp/shibboleth",
          "SAML:aud": "https://signin.aws.amazon.com/saml"
        }
      }
    }
  ]
}


Step 5: Configure Shibboleth IdP

Shibboleth IdP 는 다양한 소스에서 데이터를 가져와서 그 데이터를 사용자 인증 및 외부 엔티티에 대한 인증된 identity 로 통신을 하는데 사용할 수 있다. 

Shibboleth IdP consumes data from a variety of sources and uses that data to both authenticate a user and communicate the authenticated identity to external entities. You can configure nearly every part of the process, and you can extend with code the portions of the IdP that do not support configuration settings.

About Shibboleth Data Connectors

The basic flow for attribute data through Shibboleth is the same, regardless of whether the data comes from a database, LDAP, or another source. A component called a data connector fetches attribute data from its source. The data connector defines a query or filter used to get the identity data. Predefined data connectors exist for relational databases, LDAP, and configuration files.

The results returned by the data connector persist into the next step in the process, which is the attribute definition. In this step, you can process the identity data pulled from the store (and potentially from other attributes defined earlier in the configuration) to produce attributes with the format you need. For example, an attribute can pull several columns of a relational database together with appropriate delimiters and format an email address. Like data connectors, Shibboleth supports predefined attribute definitions. One definition passes identity values through with no modification. With the mapped attribute definition, you can use regular expressions to transform the format of attributes. A number of special attribute definitions expose some of Shibboleth's internal mechanisms, which are interesting but will not be used here.

However, these attributes are still in a Shibboleth-specific internal format. You can attach attribute encoders to the attribute definitions so that you can serialize the internal attributes into whatever wire format you need. This walkthrough uses the SAML 2.0 string encoder to create the required XML for the SAML authentication responses.

After you have fetched, transformed, and encoded data into the correct format, you can use attribute filters to dictate which attributes to include in communication with various relying parties. Predefined attribute filter policies give you great flexibility in releasing attributes to relying parties. You can use filters to write attributes to specific relying parties only, and to write only specific values of the attributes, specific users, or specific authentication methods. You can also string together Boolean combinations of all the above. A complete overview of the process appears in Figure 10.


data connector 를 통하여 database, LDAP 또는 다른 소스에서 데이터를 가져올 수 있다. data connector 는 identity data를 가져올 수 있는 쿼리나 필터를 정의한다. 미리 정의된 data connector 가 있으며 관계형 DBMS, LDAP, 설정 파일 등이 있다.

data connecotr를 통해서 가져온 데이터는 attribute definition 으로 넘겨진다. 가져온 데이터를 정의하는 부분이 attribute definition 임. 이렇게 가져온 속성들은 shibboleth 자체 내부포맷이며 attribute encoders를 통해서 SAML에서 필요한 포맷으로 변경을 할 수 있다. 

데이터를 가져와 변형을 시키고 적절한 포맷으로 인코딩을 했으면 다른 relying parties 와 통신을 할 때 어떤 속성을 포함할 수 있는지 알려주는데 attribute filers를 사용할 수 있다. 

Fetch Attributes from OpenLDAP

attribute-resolver.xml 에서 설정을 함. openldap 연결 정보, 가져올 attributes 를 지정함. 

/home/ubuntu/server/shibidp/conf/attribute-resolver.xml 파일에서  다음 섹션의  주석을 없애라고 나와 있음.

해당 문서에서 openldap 까지 함께 테스팅을 하거나 여러가지 LDAP 의 정보를 가져온다면 필요하지만 LDAP에서 uid 만 가져온다면 "Configuring AWS-specifil attirube definitions" 에서 uid만 ldap에서 가져오도록 설정을 하면 된다. ldap 서버에 대한 인증 정보는 넣어주어야 한다.

# <!-- Schema: eduPerson attributes -->

ldap 설정 정보는 변경을 해 주어야 한다. 

     <resolver:DataConnector id="myLDAP" xsi:type="dc:LDAPDirectory"
        ldapURL="ldap:///"
        baseDN="ou=people,dc=example,dc=com"
        authenticationType="ANONYMOUS">
        <dc:FilterTemplate>
            <![CDATA[
                (uid=$requestContext.principalName)
            ]]>
        </dc:FilterTemplate>
    </resolver:DataConnector>


About Attribute Definitions

/home/ubuntu/server/shibidp/conf/attribute-resolver.xml  파일에서 설정을 함. 

resolver:DataConnector 에는 ldap 에 대한 정보를 설정을 한다. 아래 예에서 ref=myLDAP은 resolver:DataConnector 에서 정의한 LDAP 설정을 가리킨다. id 는 내부 name 을지정하는 것이고 sourceAttributeID 는 data connector 에서 가져오는 속성의 이름을 정의하게 되는데 여기서는 LDAP 의 attributes 를 가리키게 된다.

The most relevant part of an LDAP data connector block is the filter template near the bottom of the definition. When Shibboleth requests attributes for a user, it runs this query on the OpenLDAP database. OpenLDAP needs to authenticate and needs to know where to search. This is what the authenticationType and baseDN attributes define. The reference myLDAP is used to refer to this specific OpenLDAP query. If there are other attributes in OpenLDAP that require a different query, you can copy this block, give it a different ID, and change the query.

The block contains the following eduPerson attribute definition.

    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonAffiliation" sourceAttributeID="eduPersonAffiliation">
        <resolver:Dependency ref="myLDAP" />
        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonAffiliation" />
        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" friendlyName="eduPersonAffiliation" />
    </resolver:AttributeDefinition>

The xsi:type="ad:Simple" attribute in these definitions indicates that these attributes simply copy their values from the data connector as is. This is appropriate for attributes that map directly to single columns of a database, to single attributes from OpenLDAP, or to static configuration data.
The id="eduPersonAffiliation" portion gives this configuration section an internal name that can be referenced elsewhere in the configuration. It is never released to relying parties. The sourceAttributeID="eduPersonAffiliation" portion defines the name of the attribute released by the data connector to use as the source of data for this attribute definition. Because this attribute definition gets data from OpenLDAP, the configuration specifies a dependency on myLDAP, which is the ID that you assigned to the OpenLDAP data connector. 

Finally, a number of encoders are attached. In the SAML 2.0 string encoder, the name and friendlyName are used to set the same portions of a SAML2 attribute.

Configuring AWS-specifil attirube definitions

To use SAML identity federation with AWS, you must configure two AWS-specific attributes. The first is a simple attribute that sets the name of the session granted to users. This value is captured in logs and displayed in the console when the user signs in. Good candidates for this value are a user's login name or email address. Some format restrictions exist for the value:

  • It must be between 2 and 32 characters in length.
  • It can contain only alphanumeric characters, underscores, and the following characters: +=,.@-.
  • It is typically a user ID (bobsmith) or an email address (bobsmith@example.com).
  • It should not include blank spaces, such as often appear in a user’s display name (Bob Smith).

This example uses the uid of the user from OpenLDAP by setting the sourceAttributeID to uid and adding a dependency on the OpenLDAP data connector.

The other attribute that needs to be set is the list of roles the user can assume. This could be as simple as a static value attached to all users in an organization or as complex as a per-user, per-department, ACL (access control list)–based value. This example uses a flexible option that is not difficult to implement.


AWS와 SAML identity federation 을 사용하려면 AWS 와 관련된 attributes 를 설정해야 한다.

첫번째는 사용자가 로그인을 할 이름이다. login name 이나 email 주소 같은 것을 예로 들 수 있다. 이 문서의 예에서는 sourceAttributeID 를 uid로 지정을 하여 openldap 의 uid를 이용하도록 설정하고 있다. 

또 다른 attribute는 사용자에게 부여할 role 목록이다. 이 값은 조직의 모든 사용자에게 부여하는 값 또는 사용자별, 부서별, ACL 기반의 값등으로 설정을 할 수 있다. 예제에서는 ldap 사용자에게 지정한 ou 그룹정보를 이용하여 IAM role을 설정하고 있다.  또한 여러 개의 AWS root account에 대해서 설정을 해도 잘 동작을 한다.

/home/ubuntu/server/shibidp/conf/attribute-resolver.xml  파일에서 설정을 함. 아래 예에서  000000000000 은 AWS account number로 변경을 해야 한다. mappted attribute definition 에서는 입력 값과 출력값을 매핑하는데 정규표현식을 사용할 수 있다. 

아래에서는  eduPersonOrgUnitDN 의 값을 체크하여 IAM role을 매핑하고 있다.

해당하는 정보가 있으면 ReturnValue 가 attribute definition 에 추가가 된다.  ReturnValue 의 포맷은 , 로 구분을 한 role ARN 과 provider ARN 이다. 두 ARN의 순서는 상관이 없다. 


    <resolver:AttributeDefinition
      id="awsRoles"
      xsi:type="ad:Mapped"
      sourceAttributeID="eduPersonOrgUnitDN">

      <resolver:Dependency ref="myLDAP"/>
      <resolver:AttributeEncoder
        xsi:type="enc:SAML2String"
        name="https://aws.amazon.com/SAML/Attributes/Role" friendlyName="Role" />

      <ad:ValueMap>
        <ad:ReturnValue>arn:aws:iam::000000000000:role/BIO,arn:aws:iam::000000000000:saml-provider/ShibDemo</ad:ReturnValue>
        <ad:SourceValue>.*ou=biology.*</ad:SourceValue>
      </ad:ValueMap>

      <ad:ValueMap>
        <ad:ReturnValue>arn:aws:iam::000000000000:saml-provider/ShibDemo,arn:aws:iam::000000000000:role/CSE</ad:ReturnValue>
        <ad:SourceValue>.*ou=computersci.*</ad:SourceValue>
        <ad:SourceValue>.*ou=computereng.*</ad:SourceValue>
      </ad:ValueMap>

      <ad:ValueMap>
        <ad:ReturnValue>arn:aws:iam::000000000000:role/HR,arn:aws:iam::000000000000:saml-provider/ShibDemo</ad:ReturnValue>
        <ad:SourceValue>.*ou=hr.*</ad:SourceValue>
      </ad:ValueMap>

    </resolver:AttributeDefinition>


    <resolver:AttributeDefinition
      id="awsRoleSessionName"
      xsi:type="ad:Simple"
      sourceAttributeID="uid">
        <resolver:Dependency ref="myLDAP"/>
        <resolver:AttributeEncoder
          xsi:type="enc:SAML2String"
          name="https://aws.amazon.com/SAML/Attributes/RoleSessionName"
          friendlyName="RoleSessionName" />
    </resolver:AttributeDefinition>

With the mapped attribute definition, you can use a regular expression to map input values into output values. This example maps eduPersonOrgUnitDN to an IAM role (depending on the organizational unit) in order to give entire departments access to resources by using existing access control rules. The attribute definition contains several value maps, each with its own pattern. Each of the values associated with the eduPersonOrgUnitDN (because it is multivalued) is checked against the patterns specified in the SourceValue nodes. If the check finds a match, the ReturnValue value is added to the attribute definition. The format of the ReturnValue is a role ARN and a provider ARN, separated by a comma. The order of the two ARNs does not matter. If you are using regular expressions in the SourceValue fields, you can use back references in the ReturnValue so that you can simplify the configuration by capturing the organizational unit and using a back reference, although delving into further possibilities of using pattern matching is beyond our scope.

Release Attributes to Relying Parties

attribute fileter 정의를 이용하여 필터를 정의하며 누구한테 attributes를 release 할 수 있는지 relying parties를 설정할 수 있다. 이 예제에서는  AWS "urn:amazon:webservices" 를 설정하였다. OpenLDAP에 있는 attributes를 이용한 조건을 포함하여 IAM 에서 정책을 만들 수 있다. 

Sometimes attributes can contain sensitive data that is useful for authentication within the organization. No one should release the sensitive data outside of the organization. The first part of an attribute filter defines to whom the filter applies. By using an AttributeRequesterString filter policy, an
administrator can choose the relying parties to whom to release the attributes. This example uses the entity ID of AWS "urn:amazon:webservices". This walkthrough uses a simple directory, so all possible values of all the eduPerson and AWS attributes are released to AWS. This allows you to write policies in IAM that can include conditions based on attributes that represent OpenLDAP information. You do this by including an AttributeRule element for each eduPerson entity or AWS attribute, and setting PermitValueRule to basic:ANY

원래 문서의 예제에는 openldap 관련한 각종 설정이 많이 나와 있다. 여기서 설정한 정보를 AWS 에 넘겨줄 수 있으며 이 정보를 이용하여 IAM에서 추가로 조건을 설정을 해서 사용할 수 있다. 아래에서는 awsRoles, awsRoleSessionName 만 설정을 하였다. 

    <afp:AttributeFilterPolicy id="releaseEduAndAWSToAWS">
        <afp:PolicyRequirementRule
          xsi:type="basic:AttributeRequesterString"
          value="urn:amazon:webservices" />

        <afp:AttributeRule attributeID="awsRoles">
             <afp:PermitValueRule xsi:type="basic:ANY"/>
        </afp:AttributeRule>
        <afp:AttributeRule attributeID="awsRoleSessionName">
             <afp:PermitValueRule xsi:type="basic:ANY"/>
        </afp:AttributeRule>
    </afp:AttributeFilterPolicy>
Enable Login Using OpenLDAP as a User Store

https://idp.example.com 에 로그인 하는 방식을 설정하는 부분이다. 

Shibboleth 에서는 여러가지 인증 방식을 지원을 한다. 기본은 remote user 인증인데 이 경우에는 tomcat 을 통해서 인증 정보를 넘긴다. ldap을 통해서 인증을 할 경우에는 remote user authenticatin 을 비활성화해야 한다.User name/password authentication via JAAS and the login.config file are already defined in the configuration file; you just need to uncomment it. Follow these steps:

/home/ubuntu/server/shibidp/conf/handler.xml 에서  다음 블락을 주석처리한다.

<ph:LoginHandler xsi:type="ph:RemoteUser">

그리고 다음 block은 주석을 해제해야 한다.

<ph:LoginHandler xsi:type="ph:UsernamePassword ...>

/home/ubuntu/server/shibidp/conf/login.config 파일에는 ldap 에 대한 정보를 넣어야 한다.

edu.vt.middleware.ldap.jaas.LdapLoginModule required
	ldapUrl="ldap://localhost"
	baseDn="ou=People,dc=example,dc=com"
	bindDn="cn=admin,dc=example,dc=com"
	bindCredential="password"
	userFilter="uid={0}";
Configure Shibboleth to Talk to AWS

LDAP 서비스 설정, Shibboleth 설정을 하고 AWS 에서 Shibboleth 와 신뢰할 수 있도록 IAM 설정을 했다. 이제 남은 것은 Shibboleth(IdP)와 AWS (Service provider)간에 신뢰를 연결하는 것이다. Shibboleth 에서 AWS SAML 2.0 metadata document 의 위치를 지정하면 된다. metadata document 에는 두 파티간에 internet endpoiints, public keys 와 같이 통신을 하는데 필요한 모든 정보가 들어있다. shibboleth 는 FileBackedHTTPMetadataProvider 옵션을 이용하면 AWS 에서 medatadata 를 변경을 할 때 자동으로 갱신을 할 수 있도록 설정을 할 수 있다. 관리자가 수동으로 이 부분을 관리하고자 한다면 관리자가 수동으로 metadata 를 다운로드 받고 FileSystemMetadataProvider 옵션을 이용하면 된다.

/home/ubuntu/server/shibidp/conf/relying-party.xml 파일의 IdPMD entry 에 다음 내용을 추가한다.

       <metadata:MetadataProvider
         id="AWS"
         xsi:type="metadata:FileBackedHTTPMetadataProvider"
         metadataURL="https://signin.aws.amazon.com/static/saml-metadata.xml"
         backingFile="/home/ubuntu/server/shibidp/metadata/aws.xml" />

The file contains settings that cause Shibboleth to apply a set of default configurations to AWS. You can find these settings inside the DefaultRelyingParty and AnonymousRelyingParty blocks.

To change the configuration for a specific relying party, insert the following block after the DefaultRelyingParty block (after the closing </DefaultRelyingParty> tag).

    <rp:RelyingParty
      id="urn:amazon:webservices"
      provider="https://idp.example.com/idp/shibboleth"
      defaultSigningCredentialRef="IdPCredential">

      <rp:ProfileConfiguration
        xsi:type="saml:SAML2SSOProfile"
        includeAttributeStatement="true"
        assertionLifetime="PT5M" assertionProxyCount="0"
        signResponses="never" signAssertions="always"
        encryptAssertions="never" encryptNameIds="never"
        includeConditionsNotBefore="true"
        maximumSPSessionLifetime="PT1H" />
    </rp:RelyingParty>

Shibboleth (IdP)와 AWS (service provider)간에 trust를 연결해야 함. Shibboleth 에서 AWS SAML 2.0 metadata 문서의 위치를 지정하여 설정을 함. metadata 문서는 두개의 parties 간에 통신을 하기 위한 정보가 모두 들어있음.  특정 relying party에 대해서 설정을 변경할 수 있음. 예를 들면  assertionLifetime, maximumSPSessionLifetime 값 등.

  • defaultSigningCredentialRef – The keys used to sign and encrypt requests.
  • ProfileConfiguration – Which SAML 1.x or SAML 2.0 profiles to respond to. Keep in mind that AWS supports only SAML2SSOProfile.
  • assertionLifetime – The length of time (expiration) for the user to provide the authentication information to AWS before it is no longer valid.
  • signResponses/signAssertions – The portions of the response to sign.
  • maximumSPSessionLifetime – The length of a session that AWS should provide based on the authentication information provided.

relying-party.xml  파일은 examples 에서 제공하는것을 경로나 idp url 정보만 바꾸어서 사용을 하면 된다. 

Test Configuration Changes by Using AACLI

attribute authority command line interface(AACLI) 프로그램을 이용하면 지정한 설정 디렉토리의 정보를 이용하여 shibboleth의 attribute 값을 시뮬레이션해 볼 수있다. tomcat  application을 재시작 안 해도 된다.

aacli를 실행하여 Role, RoleSessiongName, eduPersonPrincipalName 결과가 나오는지 확인을 하면 된다.  Role, RoleSessiongName 이 정상적으로 나와야 작동을 하는 것이다. 테스팅을 하여 문제가 없으면 tomcat를 재시작하여 적용을 해보면 된다.

# /home/ubuntu/server/shibidp/bin/aacli.sh --configDir=/home/ubuntu/server/shibidp/conf  --requester "urn:amazon:webservices" --principal taejoon.moon
 
<?xml version="1.0" encoding="UTF-8"?><saml2:AttributeStatement xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
   <saml2:Attribute FriendlyName="Role" Name="https://aws.amazon.com/SAML/Attributes/Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
      <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">arn:aws:iam::00000000000:role/SAMLTEST,arn:aws:iam::000000000000:saml-provider/ShibDemo2</saml2:AttributeValue>
   </saml2:Attribute>
   <saml2:Attribute FriendlyName="RoleSessionName" Name="https://aws.amazon.com/SAML/Attributes/RoleSessionName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
      <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">taejoon.moon</saml2:AttributeValue>
   </saml2:Attribute>
   <saml2:Attribute FriendlyName="eduPersonPrincipalName" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
      <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">taejoon.moon@example.com</saml2:AttributeValue>
   </saml2:Attribute>

AACLI로 필요한 속성을 받았으면 tomcat 을 재시작한다.

sudo /home/ubuntu/server/tomcat/bin/shutdown.sh
sudo /home/ubuntu/server/tomcat/bin/startup.sh

Step 6: Test Shibboleth Federation

다음 url 에서 aws 에 대한 federation 을 테스팅을 할 수 있다.  

https://idp.example.com/idp/profile/SAML2/Unsolicited/SSO?providerId=urn:amazon:webservices 에서 로그인을 하면 다음과 같은 화면이 나타난다.

ldap에 있는 uesr와 비밀번호를 입력하고 정상적으로 로그인이 되면 AWS management console 로 redirect 가 된다. 지정한 role 이 여러개 인 경우 (여러 개의 AWS account 를 가지고 있는 등)에는 선택 가능한 role이 모두 나온다. 

다른 유저로 테스팅을 해보려면 https://idp.example.com/idp/profile/Logout 에서 logout을 하고 나서 다시 로그인을 해 보면 됨.

접근에 대한 제어는 두가지 전략을 이용할 수 있다.

  • Shibboleth 에서 설정. 특정 사용자에게 특정 AWS role 을 가지도록 설정
  • IAM role trust policy 에서 설정. 특정 role을 가지도록 제한할 수 있는 SAML attribute에 기반하여 조건을 설정함.
  • 두개를 조합하여 사용도 가능함.

Conclusion

온프라미스 LDAP 을 IAM에 통합을 해서 온프라미스 환경과 클라우드 간에 권한을 동기화하는데 시간을 덜 쓸 수 있게 되었다. SAML 속성과 RBAC 를 조합을 하여 LDAP user data와 AWS 리소스간에 접근 제한 설정을 만들 수 있다. 

더 읽을 거리

원래의 문서 참고.

참고사항

    <resolver:AttributeDefinition 
      id="awsRoles" 
      xsi:type="ad:Mapped" 
      sourceAttributeID="memberOf">
.....
    <resolver:DataConnector id="myLDAP" xsi:type="dc:LDAPDirectory"
	xmlns="urn:mace:shibboleth:2.0:resolver:dc"
        ldapURL="ldap://ldap.example.com" 
        baseDN="o=example,dc=com" 
        searchScope="SUBTREE"
        principal="cn=xxxxxxx,o=admingroup,dc=com"
        principalCredential="CHANGEME">
        <dc:FilterTemplate>
            <![CDATA[
                (uid=$requestContext.principalName)
            ]]>
        </dc:FilterTemplate>
	<ReturnAttributes>cn uid memberOf eduPersonAffiliation eduPersionEntitlement</ReturnAttributes>

    </resolver:DataConnector>
  • 조직정보가 각 사용자 dn의 OuCode에 있는 경우. 아래는 OuCode가 000013815 인 경우에 role을 주는 것이며  000013815 는 devops팀임.

        <resolver:AttributeDefinition
          id="awsRoles"
          xsi:type="ad:Mapped"
          sourceAttributeID="OuCode">
    
          <resolver:Dependency ref="myLDAP"/>
          <resolver:AttributeEncoder
            xsi:type="enc:SAML2String"
            name="https://aws.amazon.com/SAML/Attributes/Role" friendlyName="Role" />
    
          <ad:ValueMap>
            <ad:ReturnValue>arn:aws:iam::763432659218:role/SAMLTEST,arn:aws:iam::763432659218:saml-provider/ShibDemo2</ad:ReturnValue>
            <ad:SourceValue>000013815</ad:SourceValue>
          </ad:ValueMap>
    
        </resolver:AttributeDefinition>
  • shibboleth 로그 디렉토리는 /home/ubuntu/server/shibidp/logs 임. 

shibboleth v2 추가 설정

shibboleth v2 문서 : https://wiki.shibboleth.net/confluence/display/SHIB2

idpInstall : https://wiki.shibboleth.net/confluence/display/SHIB2/IdPInstall

설정하기 : https://wiki.shibboleth.net/confluence/display/SHIB2/Configuration

idp 설정 : https://wiki.shibboleth.net/confluence/display/SHIB2/IdPConfiguration

LDAP Data Connector : https://wiki.shibboleth.net/confluence/display/SHIB2/ResolverLDAPDataConnector  

Example login page 에 subtree 명시 : https://wiki.shibboleth.net/confluence/display/SHIB2/IdPAuthUserPass

LDAP 에서 검색시 subtree 를 명시적으로 지정을 해주어야 여러개의 하위 dn 이 있는 경우에도 검색이 가능하였다. 이 경우에는 LDAP Data Connector, Example login page 에 subtree 명시를 해 주어야 한다.


idp 서버의 설정 정보 : https://wiki.shibboleth.net/confluence/display/SHIB2/IdPProdConfigFiles

idp 서버의 설정 정보는 IDP_HOME/conf directory 에 저장이 된다. (attribute-filter.xml, attribute-resolver.xml, handler.xml, relying-party.xml 등)

이 부분은 server.xml 설정을 통해서  http/svn 등에 저장을 하는 것도 가능하며 ldap 비밀번호 같은 민감한 데이터는 별도의 파일에 설정을 하는 것도 가능하다.

또한 호스트별 또는 tier 별 등 으로 여러 개의 리소스 파일을 나누어 사용하는 것도 가능하다.

설정파일을 자동으로 읽어들이는 설정도 가능하며 configurationResourcePollingFrequency 옵션을 설정하면 된다.

https://wiki.shibboleth.net/confluence/display/SHIB2/IdPConfigConfig

테스팅을 했던 것은  idp 2.4 이고 최신 버전은 3.x  이다. 그런데  3.x 에서도 설정파일을 http, subversion 에서만 저장을 할 수 있다. git 은 지원을 하지 않는 것 같다.

https://wiki.shibboleth.net/confluence/display/IDP30/ReloadableServices


기타 정보

http://www.slideshare.net/awskorea/20150109-aws-black-belt-iam-younjin : IAM ROLE Base access