네트워크 보안 기초부터 실전까지 5편: VPN과 암호화 통신
Network Security Series Part 5: VPN and Encrypted Communication
서론: 안전한 통신의 핵심, 암호화와 VPN
현대 네트워크 환경에서 데이터가 인터넷을 통해 전송될 때, 해당 데이터는 수많은 라우터와 네트워크 장비를 거치게 됩니다. 이 과정에서 악의적인 공격자가 데이터를 도청하거나 변조할 수 있는 위험이 항상 존재합니다. 암호화 기술과 VPN(Virtual Private Network)은 이러한 위협으로부터 데이터를 보호하는 핵심 기술입니다.
이번 5편에서는 암호화의 기본 개념부터 시작하여 SSL/TLS 프로토콜, PKI(공개키 기반 구조), 그리고 다양한 VPN 기술과 실제 구축 방법까지 상세히 다루겠습니다.
1. 암호화 기초
암호화(Encryption)는 평문(Plaintext)을 암호문(Ciphertext)으로 변환하여 권한이 없는 사용자가 내용을 이해할 수 없도록 만드는 기술입니다. 암호화 방식은 크게 대칭키 암호화, 비대칭키 암호화, 그리고 해시 함수로 구분됩니다.
1.1 대칭키 암호화 (Symmetric Encryption)
대칭키 암호화는 암호화와 복호화에 동일한 키를 사용하는 방식입니다. 처리 속도가 빠르지만 키 교환 문제가 있습니다.
주요 대칭키 알고리즘:
- AES (Advanced Encryption Standard): 현재 가장 널리 사용되는 대칭키 알고리즘으로, 128/192/256비트 키 길이를 지원합니다.
- 3DES (Triple DES): DES를 세 번 적용하는 방식으로, 레거시 시스템에서 사용됩니다.
- ChaCha20: 소프트웨어 구현에 최적화된 스트림 암호로, 모바일 환경에서 인기가 높습니다.
- Blowfish/Twofish: 라이선스가 자유로운 블록 암호 알고리즘입니다.
# Python에서 AES 암호화 예제
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
# 256비트 키 생성
key = get_random_bytes(32)
# 암호화
cipher = AES.new(key, AES.MODE_CBC)
plaintext = b"This is a secret message"
ciphertext = cipher.encrypt(pad(plaintext, AES.block_size))
iv = cipher.iv
print(f"IV: {iv.hex()}")
print(f"Ciphertext: {ciphertext.hex()}")
# 복호화
decipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = unpad(decipher.decrypt(ciphertext), AES.block_size)
print(f"Decrypted: {decrypted.decode()}")
1.2 비대칭키 암호화 (Asymmetric Encryption)
비대칭키 암호화는 공개키(Public Key)와 개인키(Private Key) 쌍을 사용합니다. 공개키로 암호화된 데이터는 개인키로만 복호화할 수 있습니다.
주요 비대칭키 알고리즘:
- RSA: 가장 널리 사용되는 비대칭키 알고리즘으로, 소인수분해의 어려움에 기반합니다. 일반적으로 2048비트 이상의 키를 사용합니다.
- ECC (Elliptic Curve Cryptography): 타원 곡선 수학에 기반한 알고리즘으로, RSA보다 짧은 키로 동등한 보안성을 제공합니다.
- Diffie-Hellman: 안전하지 않은 채널에서 공유 비밀을 교환하기 위한 키 교환 프로토콜입니다.
- ECDH (Elliptic Curve Diffie-Hellman): ECC를 사용한 Diffie-Hellman 변형입니다.
# Python에서 RSA 키 쌍 생성 및 암호화 예제
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
# RSA 키 쌍 생성
key = RSA.generate(2048)
private_key = key.export_key()
public_key = key.publickey().export_key()
# 공개키로 암호화
recipient_key = RSA.import_key(public_key)
cipher_rsa = PKCS1_OAEP.new(recipient_key)
encrypted = cipher_rsa.encrypt(b"Secret message")
# 개인키로 복호화
private_rsa = RSA.import_key(private_key)
decipher_rsa = PKCS1_OAEP.new(private_rsa)
decrypted = decipher_rsa.decrypt(encrypted)
print(f"Decrypted: {decrypted.decode()}")
1.3 해시 함수 (Hash Functions)
해시 함수는 임의의 길이의 입력을 고정된 길이의 출력(해시값 또는 다이제스트)으로 변환합니다. 단방향 함수이므로 해시값에서 원본을 복원할 수 없습니다.
주요 해시 알고리즘:
- SHA-256/SHA-384/SHA-512: SHA-2 계열로 현재 표준으로 사용됩니다.
- SHA-3: Keccak 알고리즘 기반의 최신 SHA 표준입니다.
- BLAKE2/BLAKE3: 매우 빠른 암호학적 해시 함수입니다.
- MD5/SHA-1: 취약점이 발견되어 보안 용도로는 사용하지 않습니다.
| 알고리즘 | 출력 크기 | 보안 상태 | 용도 |
|---|---|---|---|
| MD5 | 128비트 | 취약 | 파일 체크섬 (비보안) |
| SHA-1 | 160비트 | 취약 | 레거시 시스템 |
| SHA-256 | 256비트 | 안전 | 디지털 서명, TLS |
| SHA-3-256 | 256비트 | 안전 | 최신 시스템 |
2. SSL/TLS 프로토콜
SSL(Secure Sockets Layer)과 TLS(Transport Layer Security)는 네트워크 통신에서 암호화, 인증, 무결성을 제공하는 프로토콜입니다. SSL은 더 이상 사용되지 않으며, 현재는 TLS 1.2와 TLS 1.3이 표준입니다.
2.1 TLS 핸드셰이크 과정
TLS 1.2 핸드셰이크:
- Client Hello: 클라이언트가 지원하는 TLS 버전, 암호화 스위트, 랜덤 데이터 전송
- Server Hello: 서버가 선택한 TLS 버전, 암호화 스위트, 랜덤 데이터 전송
- Server Certificate: 서버의 인증서 전송
- Server Key Exchange: 키 교환에 필요한 파라미터 전송 (선택적)
- Server Hello Done: 서버 Hello 단계 완료 알림
- Client Key Exchange: 클라이언트가 프리마스터 시크릿 전송
- Change Cipher Spec: 양측이 암호화 시작 알림
- Finished: 핸드셰이크 완료 확인
TLS 1.3 핸드셰이크 (개선점):
- 1-RTT(Round Trip Time)로 핸드셰이크 시간 단축
- 0-RTT 재연결 지원으로 더욱 빠른 연결
- 취약한 암호화 스위트 제거 (RC4, 3DES, MD5 등)
- Perfect Forward Secrecy(PFS) 필수화
2.2 TLS 암호화 스위트
TLS 암호화 스위트는 키 교환, 인증, 암호화, 해시 알고리즘의 조합입니다.
# OpenSSL로 지원되는 암호화 스위트 확인
openssl ciphers -v
# TLS 1.3 암호화 스위트 확인
openssl ciphers -v -tls1_3
# 권장 암호화 스위트 예시 (TLS 1.3)
# TLS_AES_256_GCM_SHA384
# TLS_CHACHA20_POLY1305_SHA256
# TLS_AES_128_GCM_SHA256
# 서버 TLS 설정 테스트
openssl s_client -connect example.com:443 -tls1_3
2.3 Nginx TLS 설정
# /etc/nginx/conf.d/ssl.conf
server {
listen 443 ssl http2;
server_name example.com;
# 인증서 설정
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# TLS 버전 설정 (1.2, 1.3만 허용)
ssl_protocols TLSv1.2 TLSv1.3;
# 암호화 스위트 설정
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/chain.pem;
# SSL 세션 캐시
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# HSTS (HTTP Strict Transport Security)
add_header Strict-Transport-Security "max-age=63072000" always;
}
3. 인증서와 PKI (Public Key Infrastructure)
3.1 디지털 인증서
디지털 인증서는 공개키와 소유자 정보를 신뢰할 수 있는 기관(CA)이 서명한 전자 문서입니다. X.509는 가장 널리 사용되는 인증서 표준입니다.
인증서 구성 요소:
- 버전 (Version)
- 일련번호 (Serial Number)
- 서명 알고리즘 (Signature Algorithm)
- 발급자 (Issuer)
- 유효 기간 (Validity Period)
- 주체 (Subject)
- 공개키 정보 (Public Key Info)
- 확장 필드 (Extensions)
- 서명 (Signature)
# 인증서 내용 확인
openssl x509 -in certificate.pem -text -noout
# 인증서 체인 확인
openssl verify -CAfile ca-bundle.crt certificate.pem
# 서버 인증서 다운로드 및 확인
openssl s_client -connect example.com:443 -showcerts
3.2 PKI 구성 요소
- CA (Certificate Authority): 인증서를 발급하고 서명하는 신뢰 기관
- RA (Registration Authority): 인증서 발급 신청을 검증하는 기관
- CRL (Certificate Revocation List): 폐기된 인증서 목록
- OCSP (Online Certificate Status Protocol): 인증서 유효성을 실시간으로 확인하는 프로토콜
3.3 Let's Encrypt를 이용한 무료 인증서 발급
# Certbot 설치 (Ubuntu/Debian)
sudo apt update
sudo apt install certbot python3-certbot-nginx
# Nginx용 인증서 발급
sudo certbot --nginx -d example.com -d www.example.com
# 인증서 자동 갱신 테스트
sudo certbot renew --dry-run
# 수동 인증서 발급 (DNS 인증)
sudo certbot certonly --manual --preferred-challenges dns -d *.example.com
# 인증서 갱신 크론 설정
# /etc/cron.d/certbot
0 0,12 * * * root certbot renew --quiet
4. VPN 종류
4.1 Site-to-Site VPN
Site-to-Site VPN은 두 개 이상의 네트워크(사이트)를 연결하여 하나의 논리적 네트워크처럼 동작하게 합니다. 주로 본사와 지사 간 연결에 사용됩니다.
특징:
- 라우터나 방화벽 레벨에서 설정
- 영구적인 연결 유지
- 전체 네트워크 트래픽 암호화
- 사용자가 별도 VPN 클라이언트 불필요
4.2 Remote Access VPN
Remote Access VPN은 개별 사용자가 원격에서 사내 네트워크에 접속할 때 사용합니다. 재택근무, 출장 시 많이 사용됩니다.
특징:
- 클라이언트 소프트웨어 필요
- 필요시 연결/해제
- 사용자 인증 필수
- Split Tunneling 옵션 제공
4.3 SSL VPN vs IPSec VPN 비교
| 특성 | SSL VPN | IPSec VPN |
|---|---|---|
| OSI 계층 | Application/Transport | Network |
| 클라이언트 | 웹 브라우저 가능 | 전용 클라이언트 필요 |
| NAT 통과 | 용이 | NAT-T 필요 |
| 포트 | 443 (HTTPS) | 500, 4500 (UDP) |
| 설정 복잡도 | 낮음 | 높음 |
| 사용 사례 | 원격 접속 | Site-to-Site |
5. VPN 프로토콜
5.1 IPSec (Internet Protocol Security)
IPSec은 IP 계층에서 암호화와 인증을 제공하는 프로토콜 스위트입니다.
주요 구성 요소:
- AH (Authentication Header): 무결성과 인증 제공, 암호화 없음
- ESP (Encapsulating Security Payload): 기밀성, 무결성, 인증 제공
- IKE (Internet Key Exchange): 보안 연관(SA) 협상 및 키 교환
IPSec 모드:
- Transport Mode: IP 페이로드만 암호화, 호스트 간 통신
- Tunnel Mode: 전체 IP 패킷 암호화, VPN 게이트웨이 간 통신
# strongSwan IPSec 설치 (Ubuntu)
sudo apt install strongswan strongswan-pki
# IPSec 상태 확인
sudo ipsec status
# SA(Security Association) 확인
sudo ipsec statusall
5.2 OpenVPN
OpenVPN은 SSL/TLS 기반의 오픈소스 VPN 솔루션으로, 높은 유연성과 보안성을 제공합니다.
특징:
- SSL/TLS 사용으로 방화벽 친화적
- UDP/TCP 지원
- 사용자 정의 암호화 알고리즘 선택 가능
- TAP(브리지) 또는 TUN(라우팅) 모드 지원
# OpenVPN 서버 설치 (Ubuntu)
sudo apt update
sudo apt install openvpn easy-rsa
# Easy-RSA 초기화
make-cadir ~/openvpn-ca
cd ~/openvpn-ca
./easyrsa init-pki
./easyrsa build-ca
# 서버 키 생성
./easyrsa gen-req server nopass
./easyrsa sign-req server server
# DH 파라미터 생성
./easyrsa gen-dh
# TLS 키 생성
openvpn --genkey secret ta.key
5.3 WireGuard
WireGuard는 현대적이고 간결한 VPN 프로토콜로, 최소한의 코드베이스와 최신 암호화 기술을 사용합니다.
특징:
- 약 4,000줄의 간결한 코드 (OpenVPN 대비 1/100)
- ChaCha20, Curve25519, BLAKE2s 등 최신 암호화
- 커널 레벨 구현으로 높은 성능
- 간단한 설정
- UDP 기반 (TCP 미지원)
6. WireGuard 서버 구축
6.1 서버 설치 및 구성
# WireGuard 설치 (Ubuntu 20.04+)
sudo apt update
sudo apt install wireguard
# 서버 키 쌍 생성
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key
chmod 600 /etc/wireguard/server_private.key
# 클라이언트 키 쌍 생성
wg genkey | tee /etc/wireguard/client1_private.key | wg pubkey > /etc/wireguard/client1_public.key
6.2 서버 설정 파일
# /etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY_HERE
# IP 포워딩 및 NAT 설정
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# 클라이언트 1
[Peer]
PublicKey = CLIENT1_PUBLIC_KEY_HERE
AllowedIPs = 10.0.0.2/32
# 클라이언트 2
[Peer]
PublicKey = CLIENT2_PUBLIC_KEY_HERE
AllowedIPs = 10.0.0.3/32
6.3 클라이언트 설정 파일
# client1.conf
[Interface]
PrivateKey = CLIENT1_PRIVATE_KEY_HERE
Address = 10.0.0.2/24
DNS = 1.1.1.1, 8.8.8.8
[Peer]
PublicKey = SERVER_PUBLIC_KEY_HERE
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0 # 모든 트래픽을 VPN으로 라우팅
# AllowedIPs = 10.0.0.0/24, 192.168.1.0/24 # Split Tunneling
PersistentKeepalive = 25
6.4 WireGuard 서비스 시작
# IP 포워딩 활성화
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# WireGuard 인터페이스 시작
sudo wg-quick up wg0
# 부팅 시 자동 시작
sudo systemctl enable wg-quick@wg0
# 상태 확인
sudo wg show
# 실시간 모니터링
sudo watch wg show
6.5 방화벽 설정
# UFW 사용 시
sudo ufw allow 51820/udp
sudo ufw allow OpenSSH
sudo ufw enable
# iptables 직접 사용 시
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
sudo iptables -A FORWARD -i wg0 -j ACCEPT
sudo iptables -A FORWARD -o wg0 -j ACCEPT
7. SSL VPN 설정 (OpenVPN)
7.1 OpenVPN 서버 설정
# /etc/openvpn/server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
tls-auth ta.key 0
cipher AES-256-GCM
auth SHA256
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
7.2 클라이언트 설정 파일 생성 스크립트
#!/bin/bash
# generate-client-config.sh
CLIENT_NAME=$1
OUTPUT_DIR="/etc/openvpn/client-configs"
# 클라이언트 키 생성
cd ~/openvpn-ca
./easyrsa gen-req ${CLIENT_NAME} nopass
./easyrsa sign-req client ${CLIENT_NAME}
# 설정 파일 생성
cat > ${OUTPUT_DIR}/${CLIENT_NAME}.ovpn << EOF
client
dev tun
proto udp
remote vpn.example.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
key-direction 1
verb 3
$(cat /etc/openvpn/ca.crt)
$(cat ~/openvpn-ca/pki/issued/${CLIENT_NAME}.crt)
$(cat ~/openvpn-ca/pki/private/${CLIENT_NAME}.key)
$(cat /etc/openvpn/ta.key)
EOF
echo "Client config created: ${OUTPUT_DIR}/${CLIENT_NAME}.ovpn"
7.3 OpenVPN 서비스 관리
# 서비스 시작
sudo systemctl start openvpn@server
sudo systemctl enable openvpn@server
# 상태 확인
sudo systemctl status openvpn@server
# 연결된 클라이언트 확인
sudo cat /var/log/openvpn/openvpn-status.log
# 로그 확인
sudo tail -f /var/log/openvpn/openvpn.log
8. VPN 보안 고려사항
8.1 인증 강화
- 다단계 인증 (MFA): 인증서 + OTP 또는 인증서 + 비밀번호 조합
- 인증서 기반 인증: 공유 비밀번호보다 강력한 보안
- LDAP/RADIUS 통합: 중앙 집중식 사용자 관리
# OpenVPN LDAP 인증 플러그인 설정
# /etc/openvpn/auth-ldap.conf
URL ldaps://ldap.example.com
BindDN cn=admin,dc=example,dc=com
Password secretpassword
Timeout 15
TLSEnable yes
BaseDN ou=users,dc=example,dc=com
SearchFilter "(&(uid=%u)(memberOf=cn=vpnusers,ou=groups,dc=example,dc=com))"
RequireGroup true
8.2 네트워크 분리
- VPN 전용 서브넷: VPN 사용자를 별도 네트워크에 배치
- 접근 제어 목록 (ACL): VPN 사용자가 접근 가능한 리소스 제한
- 마이크로 세그멘테이션: 세분화된 접근 정책 적용
8.3 모니터링 및 로깅
# WireGuard 연결 로깅 스크립트
#!/bin/bash
# /etc/wireguard/log-connections.sh
while true; do
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
wg show wg0 dump | while read line; do
PUBLIC_KEY=$(echo $line | awk '{print $1}')
ENDPOINT=$(echo $line | awk '{print $3}')
LAST_HANDSHAKE=$(echo $line | awk '{print $5}')
RX=$(echo $line | awk '{print $6}')
TX=$(echo $line | awk '{print $7}')
if [ "$LAST_HANDSHAKE" != "0" ]; then
echo "$TIMESTAMP - Peer: $PUBLIC_KEY, Endpoint: $ENDPOINT, RX: $RX, TX: $TX"
fi
done >> /var/log/wireguard/connections.log
sleep 60
done
8.4 보안 모범 사례
- 강력한 암호화 사용: AES-256-GCM, ChaCha20-Poly1305 등 최신 알고리즘 사용
- 정기적인 키 교체: 인증서와 Pre-Shared Key 주기적 갱신
- Perfect Forward Secrecy: ECDHE 키 교환 사용으로 과거 세션 보호
- Kill Switch: VPN 연결 끊김 시 인터넷 차단
- DNS 누출 방지: VPN 터널을 통한 DNS 쿼리 강제
- Split Tunneling 주의: 필요한 경우에만 사용하고 위험성 인지
8.5 VPN 프로토콜 비교
| 프로토콜 | 보안성 | 속도 | 설정 난이도 | 플랫폼 지원 |
|---|---|---|---|---|
| WireGuard | 매우 높음 | 매우 빠름 | 쉬움 | 대부분 |
| OpenVPN | 높음 | 보통 | 보통 | 모든 플랫폼 |
| IPSec/IKEv2 | 높음 | 빠름 | 어려움 | 네이티브 지원 |
| L2TP/IPSec | 보통 | 보통 | 쉬움 | 네이티브 지원 |
| PPTP | 취약 | 빠름 | 쉬움 | 레거시 |
결론
VPN과 암호화 기술은 현대 네트워크 보안의 핵심 요소입니다. 이번 글에서 다룬 내용을 정리하면:
- 암호화 기초: 대칭키, 비대칭키, 해시 함수의 특성과 용도를 이해
- SSL/TLS: 안전한 통신을 위한 표준 프로토콜, TLS 1.3 사용 권장
- PKI: 인증서 기반의 신뢰 체계 구축
- VPN 종류: Site-to-Site와 Remote Access VPN의 특성 파악
- VPN 프로토콜: 용도에 맞는 프로토콜 선택 (신규 구축 시 WireGuard 권장)
- 보안 고려사항: 인증 강화, 네트워크 분리, 모니터링 필수
다음 6편에서는 웹 애플리케이션 보안과 OWASP Top 10에 대해 자세히 알아보겠습니다.