
방화벽(Firewall): 서버를 지키는 까칠한 문지기
내 서버가 해킹당하지 않는 이유. 포트와 IP를 검사하는 '패킷 필터링'부터 AWS Security Group까지, 방화벽의 진화 과정.

내 서버가 해킹당하지 않는 이유. 포트와 IP를 검사하는 '패킷 필터링'부터 AWS Security Group까지, 방화벽의 진화 과정.
내 서버는 왜 걸핏하면 뻗을까? OS가 한정된 메모리를 쪼개 쓰는 처절한 사투. 단편화(Fragmentation)와의 전쟁.

미로를 탈출하는 두 가지 방법. 넓게 퍼져나갈 것인가(BFS), 한 우물만 팔 것인가(DFS). 최단 경로는 누가 찾을까?

프론트엔드 개발자가 알아야 할 4가지 저장소의 차이점과 보안 이슈(XSS, CSRF), 그리고 언제 무엇을 써야 하는지에 대한 명확한 기준.

이름부터 빠릅니다. 피벗(Pivot)을 기준으로 나누고 또 나누는 분할 정복 알고리즘. 왜 최악엔 느린데도 가장 많이 쓰일까요?

첫 서비스를 배포하고 나서 3일 뒤, AWS 대시보드를 보니 알 수 없는 IP에서 SSH 접속을 시도한 로그가 수백 개 찍혀 있었다. 소름이 돋았다. "내 서버가 지금 공격받고 있구나." 서둘러 Security Group 설정을 뒤져봤는데, SSH 포트 22번이 0.0.0.0/0 (전 세계 모든 IP 허용)으로 열려 있었다. 황급히 내 집 IP로만 제한했고, 그제야 공격 로그가 멈췄다.
그때 깨달았다. 코드를 아무리 잘 짜도, 방화벽이 뚫려 있으면 무용지물이라는 걸. 그 뒤로 나는 방화벽을 "까칠한 문지기"로 받아들였다. 귀찮게 구는 게 아니라, 내 서버를 지켜주는 존재였다.
방화벽 공부를 시작하니 용어가 쏟아졌다. Inbound, Outbound, Stateful, Stateless, Security Group, NACL, iptables, ufw, WAF... 하나하나가 다 다른 건지, 비슷한 건지 도통 모르겠더라. 특히 AWS를 쓰면 Security Group과 NACL이라는 게 둘 다 있는데, "방화벽이 왜 두 개야?"라는 의문에 빠졌다.
더 혼란스러웠던 건, 방화벽 규칙을 설정했는데도 접속이 안 되는 경우였다. "분명 80번 포트 열었는데 왜 안 돼?"를 외치며 한 시간을 헤맸는데, 알고 보니 서버 안쪽에 ufw라는 또 다른 방화벽이 있어서 거기서 막고 있었다. 방화벽이 여러 겹이라는 걸 그때 처음 알았다.
방화벽은 클럽 입구에 서 있는 덩치 큰 문지기(Bouncer)다. 나는 이 비유로 모든 게 정리됐다. 아무나 들여보내지 않는다. 명단에 있거나(WhiteList), 복장 규정을 지킨 사람만 통과시킨다. 이름표(IP 주소)를 확인하고, 어느 입구로 들어오는지(포트 번호), 어디서 왔는지(소스 IP), 심지어 가방 안에 뭐가 들었는지(패킷 내용)까지 검사한다.
인터넷 세상은 위험하다. 문을 활짝 열어두면 러시아 해커, 중국 봇, 옆집 철수의 디도스 공격이 24시간 쏟아진다. 그래서 우리는 방화벽이라는 문지기를 세워두고 규칙을 정해준다. "22번 포트(SSH)는 우리 사무실 IP에만 열어줘", "80번(HTTP)과 443번(HTTPS)은 누구든 들어와도 돼", "그 외에는 전부 거절해" 같은 식이다.
방화벽의 가장 중요한 철학은 "기본적으로 모두 거부(Deny by Default)"다. 클럽 문지기가 "일단 다 못 들어와. 명단에 있는 사람만 통과"라고 하는 것처럼, 방화벽도 "일단 다 막아. 내가 허용한 것만 들어와"라고 동작한다. 이게 보안의 핵심이다. 허용 목록(Whitelist)을 만들어두고, 그 외에는 전부 차단하는 방식이다.
반대로 "일단 다 허용하고, 위험한 것만 차단"하는 방식(Blacklist)도 있지만, 이건 위험하다. 새로운 공격 방법이 매일 나오는데, 그걸 일일이 차단 목록에 추가하기엔 너무 느리다. 그래서 현대 방화벽은 대부분 Whitelist 방식을 쓴다.
방화벽 설정의 가장 기본적인 패턴(Default Policy)은 이렇다.
외부에서 내 서버로 들어오는 트래픽이다. 기본적으로 모두 차단(Deny All)한다. 그리고 "웹사이트 보여줘야 하니까 80(HTTP), 443(HTTPS)번 문만 열어줘"라고 예외를 둔다.
왜 기본적으로 막냐고? 내가 요청하지도 않았는데 갑자기 들어오는 패킷은 대부분 공격이기 때문이다. 포트 스캐닝(Port Scanning)이라고, 해커들이 "이 서버 어느 포트가 열려 있나?" 하고 1번부터 65535번까지 다 두드려보는 공격이 있다. 만약 필요 없는 포트까지 열어뒀다면, 해커는 그 포트로 침투를 시도한다.
실제로 내가 겪은 사례가 있다. MySQL을 설치했는데, 기본 포트 3306이 0.0.0.0/0으로 열려 있었다. 그날 밤 중국 IP에서 수천 번의 로그인 시도가 있었고, 비밀번호를 추측하려는 Brute Force 공격이었다. 다행히 비밀번호가 복잡해서 뚫리진 않았지만, Security Group에서 3306을 막자 공격이 즉시 멈췄다.
내 서버에서 외부로 나가는 트래픽이다. 기본적으로 모두 허용(Allow All)한다. 내 서버가 apt update를 하거나 외부 API를 호출해야 하기 때문이다.
예를 들어, Node.js 서버가 npm install을 하려면 npm 레지스트리(registry.npmjs.org)에 접속해야 한다. Python 서버가 pip install을 하려면 PyPI(pypi.org)에 접속해야 한다. 만약 Outbound를 막으면, 서버가 외부와 통신할 수 없어서 패키지 설치도, API 호출도 불가능해진다.
하지만 보안을 극도로 중요시하는 환경(금융, 국방 등)에서는 Outbound도 화이트리스트 방식으로 관리한다. "이 서버는 오직 이 IP의 이 포트로만 나갈 수 있다"고 제한하는 식이다. 그러면 혹시 서버가 해킹당해도, 해커가 외부로 데이터를 빼내기 어렵게 만들 수 있다.
방화벽은 세대별로 진화해왔다. 나는 이걸 "문지기가 점점 똑똑해지는 과정"으로 이해했다.
가장 단순한 형태다. 네트워크 패킷의 헤더(주소표)만 본다. 패킷 내용은 안 본다.
검사 항목:예를 들어, "너 22번 포트(SSH)로 들어오네? 출발지가 우리 사무실 IP야? 아니네? 꺼져."라고 판단한다. 간단하고 빠르다. CPU를 거의 안 먹는다. 그래서 지금도 많이 쓰인다.
한계: 패킷 내용을 안 보기 때문에, 80번 포트로 들어오는 해킹 공격은 못 막는다. 예를 들어, 정상적인 HTTP 요청인 척하면서 SQL Injection 코드를 숨겨 보내면, 패킷 필터링 방화벽은 "80번 포트니까 OK"라고 그냥 통과시킨다.
대표 예시:iptables (Linux)실제로 iptables 명령어를 보면 이렇다:
# 22번 포트(SSH)는 192.168.1.100에서만 허용
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.100 -j ACCEPT
# 그 외 22번 포트는 전부 거부
iptables -A INPUT -p tcp --dport 22 -j DROP
# 80번(HTTP), 443번(HTTPS) 포트는 누구나 허용
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 나머지는 전부 거부
iptables -P INPUT DROP
이게 1세대 방화벽의 전형이다. IP와 포트만 보고 "통과" 또는 "차단"을 결정한다.
조금 더 똑똑해졌다. "연결 상태(Connection State)"를 기억한다. 이게 무슨 말이냐면, "아까 내 서버가 먼저 요청 보낸 거에 대한 응답이네? 그럼 들어와."라고 판단할 수 있다는 뜻이다.
핵심 개념: TCP의 3-Way Handshake 추적TCP 연결은 3단계로 이뤄진다:
Stateful 방화벽은 이 과정을 추적한다. 만약 1번(SYN) 없이 갑자기 3번(ACK) 패킷이 날아오면, "너 누구야? 우리 연결한 적 없는데?"라고 차단한다. 이걸 "연결 테이블(Connection Table)"에 기록하면서 관리한다.
예시: 웹 브라우징 시나리오naver.com에 접속하려고 Outbound 요청을 보낸다.naver.com 서버가 응답을 보내면(Inbound), 방화벽은 "이건 아까 내가 요청한 거에 대한 답변이니까 통과"시킨다.이 방식의 장점은, Inbound 규칙을 일일이 열어주지 않아도 된다는 것이다. Outbound 요청에 대한 응답은 자동으로 허용되기 때문이다. 이게 바로 AWS Security Group이 Stateful한 이유다.
한계: 여전히 패킷 내용은 안 본다. 80번 포트로 정상 HTTP 요청인 척하면서 XSS(Cross-Site Scripting) 공격 코드를 숨겨 보내면, Stateful 방화벽도 "정상 연결이네"라고 통과시킨다.
대표 예시:iptables (conntrack 모듈 사용)이제 패킷을 뜯어서 내용을 본다. 택배 상자를 열어서 안에 뭐가 들었는지 확인하는 문지기가 된 것이다.
검사 항목:"80번 포트로 들어와서 합격인 줄 알았더니, 내용물에 DROP TABLE users 같은 SQL 인젝션 공격 코드가 있네? 체포해."라고 판단한다. 가장 강력하지만 비싸고, CPU를 많이 먹는다.
POST /login HTTP/1.1
Host: myapp.com
Content-Type: application/json
{
"username": "admin' OR '1'='1",
"password": "anything"
}
위 요청은 SQL Injection 공격이다. WAF는 username 필드에 ' (작은따옴표)와 OR 같은 SQL 문법이 들어간 걸 감지하고, "이거 공격이네"라고 차단한다.
또 다른 예시:
GET /search?q=<script>alert('XSS')</script> HTTP/1.1
이건 XSS 공격이다. WAF는 URL에 <script> 태그가 들어간 걸 보고 차단한다.
한계: 모든 패킷을 뜯어보니 성능 부담이 크다. 특히 HTTPS는 암호화되어 있어서, WAF가 SSL 인증서를 갖고 있어야 복호화해서 볼 수 있다. 이걸 "SSL Termination"이라고 한다. 또한, 오탐(False Positive)이 잦다. 정상 요청인데 공격으로 오인해서 차단하는 경우가 있다.
이론만 알아선 소용없다. 실제로 서버에 방화벽을 설정해본다.
Ubuntu에서 가장 많이 쓰는 방화벽이다. iptables를 쉽게 쓸 수 있게 감싼 래퍼(wrapper)다.
# ufw 설치 (Ubuntu는 기본 설치되어 있음)
sudo apt install ufw
# 현재 상태 확인
sudo ufw status
# 방화벽 활성화 전, 기본 정책 설정
sudo ufw default deny incoming # 들어오는 건 기본 차단
sudo ufw default allow outgoing # 나가는 건 기본 허용
# SSH 포트 22번 열기 (이거 안 하면 SSH 접속 끊김!)
sudo ufw allow 22/tcp
# HTTP(80), HTTPS(443) 열기
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# 특정 IP에만 SSH 허용 (내 집 IP가 203.0.113.50이라면)
sudo ufw allow from 203.0.113.50 to any port 22
# 방화벽 활성화
sudo ufw enable
# 상태 확인 (번호와 함께 보기)
sudo ufw status numbered
# 특정 규칙 삭제 (예 - 3번 규칙 삭제)
sudo ufw delete 3
# 방화벽 비활성화
sudo ufw disable
실제 겪은 실수:
한번은 SSH로 접속한 상태에서 ufw enable을 했는데, 22번 포트를 미리 열어두지 않아서 SSH 연결이 끊겼다. 다행히 AWS 콘솔의 Session Manager로 접속해서 ufw disable로 해결했다. 꼭 SSH 포트를 먼저 열고 ufw enable하라.
iptables는 Linux 커널에 직접 방화벽 규칙을 설정하는 저수준 도구다. 강력하지만 복잡하다.
# 현재 규칙 확인
sudo iptables -L -v -n
# 기본 정책 설정
sudo iptables -P INPUT DROP # 들어오는 건 기본 차단
sudo iptables -P FORWARD DROP # 포워딩은 차단
sudo iptables -P OUTPUT ACCEPT # 나가는 건 허용
# 로컬 루프백 허용 (localhost 통신 허용)
sudo iptables -A INPUT -i lo -j ACCEPT
# 이미 연결된(established) 것과 관련된(related) 패킷 허용
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# SSH 포트 22번 허용
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# HTTP(80), HTTPS(443) 허용
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Ping (ICMP) 허용
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# 특정 IP만 MySQL 접속 허용 (192.168.1.100만 3306 허용)
sudo iptables -A INPUT -p tcp -s 192.168.1.100 --dport 3306 -j ACCEPT
# 규칙 저장 (재부팅 후에도 유지)
sudo apt install iptables-persistent
sudo netfilter-persistent save
iptables의 체인(Chain) 개념:
클라우드(AWS)를 쓰면 방화벽이 두 개라 헷갈린다. 나는 이걸 "건물 입구 검문소(NACL)와 사무실 문(Security Group)"으로 정리했다.
서버(EC2) 바로 앞에 있는 문지기다. Stateful하다. 들어오는 거 허용하면, 나가는 건 자동으로 허용된다. 주로 이걸로 관리한다.
특징:| Type | Protocol | Port Range | Source | Description |
|---|---|---|---|---|
| HTTP | TCP | 80 | 0.0.0.0/0 | Public web traffic |
| HTTPS | TCP | 443 | 0.0.0.0/0 | Public web traffic |
| SSH | TCP | 22 | 203.0.113.50/32 | My office IP |
| MySQL | TCP | 3306 | sg-12345678 | From web server SG |
마지막 줄을 주목하라. Source에 IP 대신 다른 Security Group ID(sg-12345678)를 넣을 수 있다. "이 보안 그룹이 적용된 서버들에서만 접속 허용"이라는 뜻이다. 웹 서버에서 DB 서버로의 접속을 허용할 때 유용하다.
0.0.0.0/0으로 열지 마라. 내 IP로만 제한하거나, VPN을 통해서만 접속하게 하라.web-server-sg, db-server-sg 같은 식으로.서브넷(마을 입구)에 있는 검문소다. Stateless하다. 들어오는 문, 나가는 문 따로따로 열어줘야 한다.
특징:| Rule # | Type | Protocol | Port Range | Source | Allow/Deny |
|---|---|---|---|---|---|
| 100 | HTTP | TCP | 80 | 0.0.0.0/0 | Allow |
| 200 | HTTPS | TCP | 443 | 0.0.0.0/0 | Allow |
| 300 | SSH | TCP | 22 | 203.0.113.0/24 | Allow |
| * | All | All | All | 0.0.0.0/0 | Deny |
NACL은 Stateless라서, 클라이언트가 서버에 요청을 보낼 때 사용하는 임시 포트(Ephemeral Ports)도 열어줘야 한다. 보통 32768-65535 범위다.
예를 들어, 내가 80번 포트로 요청을 보내면, 서버는 내 임시 포트(예: 54321)로 응답을 보낸다. Security Group은 Stateful이라 알아서 허용하지만, NACL은 Stateless라 명시적으로 열어줘야 한다.
Outbound NACL 규칙:
Rule 100: TCP 32768-65535 → 0.0.0.0/0 Allow
이게 헷갈려서, 대부분 NACL은 기본 설정(Allow All)으로 두고, Security Group으로만 관리한다.
NACL을 쓰는 경우:방화벽이 네트워크 스택의 어느 계층에서 동작하는지 정리해봤다.
| 방화벽 종류 | OSI Layer | 검사 항목 |
|---|---|---|
| 패킷 필터링 (iptables) | Layer 3-4 | IP, Port |
| Stateful (AWS SG) | Layer 3-4 | IP, Port, Connection State |
| WAF (AWS WAF) | Layer 7 | HTTP Header, Body, Cookie |
| Next-Gen Firewall (NGFW) | Layer 7 | Application, User Identity, Content |
Layer가 높을수록 더 많은 정보를 볼 수 있지만, 성능 부담이 커진다.
nginx는 웹 서버이면서 동시에 리버스 프록시(Reverse Proxy)로도 쓰인다. 여기에 간단한 방화벽 기능을 추가할 수 있다.
# 특정 IP만 허용 (나머지는 차단)
location /admin {
allow 203.0.113.50; # 내 사무실 IP
allow 192.168.1.0/24; # 내부 네트워크
deny all; # 나머지 전부 차단
proxy_pass http://backend;
}
# 특정 User-Agent 차단 (봇 트래픽 차단)
if ($http_user_agent ~* (bot|crawler|spider)) {
return 403;
}
# Rate Limiting (DDoS 방어)
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
location /api {
limit_req zone=mylimit burst=20 nodelay;
proxy_pass http://backend;
}
}
# 특정 국가 IP 차단 (GeoIP 모듈 사용)
geo $block_country {
default 0;
CN 1; # 중국
RU 1; # 러시아
}
server {
if ($block_country) {
return 403;
}
}
이런 식으로 nginx를 Application-Level Firewall처럼 쓸 수 있다. 특히 Rate Limiting은 DDoS 공격을 막는 데 효과적이다.
기업 네트워크에서는 방화벽을 여러 겹으로 둔다. 이걸 네트워크 세그멘테이션(Network Segmentation)이라고 한다.
DMZ (Demilitarized Zone, 비무장지대): 외부 인터넷과 내부 네트워크 사이에 있는 중간 지대다. 웹 서버처럼 외부에 노출되어야 하는 서버는 DMZ에 두고, DB 서버 같은 민감한 서버는 내부 네트워크(Private Zone)에 둔다.
인터넷
│
[Firewall 1: Edge Firewall]
│
DMZ (Web Server, API Server)
│
[Firewall 2: Internal Firewall]
│
Private Zone (DB Server, Admin Server)
만약 DMZ의 웹 서버가 해킹당해도, Firewall 2가 막고 있어서 DB 서버까지 침투하기 어렵다. 이게 Defense in Depth(심층 방어) 전략이다.
전통적인 보안 모델은 Perimeter-Based Security(경계 기반 보안)였다. "내부 네트워크는 안전하고, 외부는 위험하다"고 가정하고, 경계에 방화벽을 세우는 방식이다.
하지만 요즘은 Zero Trust Security(제로 트러스트 보안)로 바뀌고 있다. "내부든 외부든 아무도 믿지 마. 모든 요청을 검증해."라는 철학이다.
Zero Trust의 핵심 원칙:예를 들어, 옛날에는 "VPN으로 내부 네트워크에 들어오면 모든 리소스 접근 가능"이었다면, 지금은 "VPN 들어와도, 매번 MFA(Multi-Factor Authentication)로 인증하고, 필요한 서버에만 접근 가능"이다.
방화벽 설정하면서 내가 겪었던 실수들을 정리해봤다.
가장 흔한 실수다. SSH(포트 22)를 전 세계에 열어두면, 봇들이 24시간 Brute Force 공격을 시도한다. /var/log/auth.log를 보면 중국, 러시아, 브라질 IP에서 수천 번의 로그인 시도 로그가 찍혀 있을 것이다.
allow from 203.0.113.50개발할 때 귀찮다고 "일단 다 열어두고 나중에 막지 뭐"라고 생각하면 위험하다. 나중엔 잊어버린다.
해결책:nmap으로 스캔해서 불필요한 포트 확인NACL은 Stateless라서 Inbound/Outbound 둘 다 설정해야 한다. 한쪽만 설정하면 통신이 안 된다.
해결책:iptables나 NACL은 규칙을 순서대로 평가한다. 먼저 매칭되는 규칙이 적용되므로, 순서가 중요하다.
# 잘못된 예 - 먼저 모두 차단하면 아래 규칙이 무시됨
iptables -A INPUT -j DROP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT # 이건 절대 실행 안 됨
# 올바른 예 - 허용 규칙을 먼저 쓰고, 마지막에 차단
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -j DROP
Docker를 쓰면 방화벽 설정이 꼬이는 경우가 있다. Docker는 자체적으로 iptables 규칙을 추가하기 때문이다.
문제 상황:
ufw로 포트를 막아뒀는데, Docker 컨테이너가 그 포트를 열면 외부에서 접속이 된다. ufw가 무시당하는 것처럼 보인다.
원인:
Docker는 iptables의 FORWARD 체인에 규칙을 추가한다. ufw는 INPUT 체인만 관리하므로, Docker의 규칙이 우선 적용된다.
// /etc/docker/daemon.json
{
"iptables": false
}
이렇게 하면 Docker가 iptables를 건드리지 않는다. 하지만 컨테이너 간 네트워킹이 안 될 수 있다.
해결책 2: ufw 규칙을 FORWARD 체인에도 추가# /etc/ufw/after.rules 파일 수정
*filter
:DOCKER-USER - [0:0]
-A DOCKER-USER -j RETURN
COMMIT
Docker가 사용하는 DOCKER-USER 체인에 ufw 규칙을 적용한다.
해결책 3: Docker 포트를 localhost에만 바인딩# 잘못된 예 - 모든 인터페이스에 바인딩
docker run -p 3306:3306 mysql
# 올바른 예 - localhost에만 바인딩
docker run -p 127.0.0.1:3306:3306 mysql
이렇게 하면 localhost에서만 접속 가능하고, 외부에서는 접속 불가능하다.
개발하다가 "DB 접속이 안 돼요", "SSH가 안 먹혀요" 하면 99%는 방화벽 문제다. 당황하지 말고 이 체크리스트를 따라가보자.
# 방화벽 상태 확인
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
Linux:
sudo ufw status
sudo iptables -L -v -n
# Linux/Mac
traceroute example.com
# Windows
tracert example.com
어느 지점에서 막히는지 확인할 수 있다.
# telnet으로 확인
telnet example.com 80
# netcat으로 확인
nc -zv example.com 80
# nmap으로 확인 (여러 포트 스캔)
nmap -p 22,80,443 example.com
"Connection refused"가 나오면 서버가 그 포트를 닫은 것이고, "No route to host"나 타임아웃이 나오면 방화벽이 막은 것이다.
# SSH로 서버 접속 후
sudo ufw status verbose
sudo iptables -L -v -n | grep <포트번호>
# 특정 포트가 LISTEN 중인지 확인
sudo netstat -tlnp | grep <포트번호>
# 또는
sudo ss -tlnp | grep <포트번호>
# 프로세스가 살아있는지
ps aux | grep <프로세스명>
# 로그 확인
sudo journalctl -u <서비스명> -n 50
# Docker 컨테이너라면
docker ps
docker logs <컨테이너명>
때로는 방화벽이 아니라 SELinux나 AppArmor 같은 보안 모듈이 막는 경우도 있다.
# SELinux 상태 확인 (CentOS/RHEL)
getenforce
# 임시로 끄기 (재부팅 시 다시 켜짐)
sudo setenforce 0
# AppArmor 상태 확인 (Ubuntu)
sudo aa-status
처음 방화벽을 공부할 땐 "왜 이렇게 복잡해?"라고 짜증났다. 포트 하나 열려면 ufw도 설정하고, Security Group도 설정하고, NACL도 확인하고... 단계가 너무 많았다. 하지만 실제로 서버가 공격받는 걸 보고 나니, 이 모든 게 필요한 방어막이라는 걸 깨달았다.
방화벽은 "까칠한 문지기"지만, 내 서버를 지켜주는 고마운 존재다. 귀찮더라도 제대로 설정해두면, 밤에 편하게 잘 수 있다. "내 서버가 지금 공격받고 있는 건 아닐까?" 하는 불안감 없이.
결국 방화벽은 "기본적으로 모두 거부(Deny by Default)"라는 철학으로 귀결된다. 필요한 것만 열고, 나머지는 닫아두자. 그게 가장 안전한 방법이다.