폐쇄망 서버에서 보안 패치가 실패했다는 알림이 왔습니다. 인터넷이 막힌 환경이라 yum update도, 외부 패키지 저장소 접근도 모두 타임아웃됩니다.
네트워크를 무작정 열 수는 없고, 감사 로그가 남는 제한된 통로만 허용해야 합니다. 이때 프록시 서버 설계가 운영과 보안을 동시에 살립니다.
폐쇄망 환경과 프록시 서버 구성
금융, 국방, 의료, 공공기관 시스템을 운영하다 보면 반드시 마주치는 환경이 있습니다. 바로 폐쇄망입니다. 인터넷이 완전히 차단된 서버에서 어떻게 OS 패키지를 업데이트하고, 의존성 라이브러리를 설치할까요? 이 챕터에서는 DMZ 존에 배치된 Squid Proxy를 통해 폐쇄망 서버가 안전하게 외부 패키지 저장소에 접근하는 방법을 배웁니다.
폐쇄망 아키텍처 이해
- 1폐쇄망(Air-Gap Network) 개념을 이해하고 물리적·논리적 망 분리 수준을 비교할 수 있다
- 2인터넷 / DMZ / 내부망으로 이어지는 3단계 망 분리 아키텍처를 구성할 수 있다
- 3DMZ와 Bastion Host의 역할을 이해하고 보안 강화 설정을 적용할 수 있다
- 4Squid Proxy ACL 화이트리스트로 허용 도메인을 제한할 수 있다
- 5폐쇄망 서버에서 apt, pip, yum/dnf의 프록시를 설정할 수 있다
sudo apt-get install squid -ysudo squid -k parsesudo squid -z && sudo systemctl restart squid/etc/apt/apt.conf.d/01proxy — Acquire::http::Proxy 항목 추가
망 분리 아키텍처 — 물리적/논리적 분리와 DMZ
금융권 프로젝트에 투입됐더니 개발 서버에서 apt update가 아예 안 됩니다. 인터넷 연결이 차단된 폐쇄망 환경이기 때문입니다. 패키지 하나 설치하려 해도 프록시 서버를 거쳐야 하고, 어떤 서버는 특정 포트만 열려있습니다. 망 분리 아키텍처의 구조를 이해하지 못하면 이 환경에서 기본 작업조차 막혀서 손도 못 댑니다.
확대
망 분리의 필요성
보안이 중요한 시스템은 인터넷과의 연결을 차단하여 외부 공격 표면을 최소화합니다.
망 분리 수준:
1. 논리적 분리 (소프트웨어 기반)
- VLAN, 방화벽, ACL로 트래픽 제어
- 물리 인프라 공유, 설정 오류 시 데이터 유출 가능
- 구현 비용 낮음
2. 물리적 분리 (Air-Gap)
- 완전히 다른 물리 네트워크 장비 사용
- 케이블 자체가 연결되지 않음
- 최고 수준 보안 (군사, 원자력, 금융 핵심 시스템)
3단계 망 분리 아키텍처
실제 엔터프라이즈 환경에서 흔히 볼 수 있는 구성입니다.
확대
DMZ (비무장 지대)
DMZ(DeMilitarized Zone)는 외부 인터넷과 내부 폐쇄망 사이에 위치한 중간 지대입니다.
DMZ의 역할:
- 외부에서 접근 가능한 서비스 호스팅 (웹, 메일, DNS)
- 내부망과 외부망 사이의 완충 역할
- Squid Proxy를 통한 제한적 인터넷 접근 통로 제공
DMZ 보안 원칙:
외부 방화벽: 인터넷 → DMZ 허용 (필요한 포트만)
내부 방화벽: DMZ → 내부망 차단 (원칙), 특정 트래픽만 허용
Bastion Host
Bastion Host(요새 호스트)는 외부에서 내부망으로의 유일한 SSH 진입점입니다.
접속 경로: 외부 엔지니어 → (SSH 22번) → Bastion Host (DMZ) → (SSH) → 내부 서버 (폐쇄망)
Bastion Host 특징:
- 모든 접근 로그 기록
- MFA 필수 적용
- 최소한의 소프트웨어만 설치
- 강화 OS 설정 (CIS Benchmark)
Squid Proxy — 폐쇄망의 패키지 업데이트 통로
Squid Proxy가 필요한 이유
폐쇄망 서버는 인터넷 직접 연결이 불가능하지만, OS 보안 패치와 패키지 업데이트는 꾸준히 해야 합니다. Squid Proxy는 DMZ에서 제한된 도메인으로만 트래픽을 중계합니다.
확대
Squid Proxy 동작 원리
HTTP 프록시 흐름:
클라이언트 → GET http://archive.ubuntu.com/ubuntu/... HTTP/1.1
Host: archive.ubuntu.com
[Proxy 요청 형식: 전체 URL 포함]
Squid → ACL 검사 → 허용됨
Squid → archive.ubuntu.com에 직접 요청
Squid → 응답 캐시 저장 (선택)
Squid → 클라이언트에 응답 전달
Squid 주요 설정 지시어:
| 지시어 | 역할 | 예시 |
|---|---|---|
http_port | 리스닝 포트 | http_port 3128 |
acl | 접근 제어 목록 정의 | acl allowed_sites dstdomain .ubuntu.com |
http_access | ACL 허용/차단 | http_access allow allowed_sites |
cache_dir | 캐시 저장 위치 | cache_dir ufs /var/spool/squid 10000 16 256 |
Squid 캐시의 장점
패키지 파일을 캐시하면 같은 파일을 여러 서버가 요청할 때 외부 트래픽을 줄일 수 있습니다.
첫 번째 서버의 요청:
서버A → Squid → 인터넷 (package.deb 다운로드) → Squid 캐시 저장
두 번째 서버의 요청:
서버B → Squid → 캐시 히트! → 인터넷 요청 없이 즉시 응답
폐쇄망 서버가 pip install 한 줄로 외부 패키지를 받기까지 — 프록시 대리 요청 6단계
폐쇄망 서버에서 pip install pandas 한 줄. 인터넷이 완전히 막힌 서버인데도 잠시 뒤 Successfully installed pandas가 뜹니다. 이 짧은 사이에 내부 서버 → 프록시 → 외부 미러 세 주체 사이에서 요청 전달 → ACL·인증 확인 → 이름 해석 → 대리 요청 → 캐시·응답 → 내부 전달이 순서대로 일어납니다. 이 흐름을 알면 "왜 timeout이지", "왜 403이지", "왜 503이지"를 각각 다른 단계의 문제로 좁힐 수 있습니다. 폐쇄망에서 패키지가 받아지는 것은 "인터넷이 조금 열려서"가 아니라 아래 6단계의 결과입니다.
[내부 서버] pip install pandas (http_proxy·https_proxy=http://dmz-proxy:3128)
│
① 프록시로 요청 전달 (직접 egress로 안 나가고 절대 URL / CONNECT를 프록시에)
│
② 프록시가 ACL·인증 확인 (허용 도메인 목록 dstdomain · 필요시 프록시 인증)
│
③ 프록시가 목적지 이름 해석 (프록시의 DNS로 files.pythonhosted.org → IP)
│
④ 외부 미러·업스트림에 대리 요청 (프록시가 자신의 egress로 TCP·TLS 연결)
│
⑤ 응답 수신 → 캐시 저장(선택) (최초 TCP_MISS → 캐시 저장 → 재요청 시 TCP_HIT)
│
⑥ 내부 서버로 응답 전달 (프록시 → 내부, 패키지 바이트 도착)
▼
[내부 서버] Successfully installed pandas
각 단계에서 무슨 일이 일어나고, 막히면 어떤 증상인가:
| 단계 | 하는 일 | 여기서 막히면 |
|---|---|---|
| ① 프록시로 요청 | 내부 서버가 직접 나가지 않고 http_proxy·https_proxy가 가리키는 프록시로 보낸다. HTTP는 요청 라인에 절대 URL, HTTPS는 CONNECT host:443 | 프록시 환경변수 누락 → 직접 egress를 시도하다 Connection timed out(폐쇄망은 아웃바운드가 0) / https_proxy만 빠지면 HTTP는 되고 HTTPS만 timeout |
| ② ACL·인증 확인 | 프록시가 요청 도메인이 허용 목록(dstdomain)에 있는지, 인증이 필요하면 자격이 맞는지 검사 | 허용 목록에 없는 도메인 → TCP_DENIED/403(access.log에 DENIED) / 프록시 인증 실패 → 407 Proxy Authentication Required |
| ③ 이름 해석 | 목적지 도메인의 DNS를 프록시가 푼다(내부 서버가 아님) — 그래서 폐쇄망 클라이언트엔 DNS·egress가 0이어도 됨 | 프록시 DNS가 외부를 못 풀거나 split-horizon으로 사내 IP가 잡힘 → NONE/503·HIER_NONE, cache.log에 unable to determine IP address |
| ④ 대리 요청 | 프록시가 자신의 egress로 외부 미러·업스트림에 TCP를 열고, HTTPS면 CONNECT 터널로 TLS 바이트를 그대로 통과시킴(blind 터널) | 외부 방화벽이 프록시의 80·443 아웃바운드를 막음 → 프록시에서 목적지로 timeout / CONNECT 대상 포트 ACL 누락 → 403 after CONNECT |
| ⑤ 캐시·응답 | 응답을 받아 캐시 대상이면 저장(최초 TCP_MISS, 이후 TCP_HIT)하고 클라이언트로 넘길 준비를 함 | 캐시 오염·용량 부족 → 깨진 바이너리 반복 수신, 적중률 저하(squid -z로 캐시 재생성) |
| ⑥ 내부로 전달 | 프록시가 받은 바이트를 요청한 내부 서버로 되돌려준다 | 내부 방화벽이 내부↔프록시 3128을 막음 → 내부 서버에서 프록시 자체에 timeout(②까지도 못 감) |
즉 "폐쇄망에서 패키지가 받아졌다"는 세 주체가 각자 역할을 다했다는 뜻입니다 — 내부 서버가 프록시로 보냈고(①), 프록시가 허용·이름해석을 통과했고(②③), 프록시의 egress가 외부에 닿았습니다(④). 막힐 때는 access.log의 결과 코드로 층을 가르는 것이 진단의 핵심입니다 — 403은 ACL(②), 503·HIER_NONE은 이름 해석(③), timeout은 egress(④)나 프록시 미설정(①)입니다. 그래서 이름 해석·egress 문제는 클라이언트가 아니라 프록시에서 getent hosts·curl로 확인해야 합니다.
폐쇄망 환경에서 프록시 설정이 제대로 동작하는지 단계별로 검증합니다.
# 1단계: 직접 연결 차단 확인 (폐쇄망 서버에서)
curl -v --connect-timeout 5 https://pypi.org/
# curl: (28) Connection timed out after 5000 milliseconds
# → 직접 연결 불가 확인
# 2단계: 프록시 경유 연결 시도
curl -v https://pypi.org/ --proxy http://dmz-proxy:3128
# * Connected to dmz-proxy (10.0.1.10) port 3128
# * CONNECT pypi.org:443 HTTP/1.1
# * Proxy replied 200 to CONNECT request
# → 프록시 경유 성공
# 3단계: 환경 변수로 프록시 설정 후 apt 동작 확인
export http_proxy="http://dmz-proxy:3128"
export https_proxy="http://dmz-proxy:3128"
apt-get update -y
# 4단계: Squid 로그에서 요청 흔적 확인 (프록시 서버에서)
sudo tail -20 /var/log/squid/access.log
# 1711504800.123 125 10.0.0.20 TCP_MISS/200 12345 GET http://archive.ubuntu.com/...
curl -v https://pypi.org/ --proxy http://localhost:3128- curl --proxy 로 pypi.org에 접근할 때 CONNECT 메서드가 사용되는지 확인 (HTTPS 터널링)
- Squid access.log에서 TCP_MISS(최초 요청)와 TCP_HIT(캐시 재사용) 차이 확인
- 같은 패키지 파일을 두 번 요청했을 때 두 번째 요청이 더 빠른지 (Squid 캐시 효과)
- http_proxy 설정 없이 curl 하면 타임아웃이 나는지 확인 (폐쇄망 격리 검증)
- squid -k parse 명령이 에러 없이 통과하는지 확인 (설정 문법 오류 없음)
트러블슈팅
폐쇄망 프록시 환경에서의 인증 및 캐시 만료 장애 극복
보안 통제를 위해 폐쇄망에서 Squid 프록시를 통해 외부 오픈소스 레포지토리에 연결할 때, 다운로드 타임아웃이나 인증 실패 장애가 다발합니다.
환경 변수 상속 및 확인: 리눅스 셸 세션에서 curl이나 apt 패키지 매니저가 프록시를 타도록 http_proxy 및 https_proxy 환경 변수를 정상 주입했는지 점검합니다.
# 실습 디렉토리 준비
mkdir -p /tmp/networking/part6/exam_29 && cd /tmp/networking/part6/exam_29
$ export http_proxy="http://192.168.1.100:3128"
프록시 캐시 풀 강제 Prune: 캐시 오염으로 인해 계속 깨진 바이너리가 받아진다면 Squid 서버 데몬의 캐시 디렉토리를 완전히 비워주거나 재기동하여 캐시 풀을 정화시킵니다.
증상
폐쇄망 서버에서 pip install 실행 시 일부 패키지만 설치되고 의존성 패키지 설치가 실패합니다.
pip install pandas
# Collecting pandas
# Downloading pandas-2.0.0.tar.gz ...
# Collecting numpy>=1.21 (from pandas)
# ERROR: Could not find a version that satisfies the requirement numpy
# ERROR: No matching distribution found for numpy
curl로 직접 확인:
curl -v http://files.pythonhosted.org/packages/numpy-1.24.tar.gz \
--proxy http://dmz-proxy:3128
# [Response] HTTP/1.1 403 Forbidden
# [Response] X-Squid-Error: ERR_ACCESS_DENIED 0
원인 진단
# Squid 프록시 서버에서 access.log 확인
sudo tail -100 /var/log/squid/access.log | grep DENIED
# 출력 예시:
# 1711504800.123 125 10.0.0.20 TCP_DENIED/403 4567 GET
# http://files.pythonhosted.org/... - HIER_NONE/- text/html
# files.pythonhosted.org가 ACL에 없음을 확인
grep pythonhosted /etc/squid/squid.conf
# (아무것도 안 나옴 = ACL 미등록)
해결
이 명령은 실행 중인 서비스 상태를 바꿔 순간적인 중단이나 설정 반영 실패를 만들 수 있습니다. 운영 트래픽 영향과 재시작 후 확인 명령을 먼저 준비하세요.
# Squid 설정에 누락된 도메인 추가
sudo vi /etc/squid/squid.conf
# 기존 pypi ACL 라인 찾아서 추가:
# acl pypi_repos dstdomain pypi.org
# acl pypi_repos dstdomain files.pythonhosted.org ← 이 줄 추가
# 설정 문법 검사
sudo squid -k parse
# 설정 재로드 (무중단)
sudo squid -k reconfigure
# 또는 재시작
sudo systemctl restart squid
체계적인 도메인 파악 방법:
# 설치 시도 후 Squid 로그에서 차단된 도메인 수집
sudo tail -f /var/log/squid/access.log | grep DENIED
# 또는 인터넷 연결된 환경에서 먼저 테스트하여 필요한 도메인 파악
# strace나 wireshark로 DNS 쿼리 캡처
예방 — 도메인 파악 사전 작업
# 인터넷 연결 환경에서 pip이 접근하는 도메인 파악
pip install pandas --dry-run -v 2>&1 | grep "Downloading\|http"
# curl로 실제 연결 도메인 확인 (DNS 쿼리 포함)
strace -e trace=network pip install pandas 2>&1 | grep connect
증상
HTTP는 잘 되는데 HTTPS 요청이 실패합니다.
curl http://archive.ubuntu.com/ --proxy http://dmz-proxy:3128
# 200 OK → 성공
curl https://pypi.org/ --proxy http://dmz-proxy:3128
# curl: (56) Received HTTP code 403 from proxy after CONNECT
원인
HTTPS 트래픽은 HTTP CONNECT 터널링 방식으로 프록시를 통과합니다. Squid에서 CONNECT 메서드와 443 포트를 허용해야 합니다.
HTTPS 프록시 흐름:
클라이언트 → CONNECT pypi.org:443 HTTP/1.1 (프록시에게 터널 요청)
Squid → CONNECT ACL 검사
Squid → pypi.org:443 TCP 연결 수립
Squid → "HTTP/1.1 200 Connection established" 응답
클라이언트 ↔ pypi.org (TLS 핸드셰이크, Squid는 투명하게 중계)
해결
# /etc/squid/squid.conf 확인 및 수정
# 올바른 CONNECT 설정이 있는지 확인
grep -A5 "CONNECT" /etc/squid/squid.conf
# 필요한 설정:
# acl CONNECT method CONNECT
# acl ssl_ports port 443
# http_access deny CONNECT !ssl_ports ← 443 외 CONNECT 차단
# http_access allow internal_nets pypi_repos ← 이후 허용 규칙
# 또한 CONNECT 허용 규칙이 명시적으로 있어야 함
# squid.conf에 추가:
# http_access allow CONNECT internal_nets pypi_repos
sudo squid -k reconfigure
SSL Bump (선택 사항 — 기업 환경에서 HTTPS 검사):
# Squid에서 HTTPS 내용을 검사하려면 SSL Bump 설정 필요
# (별도 인증서 설치 및 클라이언트 신뢰 설정 필요)
# 이는 고급 설정으로, 일반적인 패키지 업데이트용에는 불필요
심화 — 프록시가 대신 푸는 이름, 그리고 규칙의 순서
심화: 프록시가 요청을 처리하는 내부 — 이름 해석과 규칙 평가
DNS도 기본 라우팅도 없는 폐쇄망 서버에 프록시 한 줄만 꽂으면 외부가 뚫립니다. 이 "마법"의 정체를 알아야 장애 당일에 엉뚱한 곳을 뒤지지 않습니다.
- 클라이언트가 넘기는 것은 이름입니다: HTTP는 요청 라인에 절대 URL(
GET http://host/path)을, HTTPS는CONNECT host:443을 그대로 보냅니다. 둘 다 IP가 아니라 도메인 이름입니다. - 해석과 연결은 프록시 몫: Squid가 그 이름을 DNS로 풀고, 목적지로 TCP를 열고, HTTPS면 TLS는 건드리지 않은 채 바이트만 왕복시키는 blind 터널이 됩니다. 그래서 클라이언트엔 DNS·egress가 0이어도 되고, 대신 DMZ 프록시가 DNS와 아웃바운드를 갖춰야 합니다.
- split-horizon DNS 엣지: 프록시가 사내 DNS를 바라보면 외부 도메인이 내부 IP로 잡혀 엉뚱한 곳에 연결될 수 있습니다. "허용했는데 안 된다"의 상당수는 ACL이 아니라 이 이름 해석 문제입니다.
- http_access는 첫 일치에서 끝납니다: 규칙은 위에서 아래로 평가되고 처음 매칭되는 줄에서 판정이 확정됩니다. 새 allow 규칙을 파일 맨 아래(
http_access deny all뒤)에 붙이면 앞의 deny all이 먼저 잡아 영영 열리지 않습니다. ACL은 membership이 아니라 순서로 동작합니다. - HTTPS 터널의 한계: SSL Bump 없이는 Squid가 CONNECT의 host만 볼 뿐 SNI·URL·본문은 못 봅니다. dstdomain ACL도 CONNECT의 host를 기준으로만 걸립니다.
상황: 신규 저장소 도메인을 allowlist에 넣고 squid -k reconfigure까지 마쳤는데 클라이언트는 여전히 실패합니다. 그런데 이번엔 즉시 403이 아니라, 한참 뜸을 들이다 503으로 떨어집니다.
원인: 문제는 ACL이 아니라 이름 해석입니다. 포워드 프록시에서 목적지 DNS는 프록시가 풉니다. DMZ의 Squid가 바라보는 resolv.conf의 DNS가 외부를 못 풀거나, split-horizon 내부 DNS라 그 도메인이 사내 IP로 잡히면, 허용된 도메인이어도 연결할 IP를 정하지 못해 실패합니다.
진단: access.log의 결과 코드로 층을 가릅니다 — TCP_DENIED/403이면 ACL, NONE/503에 HIER_NONE이면 이름 해석·포워딩 실패입니다. cache.log에서 unable to determine IP address 류의 로그를 확인하고, 반드시 프록시 서버에서 직접 nslookup 또는 getent hosts로 그 도메인이 무엇으로 해석되는지 봅니다. 클라이언트가 아니라 프록시에서 확인하는 것이 핵심입니다.
해결: 프록시의 resolv.conf에 외부를 풀 수 있는 포워더(또는 사내 정식 DNS)를 지정하고, split-horizon 환경이면 외부 조회용 조건부 포워더/뷰를 씁니다. 급하면 프록시의 /etc/hosts에 목적지를 임시로 박아 이름 해석만 분리해 검증합니다. 근본 해결은 프록시가 목적지를 정상 해석하도록 DNS 경로를 바로잡는 것이라, 클라이언트를 아무리 손봐도 열리지 않습니다(wget/curl로 외부 연동 방화벽 차단 여부 판별법).
실무 맥락
폐쇄망 환경의 현실
금융권, 공공기관, 국방 분야에서는 망 분리가 법적으로 의무화되어 있습니다.
금융권 망 분리 규정:
- 전자금융감독규정: 인터넷망과 업무망 분리 의무
- 개인정보 처리 시스템: 인터넷망 차단 필수
공공기관:
- 국가사이버안전관리규정: 1·2등급 정보는 인터넷망 완전 분리
패키지 배포 대안 전략
Squid Proxy 외에도 폐쇄망에서 패키지를 관리하는 다양한 방법이 있습니다.
# 방법 1: 내부 미러 서버 구축
# apt-mirror로 Ubuntu 저장소 전체를 내부 서버에 복제
sudo apt-get install apt-mirror
# /etc/apt/mirror.list 설정 후 apt-mirror 실행 (수백 GB)
# 방법 2: 오프라인 패키지 번들
# 인터넷 환경에서 패키지 다운로드
apt-get download package1 package2 package3
# USB/CD로 폐쇄망 반입 후 설치
sudo dpkg -i *.deb
# 방법 3: Nexus Repository Manager (엔터프라이즈)
# Maven, npm, PyPI, Docker 등 다양한 패키지 타입을 내부 프록시로 관리
# https://www.sonatype.com/nexus-repository-oss
# 방법 4: JFrog Artifactory (클라우드/온프레미스)
# 유사한 기능, 엔터프라이즈 라이선스
Bastion Host 운영 실무
이 명령은 실행 중인 서비스 상태를 바꿔 순간적인 중단이나 설정 반영 실패를 만들 수 있습니다. 운영 트래픽 영향과 재시작 후 확인 명령을 먼저 준비하세요.
# Bastion Host 강화 설정 예시
# 먼저 현재 SSH 세션과 콘솔/OOB 접속을 확보하고 설정을 백업합니다.
sudo cp -a /etc/ssh/sshd_config "/etc/ssh/sshd_config.bak.$(date +%Y%m%d%H%M%S)"
sudoedit /etc/ssh/sshd_config
# sudoedit 안에서 기존 항목을 중복 추가하지 말고 다음 값을 검토·수정합니다.
# PermitRootLogin no
# PasswordAuthentication no
# 3. 모든 SSH 세션 기록 (감사 로그)
# /etc/bashrc 에 추가:
# export HISTTIMEFORMAT="%F %T "
# export PROMPT_COMMAND='history -a'
# readonly HISTFILE
# 4. 접속 허용 IP 제한
# AllowUsers engineer@203.0.113.0/24
# 5. MFA 설정 (Google Authenticator)
sudo apt-get install libpam-google-authenticator
# /etc/pam.d/sshd 에:
# auth required pam_google_authenticator.so
# 6. 세션 타임아웃
# ClientAliveInterval 300
# ClientAliveCountMax 2
# 문법 검사에 실패하면 reload하지 않습니다. 기존 세션을 유지한 채 결과를 확인하세요.
sudo sshd -t
sudo systemctl reload sshd
sudo systemctl is-active --quiet sshd && echo "sshd active"
망 분리 환경 구축 시 체크리스트
사전 계획:
□ 허용해야 할 도메인/서비스 목록 작성 (최소화 원칙)
□ 내부 서버의 OS/언어 스택 확인 (apt/yum/pip/npm 등)
□ DMZ 서버 IP 대역 및 방화벽 정책 확정
□ Bastion Host HA 구성 여부 결정
구축 단계:
□ DMZ에 Squid Proxy 설치 및 ACL 설정
□ 내부 방화벽: 폐쇄망 → DMZ 3128 포트만 허용
□ 외부 방화벽: DMZ → 인터넷 80/443 허용
□ 폐쇄망 서버에 프록시 환경 변수 배포
운영 단계:
□ Squid 접근 로그 주기적 검토
□ 허용 도메인 목록 정기 검토 (분기별)
□ 불필요한 도메인 제거
□ 캐시 용량 모니터링
□ 보안 패치 적용 프로세스 문서화
정리
폐쇄망 아키텍처
- 물리적 분리: 케이블 자체 분리 (최고 보안)
- 논리적 분리: VLAN, 방화벽 (실용적)
- DMZ: 외부망-내부망 사이 완충 구역
- Bastion Host: 유일한 SSH 진입점
Squid Proxy 핵심
- ACL (acl 지시어): 허용/차단 기준 정의
- http_access: ACL 기반 허용/거부 규칙 (순서 중요!)
- 기본 거부: http_access deny all 마지막에 추가
- 캐시: 자주 요청되는 파일 로컬 저장 (대역폭 절감)
폐쇄망 서버 프록시 설정
- 환경 변수: export http_proxy=http://dmz-proxy:3128
- apt: /etc/apt/apt.conf.d/01proxy
- pip: ~/.config/pip/pip.conf
- yum/dnf: /etc/yum.conf 또는 /etc/dnf/dnf.conf
트러블슈팅
- 403 Forbidden → ACL에 도메인 추가 필요 (Squid access.log에서 차단된 도메인 확인)
- HTTPS 실패 → CONNECT 메서드 및 ssl_ports ACL 확인
명령어·단축키 빠른 참조
이 모듈에서 다룬 폐쇄망 프록시 구성·진단 명령을 실전 옵션과 함께 모았습니다. "예" 열의 조합을 그대로 써도 됩니다.
| 명령어/단축키 | 용도 | 자주 쓰는 예 |
|---|---|---|
curl --proxy | 프록시 경유 연결 테스트 | curl -v https://pypi.org/ --proxy http://dmz-proxy:3128 |
curl --connect-timeout | 직접 연결 차단(폐쇄망 격리) 확인 | curl -v --connect-timeout 5 https://pypi.org/ (타임아웃=격리 정상) |
export http_proxy / https_proxy | 셸에 프록시 주입(HTTP·HTTPS 별도) | export https_proxy=http://dmz-proxy:3128 |
squid -k parse | squid.conf 문법 검사 | 재시작 전 항상 — 에러 없이 통과해야 |
squid -k reconfigure | 무중단 설정 재로드 | ACL 추가 후 sudo squid -k reconfigure |
squid -z | 캐시 디렉토리 초기화 | sudo squid -z && sudo systemctl restart squid |
tail .../squid/access.log | 프록시 요청·차단 감사 | tail -f /var/log/squid/access.log | grep DENIED |
grep <도메인> squid.conf | ACL에 도메인 등록됐는지 확인 | grep pythonhosted /etc/squid/squid.conf |
getent hosts (프록시에서) | 목적지 이름 해석 주체 확인 | 프록시에서 getent hosts pypi.org (NONE/503 진단) |
| apt 프록시 파일 | apt가 프록시 경유하게 | /etc/apt/apt.conf.d/01proxy 에 Acquire::http::Proxy |
strace -e trace=network | pip 접근 도메인 사전 파악 | strace -e trace=network pip install pandas 2>&1 | grep connect |
관련 모듈로 더 깊이:
- 방화벽 정책 설계와 접근 제어 리스트(ACL) 구성 실무 — Squid의 ACL 사고방식이 그대로 적용되는 방화벽 정책 설계
- wget/curl로 외부 연동 방화벽 차단 여부 판별법 — 폐쇄망에서 막힌 아웃바운드 경로를 점검하는 법
- HTTPS/TLS 작동 원리와 curl SSL 에러 장애 디버깅 — 프록시 HTTPS(CONNECT) 실패를 이해하기 위한 TLS 기본기
다음 챕터에서는 DNS 질의 실패와 /etc/resolv.conf 설정을 학습하여, "IP ping은 되는데 도메인 ping이 안 되는" 문제를 즉시 해결하는 방법을 배웁니다.