Post

Calico 보안 기능(wireguard)

Calico 보안 기능(Wireguard) 알아보기

💡 KANS 스터디
CloudNet에서 주관하는 KANS(Kubernetes Advanced Networking Study)으로 쿠버네티스 네트워킹 스터디입니다. 아래의 글은 스터디의 내용을 기반으로 작성했습니다.

스터디에 관심이 있으신 분은 CloudNet Blog를 참고해주세요.

WireGuard란

파드마다 패킷을 암호화하면 비효율적이겠지만, 최근의 보안이 대두되고 있는 만큼 Zero Trust 등 보안상으로 중요한 환경에서는 필요할 것 같다. 이때 Wireguard를 이용할 수 있다.

WireGuard는 오픈소스 VPN 프로젝트이다. “WireGuard는 구닥다리 IPsec 및 OpenVPN의 대항마로 등장한 open source VPN project 이며 작년, Linux 5.6 커널에 WireGuard 1.0.0 기본 패키지로 탑재되었다.” 라고 설명해주셨다. 코드도 간결하고, 성능도 잘나온다고 한다. *아래 그림 참고

image.png

사진출처: https://www.wireguard.com/papers/wireguard.pdf

파드 패킷 암호화

Cilium에서도 WireGuard를 지원한다고 한다. 간단한 세팅을 통해 보안을 높일 수 있다. 통신에서 사용하는 암호화 키는 처음에 생성해둔다고 한다.

실습 진행

WireGuard는 CloudFormation을 통해 배포할 때, 이미 설치되어있다. 아래의 명령어를 통해 설정을 확인해본다.

  • 버전 확인
1
2
wg version
wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/
  • calico wireguard 설정 진행
1
2
calicoctl patch felixconfiguration default --type='merge' -p '{"spec":{"wireguardEnabled":true}}'
Successfully patched 1 'FelixConfiguration' resource
  • 설정 확인
1
2
calicoctl get felixconfiguration default -o yaml | grep wireguardEnabled
  wireguardEnabled: true

암호화 키 확인

명령어를 통해 wireguard 키를 확인한다.

  • 퍼블릭 키를 확인
1
2
3
4
5
calicoctl get node -o yaml | grep wireguardPublicKey
    wireguardPublicKey: F1CNZ1aM8BmjssQrwymkj1XYONOD6OEEOBh1NLYy+Xw=
    wireguardPublicKey: rzxlh1ayqHU14f7YK3UOGvW1tS/okOXBv0Yhw9Reyzg=
    wireguardPublicKey: K6EBHlSJwrj0lDtGCE7jDtSRwaiIYOaazhWSK5yodEE=
    wireguardPublicKey: /OPVSG6BUxiQ7Q9CnV5Cj0WEav7zpAYo7dwEQON8k2Q=
  • 각 노드의 private key 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
wg showconf wireguard.cali
[Interface]
ListenPort = 51820
FwMark = 0x100000
PrivateKey = GCnqtCks8LkZJNas/RB/8Xtgk7e2KLHehcSmkTKf8kQ=

[Peer]
PublicKey = /OPVSG6BUxiQ7Q9CnV5Cj0WEav7zpAYo7dwEQON8k2Q=
AllowedIPs = 172.16.184.0/24, 172.16.184.2/32, 172.16.184.3/32
Endpoint = 192.168.10.102:51820

[Peer]
PublicKey = K6EBHlSJwrj0lDtGCE7jDtSRwaiIYOaazhWSK5yodEE=
AllowedIPs = 172.16.158.0/24, 172.16.158.6/32, 172.16.158.7/32
Endpoint = 192.168.10.101:51820

[Peer]
PublicKey = rzxlh1ayqHU14f7YK3UOGvW1tS/okOXBv0Yhw9Reyzg=
AllowedIPs = 172.16.34.0/24, 172.16.34.1/32, 172.16.34.2/32
Endpoint = 192.168.20.100:51820

포트 확인

wireguard는 51820 포트를 사용한다고 한다.

관련해서 노드의 포트 정보를 확인할 수 있다. 파드 1 기준(worker node1에 위치)

1
2
3
4
5
6
7
8
ss -unlp
State    Recv-Q   Send-Q           Local Address:Port      Peer Address:Port  Process
UNCONN   0        0                127.0.0.53%lo:53             0.0.0.0:*      users:(("systemd-resolve",pid=344,fd=13))
UNCONN   0        0          192.168.10.101%ens5:68             0.0.0.0:*      users:(("systemd-network",pid=341,fd=15))
UNCONN   0        0                    127.0.0.1:323            0.0.0.0:*      users:(("chronyd",pid=485,fd=5))
UNCONN   0        0                      0.0.0.0:51820          0.0.0.0:*
UNCONN   0        0                        [::1]:323               [::]:*      users:(("chronyd",pid=485,fd=6))
UNCONN   0        0                         [::]:51820             [::]:*

통신 진행

파드 ping 통신을 진행한다.

1
2
kubectl exec pod1 -it -- zsh
ping {pod ip}

통신을 덤프뜬다.

1
tcpdump -i {노드 이더넷} udp port 51820 -w /tmp/calico-wireguard.pcap

Wireshark

와이어샤크로 덤프를 확인하면 아래와 같이 패킷이 암호화된 것을 확인할 수 있다.

image.png

복호화 시도

한번 위에서 확인한 private key를 통해 패킷을 복호화시도를 진행했다. 진행 프로세스는 아래와 같다.

  1. tcpdump를 진행할 노드의 private key 확인
  2. 패킷 덤프(tcpdump -i {노드 이더넷} udp 51820 -w {파일 다운로드 경로}
  3. wireshark 설정 진행
    1. Protocols > WireGuard > Private Key 추가

관련해서 블로그에 유사한 시도가 나와있으나, 여기선 별도의 Log File 추출기를 통해서 진행했다. 해당 추출기와 유사하게 Public key, 임시키를 넣었는데 여전히 동작하지 않았다. 추후 한번 더 찾아봐야겠다. tcpdump를 진행하면 처음에 핸드쉐이크하는 패킷도 아래와 같이 확인할 수 있다.

image.png

This post is licensed under CC BY 4.0 by the author.