서론: 안전한 통신의 핵심, 암호화와 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 핸드셰이크:

  1. Client Hello: 클라이언트가 지원하는 TLS 버전, 암호화 스위트, 랜덤 데이터 전송
  2. Server Hello: 서버가 선택한 TLS 버전, 암호화 스위트, 랜덤 데이터 전송
  3. Server Certificate: 서버의 인증서 전송
  4. Server Key Exchange: 키 교환에 필요한 파라미터 전송 (선택적)
  5. Server Hello Done: 서버 Hello 단계 완료 알림
  6. Client Key Exchange: 클라이언트가 프리마스터 시크릿 전송
  7. Change Cipher Spec: 양측이 암호화 시작 알림
  8. 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 보안 모범 사례

  1. 강력한 암호화 사용: AES-256-GCM, ChaCha20-Poly1305 등 최신 알고리즘 사용
  2. 정기적인 키 교체: 인증서와 Pre-Shared Key 주기적 갱신
  3. Perfect Forward Secrecy: ECDHE 키 교환 사용으로 과거 세션 보호
  4. Kill Switch: VPN 연결 끊김 시 인터넷 차단
  5. DNS 누출 방지: VPN 터널을 통한 DNS 쿼리 강제
  6. 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에 대해 자세히 알아보겠습니다.