본문 바로가기

카테고리 없음

AWS VPN 연동(VGW to Strongswan)

today keys : vpn, vgw, aws, strongswan, ipsec, site, s2s, virtual, private, network


이번 포스팅은 AWS VGW를 Software VPN은 Strongswan와 IPSec 연동을 테스트하는 내용입니다. 

실제 VPN SVR를 통해서 다른 서비스가 VPN 연결된 통신을 위해서는 추가적인 설정이 필요하지만, 

본 포스팅에서는 AWS와 StrongSwan에서 VPN 연결을 하는 것으로 한정하여 진행했습니다.



먼저, VGW를 생성합니다.

VGW의 이름은 'ZIGI-VGW'로 하였고, BGP에 사용되는 ASN은 default 값으로 그냥 둡니다.

참고로 본 포스팅에서는 BGP를 사용하지는 않습니다.

 

 

생성된 VGW를 VPC에 Attach 합니다.

 

 

ZIGI-VGW를 ZIGI-VPC1에 Attach 합니다.

 

VGW가 정상적으로 생성 및 Attached 된 것을 확인 할 수 있습니다.

 

이제 VGW와 VPN을 연결할 Cutomer gateway를 만듭니다.

Cutomer gateway의 IP Address는 VGW와 연결할 VPN의 공인 IP를 입력하면 됩니다.

여기에서는 EC2에 Strongswan을 올릴 것이기 때문에 EC2의 공인 IP를 입력합니다.

 

이제 VGW와 연결할 VPN Connection을 생성합니다.

VPN Connection의 이름을 입력하고, 

어떤 Gateway를 사용할 것인지 선택합니다.

여기에서는 VGW(Virtual Private Gateway)를 사용하기 때문에 VGW를 선택하고, 

앞서 만든 VGW를 고릅니다.

그리고 방금 만든 Customer gateway를 선택합니다. 

Routing은 BGP를 사용하지 않고, static으로 연결합니다. 

VPN으로 연결할 곳의 IP 대역을 Static IP prefixes 에 설정합니다.

 

Connection을 만들면 이중화를 위해서 Tunnel이 2개가 생성됩니다.

정기적인 AWS 서비스 점검 시에, Tunnel 별로 장비 점검을 하기 때문에 안정적인 서비스를 위해서는

2개의 Tunnel을 모두 연결하는 것을 권고합니다.

다른 값은 기본 값으로 두고, Pre-shared key만 설정하겠습니다.

각 터널 별로, 'zigikey1' , 'zigikey2' 로 설정합니다.

 

정상적으로 Connection이 생성된 것을 확인할 수 있습니다.

 

하지만, 아직 AWS쪽만 설정했기 때문에 Tunnel의 status는 현재 Down 상태입니다.

 

이제 EC2에 Strongswan을 설치하고 AWS와 VPN 연결을 해보겠습니다.


사전 패키지 설치

Strongswan을 설치하고 실행하기 위해 필요한 패키지를 설치합니다.

Strongswan을 바이너리로 받아서, 컴파일을 해야 하고, IPSec 암호화 처리를 위한 패키지 등이 필요합니다.

sudo dnf groupinstall "Development Tools" -y
sudo dnf install systemd-devel openssl-devel -y

 

Strongswan 소스코드 다운로드 및 압축 해제

Strongswan 공식 사이트에서 최신 소스 코드를 받아서 빌드하기 위해서, 다운로드 및 압축을 해제합니다.

wget https://download.strongswan.org/strongswan.tar.bz2
tar -jxvf strongswan.tar.bz2
cd strongswan-*

 

빌드(Build) 

strongswan을 빌드합니다.

./configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --enable-openssl \
  --enable-charon \
  --enable-ikev2 \
  --enable-systemd \
  --with-systemdsystemunitdir=/etc/systemd/system

 

옵션 역할
--prefix=/usr 바이너리 설치 경로를 /usr 하위로 지정
--sysconfdir=/etc 설정 파일 경로를 /etc 하위로 지정 (/etc/swanctl/ 등)
--enable-openssl OpenSSL 기반 암호화 플러그인 활성화
--enable-charon IKE 데몬인 charon 빌드 활성화
--enable-ikev2 IKEv2 프로토콜 지원 활성화
--enable-systemd charon-systemd 빌드 + systemd 유닛 자동 생성
--with-systemdsystemunitdir 유닛 파일 설치 경로 명시 (/etc/systemd/system)

 

 

컴파일 및 설치

strongswan을 컴파일 후, 설치하는 데, -j$(nproc)는 CPU 코어 수 만큼 병렬 컴파일을 하여 빌드 시간을 단축하는 거라서, 굳이 사용하지 않아도 됩니다.

make -j$(nproc)
sudo make install

 

서비스 등록 및 시작 및 상태 확인

서비스를 등록 후, 실행합니다.

정상적으로 서비스가 active 상태인지도 확인합니다.

sudo systemctl daemon-reload
sudo systemctl enable strongswan
sudo systemctl start strongswan
sudo systemctl status strongswan

 

Strongswan 설정 파일 작성

/etc/swanctl/swanctl.conf 파일에서 Tunnel 연결을 위한 설정을 다음과 같이 합니다.

 

connections {
    # ==========================================================
    # Tunnel-1
    # ==========================================================
    aws-tunnel1 {

        # ── IKE (Phase 1) 설정 ──────────────────────────────
        version      = 2
        local_addrs  = 10.20.0.61          # strongSwan EC2 사설 IP
        remote_addrs = 13.125.16.222       # AWS VGW Tunnel-1 Outside IP

        proposals    = aes256-sha256-modp2048
        rekey_time   = 28800s              # IKE SA 재협상 (8시간)
        reauth_time  = 0s

        dpd_delay    = 30s
        dpd_timeout  = 120s

        # ── 로컬 인증 ─────────────────────────────────────────
        local {
            auth = psk
            id   = 43.201.247.188          # strongSwan EC2 공인 IP (IKE ID)
        }

        # ── 원격 인증 ─────────────────────────────────────────
        remote {
            auth = psk
            id   = 13.125.16.222           # AWS VGW Tunnel-1 Outside IP
        }

        # ── Child SA (Phase 2) ────────────────────────────────
        children {
            aws-tunnel1-child {
                local_ts  = 10.20.0.0/22   # ★ strongSwan 측 VPC CIDR
                remote_ts = 10.1.0.0/16    # ★ AWS VGW 너머 원격 VPC CIDR

                esp_proposals = aes256-sha256-modp2048

                rekey_time    = 3600s
                rekey_bytes   = 0
                rekey_packets = 0

                mode          = tunnel
                start_action  = start
                close_action  = restart
                dpd_action    = restart
            }
        }
    }


    # ==========================================================
    # Tunnel-2 
    # ==========================================================
    aws-tunnel2 {

        # ── IKE (Phase 1) 설정 ──────────────────────────────
        version      = 2
        local_addrs  = 10.20.0.61          # strongSwan EC2 사설 IP (동일)
        remote_addrs = 15.165.169.50        # AWS VGW Tunnel-2 Outside IP

        proposals    = aes256-sha256-modp2048
        rekey_time   = 28800s
        reauth_time  = 0s

        dpd_delay    = 30s
        dpd_timeout  = 120s

        # ── 로컬 인증 ─────────────────────────────────────────
        local {
            auth = psk
            id   = 43.201.247.188          # strongSwan EC2 공인 IP (IKE ID, 동일)
        }

        # ── 원격 인증 ─────────────────────────────────────────
        remote {
            auth = psk
            id   = 15.165.169.50            # AWS VGW Tunnel-2 Outside IP
        }

        # ── Child SA (Phase 2) ────────────────────────────────
        children {
            aws-tunnel2-child {
                local_ts  = 10.20.0.0/22   # ★ strongSwan 측 VPC CIDR (Tunnel-1과 동일)
                remote_ts = 10.1.0.0/16    # ★ AWS VGW 너머 원격 VPC CIDR (Tunnel-1과 동일)

                esp_proposals = aes256-sha256-modp2048

                rekey_time    = 3600s
                rekey_bytes   = 0
                rekey_packets = 0

                mode          = tunnel
                start_action  = start
                close_action  = restart
                dpd_action    = restart
            }
        }
    }
}


# ============================================================
# Pre-Shared Key (PSK) — 터널별 개별 키 설정
# secrets 블록의 id 값은 connections의 local.id / remote.id 와 반드시 일치해야 함
# ============================================================
secrets {

    # Tunnel-1 PSK
    ike-tunnel1 {
        id-local  = 43.201.247.188       # 로컬 IKE ID
        id-remote = 13.125.16.222          # Tunnel-1 원격 ID
        secret    = "zigikey1"               # Tunnel-1 PSK
    }

    # Tunnel-2 PSK
    ike-tunnel2 {
        id-local  = 43.201.247.188         # 로컬 IKE ID (동일)
        id-remote = 15.165.169.50           # Tunnel-2 원격 ID
        secret    = "zigikey2"               # Tunnel-2 PSK
    }
}

 

 

VPN 설정 및 터널 수립

strongswan 설정 파일을 작성하고 나면, 해당 설정을 반영하고, 정상적으로 연결이 되었는지 확인합니다.

# /etc/swanctl/swanctl.conf 작성 후
sudo swanctl --load-all       # 설정 반영
sudo swanctl --list-conns     # 로드된 커넥션 확인
sudo swanctl --list-sas       # 터널 상태 확인 (ESTABLISHED 여부)

 

AWS의 VPN Connection을 보면, 이제 Tunnel의 status가 'UP'이 된 것을 볼 수 있습니다.

 

 


참고 Strongswan의 상태 값 확인

[ec2-user@ip-10-20-0-61 ~]$ sudo swanctl --load-all
loaded ike secret 'ike-tunnel1'
loaded ike secret 'ike-tunnel2'
no authorities found, 0 unloaded
no pools found, 0 unloaded
loaded connection 'aws-tunnel1'
loaded connection 'aws-tunnel2'
successfully loaded 2 connections, 0 unloaded
[ec2-user@ip-10-20-0-61 ~]$

 

[ec2-user@ip-10-20-0-61 ~]$ sudo swanctl --list-conns
aws-tunnel1: IKEv2, no reauthentication, rekeying every 28800s, dpd delay 30s
  local:  10.20.0.61[500]
  remote: 13.125.16.222[500]
  local pre-shared key authentication:
    id: 43.201.247.188
  remote pre-shared key authentication:
    id: 13.125.16.222
  aws-tunnel1-child: TUNNEL, rekeying every 3600s, dpd action is start
    local:  10.20.0.0/22
    remote: 10.1.0.0/16
aws-tunnel2: IKEv2, no reauthentication, rekeying every 28800s, dpd delay 30s
  local:  10.20.0.61[500]
  remote: 15.165.169.50[500]
  local pre-shared key authentication:
    id: 43.201.247.188
  remote pre-shared key authentication:
    id: 15.165.169.50
  aws-tunnel2-child: TUNNEL, rekeying every 3600s, dpd action is start
    local:  10.20.0.0/22
    remote: 10.1.0.0/16
[ec2-user@ip-10-20-0-61 ~]$

 

 

[ec2-user@ip-10-20-0-61 ~]$ sudo swanctl --list-sas
aws-tunnel2: #2, ESTABLISHED, IKEv2, 4664d3dcb25c2f07_i* db11b3f45224ebdf_r
  local  '43.201.247.188' @ 10.20.0.61[4500]
  remote '15.165.169.50' @ 15.165.169.50[4500]
  AES_CBC-256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048
  established 197s ago, rekeying in 28555s
  aws-tunnel2-child: #2, reqid 1, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-256/HMAC_SHA2_256_128
    installed 197s ago, rekeying in 3307s, expires in 3763s
    in  c63ca16b,      0 bytes,     0 packets
    out cf439989,      0 bytes,     0 packets
    local  10.20.0.0/22
    remote 10.1.0.0/16
aws-tunnel1: #1, ESTABLISHED, IKEv2, a2ba3e2a4861976c_i* d79f6e44e2fe733a_r
  local  '43.201.247.188' @ 10.20.0.61[4500]
  remote '13.125.16.222' @ 13.125.16.222[4500]
  AES_CBC-256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048
  established 201s ago, rekeying in 27459s
  aws-tunnel1-child: #1, reqid 1, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-256/HMAC_SHA2_256_128
    installed 201s ago, rekeying in 3155s, expires in 3759s
    in  c843c762,      0 bytes,     0 packets
    out c8505cda,      0 bytes,     0 packets
    local  10.20.0.0/22
    remote 10.1.0.0/16
[ec2-user@ip-10-20-0-61 ~]$