🌍 네트워크

Firewall

방화벽

네트워크 트래픽을 필터링하는 보안 장치. 인바운드/아웃바운드 규칙 적용.

📖 상세 설명

방화벽(Firewall)은 네트워크 트래픽을 모니터링하고 사전 정의된 보안 규칙에 따라 데이터 패킷을 허용하거나 차단하는 네트워크 보안 시스템입니다. 마치 건물의 보안 검색대처럼 들어오고 나가는 모든 트래픽을 검사하여 악의적인 접근을 방지합니다.

방화벽은 크게 Stateless(무상태)와 Stateful(상태 유지) 두 가지 방식으로 작동합니다. Stateless 방화벽은 각 패킷을 개별적으로 검사하며, Source/Destination IP, Port, Protocol만 확인합니다. 반면 Stateful 방화벽은 연결의 전체 컨텍스트를 추적하여 세션 상태를 기반으로 더 정교한 필터링을 수행합니다. 예를 들어 내부에서 시작된 요청의 응답 패킷은 자동으로 허용됩니다.

패킷 필터링은 방화벽의 핵심 기능입니다. OSI 7계층 중 3~4계층(네트워크/전송 계층)에서 IP 주소와 포트 번호를 기반으로 트래픽을 제어합니다. 리눅스에서는 iptables/nftables가, 클라우드 환경에서는 AWS Security Group, Azure NSG 등이 패킷 필터링 방화벽 역할을 합니다.

WAF(Web Application Firewall)는 7계층(애플리케이션 계층)에서 작동하는 특수한 방화벽입니다. SQL Injection, XSS, CSRF 같은 웹 공격을 HTTP/HTTPS 트래픽을 분석하여 차단합니다. AWS WAF, Cloudflare WAF, ModSecurity 등이 대표적이며, OWASP Top 10 취약점에 대한 방어 규칙을 기본 제공합니다.

💻 코드 예제

# iptables 기본 규칙 설정
# 모든 입력 차단, 출력 허용 (기본 정책)
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD DROP

# Loopback 허용 (필수)
sudo iptables -A INPUT -i lo -j ACCEPT

# 이미 연결된 세션 허용 (Stateful)
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# SSH 허용 (포트 22)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# HTTP/HTTPS 허용
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 특정 IP에서만 SSH 허용 (더 안전)
sudo iptables -A INPUT -p tcp -s 203.0.113.50 --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j DROP

# 특정 포트 범위 허용
sudo iptables -A INPUT -p tcp --dport 8000:9000 -j ACCEPT

# ICMP (ping) 허용
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# 로그 후 차단 (디버깅용)
sudo iptables -A INPUT -j LOG --log-prefix "DROPPED: "
sudo iptables -A INPUT -j DROP

# 규칙 확인
sudo iptables -L -n -v

# 규칙 저장 (재부팅 후에도 유지)
sudo iptables-save > /etc/iptables/rules.v4
# AWS Security Group (boto3)
import boto3

ec2 = boto3.client('ec2')

# Security Group 생성
response = ec2.create_security_group(
    GroupName='web-server-sg',
    Description='Security group for web servers',
    VpcId='vpc-12345678'
)
security_group_id = response['GroupId']
print(f'Security Group Created: {security_group_id}')

# 인바운드 규칙 추가
ec2.authorize_security_group_ingress(
    GroupId=security_group_id,
    IpPermissions=[
        # SSH 허용 (특정 IP만)
        {
            'IpProtocol': 'tcp',
            'FromPort': 22,
            'ToPort': 22,
            'IpRanges': [{'CidrIp': '203.0.113.0/24', 'Description': 'Office IP'}]
        },
        # HTTP 허용 (전체)
        {
            'IpProtocol': 'tcp',
            'FromPort': 80,
            'ToPort': 80,
            'IpRanges': [{'CidrIp': '0.0.0.0/0', 'Description': 'Public HTTP'}]
        },
        # HTTPS 허용 (전체)
        {
            'IpProtocol': 'tcp',
            'FromPort': 443,
            'ToPort': 443,
            'IpRanges': [{'CidrIp': '0.0.0.0/0', 'Description': 'Public HTTPS'}]
        },
        # 다른 Security Group에서 오는 트래픽 허용
        {
            'IpProtocol': 'tcp',
            'FromPort': 3306,
            'ToPort': 3306,
            'UserIdGroupPairs': [{'GroupId': 'sg-app-server', 'Description': 'From App Server'}]
        }
    ]
)

# 아웃바운드 규칙 (기본: 전체 허용)
# 필요시 제한 가능
ec2.authorize_security_group_egress(
    GroupId=security_group_id,
    IpPermissions=[
        {
            'IpProtocol': 'tcp',
            'FromPort': 443,
            'ToPort': 443,
            'IpRanges': [{'CidrIp': '0.0.0.0/0', 'Description': 'HTTPS outbound only'}]
        }
    ]
)
# UFW (Uncomplicated Firewall) - Ubuntu 기본 방화벽
# iptables를 쉽게 관리할 수 있는 프론트엔드

# UFW 상태 확인
sudo ufw status verbose

# 기본 정책 설정
sudo ufw default deny incoming   # 인바운드 기본 차단
sudo ufw default allow outgoing  # 아웃바운드 기본 허용

# SSH 허용 (중요: 원격 접속 시 먼저 설정!)
sudo ufw allow ssh          # 또는 ufw allow 22
sudo ufw allow 22/tcp

# HTTP/HTTPS 허용
sudo ufw allow http         # 또는 ufw allow 80
sudo ufw allow https        # 또는 ufw allow 443

# 특정 IP에서만 허용
sudo ufw allow from 203.0.113.50 to any port 22

# 포트 범위 허용
sudo ufw allow 8000:9000/tcp

# 특정 서브넷 허용
sudo ufw allow from 192.168.1.0/24 to any port 3306

# 애플리케이션 프로필 사용
sudo ufw app list           # 사용 가능한 앱 프로필
sudo ufw allow 'Nginx Full' # Nginx HTTP + HTTPS
sudo ufw allow 'OpenSSH'

# 규칙 삭제
sudo ufw delete allow 80
sudo ufw delete allow from 203.0.113.50

# UFW 활성화/비활성화
sudo ufw enable
sudo ufw disable

# 모든 규칙 초기화
sudo ufw reset

# 로깅 설정
sudo ufw logging on
sudo ufw logging medium

🗣️ 실무에서 이렇게 말하세요

💬 보안 아키텍처 회의에서
"웹 서버 앞단에 WAF를 배치해서 OWASP Top 10 공격을 차단하고, Security Group은 ALB에서 오는 트래픽만 허용하도록 설정합니다. DB 서버는 Private Subnet에 두고 앱 서버의 Security Group에서만 3306 포트 접근을 허용하면 됩니다."
💬 장애 대응 상황에서
"특정 IP에서 비정상적인 요청이 들어오고 있습니다. 먼저 iptables로 해당 IP 대역을 임시 차단하고, 근본적으로는 WAF에서 Rate Limiting 규칙을 추가해서 분당 100회 이상 요청하는 IP를 자동 차단하도록 하겠습니다."
💬 면접에서
"Stateful 방화벽과 Stateless 방화벽의 차이는 연결 상태 추적 여부입니다. AWS Security Group은 Stateful이라 인바운드 허용 시 응답 트래픽이 자동 허용되지만, NACL은 Stateless라 인바운드/아웃바운드 모두 명시적으로 설정해야 합니다. 실무에서는 Security Group으로 인스턴스 레벨 보안을, NACL로 서브넷 레벨 보안을 이중으로 구성합니다."

⚠️ 흔한 실수 & 주의사항

0.0.0.0/0 SSH 오픈

SSH 22번 포트를 전체 IP(0.0.0.0/0)에 오픈하면 무차별 대입 공격에 노출됩니다. 사무실 IP만 허용하고, VPN/Bastion Host를 통해 접속하세요.

아웃바운드 규칙 무시

인바운드만 신경 쓰고 아웃바운드를 전체 허용하면 악성코드 감염 시 데이터 유출 위험이 있습니다. 필요한 목적지(패키지 저장소, API 서버)만 허용하세요.

원격 접속 중 방화벽 설정 실수

SSH로 원격 접속 중 실수로 22번 포트를 차단하면 서버 접근이 불가능해집니다. UFW는 ufw allow ssh를 먼저 실행하고, 클라우드는 콘솔 접근 수단을 확보하세요.

올바른 방화벽 설정 원칙

기본 정책은 모든 트래픽 차단(Deny All), 필요한 것만 명시적 허용(Allow List). 규칙에는 설명(Description)을 추가하고, 정기적으로 미사용 규칙을 정리하세요.

🔗 관련 용어

📚 더 배우기