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

이 포스트는 이 문서이 문서를 기반으로 작성되었다.

Securing a Network

strongSwan은 서버와 클라이언트에게 암호화와 인증을 제공하는 IPsec 솔루션으로 원격 네트워크와의 통신을 안전하게 보호한다. 이로서 원격 연결 네트워크를 로컬 연결 네트워크처럼 만들어준다.

Gateway

gateway는 방화벽으로 주로 사용되지만 네트워크 내의 모든 호스트가 될 수 있다. 이밖에도 DHCP, DNS를 사용하는 소규모 네트워크를 제공할 수도 있다. 위의 사진에서 host moon과  sun은 내부 host인 alice, venus 그리고 bob 각각을 위한 게이트웨이 역할을 한다.

Remote Access / Roadwarrior Clients

일반으로, roadwarriors는 gateway를 통해 우리들의 집 네트워크에 원격으로 연결되는 노트북이나 핸드폰과 같은 디바이스들이다. 위 사진에서 carol과 dave는 두 게이트웨이(moon & sun) 뒤에 있는 두 네트워크에 접근하고자 하는 roadwarrior를 나타낸다.

Remote Hosts / Host-to-Host

위 사진에서 호스트 winnetou와 게이트웨이 moonsun 중 하나가 원격 웹 서버나 백업 시스템을 나타낼 수 있다. 두 호스트 간의 연결은 일반적으로 (호스트)둘중 하나에 의해서 시작된다.

Remote Sites / Site-to-Site

서로 다른 위치의 두 개 이상의 서브넷에 속한 호스트들이 서로 접근할 수 있어야 한다. 위 사진에서 게이트웨이 moon과 sun뒤에 각각 존재하는 10.1.0.0/16과 10.2.0.0/24 서브넷이 연결되어, alice와 bob과 같은 호스트들이 안전하게 통신할 수 있어야 한다.

 


IKE and IPsec Basics

strongSwan은 기본적으로 두 peer 간에 SA(Security Associations)를 만들고 SP(Security Policies)를 협상하기 위해 IKEv2 프로토콜을 사용하는 keying daemon이다.

 

Keying Daemon은 VPN 연결을 설정하고 관리하는 핵심 프로세스다. strongSwan에서는 charon 프로세스로 IKEv2 프로토콜 관련 모든 기능을 처리한다.

 

IKE는 VPN 피어 간 강력한 인증 과정 제공하며 암호화 및 인증에 사용되는 고유한 세션 키를 생성한다. 그리고 IPsec SA를 협상해 어떤 네트워크 트래픽을 보완할지, 어떻게 암호화 및 인증을 제공할지 결정한다.

 

IKE_SA는 IKE 세션 자체를 나타낸다. 이 세션은 인증과 키 생성을 담당한다.

CHILD_SA는 실제 IPsec 트래픽을 보호하는 보안 연결을 나타내며 IKE_SA 내에서 협상된다.

CHILD_SA의 구성 요소

트래픽을 암호화하고 인증하는 데 사용되는 알고리즘과 키를 정의하는 IPsec SA와 어떤 네트워크 트래픽이 해당 SA를 사용해야 하는지 정의하는 Policy로 구성된다. Policy는 양방향으로 적용되며, 일치하는 인바운드 policy가 없는 트래픽은 삭제된다.

IPsec 트래픽 처리

IPsec 트래픽은 운영 체제 커널의 네트워크 및 IPsec 스택에 의해 처리된다. strongSwan은 협상된 IPsec SA와 SP를 커널에 설치하는 역할을 한다.

Policy와 SA의 구분

위 사진에서 host moon이 host sun과 site-to-site connection을 갖고 있고, host carol이 host sun과 roadwarrior connection을 갖고 있으며 sun이 포워딩이 가능하다해도 carol은 alice와 통신할 수 없다.

그 이유는 carolalice 사이에 traffic을 허용하는 IPsec Policy가 없기 때문이다. 이때 moonsun 사이 가상 서브넷을 연결하는 추가 SA가 있다면 carolalice의 통신이 가능하게 될 것이다. 이처럼 Policy는 CHILD_SA를 생성할 때 IKE를 통해 협상되는 traffic selectors(TS)에 의해서 파생된다.

Routing과 IPsec  Processing의 관계

IPsec은 일반적으로 네트워크 스택에 투명하게 적용되어 policy에 따라 트래픽을 처리한다. 따라서 원격 TS로 향하는 어떤 경로를 사용해도 IPsec 처리가 가능하다. 그러나 VPN 호스트 자체에서 트래픽이 발생하는 경우, 소스 주소 선택이 문제가 될 수 있다. 로컬 TS에 public 주소가 포함되어 있지 않으면 기본 경로에 따라 선택된 소스 주소로 인해 IPsec 처리가 되지 않을 수 있다. 이는 가상 IP주소를 사용하는 경우에 특히 문제가 될 수 있다.

소스 주소 선택이 IPsec VPN에서 왜 문제가 될까?
IPsec VPN 터널을 통해 트래픽을 보내려면, 소스 주소가 로컬 TS에 포함되어 있어야 한다. 그렇지 않으면 트래픽이 IPsec 처리를 받지 못하고 일반 경로로 전달될 수 있기 때문이다.

 

이 문제를 해결하기 위해 strongSwan의 charon IKE daemon은 기본적으로 대부분의 CHILD_SA에 대해 원격 TS로의 특정 경로를 설치해 이를 통해 로컬 TS의 주소가 소스 주소로 선택될 수 있도록 한다.

대안으로 인터페이스와 explict route를 사용하여 IPsec 터널에 의해 처리될 트래픽을 제어하는 route-based IPsec를 사용하기도 한다.

 


Authentication Basics

To ensure that the peer with which an IKE_SA is established is really who it claims to be, it has to be authenticated.

IKE_SA가 설정되려면 peer가 인증이 필수적이다. IKE_SA를 통해 VPN 터널이 설정되면 양측 peer가 서로를 신뢰할 수 있어야 하고, peer 인증을 거치지 않으면 중간자 공격(MITM attack)에 취약해질 수 있기 때문이다.

 

그렇다면 어떻게 peer간 인증을 진행할까?


Public Key Authentication

  • RSA, ECDSA 또는 EdDSA X.509 인증서를 사용해 peer의 진위 여부를 검증한다.
  • 자체 서명된 인증서 혹은 인증 기관(CA)에서 서명된 인증서를 사용할 수 있다.
  • CA 인증서만 있으면 모든 peer를 인증할 수 있어 배포와 구성이 간단해진다.
  • 중간자 공격을 방지하기 위해 peer의 ID가 인증서의 subject DN 또는 subjectAltName 확장자와 일치해야 한다.

Pre-Shared-Key Authentication (PSK)

  • 배포는 쉽지만 강력한 비밀 키가 필요하다.
  • 많은 사용자가 PSK를 알고 있는 경우 누구나 게이트웨이를 가장할 수 있어 대규모 배포에는 적합하지 않다.

Extensible Authentication Protocol (EAP)

  • EAP-MD5, EAP-MSCHAPv2, EAP-GTC, EAP-TLS 등 다양한 인증 방식을 지원한다.
  • RADIUS 서버를 사용하여 사용자 인증을 위임할 수 있다.
  • IKEv2에서만 사용 가능하다

 

IKEv2 프로토콜에서는 RFC 4739에 따라 Multiple Authentication Exchanges가 가능하다. 그렇기 때문에 한 번에 IKE_AUTH 교환 내에서 여러 번의 인증 과정을 수행할 수 있다. 그 예시로 첫 번째 authentication round에서 gateway를 인증서로 인증하고, 두 번째 authentication round에서 client를 username/password 기반 EAP 방식으로 인증할 수 있다.

 

다양한 인증 방식을 조합하는 것이 IKEv2 구현체의 특징이지만, 모든 IKEv2 구현체가 그런건 아니므로 사용 전 확인이 필요하다.

 


Configuration Files

strongSwan을 구성하는 가장 좋은 방법은 vici control interface나 swanctl command line tool을 사용하는 것이다.

swanctl.conf configuration file은 인증서와 private key와 함께 swanctl 디렉토리에 저장된다.

 

swanctl.conf 파일은 다음과 같은 주요 섹션으로 구성된다.

  • connections: VPN 연결 설정 (IKE 및 IPsec parameter, 인증 방법, 암호화 알고리즘 등이 포함된다.)
  • secrets: 공유 키, 개인 키 등의 비밀 정보
  • authorities: 신뢰할 수 있는 인증 기관(CA) 정의
  • pki: 인증서 관리 설정

'VPN' 카테고리의 다른 글

Netfilter에서의 IPsec VPN (strongSwan)  (0) 2024.07.31
IPSec Protocol이란?  (0) 2024.05.29

+ Recent posts