금백조의 개발 블로그

[Nginx]Nginx로 리버스 프록시 구성하여 X-Forwarded-For 헤더를 읽어 클라이언트 ip 얻기 본문

Web/Proxy

[Nginx]Nginx로 리버스 프록시 구성하여 X-Forwarded-For 헤더를 읽어 클라이언트 ip 얻기

금백조 2023. 8. 26. 15:11
반응형

서론

 

Docker 웹서버 환경에서 클라이언트 ip를 얻으려는 중에 이슈가 발생했습니다. Docker 내부에서 클라이언트 ip를 얻으려해도 도커 내부에 설정된 ip가 반환이 되었습니다. 이를 해결하기 위해 리버스 프록시를 구성하여 프록시를 통해 클라이언트 ip를 가져와서 해결했습니다. 실제로 저는 웹서버에서 프록시 ip를 얻는 업무만 수행했지만 리버스 프록시를 예제로 구성하여 해보고 싶은 마음에 해당 포스팅을 준비하게 되었습니다.

 

아래 예제는 다음과 같은 상황을 가정합니다.

 

가정

nginx 를 이용해 리버스 프록시 구성

windows wsl linux (윈도우 리눅스 서브 시스템)에 nginx 설치

https 인증서는 있다고 가정 (예제 설명엔 abcde.pfx 로 되어있음.)

웹서버는 .NET Core라고 가정

 

본론

 

1.CMD 관리자 권한 실행

2.윈도우에서 linux에다 nginx 설치를 위해 wsl 설치

wsl --install

3.ubuntu 20.04 설치

wsl --install -d Ubuntu-20.04

실행된 ubuntu 가상머신에서 아래 명령어 순차적으로 실행

4.apt 최신화

sudo apt update

5.nginx 설치

sudo apt install nginx

6./etc/nginx 경로에 있는 nginx.conf 파일 수정 (sudo 권한으로 실행)

cd /etc/ginx
sudo vi nginx.conf

7.nginx.conf에 아래 설정 추가하여 저장 (ssl 설정, 리버스 프록시 설정, X-Forwarded-For 설정)

http {
     server {
                listen 443 ssl;
                server_name localhost;  # 도메인 또는 서버 IP 주소
                    ssl_certificate /etc/nginx/abcde.pem;  # SSL 인증서 파일 경로
                    ssl_certificate_key /etc/nginx/abcde.pem;  # 개인 키 파일 경로
                location / {
                    proxy_pass <https://localhost:12345>;  # 웹 애플리케이션의 주소와 포트
                    proxy_http_version 1.1;
                    proxy_set_header Upgrade $http_upgrade;
                    proxy_set_header Connection keep-alive;
                    proxy_set_header Host $host;
                    proxy_cache_bypass $http_upgrade;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # X-Forwarded-For 헤더 설정
                }
        }
}

사용하던 .pfx 확장자 인증서 파일이 있다면 openssl을 통해 .pem 확장자 파일로 변환해줘야 한다.

8.openssl 설치

sudo apt install openssl

9.윈도우 /d/cert 경로에 있는 인증서를 wsl ubuntu 가상머신 /etc/nginx/ 경로로 이동

mv /mnt/d/cert/abcde.pfx /etc/nginx/

10.pfx 확장자 pem으로 변환

sudo openssl pkcs12 -in abcde.pfx -out abcde.pem -nodes -password pass:[인증서비밀번호]

11.nginx 실행, 재실행, 종료 (저는 start로 하니 안켜져서 restart로 다시 켜보니 실행되었습니다.)

sudo service nginx start    #실행
sudo service nginx restart  #재실행
sudo service nginx stop     #종료

12.실행 후 nginx 실행 여부 확인

service nginx status

실행되고 있는 중일경우 아래와 같은 명령어가 뜬다.

* nginx is running

13.localhost:80으로 접속하여 nginx가 뛰워져 있는지 확인 (http 로 접속)

<http://localhost:80>

14.https://localhost:443로 접속하여 프록시를 거쳐서 설정한 웹서버로 접속이 되는지 확인

<https://localhost:443>

 

15. .net core 웹서버 Controller에서 아래와 같이 코딩하여 X-Forwarded-For 헤더를 읽어 클라이언트의 ip 를 확인

string clientIpAddress = string.Empty;

if (HttpContext.Request.Headers != null)
{
	var forwardedHeader = HttpContext.Request.Headers["X-Forwarded-For"];
	if (!Microsoft.Extensions.Primitives.StringValues.IsNullOrEmpty(forwardedHeader))
	{
		clientIpAddress = forwardedHeader.FirstOrDefault();
	}
}

로컬 호스트이므로 127.0.0.1 가 clientIpAddress 에 담기는 것을 확인.

 

결론

 

예제에서는 웹서버에서 x-Forwared-For 헤더를 읽는 부분이 .NET Core로 되어있지만 프록시 구성만 잘 되어있으면 Spring과 같은 다른 웹서버 프레임워크에서도 헤더를 읽어 클라이언트 ip를 얻어올 수 있다고 생각합니다. 이번 포스팅을 통해 읽으신 분들이 웹서버에 프록시를 구성하는데 도움이 되었으면 좋겠습니다.

반응형