FortiGate는 FortiOS 7.0 버전 이후부터 ACME (Automated Certificate Management Environment) 를 이용하여 Let's Encrypt와 연동 후 SSL 인증서를 무료로 사용할 수 있는 기능을 제공하고 있습니다. 인증서는 90일 단위로 갱신이 필요하며 FortiGate는 자동으로 갱신 처리를 진행하기에 계속 인증서를 사용할 수 있습니다.
Let's Encrypt란?
무료 인증서 보급을 통해 HTTPS를 확산시키겠다는 취지로 시작된 비영리 프로젝트입니다.
사용하기 위한 제약조건은 아래와 같습니다.
FortiGate는 공인 IP를 가지고 있어야 하며, 그 공인 IP와 매핑된 도메인이 필요합니다. (A 레코드)
ACME 인터페이스는 인터넷 구간과 연동이 될수 있어야 하며, 80 (HTTP) 또는 443 (HTTPS) 포트에 대한 VIP 설정 (NAT, 포트포워딩) 이 없어야 합니다.
SAN 필드가 매핑된 도메인으로 자동으로 설정되어 편집이 불가하기에 와일드카드도 사용 불가하며 여러 개의 SAN을 따로 추가할 수 없습니다.
Let's Encrypt를 통해 인증서를 발급받고 나면 할 수 있는 내용은 아래와 같습니다.
방화벽의 웹 인증서를 사설 인증서 -> Let's Encrypt로 발급받은 공인 인증서로 변경함으로서 웹 UI 접근 시 발생되는 보안 경고창 제거 가능
FortiClient를 통한 SSL VPN 접속 시, 사설 인증서 사용으로 인해 사용자 연결 단계 40%에서 표출되는 신뢰할 수 없는 인증서 팝업 제거 가능
HTTPS -> HTTP 리버스 프록시 구성을 통해 내부 서버에 대한 HTTP (비암호화) 통신을 HTTPS로 암호화 가능
그럼, 아래 과정을 통해 Let's Encrypt를 통해 인증서를 발급받고, 실제로 활용하는 방법에 대해서 다루도록 하겠습니다.
1. Let's Encrypt를 통해 FortiGate에서 인증서 발급
A. GUI에서 인증서 창 활성화를 위해 System -> Feature Visibility -> Certificates, Load Balance 활성화 후 "Apply' 클릭
B. System -> Certificates -> Create/Import -> Certificate 클릭
C. Use Let's Encrypt 클릭
D. 아래 정보들을 적당히 입력한 후, Create 버튼을 클릭합니다.
1) Certificate name: 인증서 이름을 자유롭게 입력
2) Domain: 도메인 주소 입력 (A 레코드 등록 필요) ex) abc.co.kr
3) Email: 관리 이메일 입력 필요 (적당히 입력)
E. ACME 인터페이스는 외부 인터페이스 (wan) 으로 설정한 뒤 대기
F. 문제가 없을 경우 시간이 흐른 뒤 정상적으로 생성되었다는 메세지 표출
2. 발급받은 인증서를 FortiGate에 적용
1) SSL VPN에 적용
VPN -> SSL-VPN Settings -> Server Certificate를 발급받은 인증서로 변경 -> Apply 버튼을 눌러 적용
2) 웹 GUI에 적용
System -> Settings -> HTTPS server certificate를 발급받은 인증서로 변경 -> Apply 버튼을 눌러 적용
3. 적용 테스트
1) SSL VPN
FortiClient의 연결 설정 창에서 IP 대신 방화벽과 매핑한 도메인 정보를 입력한 뒤, 40%에서 보안 경고창이 표출되는지 확인
2) 관리 웹 UI 접속
매핑한 도메인을 통해 ex)https://abc.co.kr 접속 시도한 후 보안 경고창이 표출되는지 확인
*** HTTPS (443) 포트를 포트포워딩으로 사용하고 있을 경우
HTTP (80) 또는 HTTPS (443) 포트를 ACME 데몬이 사용하는데, 외부 HTTPS (443) 포트에 대한 VIP 객체가 있을 경우 즉시 HTTP (80) 포트로 ACME 데몬이 시도하게 하기 위해 아래 설정을 진행합니다.
A. System -> Settings -> Telnet port를 443으로 변경
위 과정을 거치게 되면 ACME 데몬은 HTTPS (443) 포트 대신 HTTP (80) 포트로 즉시 시도하게 됩니다.
참고로 텔넷 포트로 설정한 이유는 보안 상의 이유로 잘 쓰지 않는 프로토콜이기 때문입니다.
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 포트
# 배포 진행 (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
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 사용)
어제.. 일요일 방화벽 교체 작업 진행 중 DHCP 관련 처음 보는 증상이 발생하여 처리 내역을 공유합니다.
1. 작업 내역
- 노후화 방화벽 교체 작업
# 기존: FG-100D (v5.6.13) -> 신규: FG-100F (v7.2.10)
2. 증상
- 방화벽 교체 (FG-100D -> FG-100F) 이후 특정 포트에서 DHCP IP 할당 불가 이슈 발생.
3. 확인 내역
1) port 67로 패킷 스니핑하여 DHCP Discover 패킷에 대해 정상적으로 방화벽이 응답을 주는지 확인
dia sni pack any 'port 67' 4
50.424415 internal in 0.0.0.0.68 -> 255.255.255.255.67: udp 300
위 패킷만 확인되고, 방화벽에서의 응답 패킷이 확인되지 않음.
2) DHCP 설정 이상 없고 임대할 IP가 충분함에도 방화벽이 응답을 주지 않는걸로 파악, dhcps debug 진행
dia debug application dhcps -1
dia debug enable
[debug]locate_network prhtype(1) pihtype(1)
[warn]Can't locate subnet in shared network of packet and packet is not a DHCPREQUEST and htype(1) != intf htype(1)..dropping
[debug]locate_network prhtype(1) pihtype(1)
??? 이게 뭐지. 방화벽에서 dropping 하는 Debug를 확인. 해당 내역 확인 결과 언제 설정된건지 모를 DHCP vci 패턴 매칭 설정으로 인한 이슈로 확인됨.
config system dhcp server
edit 2
set dns-service default
set ntp-service default
set default-gateway 192.168.0.1
set netmask 255.255.255.0
set interface "internal"
config ip-range
edit 1
set start-ip 192.168.0.2
set end-ip 192.168.0.254
next
end
set timezone-option default
set vci-match enable --> 문제의 Config 부분
set vci-string "FortiSwitch" "FortiExtender" --> 문제의 Config 부분
next
config system dhcp server
edit 2
set vci-match disable
end
명령어 입력 이후 정상 IP 할당 확인됨.
분명 Config 그대로 마이그레이션했는데 왜 이게 포함되었을까?
- 기존 장비 Config 확인 시에 해당 Config는 확인되지 않음.
- 펌웨어 버전도 v7.2.10 그대로 올렸기에 업그레이드 과정도 없었음
- 기존 장비 Config를 부분마다 스크립트 업로드로 올렸기에 이상하게 넣었을 리도 없음
- 다른 포트는 안들어가있으니 default로 넣어버리거나 하는 건 아닌 듯..
아무튼 저게 왜 들어갔는지는 의문이나 빠르게 해결 완료.
내용 추가 (24.10.16)
곰곰히 생각해보니 문제의 vci Config는 장비에 Default로 포함된 Fortiswitch 연동 관련 DHCP 컨피그입니다.
고객사의 DHCP ID와 Default 설정으로 된 FortiSwitch 연동을 위한 ID가 겹치면서 설정이 덮어씌워지며 발생된 증상으로 보입니다.
따라서, DHCP 서버 설정 관련하여 마이그레이션을 할 때, 모든 Default DHCP Server 설정을 지우고서 마이그레이션 하시는 것이 좋을 것 같습니다.
인프런 일프로님의 쿠버네티스 어나더 클래스 강의를 수강하며, 저희 사내 환경에 맞게 쿠버네티스를 설치하는 내용을 다루도록 하겠습니다.
환경
PC: Windows 10
IDE: vscode
HCI: Proxmox VE v8.1.4
IaC: Terraform
OS: Rocky linux 8.10
우선, 제가 구축할 환경은 아래와 같습니다. (빨간색 점선 부분이 추가 부분)
강의에서는 VirtualBox를 사용하였으나, 현재 저는 사내 데스크탑에 Proxmox 서버를 구축해 둔 관계로, 제공해주신 스크립트를 Proxmox에 맞춰 변경하는 작업이 필요합니다. 저는 굳이 VirtualBox를 사용하지 않기 때문에, Terraform을 이용하여 스크립트를 다시 작성하도록 하겠습니다.
A. vscode를 연 뒤 테라폼 코드를 저장한 폴더를 열고 Open in integrated Terminal 버튼을 클릭합니다.
B. 아래 명령어를 입력하여 테라폼으로 배포를 시작합니다.
> terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of telmate/proxmox from the dependency lock file
- Using previously-installed telmate/proxmox v3.0.1-rc4
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
> terraform plan
각종 정보 확인..
> terraform apply
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: -> yes 입력 후 진행
C. 완료되었는지 확인합니다. 정상적일 경우 아래와 같이 메세지가 표기됩니다.
D. 쿠버네티스 대시보드로 접속하여 잘 설치되었는지 확인합니다. ex) https://192.168.56.30:30000
일프로님의 쿠버네티스 강의 수강 중, 192.168.56.1/24 대역을 사용해야 하는데 사내 인프라 구성 상 약간의 구성 변경이 필요함을 느껴 구성 변경 작업을 진행하였다. (정말 귀찮다..) 이에 따라 FortiSwitch의 Trunk Port 설정 및 Proxmox의 VLAN 인터페이스 설정 방법을 아래에 정리한다.
주의사항) 네트워크 구성 변경이기에, 서버의 설정과 네트워크 설정의 순서를 올바르게 하지 않으면 직접 서버에 모니터를 연결, 또는 중간에 설정을 원복하고 다시 접속해야 하는 불상사가 있을 수 있습니다.
네트워크 구성은 어느정도 비슷하나, IP는 사내 실제 환경이 아님을 미리 밝힙니다.
기존 환경 (AS-IS)
변경 후 환경 (TO-BE)
1. Proxmox 설정 변경
A. /etc/network/interfaces 설정으로 진입한다. (vim이 익숙하지 않아 우선 nano를 사용..)
nano /etc/network/interfaces
B. 아래와 같이 설정 파일을 적절하게 수정한다.
auto lo
iface lo inet loopback
iface enp6s0 inet manual
auto vmbr0
iface vmbr0 inet static
bridge-ports enp6s0
bridge-stp off
bridge-fd 0
bridge-vlan-aware yes
bridge-vids 50,56
# VLAN ID가 50이므로..
auto vmbr0.50
iface vmbr0.50 inet static
address 192.168.50.2/24
gateway 192.168.50.1
# VLAN ID가 56이므로..
auto vmbr0.56
iface vmbr0.56 inet static
address 192.168.56.2/24
gateway 192.168.56.1
source /etc/network/interfaces.d/*
C. 컨트롤+O 누른 뒤 엔터를 누르고 저장하고 컨트롤+X로 나온다.
D. 아래 명령어를 입력하여 설정을 적용한다.
(해당 명령어 적용할 경우 네트워크 환경이 맞지 않으면 원격 접속 불가하니 주의)
ifup -a
2. FortiSwitch 설정 변경 (Proxmox 연결 포트 Trunk로 변경)
A. FortiSiwtch CLI에 접속한다.
B. 접속한 후 아래 CLI 명령어를 입력한다.
config switch trunk
edit "proxmox"
set members "port23" # Trunk mode로 변경할 포트 지정
end
config switch interface
edit "proxmox"
set allowed-vlans 1,50,56 # 허용할 VLAN 설정
end
3. FortiGate VLAN 인터페이스 생성
A. Network -> Interface -> Create New -> Interface 클릭하여 생성 창으로 진입합니다.
B. 아래와 같이 인터페이스 설정을 추가한다.
Name: 인터페이스 이름
VLAN ID: 위 Proxmox에서 설정한 VLAN ID ex) vmbr0.56 -> 56
IP/Netmask: IP 대역
이외 접속 허용 및 DHCP Server 설정은 자유
C. OK 버튼을 눌러 인터페이스를 생성한 후, Policy & Objects에서 방화벽 정책을 적절히 생성한다. (과정 생략)
D. IPsec VPN이 연결되어 있을 경우, 잊지 않고 신규 대역에 대한 라우팅 및 정책 설정을 해준다.
4. 기존 Proxmox VM의 VLAN 설정 변경
- 변경할 VM 클릭 -> Hardware 클릭 -> Network Device 클릭 -> VLAN Tag 값을 적절히 변경 -> OK 버튼을 클릭한다.
이후 기존 서비스에 이상이 없는지 체크하고 안도의 한숨을 내쉬며 작업을 완료한다.
24.10.27 추가
리부팅 이후 FortiSwitch에 설정된 Trunk 설정이 날아가는 듯 하다.. 이거에 대해서 추가적인 해결책을 찾아볼 필요가 있음.
일프로님의 인프런 쿠버네티스 강의를 수강하며 테라폼으로 쿠버네티스를 설치하려는 중, 템플릿이 있으면 편할 것 같아 Proxmox에서 Rocky Linux 탬플릿을 생성하는 과정을 아래에 작성합니다.
1. VM 생성
A. 우측 상단 Create VM 클릭 -> VM ID를 800으로 입력하고 Name 적당히 입력 -> Next 클릭
B. 클라우드 이미지를 활용하기에 Do not use any media 클릭 -> Next 클릭
C. Qemu Agent 체크 후 Next 클릭
D. 디스크를 휴지통 버튼 클릭하여 제거 이후 Next 클릭
E. 별도 설정 변경 없이 Next 클릭
F. 램을 1024MB로 변경 후 Next 클릭
G. 각자 환경에 맞게 네트워크 설정 후 Next를 클릭
H. Finish 버튼을 클릭하여 완료
2. CloudInit 설정
A. 생성된 VM 클릭 -> Hardware 탭 클릭 -> Add 클릭 -> CloudInit Drive 클릭
B. Storage를 적절히 선택한 후 Add 클릭
C. SSH key 생성 (저는 cmd 창에서 진행하였습니다)
> ssh-keygen -t rsa -C proxmox
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\JJ/.ssh/id_rsa): C:\proxmox_key
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\proxmox_key.
Your public key has been saved in C:\proxmox_key.pub.
The key fingerprint is:
SHA256:GoMoV9XZuV1u2WHqxinUAi85xAMnypQvLZeOlWwBgAw proxmox
The key's randomart image is:
+---[RSA 3072]----+
|E ...o++o+ . |
| o oo..==o .o |
| .o+ = =o.ooo.|
| o + X +.+.o+ .|
|. o . @ S + +.. |
| o . = . = |
| . o |
| |
| |
+----[SHA256]-----+
D. Cloud-Init -> SSH public key 더블클릭 후 생성된 public key를 붙여넣기 (생성된 .pub 확장자 파일 내용 복사)
E. IP config 더블클릭 -> DHCP를 클릭한 후 OK 클릭
3. Cloud image 다운로드 및 설정 및 탬플릿 생성
A. SSH를 통해 Proxmox CLI 접속 후 아래 명령어 입력하여 rocky linux 클라우드 이미지를 다운로드합니다.
대시보드의 인터페이스 대역폭을 확인하면 90 Mbps, 99 Mbps지만, 막상 Fortiview 기능에서는 매우 적은 트래픽만 집계되어 제대로 확인할 수 없는 경우가 있습니다.
해당 문제는 Fortigate 장비 중 메모리만 있는 모델 (FG-X0. ex) FG-60E, 80E...)을 사용할 경우에 대하여 발생합니다.
따라서, 메모리 모델도 Fortiview 기능을 이용하여 실시간 트래픽을 확인할 수 있는 법에 대하여 공유합니다.
먼저, 트래픽을 정확히 확인할 수 없는 이유는 포티넷 장비가 아래와 같이 구성되어 있기 때문입니다.
방화벽에서 최초의 세션은 CPU에서 처리를 진행하나, 이후 처리는 NP6Lite (npu)에서 진행됩니다. 메모리가 있는 모델에서의 Fortiview 기능은 CPU를 통과한 통신들에 (최초 생성되는 세션) 대해서 집계되기 때문에, 결국 기존 세션의 통신은 Fortiview에 집계가 되지 않아 정확하지 않은 문제가 발생합니다.
(패킷 스니핑에서 최초 패킷 이후 통신 패킷이 확인되지 않는 것도 같은 이유입니다)
따라서, 아래 해결책을 공유하오니 도움이 되셨으면 좋겠습니다.
(단, 기존 통신 세션이 모두 단절되므로 인터넷이 정말 사용할 수 없을 정도로 심각할 경우 사용하실 것을 권고드립니다.)
아래의 명령어를 이용하여 npu를 비활성화 진행합니다.
config system npu
set fastpath disable
end
이후, 아래 명령어를 입력하여 전체 세션을 클리어합니다. (*주의, 기존 세션이 전부 단절되므로 심각할 경우만 사용!)