04. 네트워크와 보안 기초
"접속이 안 된다"는 신고의 원인은 대부분 이 범위 안에 있습니다. 어느 구간에서 끊겼는지 순서대로 좁히는 방법을 정리합니다.
계층으로 나눠 보기
| 계층 | 다루는 것 | 문제가 생기면 |
|---|---|---|
| 애플리케이션 | HTTP, DNS, TLS | 500 응답, 인증서 오류 |
| 전송 | TCP, UDP, 포트 | 연결 거부, 타임아웃 |
| 네트워크 | IP, 라우팅 | 경로 없음, 패킷 유실 |
이름을 외우는 것보다 어느 층에서 끊겼는지 가르는 일이 중요합니다. 포트가 닫혀 있으면 애플리케이션 로그에는 아무것도 남지 않습니다.
TCP와 UDP의 차이는 운영에서 이렇게 드러납니다.
| TCP | UDP | |
|---|---|---|
| 연결 | 수립 후 통신 | 없음 |
| 순서와 재전송 | 보장 | 없음 |
| 쓰는 곳 | HTTP, DB, SSH | DNS, 로그 전송, 실시간 스트림 |
IP와 서브넷
클라우드에서 네트워크를 만들 때 바로 쓰게 됩니다.
10.0.0.0/16 전체 VPC 65,536개 주소
10.0.1.0/24 퍼블릭 서브넷 256개
10.0.10.0/24 프라이빗 서브넷 256개/24는 앞 24비트가 고정이고 나머지 8비트가 호스트 몫이라는 뜻입니다. 숫자가 작을수록 넓은 대역입니다.
사설 대역은 인터넷에서 직접 닿지 않습니다.
10.0.0.0/8 172.16.0.0/12 192.168.0.0/16데이터베이스는 프라이빗 서브넷에 두고, 바깥으로 나가는 통신만 NAT 게이트웨이로 내보냅니다. 들어오는 경로가 없으면 포트 스캔의 대상이 되지 않습니다.
DNS
이름이 주소로 바뀌는 과정에서 생기는 문제가 많습니다.
| 레코드 | 가리키는 것 |
|---|---|
| A / AAAA | IPv4 / IPv6 주소 |
| CNAME | 다른 도메인 이름 |
| TXT | 소유 확인, 메일 설정 같은 문자열 |
| MX | 메일 서버 |
dig api.example.com +short
dig api.example.com @8.8.8.8 # 특정 서버에 직접 물어보기TTL이 캐시 시간입니다. 레코드를 바꿔도 TTL이 지나야 반영됩니다. 서버를 옮기기로 했다면 며칠 전에 TTL을 60초로 줄여 두고 당일에 바꿉니다. 3600초인 상태로 바꾸면 한 시간 동안 일부 사용자만 옛 서버로 갑니다.
HTTPS와 인증서
TLS는 암호화만 하는 것이 아니라 상대가 그 도메인의 주인인지 확인합니다.
# 만료일 확인
echo | openssl s_client -connect api.example.com:443 2>/dev/null \
| openssl x509 -noout -dates운영에서 가장 흔한 장애가 인증서 만료입니다. Let's Encrypt는 90일짜리를 발급하므로 갱신 자동화가 전제입니다.
sudo certbot renew --dry-run갱신이 돌고 있는지까지 감시합니다. cron은 조용히 실패하므로, 만료일을 지표로 내보내고 2주 전에 알림이 오게 둡니다(10. 모니터링과 관측).
중간 인증서가 빠지면 브라우저에서는 열리는데 curl이나 모바일 앱에서만 실패하는 경우가 생깁니다. 브라우저는 누락된 인증서를 알아서 보완하기 때문입니다.
방화벽과 보안 그룹
기본을 차단으로 두고 필요한 것만 엽니다.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 443/tcp
sudo ufw enable클라우드에서는 보안 그룹이 같은 일을 합니다. 규칙의 출발지를 IP 대역이 아니라 다른 보안 그룹으로 지정할 수 있는 점이 유용합니다.
DB 보안 그룹: 5432 포트를 "앱 서버 보안 그룹"에서만 허용서버가 늘고 줄어도 규칙을 고칠 필요가 없습니다.
0.0.0.0/0으로 열어 둔 포트는 정기적으로 점검합니다. 22번과 데이터베이스 포트가 열린 채 방치된 경우가 흔합니다.
진단 순서
바깥에서 안으로 좁혀 갑니다.
# 1. 이름이 풀리는가
dig api.example.com +short
# 2. 그 주소까지 닿는가
ping -c 3 10.0.1.20
# 3. 포트가 열려 있는가
nc -vz 10.0.1.20 443
# 4. 서버에서 프로세스가 그 포트를 듣고 있는가
ss -tlnp | grep 443
# 5. 애플리케이션이 응답하는가
curl -sv https://api.example.com/health| 증상 | 의심할 곳 |
|---|---|
| 이름이 안 풀림 | DNS 레코드, TTL |
| 연결 거부(refused) | 프로세스가 안 떠 있음, 포트 불일치 |
| 타임아웃 | 방화벽·보안 그룹, 라우팅 |
| 인증서 오류 | 만료, 중간 인증서 누락, 도메인 불일치 |
거부와 타임아웃을 구분하는 것이 핵심입니다. 거부는 패킷이 도착했다는 뜻이라 방화벽이 아니라 서버 쪽 문제이고, 타임아웃은 중간에서 막혔다는 신호입니다.
바깥으로 나가는 통신
들어오는 쪽만 보다가 놓치는 부분입니다. 컨테이너가 이미지를 받지 못하거나 외부 API 호출이 실패하는 원인이 됩니다.
- 프라이빗 서브넷에 NAT 게이트웨이가 있는가
- 아웃바운드 규칙이 막혀 있지 않은가
- 프록시를 거쳐야 하는 환경인가 (
HTTP_PROXY,NO_PROXY)
사설망 안끼리는 프록시를 타지 않도록 NO_PROXY에 내부 대역을 넣어 둡니다.