Linux에서 IPsec implementation은 userspace part와 kernel park로 구성되어 있다. 이번 게시물에서 다룰 userspace part IPsec implementation은 strongSwan이며. Linux kernel part IPsec implementation은 netkey stack 이라고도 불리는 xfrm framework다. 아래의 그림에서 strongSwanxfrm framework의 책임 영역을 확인할 수 있으며 이 둘의 상호작용 과정을 생각해 볼 수 있다.

Linux 에서의 IPsec implementation은 userspace part 와 kernel part로 구분되고 이 둘을 이어주는 interface가 존재한다.

Strongswan

strongSwan의 핵심은 userspace daemon인 charon이다. charon은 IKEv1/IKEv2를 구현하고 각 VPN endpoint host에서 IPsec-based VPN tunnel(connection)의 중앙 관제사 역할을 하고 있다. 

charon은 system에서 IPsec configuration을 위해 user/admin에게 interface를 제공하고 있으며, 더 정확히는 두 개의 다른 interface를 제공하고 있다. 첫 번째는 stroke interface로 IPsec을 구성하기 위해 /etc/ipsec.conf, /etc/ipsec.secrets 이 두 개의 main config 파일을 제공하고 있다. 

두 번째는 IPC(Inter-Process Communication)처럼 동작하는 vici interface로, charon daemon이 Unix Domain Socket에서 대기하고 있어, strongSwan의 cmd tool인 swanctl과 같은 클라이언트 도구가 이 Socket에 연결돼 IPsec을 구성할 수 있다. 이 구성 방식은 다른 도구들이 언제든지 동적으로 이벤트 기반 configuration을 제공하고 조정하기가 더 쉽기 때문에 앞선 방식보다 더 선호된다. 이 방식은 /etc/swanctl/swanctl.conf 파일이 charon daemon에 의해 직접 해석되는 것이 아니라, swanctl cmdline tool에 의해 해석되어 configuration 정보가 vici IPC interface를 통해 charon daemon에 전달된다는 점이다. 추가로 /etc/strongswan.conf 파일도 존재하는데, 개별적인 VPN Connection과 직접적으로 관련된 설정이 아니라 글로벌한 strongSwan 설정 관련 파일이다.

양쪽 VPN endpoint host 각각에 VPN tunnel 구성을 위한 swanctl.conf 파일을 두고. swanctl tool을 사용해 이 configuration 정보를 charon daemon에 로드해 peer endpoint 간의 IKE handshake를 시작했다고 해보자. IKE handshake를 실행할 때 charon daemon은 peer와 VPN tunnel에 대한 모든 세부 사항을 협상해 VPN Connection을 정의하는 SA와 SP instance를 생성한다. IKE_SA는 peer endpoint와의 IKE 통신을 위한 자체 보안 채널이기 때문에 userspace에 유지하고 다른 SA와 SP instance는 Netlink Socket을 통해 kernel에 전달한다. 이제 VPN Connection/Tunnel이 활성화된 상태이고, 나중에 VPN 연결을 종료하게 되면 charon은 커널에서 SA와 SP instance를 제거한다.

The xfrm framework

iproute2 man page: xfrm framework is IP framework for transforming packets (such as encrypting their payloads

xfrm(transform) 프레임워크는 리눅스 커널 내의 구성 요소다. userspace part IPsec implementationstrongSwan이 VPN connection/tunnel을 위해 전반적인 IPsec 오케스트레이션을 처리하고 VPN connection/tunnel을 설정 및 해제하기 위해 IKEv1/IKEv2 프로토콜을 실행하는 동안, kernel part IPsec implementationxfrm framework는 VPN tunnel 안에서 이동하는 network packet의 encrypting+encapsulating과 decrypting+decapsulating을 수행하며 어떤 패킷이 VPN tunnel을 통해 이동할지 선택하고 결정한다. 이를 위해서는 커널 내에 VPN connection/tunnel을 정의하는 SA와 SP instance가 존재해야 한다. 그래야만 어떤 패킷을 암호화/복호화할지, 어떤 암호화 알고리즘과 키를 사용할지에 대한 결정을 내릴 수 있다.

xfrm framework는 SA와 SP instance를 유지하기 위해 SAD(SA Database)와 SPD(SP Datebase)를 구현한다. SA는 커널 내에서 xfrm_state 구조체에 의해 표현되고 SP는 xfrm_policy 구조체를 통해 표현된다. strongSwan 같은 userspace 컴포넌트는 커널 내의 SAD와 SPD의 SA, SP를 crud 하기 위해 Netlink socket를 사용하고 있다. ip 명령어로 현재 SAD와 SPD 내에 저장된 SA와 SP instance를 확인할 수 있다.

ip xfrm state    # shows SA instances
ip xfrm policy  # shows SP instances

SP instance는 세 가지 정책에 적용될 수 있다.

SP(security policy) syntax meaning
output policy dir out 이 정책은 송신 패킷에 적용된다. 송신 패킷이 encrypted + encapsulated될지 여부를 결정한다.
즉, 어떤 패킷이 VPN 터널을 통해 전송될지 결정한다.
input policy dir in 이 정책은 수신 패킷에 적용된다. decrypted + decapsulated된 패킷 중 시스템의 로컬 IP 주소를 목적지로 하는 패킷을 선택한다.
즉, 시스템에 들어오는 패킷이 VPN 터널에서 온 것인지 결정한다.
forward policy dir fwd 이 정책은 전달 패킷에 적용된다. decrypted + decapsulated된 패킷 중 시스템의 로컬 IP 주소가 아닌 다른 목적지로 향하는 패킷을 선택한다.
즉, 패킷이 시스템을 경유해 다른 네트워크로 전달될지 결정한다.

VPN에 대해서 공부를 하고 있는 사람이라면 Netfilter packet flow 이미지를 본적이 있을 것이다. 여기에는 xfrm implementation에 대한 작은 오해들이 존재한다. 실제로는 4개 이상의 지점에서 xfrm이 수행되고, 실제로 수행되는 지점도 사진과는 다르다. 아래의 사진은 Netfilter와 xfrm framework를 중심으로 packet flow를 간략하게 보여준다. Netfilter hook은 파란색 그리고 xfrm framework의 동작은 빨간색으로 표현되었다.

IPsec tunnel-mode에서의 xfrm action과 Netfilter hooks
Netfilter packet flow 이미지에 적용

두개의 routing lookup은 incoming packet과 outgoing packet 모두에 대해서 실행된다. 함수 fib_lookup()은 policy routing rule과 routing table에 대한 lookup을 수행한다. lookup을 통해 확인된 routing 정보는 라우팅 테이블을 경유하는(traversing) network packet(skb)에 부탁된다. 이 패킷은 dst_entry 구조체를 감싸는 rtable 구조체의 인스턴스로 output network interface, ip address of next hop gateway, 다음으로 패킷이 향해야 할 곳을 가리키는 함수 포인터 등의 정보를 갖고 있다. 언뜻 보기에는 routing은 xfrm framework와 관련이 없어보이지만, 이 글을 읽다보면 관련성을 발견해나갈 수 있을 것이다.
xfrm lookup out policy는 routing 조회 후 forward된 packet과 outgoing packet 모두에 대해서 실행된다.함수 xfrm_lookup()은 IPsec SPD에서 일치하는 output policy(dir out SP)를 조회한다. 일치하는 policy가 없으면 패킷은 변경되지 않고 그대로 계속 진행되지만, 일치하는 policy가 있다면 일치하는 SP에 해당하는 SA를 해석하기 위해 SAD에서 조회가 수행된다(Xfrm lookup state). 해석된(resolved) SA가 tunnel-mode를 지정하면, 이번에는 현재 패킷을 나중에 캡슐화할 외부 IPv4 패킷에 대한 또 다른 라우팅(Routing) 조회가 수행된다. 실제 패킷 변환이 수행되지는 않지만, 이 패킷에 대한 변환 지침의 bundle조립된다. 여기서 bundle은 커널 소스 코드에서 비롯되며 서로를 가리키는 여러 구조체 인스턴스를 의미하는데 여기에는 원래 routing decision , SP, SA, 미래의 외부 IP 패킷에 대한 routing decision 등이 포함되어 xfrm_dst 인스턴스에 조립된다



이렇게 만들어진 bundle은 network packet(skb)에 부착되어 원래 부착된 routing decision을 대체한다. bundle 내 함수 포인터는 패킷이 커널 네트워크 스택의 나머지 부분을 통해 다른 경로를 따르도록 보장한다. 
여기서는 VPN 터널을 통과해야 하는 패킷이 암호화되고 캡슐화된다. xfrm framework는 패킷에 부착된 bundle의 지침에 따라 패킷을 변환한다. bundle 내의 함수 포인터는 패킷이 Netfilter POSTROUTING hock을 통과한 후 변환 code로 우회하도록 한다. IPv4 패킷의 경우 패킷을 이 경로로 이끄는 진입 함수는 xfrm4_output()이다. tunnel-mode의 경우, 이 변환은 IP 패킷을 새로운 외부 IP 패킷으로 캡슐화한 다음, 내부 IP 패킷을 ESP 프로토콜로 캡슐화하고 이를 암호화하는 것을 의미한다. 변환이 완료되면 xfrm components/instructions은 bundle에서 제거되고 외부 IP 패킷에 대한 라우팅 결정만이 패킷에 부착된 채로 남게 된다.
여기서는 VPN 터널을 통해 들어온 패킷이 복호화되고 역캡슐화(decapsulate)된다. local input path의 IP 패킷이 ESP 패킷을 포함하고 있다면 xfrm framework는 SPI(SA identifier)를 기반으로 SAD(xfrm lookup state)를 조회해 일치하는 SA가 있다면 ESP 패킷을 복호화하고 역캡슐화한다. 일치하는 SA가 존재하지 않으면 해당 패킷은 드롭된다.
tunnel-mode에서 outer IP 패킷은 역캡슐화되고, inner IP 패킷은 L2 receive path에 재삽입되며 이 패킷은 자신에게 사용된 SA를 추적해 추후 xfrm lookup in policy, xfrm lookup fwd policy  혹은 라우팅에 사용한다.
이미 복호화되고 역캡슐화된 패킷이 이곳에 도착하면, 해당 패킷을 복호화하고 역캡슐화 하는데 사용된 SA와 input policy(dir in SP)가 일치해야 한다. 일치하지 않는 패킷은 드롭된다.
VPN 터널을 통해 들어오지 않은 Nomal 패킷은 기본적으로 input policy와 일치하지 않으면 그냥 통과한다.
여기에 도착한 복호화되고 암호화된 패킷은 패킷을 복호화하고 역캡슐화하는 데 사용된 SA와 일치하는 forward policy(dir fwd SP)와 일치해야 한다. 일치하지 않는 패킷은 드롭된다.
Nomal 패킷은 기본적으로 forward policy와 일치하지 않으면 그냥 통과한다.

 

xfrm framework implementation은 VPN 트래픽과 Non-VPN 트래픽을 구별하기 위해 VNI(Virtual Network Interface)를 사용하지 않는다. 이는 SP의 개념이 VPN 운영에 필요한 모든 구별을 수행하기 때문이다. 그러나 VNI가 없으면 iptables 및 nftables와 같은 Netfilter 기반 패킷 필터링 시스템이 VPN 및 Non-VPN 패킷을 규칙 내에서 구별하기 더 어려워진다. VPN 트래픽이 특정 VNI를 통해 전달되면 필터링 규칙을 쉽게 작성할 수 있기 때문이다.

xfrm 프레임워크의 경우 기본적으로는 VNI를 사용하지 않지만 xfrm framework 위에 VNI 개념을 도입해 사용성을 높인 추가 기능이 도입되었다. strongSwan에서는 이런 VNI(vti, xfrm)를 기반으로 한 VPN 설정을 Route-based VPN이라 부른다.

 

다음 게시글에서는 VPN Tunnel을 구성해 SAD와 SPD를 확인하고 터널 내에서 실제로 패킷이 송신되고 수신될 때 Packet Flow를 확인해 VNI의 도입 여부를 결정하는 주제를 다루겠다.

 

 

 

이 글은 GOAT 블로그를 읽고 정리한 내용입니다. 원문을 읽어 보시길 강력 추천드립니다.

'VPN' 카테고리의 다른 글

strongSwan이란?  (0) 2024.05.31
IPSec Protocol이란?  (0) 2024.05.29

이 문서를 읽고 IPSec에 대한 정리한 글이다.

IPSec protocol은 두 개의 main components로 구성되어 있다.

  • Encapsulating Security Payload(ESP) protocol
    • 두 IPSec endpoint들 간에 전송되는 IP 패킷을 secure 하는 프로토콜
  • Internet Key Exchange Version 2(IKEv2) auxiliary protocol
    • IPSec endpoint간의 상호 인증
    • IKEv2 management protocol과 ESP payload protection에 대한 data integrity sesstion keys, encryption 자동 생성

 



Encapsulation Security Payload (ESP)


ESP는 Network layer에서 IP Packet을 전송할 때 암호화를 허용한다.


IPSec Transport Mode

IPSec Transport mode에서는 Original IP 헤더가 유지되고 IP 패킷에 의해 운반되는 Layer4 payload는 암호화된다.


ESP 헤더는 Original IP 헤더와 암호화된 페이로드 사이에 삽입된다.

IPSec Transport mode는 주로 Layer 2 Tunneling Protocol(L2TP)을 secure 하기 위해 사용되고 있다.


IPSec Tunnel Mode

IPSec Tunnel mode에서는 ESP와 outer IP header(터널의 시작, 종료 IP주소 등 정보 포함)에 의해 IP packet 전체(헤더와 페이로드)가 캡슐화된다.


ESP Packet Structure

ESP Packet은 ESP header, 암호화된 IP Payload body 그리고 padding을 위한 ESP trailer로 이루어져있다.

ESP trailer란?
ESP 패킷의 마지막 부분에 추가되는 데이터 영역이다. 암호화된 데이터의 길이를 블록 암호 알고리즘의 블록 크기에 맞추기 위한 Padding과 암호화된 페이러도의 프로토콜 타입을 나타는 필드, 패딩 데이터의 길이와 같은 정보들을 포함하고 있다.

 


암호화 체크섬으로서 Authentication Data는 데이터 무결성을 보장한다.


receiving IPSec peer는 32bit SPI를 커널 기반 DB의 Index로 사용해 ESP 패킷의 암호를 해독하고 인증하는 데 필요한 세션 키를 검색한다. 또한 암호 해독 후 inbound plaintext IP packet(ESP 패킷이 복호화된 후 수신되는 일반 IP 패킷)에 적용해야 하는 IPSec 보안 정책을 결정하는 데 사용된다.

IPSec 통신은 두 개의 IPSec endpoing 간에 이루어지며, 이 중 하나가 ESP 패킷을 전송하는 sending IPSec peer고 다른 하나가 ESP 패킷을 수신해 처리하는 receiving IPSec peer다.

 



Internet Key Exchange Version 2 (IKEv2)

IKEv2는 IPSec connection들에 대한 설정을 관리하며 source 및 destination 포트가 모두 잘 알려진 UDP 포트 500으로 설정된 UDP 데이터그램을 사용한다.

IKE_SA_INIT Request/Response

IPSec 통신을 위해서는 IKE protocol을 통해 SA(Security Association)을 설정해야 한다. IKE_SA_INIT은 SA 설정을 위한 초기 negotiation이 이루어진다.


Initiator(클라이언트)가 IKE_SA_INIT Request를 보내고 이 메시지를 통해 Responder(서버)와 암호화 알고리즘, 키 교환 방식 등의 보안 파라미터를 협상한다. Responder가 Initiator의 제안을 수락하는 Response Message를 보내면 양측은 SA를 설정할 수 있게 된다.

만약 Responder가 자신이 DoS 공격을 받고 있다고 생각되면, Response 내에 계산 비용이 많이 드는 Key Exchange(KE) payload를 보내기 전에 Initiator에게 Cookie를 요쳥해 효율적으로 IP spoofing을 방지할 수 있다.

Key Exchange(KE) payload
Diffie-Hellman 키 교환 알고리즘을 사용해 Initiator와 Responder가 shared secret key를 생성할 수 있게 한다. 이들은 각자의 공개 키를 KE payload에 포함하여 교환하고 이를 통해 shared secret key를 계산할 수 있게 된다.

Nonces(N) payload
Nonces payload에는 랜덤 하게 생성된 숫자(Nonce)가 포함된다. Initiator와 Responder는 각자의 Nonce를 교환하여, 이를 shared secret key 생성에 사용하고 message의 freshness를 보장하는데 이용한다.

 

Initiator와 Responder는 KE payload과 N payload의 교환을 통해 shared secret key를 생성한다. 이제 이 둘은 `IKE_SA`를 설정할 수 있다. `IKE_SA`에는 양측이 합의한 보안 파라미터를 나타내는 SA1i와 SA1r payload가 포함되어 이후 IKE 메시지들이 암호화되어 전송될 수 있게 한다.


IKE_AUTH Request/Response

Certificate-based Authentication

Initiator는 IKE_AUTH request message에서 자신의 id(IDi), Digital Signature(AUTHi)와 선택적으로 인증서(CERTi)를 보낸다. 또한 첫 번째 CHILD_SA에 사용될 Security Association proposal(SA2i)과 Traffic selectors(TSi, TSr)을 보낸다.

CHILD_SA란?
IPSec 통신을 위해 IKE protocol을 통해 설정되는 SA로 IPSec payload packet의 암호화와 무결성 보장을 위한 보안 파라미터가 포함된다.

이를 통해 IPSec Tunnel이 설정되고 실제 데이터 트래픽이 보호된다.

 

 



Responder는 IKE_AUTH response message에서 자신의 Digital Signature`AUTHr`과 선택적으로 인증서 CERTr를 보낸다. 또한 Initiator가 보낸 SA2i를 선택하고, 필요한 경우 Traffic selectors(TSi, TSr)을 조정한다. 추가로 Initiator가 보낸 인증서 CERTi의 유효성과 신뢰성을 검증하는데 이를 위해 Responder는 X.509 인증서 체인을 따라 올라가서 로컬에 저장된 루트 CA 인증서와 비교한다.

결과적으로 상호 인증이 완료되면, Initiator와 Responder는 IKE_AUTH 메시지에 포함된 정보를 바탕으로 CHILD_SA를 설정할 수 있다.

 

PSK-based Authentication

Authentication에 Pre-Shared Key(PSK)가 사용되는 경우 AUTHiAUTHr payload는 교환된 IKEv2 message와 pre-shared secret에 대한 해시를 가지고 있다.

PSK는 사용자가 직접 설정하는 공유 비밀키다.



IKE_AUTH 교환 시 Initiator가 먼저 AUTHi payload에 PSK hash를 보낸다. 이때 PSK의 암호 수준이 약하다면 MITM(Man In The Middle - 중간자 공격자)가 offline dictionary 공격이나 무차별 대입 공격을 통해 PSK를 크래킹 할 수 있다.

따라서 충분한 강도의 PSK를 사용할 수 없다면 PSK 기반 인증을 사용하지 말고 RSA signature 기반 인증 등 다른 인증 방식을 사용하는 것이 좋다.


EAP-based Authentication

MITM를 방어하기 위해 EAP-based Authentication이 IKEv2 표준으로 도입되었다.



만약 Initiator가 IKE_AUTH request에 AUTHi payload를 포함하지 않았다면 Responder는 AUTHr payload에 강력한 Digital Signature를 먼저 보낸다. 이로서 신뢰할 수 있는 Initiator 임을 확인하고 동시에 IKE_AUTH response에 첫 EAP request를 포함시켜서 EAP protocol을 시작한다.


CREATE_CHILD_SA Request/Response

CREATE_CHILD_SA Request/Response pairs는 CHILD_SA를 추가로 협상할 때 사용된다.

추가로 IKE_SA와 CHILD_SA는 일정 시간이 지나면 보안상의 이유로 rekeying(재협상)되어야 하는데 CREATE_CHILD_SA message pair를 사용해 이러한 rekeying을 수행할 수 있다.

 

  • IKE_SA rekey
    • IKE_SA rekey 시 N(REKEY_SA) 알림이 포함되지 않는다.
    • 새로운 Key Exchange(KE) payload가 포함되어 Perfect Forward Secrecy(PFS)가 보장된다.
      • PFS는 각 통신 세션마다 고유한 세션 키를 생성하는 키 유도 함수를 사용해 한 세션의 키가 노출되더라도 다른 세션의 키에는 영향을 주지 않는다. 즉, long-term secret key가 노출되더라도 과거의 통신 내용이 안전하게 유지되는 것이다.
  • CHILD_SA rekey
    • CHILD_SA rekey 시 N 알림이 포함된다.
    • KE payload는 선택적으로 포함될 수 있다.
     

따라서 N 알림이 포함되면 CREATE_CHILD_SA Request/Response가 CHILD_SA rekey를 위한 것임을 알 수 있다.

 



NAT Traversal

IPSec VPN에서는 ESP(IP protocol 50)과 IKE(UDP 500)이 사용된다. 여기서 ESP 프로토콜은 포트 개념이 존재하지 않으므로 PAT(Port Address Translation) 방식으로는 NAT router를 통과할 수 없다. 따라서 NAT Traversal이 등장하게 되었다.

NAT Traversal
NAT Traversal은 UDP encapsulation을 통해 구현된다. ESP 패킷을 UDP 패킷으로 캡슐화해 NAT device에서 포트 변환이 가능하도록 한다. 이를 통해 ESP traffic이 NAT router를 통과할 수 있는 것이다.

 


어떤 NAT 라우터들은 IPSec Passthrough라고 부르는 기능을 갖고 있다. NAT device 뒤에 있는 single host에서 outbound IKE traffic을 감지하고 아래 그림과 같이 inbound IKE 및 ESP packet을 특정 host로 전달한다.



하지만 이 방식은 동일한 VPN Gateway와 통신하는 여러 IPSec Client가 있는 경우는 작동하지 않는다. 이 문제를 해결하기 위해 제안된 솔루션은 ESP 패킷을 UDP Datagram으로 캡슐화하여 PAT를 적용하는 것이다.

IKE_SA_INIT 교환 시 전송되는 NAT_DETECTION_SOURCE_IPNAT_DETECTION_DESTINATION_IP 알림을 통해 NAT 상황을 감지하고 이를 통해 ESP 트래픽이 NAT 라우터를 통과할 수 있게 된다.

NAT 상황이 없다고 해도 encap=yes 옵션을 설정하면 ESP-in-UDP 캡슐화를 강제할 수 있다. charon deamon이 조작된 NAT_DETECTION_SOURCE_IP 알림 payload를 전송하여 remote peer에게 NAT 상황이 있는 것처럼 보이게 하는 것이다.


ESP-in-UDP Encapsulation

ESP 패킷에 UDP Header를 추가해 ESP 패킷이 NAT device를 통과할 수 있게 한다. 결과적으로 IPSec 통신의 범위가 확장된다.



UDP Header가 ESP 패킷의 IP Header와 ESP Header 사이에 삽입된다.




정리

IPSec은 IP 트래픽에 대한 보안 기능을 제공하는 네트워크 프로토콜이다. IPSec의 ESP 프로토콜과 IKEv2 프로토콜로 구성되어 있고, ESP는 IP 패킷을 암호화하여 전송하고, IKEv2는 IPSec 연결 설정을 관리한다.

IPSec은 Transport 모드와 Tunnel 모드로 동작하며, NAT 환경에서 작동하기 위해 NAT Traversal 기술을 사용한다.

IKEv2는 상호 인증을 위해 PSK, Digital Signature 등의 인증 방식을 사용한다.

 

 

 

'VPN' 카테고리의 다른 글

Netfilter에서의 IPsec VPN (strongSwan)  (0) 2024.07.31
strongSwan이란?  (0) 2024.05.31

+ Recent posts