SAML을 이용해 FortiGate를 SP(Service Provider) 로 하고, keycloak을 idP로 하여 keycloak의 계정을 통해 FortiClient SSO로 SSL VPN을 연결하는 방법에 대해서 다루겠습니다.
이를 위해서 저의 경우에는 1. 쿠버네티스에서 keycloak을 배포하고 2. Let's Encrypt를 통해 인증서를 발급받고 3. Load Balance 기능을 통해 https 통신을 리버스 프록시 구성으로 keycloak 서버에 http로 전달하고 4. SAML SSO 연동 설정을 통해 keycloak에 생성된 계정으로 SSL VPN 연결하는 과정까지 진행하도록 하겠습니다.
1. 쿠버네티스에서 keycloak 배포
A. yaml 파일 작성
저의 경우 Ingress를 사용하지 않고 간단하게 nodePort 설정을 통해 구성하였습니다.
- 최초 접속 포트: http://쿠버네티스 서버 IP:[노드 포트] yaml 파일 상 30082 포트
- 최초 접속 계정: admin / admin
vi dep.yaml
apiVersion: v1
kind: Service
metadata:
name: keycloak
labels:
app: keycloak
spec:
ports:
- name: http
nodePort: 30082
port: 8080
targetPort: 8080
selector:
app: keycloak
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
labels:
app: keycloak
spec:
replicas: 1
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:26.0.2
args: ["start-dev"]
env:
- name: KEYCLOAK_ADMIN
value: "admin"
- name: KEYCLOAK_ADMIN_PASSWORD
value: "admin"
- name: KC_PROXY
value: "edge"
ports:
- name: http
containerPort: 8080
readinessProbe:
httpGet:
path: /realms/master
port: 8080
B. keycloak namespace 생성
kubectl create namespace keycloak
C. keycloak namespace에 배포 진행
# 배포 진행 (service, deployment 생성 확인)
kubectl apply -f dep.yaml -n keycloak
service/keycloak created
deployment.apps/keycloak created
# pod 상태 확인
kubectl get pods -n keycloak
NAME READY STATUS RESTARTS AGE
keycloak-5bb4bd5c44-wh9w9 1/1 Running 0 107s
D. http://[쿠버네티스 서버 IP]:[노드 포트] 로 접속
yaml 파일 기준
- 접속정보: http://[쿠버네티스 서버 IP]:30082
- 계정: admin / admin
여기까지 했으면 keycloak은 우선 접어두고, 방화벽에서의 설정을 진행하겠습니다.
24.10.30 추가
만약 keycloak을 접속하시는 IP가 사설 IP가 아니실 경우, (즉 쿠버네티스의 IP가 사설 IP가 아닐 경우) https로의 로그인이 강제됩니다.
해당 사유는 HTTPS required 설정 때문인데 Default는 External requests 설정이기 때문입니다.
(localhost 또는 사설 IP는 http로 접속 허용 / 이외 통신은 https 강제)
위 상황에서는 해당 설정을 직접 pod으로 접속하여 수정이 필요합니다. (또는 yaml 파일 수정하여 https 포트 설정 추가)
# pod 이름 확인
$ kubectl get pod -n keycloak
NAME READY STATUS RESTARTS AGE
keycloak-849cc54dcd-ppnnx 1/1 Running 0 3d5h
# pod bash shell 접속
kubectl exec keycloak-849cc54dcd-ppnnx -n keycloak -it -- bash
# /opt/keycloak/bin/ 경로로 이동 (26 버전 기준)
cd /opt/keycloak/bin
# 로그인 진행, 패스워드 입력
$ ./kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin (계정명)
Logging into http://localhost:8080 as user admin of realm master
# Required SSL 설정 변경
./kcadm.sh update realms/master -s sslRequired=NONE
2. Let's Encrypt를 통해 FortiGate에서 인증서 발급
아래 링크를 참고하여 설정을 진행합니다.
3. FortiGate의 Load Balance 기능을 통해 HTTPS 통신을 HTTP로 keycloak에 전달
A. System -> Feature Visibility -> Load Balance -> Apply를 적용하여 기능을 GUI에서 보이게 설정
B. Policy & Objects -> Virtual Servers -> Create New 클릭
C. 아래와 같이 각자의 환경에 맞게 정보를 입력합니다.
- Name: 식별하기 쉬운 객체명 입력
- Type: HTTPS
- Interface: 회선 연결 인터페이스
- Virtual server IP: Let's Encrypt로 인증서 발급받은 도메인의 공인 IP
- Virtual server port: 외부에서 접근할 포트 정보
- SSL offloading: Client <-> FortiGate로 설정 (Client - FortiGate는 HTTPS 통신, FortiGate - Server는 HTTP 통신)
- Certificate: Let's Encrypt로 발급받은 인증서로 설정
- Create New 버튼 누른 뒤 Address는 내부 Keycloak 서버 IP, 포트는 접속 포트로 설정
D. 우선 인터페이스 설정만 옳게 들어간 설정을 GUI에서 추가한 뒤, CLI에서 아래 추가 설정을 진행합니다.
(이유: 정책 inspection-mode가 Proxy여야 객체를 추가할 수 있으나, FG-40F 같은 메모리가 적은 소형 장비의 경우 GUI에서 해당 설정 변경 불가)
config firewall policy
edit <생성한 정책 ID>
set inspection-mode proxy
set srcaddr all
set dstaddr keycloak
end
E. Keycloak에 로그인 후, Realm settings -> Frontend URL을 https://[Virtual server IP(도메인 IP)]:[Virtual Server Port] 로 변경 후 Save 버튼을 클릭합니다.
F. E에서 설정한 Frontend URL로 정상 접속이 가능한지 확인합니다.
* 이 과정은 정상적으로 외부 접속이 가능한 지 테스트하는 과정으로, Master realm은 굳이 외부 접속이 필요하지 않기 때문에 추후 외부 접속 차단을 권고합니다.
4. FortiGate와 Keycloak 간 SSO 연동
1. 신규 realm 생성 및 기본 정보 확인
A. 새로운 적당한 이름으로 realm을 생성합니다.
B. 좌측 탭 Realm settings -> Fronted URL을 입력 (https://서버 IP:포트) -> Save 버튼을 클릭합니다.
* 여기서의 Frontend URL이 실질적으로 사용자가 SSL VPN 로그인 시 연결되는 주소입니다.
C. SAML 2.0 Identity Provider Metadata를 클릭하여 새 창을 열고, 해당 창은 우선 띄워둡니다.
2. Keycloak의 인증서 추출 및 FortiGate에 등록
A. 1의 마지막 과정에서 확인한 SAML 메타데이터의 ds.X509Certificate 헤더 내에 있는 값을 복사한 뒤 메모장을 열고
-----BEGIN CERTIFICATE-----
ds.X509Certificate 헤더 내 값 복사
-----END CERTIFICATE-----
위와 같이 입력한 후, "REMOTE_Cert_1.cer" 이라는 이름으로 저장합니다.
* 타 이름으로 저장 시 방화벽에서 Import 시 형식 에러 발생됨
B. FortiGate에 접속한 후 System -> Certificates -> Create/Import -> Remote Certificate 버튼을 클릭합니다.
C. A의 과정에서 생성한 인증서 파일을 선택하고 OK 버튼을 클릭합니다.
3. FortiGate에서 SSO 설정
A. User & Authentication -> Single Sign-On -> Create new 버튼을 클릭합니다.
B. 아래 내용을 참고하며 내용을 입력합니다.
- Name: 적당히 입력
- Address: [도메인]:[SSL VPN 설정 포트] ex) abc.co.kr:10443
- Entity ID, Assertion consumer service URL, Single logout service URL 는 keyclaok에서 입력해야 하므로 복사해두기
C. 1의 마지막 단계에서 에서 띄워둔 창을 기반으로 하여 아래를 참고하여 그대로 입력 후 Submit을 눌러 저장합니다.
- Certificate: 2번 단계에서 생성한 인증서 지정
- Attribute used to identify users: username
- Attribute used to identify groups: group
4. Keycloak에서 Client 설정을 통한 연동
A. keycloak으로 돌아와서 좌측 탭에 Clients 클릭 후 Create client 버튼을 클릭합니다.
B. 아래 이미지를 참고하여 정보를 입력 후 Next 버튼을 클릭합니다.
- Client type :SAML
- Client ID: http://[도메인]:[ssl vpn 포트]/remote/saml/metadata
- Name: 적당히 입력
C. 아래 이미지를 참고하여 정보를 입력 후 Save 버튼을 클릭합니다.
- Valid redirect URIs: https://[도메인]:[ssl vpn 포트]/remote/saml/login
- Valid post logout redirect URIs: https://[도메인]:[ssl vpn 포트]/remote/saml/logout
D. FortiGate의 Attribute와 연동하기 위해 Client scopes -> URI-dedicated 를 클릭합니다.
E. Configure a new mapper 버튼을 클릭합니다.
F. User Attribute를 선택합니다.
G. 아래 이미지와 같이 설정 후 Save 버튼을 클릭합니다.
H. 다시 창으로 돌아와서, Add mapper -> By configuration 버튼을 클릭합니다.
I. Group list를 선택합니다.
J. 아래와 같이 입력한 후 Save 버튼을 클릭합니다.
K. Keys 탭을 클릭한 뒤 Client signature required를 비활성화 합니다.
5. Keycloak의 그룹 및 계정 생성
A. 좌측 탭의 Groups를 클릭한 후 Create Group을 클릭합니다.
B. 그룹 이름을 적당히 입력한 뒤 Create 버튼을 클릭합니다.
C. 좌측 탭의 Users 클릭 -> Create new user 버튼을 클릭합니다.
D. 적당한 username을 입력하고 B의 과정에서 생성한 그룹에 적용시킨 후 Create 버튼을 클릭하여 사용자를 생성합니다.
E. Credentials 탭을 누른 뒤 Set password 버튼을 클릭합니다.
F. 패스워드와 패스워드 확인 란을 반복 입력합니다. Temporary의 경우 임시 패스워드로 지정할 지 여부인데, 활성화되어 있을 경우 사용자가 패스워드를 재설정하게 합니다. 현재 테스트 중이므로 해당 기능은 Off 하였습니다.
6. 새로 생성한 realm에 대하여 Load Balance 설정을 통해 외부 접속 허용
3에서 이미 다뤘던 내용입니다. 로드 밸런싱 객체의 Virutal Server Port (외부 포트)에 대한 설정만 다르므로, 새로 생성한 sslvpn realm에 대한 Frontend URL 정보를 참조하여 해당 과정을 따라 객체를 생성하고 정책에 적용합니다.
7. SAML 연동 group 생성 및 SSL VPN 연관 설정
A. CLI로 접속한 뒤 아래 명령어를 입력합니다.
# con user group
(group) # edit techteam [생성할 그룹 명]
new entry 'techteam' added
(techteam) # set member keycloak [생성 SSO 객체명]
(techteam) # con match
(match) # edit 1
new entry '1' added
(1) # set server-name keycloak [생성 SSO 객체명]
(1) # set group-name techteam [keycloak에서 생성한 그룹명]
(1) # end
(techteam) # end
B. VPN -> SSL-VPN Settings -> Portal에 생성한 그룹 추가 -> Apply를 클릭합니다.
C. 기존에 적용되어 있는 SSL VPN 정책에 새로 생성한 그룹을 추가합니다.
8. 접속 테스트
A. FortiClient의 설정을 아래와 같이 변경합니다. (FortiClient v7.0.13 사용)
B. SAML Login 버튼을 클릭합니다.
C. 아까 생성한 ID와 PW를 입력한 후 Sign In 버튼을 클릭합니다.
D. 정상적으로 연결이 완료됩니다.
'Firewall > Foritgate' 카테고리의 다른 글
[FortiGate] SSL VPN 인터넷 불가 이슈 트러블슈팅 (Client DNS) (0) | 2024.11.06 |
---|---|
[FortiGate] Let's Encrypt를 통한 인증서 발급 (무료) (0) | 2024.10.27 |
[FortiGate] DHCP IP 할당 불가 이슈 (vci-match) (v7.2.10) (1) | 2024.10.14 |
[Fortigate] 최초 장비 세팅 시 NAT 모드 -> TP 모드 변환 방법 (0) | 2024.10.11 |
[Fortigate] Fortiview 기능에서 실시간 트래픽이 정확하지 않을 경우 (0) | 2022.05.11 |