Cloud 인프라/AWS

[AWS] Keycloak으로 AWS Client VPN 사용하기

rnany 2025. 3. 12. 14:34

0. 서론

AWS Clinet VPN을 "사용자 기반 인증"의 "연동 인증" 방법을 통해 구성한 내용에 대해 다룬다.

이때 사용자 인증을 위한 idP(identity provider)로 오픈 소스인 "Keycloak"을 사용했다.

Keycloak은 도커가 아닌 서버에 직접 올리는 방식을 사용했다.

 

1. Keycloak과 AWS Clinet VPN 이해하기

이해를 위해 사용자가 본인을 인증하고 VPN을 사용하기까지의 과정을 먼저 알아보자.

하단 그림에 대한 설명은 https://aws.amazon.com/ko/blogs/security/authenticate-aws-client-vpn-users-with-aws-single-sign-on/을 참고했다.

 

1. 사용자는 AWS가 제공하는 VPN 클라이언트를 실행하고 Client VPN 엔드포인트에 연결을 시도한다.

2. 클라이언트 VPN 엔드포인트는 IAM SAML 공급자에서 제공된 정보를 기반으로 Keycloak(IdP)의 URL과 인증 요청을 클라이언트로 다시 보낸다.

3. AWS에서 제공하는 VPN 클라이언트는 사용자 기기에서 새 브라우저 창을 연다. 브라우저는 Keycloak(IdP)에 요청을 하고 로그인 페이지를 표시한다.

4. 사용자가 ID 및 비밀번호를 입력하면, Keycloak은 이를 검증하고 서명된 SAML 어설션(SAML Assertion)을 생성하여 AWS VPN 클라이언트에 HTTP POST 형식으로 다시 보낸다.

5. AWS VPN 클라이언트는 Keycloak이 제공한 SAML 어설션을 AWS Client VPN 엔드포인트로 전달한다.

6. Client VPN 엔드포인트는 SAML 어설션을 검증하고 사용자의 접근을 허용하거나 거부한다.

 

2. 환경 구성

1) Keycloak 서버 구축하기

Keycloak을 설치할 서버에 접근한다. 나는 AWS EC2에 Amazon Linux 2023 AMI 환경으로 서버를 생성했다.

 

JAVA 설치

Keycloak을 위해 java 11 이상이 필요하여 본인의 서버에 맞는 방법으로 java를 설치해준다.

$ dnf list  java*
$ dnf install java-11-amazon-corretto.x86_64

 

MariaDB 설치 및 설정

Keycloak은 기본적으로 H2 DB를 사용하나 우리는 mariadb를 설치해 사용하는 방법으로 구성해보자.

$ dnf install mariadb105-server

$ systemctl start mariadb.service
$ systemctl enable mariadb.service

 

초기 보안 설정 및 keycloak db를 생성해준다.

$ mysql_secure_installation

$ mysql -u root -p
Enter password:
MariaDB [(none)]> Create DATABASE keycloak;
MariaDB [(none)]> use mysql;
MariaDB [mysql]> CREATE USER 'keycloak'@'%' IDENTIFIED BY '비밀번호';
MariaDB [mysql]> GRANT ALL PRIVILEGES ON keycloak.* TO 'keycloak'@'%' IDENTIFIED BY '비밀번호';
MariaDB [mysql]> FLUSH PRIVILEGES;

 

 

Keycloak 다운 및 설정

원하는 디렉토리에서 keycloak 파일을 다운 받은 뒤 압축을 풀어준다.

$ cd /data
$ wget https://github.com/keycloak/keycloak/releases/download/21.0.1/keycloak-21.0.1.tar.gz
$ tar -xvf keycloak-21.0.1.tar.gz

 

Keycloak 설정 파일에 접근해 하단 설정을 넣어준다.

$ vim /data/keycloak-21.0.1/conf/keycloak.conf

# Database
db=mariadb
db-url=jdbc:mariadb://localhost:3306/keycloak
db-username=keycloak
db-password=비밀번호

# HTTP
https-certificate-file=/data/keycloak-21.0.1/conf/server.crt.pem
https-certificate-key-file=/data/keycloak-21.0.1/conf/server.key.pem

http-port=80
https-port=443

#log-level=DEBUG
#quarkus.log.level=DEBUG
#quarkus.log.category."org.keycloak".level=DEBUG
#quarkus.log.category."org.keycloak.protocol.saml".level=DEBUG
#kc.spi.saml.allow-any-issuer=true

- DB 연결 정보를 입력해준다.

- 나는 인증서 적용이 가능해서 인증서 설정을 넣어줬다. Keycloak은 기본적으로 https 접근을 하기에 인증서 적용이 안되면 에러가 발생한다. 인증서가 없다면 임의 인증서를 만들어 설정하는 방식으로 진행해야한다. 인증서 관련 정보는 https://babo-it.tistory.com/145 블로그를 참고했다.

- keycloak은 8080, 8443 포트를 기본으로 사용하는데 옵션을 넣어 80, 443을 사용하게 바꿔주었다.

 

Keycloak 실행

같은 서버에서 접근하는 것이 아니면 admin 설정페이지가 뜨지 않는다 이에 환경 변수 설정으로 admin 설정을 해준다.

그 뒤 keycloak을 실행하면 된다.

$ export KEYCLOAK_ADMIN=admin
$ export KEYCLOAK_ADMIN_PASSWORD=123

$ nohup sudo -E /data/keycloak-21.0.1/bin/kc.sh start-dev &

 

나는 서비스 등록을 해서 keycloak을 실행했다.

$ vim /etc/systemd/system/keycloak.service

[Unit]
Description=Keycloak Server
After=network.target

[Service]
User=root
Group=root
WorkingDirectory=/data/keycloak-21.0.1
ExecStart=sudo -E /data/keycloak-21.0.1/bin/kc.sh start-dev
Environment="KEYCLOAK_ADMIN=admin"
Environment="KEYCLOAK_ADMIN_PASSWORD=123"
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target


$ systemctl daemon-reload

$ systemctl start keycloak
$ systemctl enable keycloak

 

서버에 port 들이 정상적으로 뜬 것을 확인 했다.

 

서버 IP로 접근시 Keycloak 페이지가 뜨는 것을 확인 할 수 있다.

 

 

2) Keycloak 설정하기

Keycloak 페이지에서 Administration Console을 눌러 관리자 페이지에 접근한다.

 

로그인 화면에서 keycloak을 실행할때 입력한 admin 계정으로 로그인한다.

 

Realm 생성

왼쪽 위의 Create Realm 버튼을 눌러 Realm을 생성 해 준다. Realm name만 입력해주면 된다.

 

Client 생성

왼쪽의 Clinets 탭에 들어가 Creat client를 눌러준다.

필수 입력 사항

Client type : SAML

Client ID : urn:amazon:webservices:clientvpn

Valid redirect URIs : http://127.0.0.1:35001/*

 

이후 생성된 client의 Keys 탭에서 Client signature required 설정을 OFF로 바꿔준다.

AWS VPN에서 서명된 값을 보내지 않기 때문에 해당 설정이 켜져있으면 안된다.

 

Client scopes 탭에서 urn:amazon:webservices:clientvpn-dedicated의 scope 탭에 들어간다.

 

Full scope allowed 설정을 off로 변경해준다.

 

User 생성

왼쪽의 User 탭의 Add user를 눌러 VPN에 접속 인증을 할 사용자를 만들어준다.

이때 username과 Email이 필수 입력 값으로 clinet VPN의 로그에 이메일로 사용자 구분이 가능하다.

 

3) Client VPN 생성하기

 

SAML 파일 다운 받기

왼쪽의 Realm settings에서 SAML 2.0 Identity Provider Metadata를 누른 뒤 ctrl+s를 눌러 SAML 파일을 다운 받는다.

다운 받은 SAML 파일을 메모장으로 열어 WantAuthnRequestsSigned 설정을 false로 바꿔준다.

 

AWS idP 생성

AWS에서 Identity and Access Management(IAM)를 들어가 ID제공업체에서 공급자 추가를 눌러준다.

 

saml 파일 업로드를 진행한다.

 

인증서 생성 및 가져오기

서버에서 Client VPN에 사용할 인증서를 만들어준다.(해당 내용은 포스팅 된 글이 많기에 자세한 설명은 생략한다.)

 $ git clone https://github.com/OpenVPN/easy-rsa.git
 $ cd easy-rsa/easyrsa3
 $ ./easyrsa init-pki
 $ ./easyrsa build-ca nopass
 $ ./easyrsa --san=DNS:keycloak build-server-full server nopass

 

AWS ACM에서 생성된 인증서를 업로드 해준다.

Client VPN 생성

AWS VPC의 Cleint VPN 엔드포인트에 가서 클라이언트 VPN 엔드포인트 생성을 눌러준다.

 

Clinet vpn 설정에 이전에 업로드한 SAML 파일과 인증서를 선택해준다. 클라이언트 IPv4는 VPN에 할당될 클라이언트의 IP로 연결할 VPC와 대역이 겹치면 안된다.

추가적으로 분할 터널 활성화를 체크해주는 것이 좋다. 아니면 VPN 연결 후 인터넷 사용이 불가하다.

 

생성된 클라이언트 VPN 엔드포인트를 선택해 대상 네트워크 연결에 연결할 VPC 설정을 해주, 권한 부여 규칙 설정을 해준다.

이때 권한 부여 규칙은 클라이언트 VPN 사용자가 접근 가능한 VPC 대역이다.

 

클라이언트 VPN 엔드포인트의 클라이언트 구성을 다운로드한다.

 

AWS client vpn에 해당 구성 파일을 등록해준다.

 

등록된 프로필의 연결 버튼을 누르면 Keycloak 로그인 페이지가 뜬다. 생성해준 user로 로그인 해준다.

 

AWS client 엔트포인트에서 user의 이메일로 사용자 이름을 확인 할 수 있다.