12장이 성능과 안정성이었다면 이번 장은 안전입니다. 개발자가 직접 만들기 쉬운 취약점과, 인터넷이 없는 환경에서의 운영을 함께 봅니다.
13.1 주요 네트워크 공격과 개발자의 방어
| 공격 | 설명 | 개발자의 방어 |
|---|---|---|
| MITM | 통신 중간에서 도청/변조 | HTTPS 강제, 인증서 검증 끄지 않기, HSTS |
| DDoS | 대량 트래픽으로 서비스 마비 | CDN/WAF, 레이트 리밋, 오토스케일 |
| SSRF | 서버가 공격자가 지정한 내부 주소로 요청하게 만듦 | URL 입력 검증, 내부 대역/메타데이터 IP 차단, 리다이렉트 추적 제한 |
| DNS 스푸핑/리바인딩 | 잘못된 IP로 유도, 검증 후 IP 변경 | HTTPS, Host 헤더 검증, 해석 후 IP 재검증 |
| 포트 스캐닝 | 열린 포트 탐색 | 불필요한 포트 비노출, 관리 포트 내부 한정 |
| Slowloris | 느린 요청으로 연결 고갈 | 리버스 프록시의 헤더/바디 타임아웃 |
SSRF는 특히 풀스택 개발자가 만들기 쉬운 취약점입니다. "URL을 입력하면 미리보기를 보여주는 기능", "웹훅 URL 등록", "이미지 URL로 업로드" 같은 기능은 모두 SSRF 후보입니다. 서버가
169.254.169.254(클라우드 메타데이터)나10.x.x.x(내부 관리 시스템)에 요청하지 않도록 DNS 해석 결과 IP 기준으로 차단해야 합니다.
13.2 방화벽
- 패킷 필터링: IP/포트/프로토콜 기준 허용·차단
- 상태 기반(Stateful): 연결 상태를 추적해 응답 트래픽 자동 허용
- WAF: L7에서 SQL 인젝션, XSS 패턴 등을 탐지
- 기본 원칙: Default Deny, 필요한 것만 허용
Linux 방화벽 확인:
sudo iptables -L -n -v
sudo nft list ruleset
sudo firewall-cmd --list-all # RHEL/CentOS/Rocky
sudo ufw status # Ubuntu방화벽 정책 요청서를 쓸 때는 출발지 IP(대역), 목적지 IP, 목적지 포트, 프로토콜(TCP/UDP), 방향을 명확히 적어야 합니다. "서버끼리 통신되게 해주세요"로는 처리되지 않습니다. WebRTC처럼 UDP 대역이 필요한 경우 특히 누락이 잦습니다.
13.3 네트워크 영역 분리
[인터넷]
│
[외부 방화벽]
│
[DMZ] — 웹서버, 리버스 프록시 (외부 노출)
│
[내부 방화벽]
│
[내부망] — 앱 서버, DB (외부 직접 접근 불가)- DMZ: 외부에 노출되어야 하는 서버만 두는 완충 구역
- Bastion(점프 서버): 내부 서버 관리 접속의 단일 관문
- VPN: 공용망 위에 암호화된 사설 터널 (IPsec, WireGuard, OpenVPN)
- 제로 트러스트: "내부망이면 신뢰" 대신 매 요청마다 인증·인가
13.4 폐쇄망(망분리) 환경에서의 개발과 운영
제조·건설·플랜트·금융·공공 분야에서는 인터넷과 물리적/논리적으로 분리된 폐쇄망 운영이 흔합니다. 폐쇄망에서 네트워크 관련 이슈는 대부분 "인터넷이 당연히 된다고 가정한 것들" 에서 발생합니다.
| 인터넷 환경의 가정 | 폐쇄망에서의 대응 |
|---|---|
| npm/pip/maven 레지스트리 | 사내 미러(Nexus, Verdaccio) 또는 오프라인 번들 반입 |
| Docker Hub | 사설 레지스트리(Harbor, registry:2), docker save/load |
| 공인 DNS | 내부 DNS 또는 /etc/hosts 관리 |
| Let's Encrypt | 사설 CA + 클라이언트 신뢰 배포 |
| NTP (시간 동기화) | 내부 NTP 서버 — 시간이 틀어지면 TLS 인증서 검증과 JWT 만료 검증이 실패 |
| 외부 CDN 폰트/스크립트 | 모든 정적 리소스 자체 호스팅 |
| STUN/TURN 공용 서버 | 내부 TURN, SFU에 내부 IP 명시 |
| 외부 API(지도, 인증, 모니터링 SaaS) | 내부 대체 또는 기능 제외 |
| 텔레메트리/업데이트 체크 | 비활성화 (타임아웃으로 기동이 느려지는 원인) |
폐쇄망 배포 시 네트워크 체크리스트
- 빌드 산출물에 외부 URL(CDN, 폰트, 분석 스크립트)이 하드코딩되어 있지 않은가?
- 컨테이너 이미지가 기동 시 외부에서 무언가를 다운로드하지 않는가?
- 내부 서버 간 통신에 필요한 방화벽 정책이 모두 반영되었는가? (DB, 스토리지, 인증 서버, 암호화 에이전트 등)
- Docker 브리지 대역이 사내 대역과 충돌하지 않는가?
- 서버 시간이 동기화되어 있는가?
- 인수인계 문서에 포트 목록, 컨테이너 간 의존 관계, 기동 순서, 인증서 위치와 만료일이 기록되어 있는가?
마지막 항목이 없으면, 서버가 재부팅된 날 원래 구성을 역추적하는 데 하루 이상이 걸립니다. docker inspect, ss -tlnp, compose 파일, Nginx 설정을 기반으로 구성을 문서화해 두는 습관이 폐쇄망 운영의 핵심 역량입니다.
더 깊이
- 풀스택 개발자를 위한 CI/CD 11강 — 폐쇄망 환경의 CI/CD: 폐쇄망에서 빌드 산출물과 이미지를 어떻게 들여보내고 배포하는지를 파이프라인 관점에서 다룹니다.
- DevOps 패턴과 안티패턴 특별편 — 폐쇄망에서의 DevOps: 같은 제약을 조직과 운영 프로세스 관점에서 정리한 글입니다.