업무를 하면서 처음으로 Nginx를 다뤄볼 예정이다. 공부해가도 뚝딱이겠지만 덜 찐따처럼 보이기위해 가볍게 훑어보고 갈 예정 😎
Nginx란
Nginx란 Nginx는 웹 서버 소프트웨어로 가벼움과 높은 성능을 목표로 한다. 비동기 이벤트 기반 구조의 경량화 웹 서버로 정적 파일을 제공하는 웹 서버로 활용되기도 하고 리버스 프록시 서버로 활용하여 WAS의 부하를 줄여주는 로드밸런서 역할을 하기도 한다.
Nginx가 만들어진 배경 참고 👉🏻 https://dkswnkk.tistory.com/513
나는 기존에 있던 서비스 위에 Nginx를 리버스 프록시로 활용할 예정이다. 이로 인해 얻을 수 있는 이점은 아래와 같다.
- 트래픽 분산
몇 프록시 서버는 로드밸런싱 기능을 제공하는데 이 중 하나가 Nginx이다. 한 서버에 트래픽이 과도하게 몰리는 경우를 방지하고자 프록시 서버에서 트래픽을 분산(로드밸런싱)시킨다. - 캐싱
미리 렌더링된 버전의 페이지를 캐시하여 페이지 로드 시간을 단축할 수 있다. 이 기능은 프록시 서버의 응답에서 수신한 콘텐츠를 캐싱하고 매번 동일한 이 콘텐츠를 프록시 서버에 연결할 필요 없이 클라이언트에 응답하는 방식으로 작동한다. - SSL 터미네이션
클라이언트와의 연결에 대한 SSL 끝점 역할을 할 수 있다. 수신 SSL 연결을 처리 및 해독하고 프록시 서버의 응답을 암호화한다. - 압축
프록시 서버가 압축된 응답을 보내지 않는 경우, 클라이언트로 보내기 전 응답을 압축하도록 Nginx를 구성할 수 있다. - DDoS 공격 완화
수신 요청과 단일 IP 주소당 연결 수를 일반 사용자에게 일반적인 값으로 제한할 수 있다. 또한 클라이언트 위치와 “User-Agent” 및 “Referer”와 같은 요청 헤더 값을 기준으로 액세스를 차단하거나 제한할 수 있다.
리버스 프록시 👉🏻 프록시 서버(Proxy Server)와 DMZ 서버 https://ijo0r98.github.io/posts/proxyNdmz/
Nginx 웹서버 설치 및 시작
brew
가 설치되어있다는 가정하에
1
brew intstall nginx
설치가 성공적으로 끝나면 설치 위치를 확인할 수 있다.
1
2
3
4
5
6
Docroot is: /opt/homebrew/var/www
The default port has been set in /opt/homebrew/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.
nginx will load all files in /opt/homebrew/etc/nginx/servers/.
brew
이용한 Nginx 서비스 기동
1
2
3
brew services start nginx # 시작
brew services restart nginx # 재시작
brew services stop nginx # 종료
Nginx 접속
기본 포트는 8080
http://localhost:8080
기본 웹 루트 디렉토리는 /usr/share/nginx/html
Nginx 설정 변경
내 스프링 부트 프로젝트의 기본 포트는 9090
http://localhost:9090
이제 이 둘을 연결해주려한다.
Nginx 설정 파일은 아까 설치 결과로 나왔던 곳 /opt/homebrew/etc/nginx
에 위치
1
vim nginx.conf
기존 설정 파일 살짝 보면
1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 8080; # 사용중인 포트
server_name localhost; # 서비스할 도메인 설정 가능
#charset koi8-r;
#access_log logs/host.access.log main; # 로그 남기고 싶으면 주석 해제
location / { # / 뒤에 경로 지정 가능
root html;
index index.html index.htm;
}
...
참고! 로그 파일에 날짜를 붙이려고 다음날 확인해보니 접속 로그 파일(host.access.log) 및 에러 로그 파일(error.log) 는 알아서 전날 로그 파일 뒤에 날짜가 붙어 히스토리가 남음. 오늘의 로그 파일은 뒤에 날짜 안붙음. 따라서 굳이 날짜 뒤에 안붙여도 일자별 관리가 가능하다..~
이제 location 블럭 하단에 proxy_pass
정보를 추가하면 리버스 프록시의 역할을 할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 8080; # 사용중인 포트
server_name localhost; # 서비스할 도메인 설정 가능
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
proxy_pass http://localhost:9090;
}
...
Nginx에 {server_name}:{listen} 으로 오는 요청을 proxy_pass http://localhost:9090 으로 연결시켜준다.
listen 지시문에 의해
포트 번호 8080으로 들어오는 요청들에 대해 server_name과 정확하게 일치하는 서버 블록을 찾으려고 시도한다.
설정 후 Nginx(8080)로 접속해보면 이렇게 기존의 Nginx 기본 페이지가 아닌 내가 스프링 프로젝트에서 설정한 웹 페이지로 연결되는 것을 확인할 수 있다!
그 외 Nginx에서 권장하는 다양한 리버스 프록시 헤더 구성 옵션들이 있다.
1
2
3
4
5
6
7
8
9
10
11
12
proxy_pass http://localhost:9090;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_pass
Nginx가 프록시로서 동작할 때 요청에 응답할 URLproxy_http_version
프록시를 위한 HTTP 프로토콜 버전 정의, 기본값은 1.0으로 웹 소켓 및 활성 연결 유지 시 버전 1.1을 사용해야 한다.proxy_cache_bypass
응답에 캐시를 적용하지 않을 조건 지정, 변수가 비어있지 않거나 ‘0’이 아니면 캐시로부터 응답을 가져오지 않는다. (동일 키워드로proxy_no_cache
가 있다.)
proxy_set_header
Nginx가 응용 프로그램 서버에 요청 전달 시 헤더 재정의할때 적용되는 설정
Upgrade
,Connection
응용 프로그램이 웹 소켓을 사용하는 경우 필요Host
Nginx hostX-Real-IP
클라이언트 IPX-Forwarded-For
클라이언트의 IP를 식별하기 위한 정보X-Forwarded-Proto
클라이언트의 요청 프로토콜 (HTTP 또는 HTTPS)X-Forwarded-Host
클라이언트가 요청한 원래의 호스트X-Forwarded-Port
클라이언트가 요청한 원래의 포트
설정 시 주의사항
내가 마주친 오류는 아니지만 블로그 읽던 중 알아두면 좋을것 같아 추가한다.
nginx 에서 proxy_set_header 재정의할 때 주의할 점 https://ohgyun.com/537
주요 내용은 프록시 서버로 전달하는 설정 재정의 시 상위 레벨에서 상속받던 값은 무시된다는 것이다. 즉 같은 location 블럭 안에 설정을 지정해야 한다는 것이다.
Nginx가 재정의하는 헤더는 Header와 Connection 두개이며 그 외의 헤더들도 모두 프록시 서버로 전달되는데, 헤더의 값이 비어있다면 그 헤더들은 전달되지 않는다. 만약 헤더의 값을 변경하려면 proxy_set_header
키워드를 사용하면 된다.
제거하고 싶은 속성이 있다면 아래처럼 빈값으로 설정하면 해당 헤더값이 전달되지 않는다.
1
proxy_set_header var “”;
proxy_set_header
는 어디서든 사용 가능하지만 proxy_pass
가 지정되는 지점에 값이 재정의된다. 이때 위에서 정의한 proxy_set_header
들은 모두 무시된다.
블로그에서 제시된 문제 코드는 다음과 같다.
1
2
3
4
5
6
7
8
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
location /~ {
# 새 헤더 재정의 및 추가로 위의 proxy_set_header는 모두 무시된다.
proxy_set_header var var;
proxy_pass http://localhost:9090;
}
위의 설정들이 제대로 적용되기 위해서는 같은 location
블럭 안에 proxy_pass
와 함께 헤더값이 지정되어야한다.
1
2
3
4
5
6
7
location /~ {
# 지정한 proxy_set_header는 모두 적용된다.
proxy_pass http://localhost:9090;
proxy_set_header var var;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Nginx란 무엇인가? https://dkswnkk.tistory.com/513
[mac] Nginx Tomcat 연동 - nginx 스프링 내장 톰캣 리다이렉트 방법 (Proxy Server) https://thalals.tistory.com/342
SW/리눅스 Linux : Nginx Reverse Proxy 설정 방법, 예제, 명령어 https://jjeongil.tistory.com/1490