안녕하세요. TAK 입니다:)
이번 포스팅은 Squid Forward Proxy(프록시) 서버 구축을 목표로 합니다.🤞
Squid Forward Proxy(프록시) 서버 구축을 통해 어떻게 동작되는지, 어떻게 활용되는지 확인해 보겠습니다!
현 구축 실습은 "#01 Proxy(프록시) 서버란?" 포스팅과 이어지기에 이해하시는데 도움이 될 거예요!
Contents
1. Forward Proxy
구성에 앞서 다시 한번 설명하자면, Forward Proxy는 클라이언트와 인터넷 사이에 위치하여 클라이언트의 요청을 대신 처리해 주는 서버입니다.
그림에서는 use's device가 클라이언트입니다.
또한, 해당 클라이언트는 내부 네트워크에 위치하며, Proxy Server는 내부 혹은 DMZ 네트워크에 위치합니다.
클라이언트가 Forward Proxy에 요청을 보내면, Proxy 서버가 이를 인터넷으로 전달하고, 응답을 받아 클라이언트에게 반환합니다.
이를 통해 클라이언트의 IP 주소를 숨기거나, 콘텐츠 필터링, 캐싱, 보안 등을 제공할 수 있습니다.
1-1. Squid Proxy란?
실제 구축 실습은 Squid Proxy라는 오픈소스 Proxy를 사용합니다.
Squid Proxy 는 일반적인 개념 설명을 기준으로는 Cache & Web Proxy Server에 가깝지만, 일반적인 Proxy Server 가 가지는 특성을 가지고 있으며 클라이언트의 요청을 전달(Forward)하는 Forward Proxy와 같은 방향성을 가집니다.
주로 HTTP와 HTTPS 트래픽을 처리하며, 캐싱을 통해 네트워크 성능을 향상시키고, 네트워크 대역폭을 절약하는 데 도움을 줍니다. Squid는 또한 웹 필터링, 액세스 제어, 로깅 등의 기능을 제공합니다.
nginx, apache 등과 달리 Squid의 경우, Proxy로 사용하기 위한 별도의 설정 없이 자체가 Proxy를 위한 오픈소스이기 구축이 쉽고, 패키지 형태로 설치 가능하기에 Config 설정만 구성한다면 변경 등 관리적 측면에서 비교적 수월할 수 있습니다.
그 외 장점은 다음과 같습니다.
- 고급 캐싱 기능: HTTP, HTTPS, FTP 등 다양한 프로토콜을 지원하며, 매우 세밀한 캐싱 제어를 제공합니다.
- 네트워크 최적화: 대역폭 절약과 응답 시간 단축을 위해 고도로 최적화되어 있습니다.
- 액세스 제어 및 필터링: 강력한 ACL(Access Control List)을 통해 상세한 접근 제어와 웹 필터링을 할 수 있습니다.
- 로깅 및 모니터링: 상세한 로그와 모니터링 기능을 제공합니다.
1-2. 구성도
이번 Forward Proxy 실습은 Azure 환경에서 진행합니다.
위 그림과 같이 [내부 내부네트워크] 표시가 있는 클라이언트에서 Server X, Y에게 요청을 할 때,
10.11.0.0/24 대역에 배포된 Squid Proxy 를 통해서 요청이 전달될 수 있도록 하는 구성(중계 요청)으로 진행하겠습니다.
구성도에 대한 상세 사항은 다음과 같습니다.
- VM 정보(상세 Spec은 테스트이기에 가장 저렴하게 맞추시면 됩니다.)
- Client A : Windows 10, Client B : Windows Server 2019
- Forward Proxy(Squid) : Linux(Ubuntu 24.04)
- Server X, Server Y : Linux(Rocky 9)
- [내부 네트워크]라고 함은 "인증 및 인가되지 않은 액세스는 불가하며, 외부 통신을 제한한다"라는 가정이 전제됩니다.
- Forward Proxy는 DMZ 구간으로 배포된 서버이며, 내/외부 네트워크 중간에 위치하여 제약 사항이 존재합니다.
1-3. 네트워크 구성
내부 네트워크와 Proxy Server 가 배포된 네트워크의 대역이 다릅니다.
이는 두 네트워크 내 배포된 서버 간 통신을 위해서 추가 작업이 필요하다는 의미입니다.
예를 들어, 다음과 같은 방법이 있습니다.
- 경로 테이블(UDR) 생성하여 Client 단의 트래픽을 Proxy Server 로 통하게 전파하는 방식으로 라우팅을 설정
- NSG(Network Security Group) 혹은 방화벽을 통한 접근 제어 방식
- VNET 간 Peering 을 구성하여 네트워크 연결
- VPN, 기타 등등
이 중 VNET 간 Peering 을 통해 사설 네트워크 간 통신 가능하도록 구성하고, ACL 역할을 하는 NSG(Network Security Group) 규칙을 통해 IP, Port 에 대해 보다 상세히 제어해 보도록 하겠습니다.
NSG의 기본 규칙 중 "가상 네트워크 간 통신은 모두 허용한다" 라는 것이 있습니다.
다만, NSG 는 우선순위 기반이기에 그 보다 더 높은 우선순위를 부여하여 출발지와 목적지를 특정할 수 있습니다.
1-3. Squid Proxy 구축
1-3-1. Squid Proxy 설치
- apt 패키지 방식으로 설치 및 서비스 상태 확인
sudo apt update && sudo apt install squid
1-4. Squid Proxy 구성
- config 파일 확인
sudo nano /etc/squid/squid.conf
Squid 가 리스닝 하는 Default 포트 정보 확인
well-known 포트이기에 실제 사용 목적이라면 변경합니다. 해당 실습에서는 기본 포트 사용합니다.
1-4-1. 인증
Squid Proxy Server에 Samab, LDAP 등 여러 가지 인증을 구성하는 방법이 있습니다.
가장 일반적인 방법 중 하나는 HTTP 기본 인증(Basic Authentication)을 사용하는 것입니다. 이를 위해서 "htpasswd" 유틸리티를 사용하여 사용자 계정을 생성합니다.
말 그대로 HTTP 기본 인증(Basic Authentication)은 서버에 액세스 할 수 있는 사용자를 식별하는 데 사용되며, 서버 보호에 이점이 있습니다.
하지만 전송되는 데이터의 경우, 암호화되지 않은 상태로 전달하기에 보안 상 취약합니다.
그래서!!
HTTPS를 통해 Squid와 클라이언트 간의 트래픽을 암호화하는 것이 좋기에...
이왕 하는 거 조금 더 번거롭지만? OpenSSL을 사용해서 자체 서명 인증서를 생성하여 TLS/SSL 인증서를 Squid Proxy 에 사용할 수 있도록 해보겠습니다!!
- 사용자 계정 생성
- 이후, 암호 생성 요청에 따라 신규 암호 생성
sudo apt-get install apache2-utils
sudo htpasswd -c /etc/squid/passwords <account_name>
- 인증서 및 키 생성
인증서와 키를 저장할 디렉터리 생성(.conf 파일과 동일한 경로)
sudo mkdir -p /etc/squid/ssl_cert
OpenSSL 사용해서 인증서와 키를 생성
원래는 key와 crt를 각각 생성하여 구분하는 것이 좋습니다만...
sudo openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout /etc/squid/ssl_cert/<CA_name>.pem -out /etc/squid/ssl_cert/<CA_name>.pem
생성 시, 국가 이름, 조직 이름 등과 같은 여러 가지 정보를 입력하게 되는데, 테스트이기에 임의로 하시면 됩니다.
- 인증서 및 키 생성 확인
1-4-2. ACL 및 인증 구성 적용
sudo nano /etc/squid/squid.conf
우선 용이한 작업을 위해 conf 파일을 복사하여 백업본을 생성한 후, 진행하겠습니다.
(.conf 파일을 들여다보면 주석 처리된 내용이 많기에, 수정하는데 번거로울 수 있습니다.)
주석 삭제 및 줄 공백 삭제 명령어
sudo sed -i '/^#/ d' /etc/squid/squid.conf
sudo sed -i '/^$/ d' /etc/squid/squid.conf
간략해진 .conf 파일을 보면 마음이 안정이 되는데요..
사실 Squid에서 요점은 간단합니다.
기본적으로 Deny 정책을 가져가되, localhost 의 액세스는 허용하고
특정 조건에 따라 적용될 ACL에 반영할 값을 정의 후, 접근 규칙에 반영 구조입니다.
요건은 다음과 같습니다.
- 내부 클라이언트에서 naver.com 접근 시 차단 / 그 외 허용
- 내부 클라이언트에서 외부 서버(4.217.253.107)에 80,443 접근 시 허용 / 그 외 IP 및 포트 접근 시 차단
따라서, 이번 실습에서 추가 및 변경할 부분은 다음과 같습니다. (이외 항목은 기본값 유지)
- 정의 규칙
- ACL 포트 정의 규칙
- ACL 특정 출발지 및 목적지 네트워크 & 도메인 정의 규칙
- 접근 제어 규칙
- 도메인 허용/차단 규칙
- 내부 네트워크에서 목적지 서버로의 접근 규칙
- 인증
- HTTPS 포트 설정
- 기본 인증(Basic Authentication)
- 인증된 사용자 ACL
위 사항들이 반영된 .conf 파일은 다음과 같습니다.
# ACL 요청을 필터링하는 데 사용되는 규칙
# 로컬 네트워크 범위 정의(Default 유지)
acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN)
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
# ACL 포트 정의 규칙(불필요한 포트 정보 삭제)
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 443 # https
# ACL 특정 출발지 및 목적지 네트워크 & 도메인 정의 규칙
acl internal_network src 172.16.10.0/24
acl destination_network dst 4.217.253.107
acl naver dstdomain .naver.com
# 접근 제어 규칙
# ACL을 기반으로 특정 요청을 허용 혹은 거부
# 포트 허용 규칙(안전하지 않은 포트와 관리 인터페이스에 대한 접근을 제어)
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localhost
http_access deny to_localhost
http_access deny to_linklocal
# 도메인 허용/차단 규칙(google, naver)
http_access deny naver
http_access allow !naver
# 내부 네트워크에서 목적지 서버로의 접근 규칙
http_access allow internal_network destination_network
http_access deny internal_network destination_network !Safe_ports
# 추가 설정 파일을 포함(Default 유지)
include /etc/squid/conf.d/*.conf
# 기본적으로 모든 접근을 차단
http_access deny all
# http 포트 정의(Default 유지)
http_port 3128
# https 포트 정의(인정서와 키 파일)
https_port 3129 tls-cert=/etc/squid/ssl_cert/<CA_name>.pem tls-key=/etc/squid/ssl_cert/<CA_name>.pem
# 기본 인증(Basic Authentication)
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwords
auth_param basic children 5
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours
auth_param basic casesensitive on
# 인증된 사용자 ACL
acl authenticated proxy_auth REQUIRED
http_access allow authenticated
# 코어 덤프를 저장할 디렉터리 지정(Default 유지)
coredump_dir /var/spool/squid
# 다양한 유형의 캐싱 정책 설정(Default 유지)
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern \/(Packages|Sources)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
refresh_pattern \/Release(|\.gpg)$ 0 0% 0 refresh-ims
refresh_pattern \/InRelease$ 0 0% 0 refresh-ims
refresh_pattern \/(Translation-.*)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
refresh_pattern . 0 20% 4320
1-5. Client 구성
- Client는 Windows 10로 브라우저(Firefox) 단에서 프록시 설정을 진행해 보겠습니다.
- 검색바에서 프록시 검색
- [수동 프록시 설정] 에서 Squid Proxy Server의 IP와 기본 포트(HTTP) 3128 그리고 HTTPS 옵션도 함께 선택
- 클라이언트에서 아운바운드 IP 확인
- IP를 확인해 보면, Squid Proxy Server 의 공용 IP가 확인됨.
1-6. Proxy 테스트
이제 클라이언트 단에서 Squid Proxy Server 테스트를 진행해 보겠습니다.
1-6-1. 도메인 제어 테스트
- naver.com 액세스 시도 > 차단
- Squid Proxy 의 (/var/log/squid/)access.log 확인 시, 403 응답 확인
- with-cloud.tistory.com 연결 시도 > 허용
- Squid Proxy 의 (/var/log/squid/)access.log 확인 시, 200 응답 확인
1-6-2. 목적지 IP 및 포트 제어 테스트
클라이언트 단에서 요청 시, 프록시가 중계 역할을 하기 때문에 Squid Proxy Server 의 IP와 Port를 지정하여, 외부 서버에 연결된 Azure NSG 규칙을 추가하여 액세스를 제한합니다.
- 목적지인 외부 서버와 80으로 서비스 중인 Nginx 액세스 시도 > 허용
- access.log에 확인되는 응답 결과는 TCP_MISS/200인데, 이는 캐시에 저장된 정보가 없어 원격 서버로부터 데이터를 가져왔으며, 성공적으로 요청에 대해 응답했음을 의미합니다.
응답 코드 304의 경우, 서버에게 동일한 요청을 보낼 때 별다른 문제나 변화가 없으면 확인될 수 있으며 이는 변경 사항이 없으므로 캐시 되어 있는 자원으로 리디렉션 하겠다는 의미를 갖습니다.
- 목적지인 외부 서버와 8080으로 서비스 중인 Tomcat 액세스 시도 > 차단
- Squid Proxy Server에서 요청에 대한 거절의 메시지 내용이 있는 HTML 파일을 보여줌.
- access.log 에서 해당 요청에 대한 응답 코드로 403을 반환
이상으로 "#02 Squid Forward Proxy(프록시) 서버 구축" 포스팅을 마치겠습니다!
원래 해당 포스팅에서 Reverse Proxy에 대한 실습 내용도 함께 작성하려고 했는데, 개인적인 이유로 시간적 여유가 부족해 별로 작성할 예정입니다. (양해를 바라며...)
그럼 빠른 시일 내 Reverse Proxy 실습으로 다시 찾아오겠습니다!
함께 해주셔서 감사합니다🫶
'TOPIC > Infra' 카테고리의 다른 글
#03 Nginx Reverse Proxy(프록시) 서버 구축 (3) | 2024.10.04 |
---|---|
#2 Docker 그리고 Docker Network (0) | 2024.06.24 |
#1 Docker 그리고 Docker Network (0) | 2024.05.29 |
Encrypting Secret Data at Rest in ETCD (0) | 2024.03.12 |
Virtual Machine으로 Kubernetes Cluster 구성하기 (2) (0) | 2024.03.11 |