리버스 프록시 지원 웹 서버

구성파일

  • /etc/nginx/nginx.conf:
    • nginx 서버에 서버 설정파일
    • TLS 나 각종 웹서버 설정 구성
  • /etc/nginx/sites-enabled/default:
    • 실제 서버에 굴러갈 파일이나 리버스 프록시를 구성 하는 기본설정 파일

    • nginx.conf에 import 되어 굴러가게 된다

      # nginx.conf 예
      include /etc/nginx/sites-enabled/*;

설명

  • 기본적으로 설정 파일은 nginx.conf 이거 하나다
  • 하지만 웹서버 자체에 서버 설정과, 프로젝트를 구분 하기위해 sites-enabled 에 따로 파일을 분리하게 된다
  • 따라서 프로젝트를 추가하거나 프록시 구성은 sites-enabled에 파일을 추가해서 하자

nginx.conf 설정

참고자료

HTTP

최상위 블록으로 해당 블록에서 설정한 값은 server 블록에 상속된다
즉 HTTP, server 블록에 설정값은 상호 호환 된다

client_max_body_size <크기>

  • 최대 Body로 보낼 수 있는 사이즈

  • 파일 업로드 할 때 해당 크기 설정을 고려해야 함

    http {
        client_max_body_size 5M;
    }

timeOut 설정

ngix 에 기본 timeout 값은 120초 이다 따라서 바꾸고 싶으면 설정하자

  • 일: d, 시: h, 분: m, 초: s

    # 최대 읽기 시간
    proxy_read_timeout 10m;
    # 최대 쓰기 시간
    proxy_send_timeout 10m;
    # 최대 연결 시간
    proxy_connect_timeout 10m;

server

하나의 서비스를 정의하는 블록
server 블록은 중복해서 사용가능하다

listen 80 & listen [::]:80

  • 해당 서비스를 80 포트로 호스팅 하겠다는 뜻
  • listen [::]:80에 경우 IPv6 이다
  • 다른 server 블록과 포트가 동일한 경우에도 server_name 이나 location 값이 다르면 상관 없다
default_server
  • 만약 listen 80 default_server 이렇게 지정하면
    정의되지 않은 location 이나 server_name 으로 접속하는 모든 요청은 여기서 처리된다

root

  • 프로젝트 디렉토리를 구성한다
  • 만약 웹서버로 사용할 시 로드될 HTML 과 CSS 등에 프로젝트 경로를 정의한다

server_name

  • 해당 server에 접속 도메인을 정의한다
  • 이걸로 도메인 리버스 프록시를 구성 할 수 있다

location <경로>

  • 해당 server에 접속 URL을 정의한다
내부 속성

참고자료

  • proxy_pass <URL | IP>: 해당 경로로 리버스 프록시를 설정한다
  • proxy_set_header <요청해더>: proxy_pass 쪽 서버에 요청해더를 설정한다.
  • add_header <응답해더>: proxy_pass 쪽 서버에서 응답을 리턴한 경우 추가적인 해더를 추가한다
주의 사항
  • 홈 경로인 / 로 설정하지 않는경우 즉 다른 경로로 지정하는경우, proxy_pass 주소와, location 주소 끝에는 반드시 /를 붙여야 한다.
  • 안그러면 proxy_pass 가 위치한 서버에서 uri에 홈주소를 /주소/ 로 인식해 버린다
location /주소/ {
	proxy_pass 주소:8080/;
}

예약 변수

  • $host: 도메인 주소
  • $request_uri: 요청한 uri (/abc/def)

리버스 프록시 구성

URL 라우팅

  • server 블록 내부에 location 부분을 수정한다

    location / {
    	proxy_pass http://172.168.0.2;
    }
     
    location /api {
    	proxy_pass http://172.168.0.3;
    }
    • /로 접속하면 http://172.168.0.2로 가지고
      /api로 접속하면 http://172.168.0.3 으로 가진다

도메인 라우팅

  • 분활 하려는 도메인 만큼 server 블록을 추가하고 이렇게 수정

    server {
    	listen 80;
    	#ipv6
    	listen [::]:80;
     
    	# 이 server_name 이 핵심!!!
    	server_name domain1.kro.kr;
    	location / {
    		proxy_pass http://172.168.0.2:8080; 
    	}
    }
    server {
    	listen 80;
    	#ipv6
    	listen [::]:80;
     
    	# 이 server_name 이 핵심!!!
    	server_name domain2.kro.kr;
    	location / {
    		proxy_pass http://172.168.0.4:8080; 
    	}
    }
    • domain1.kro.kr 로 접속하면 http://172.168.0.2:8080 로 가지고
    • domain2.kro.kr 로 접속하면 http://172.168.0.4:8080 로 가진다
    • 만약 따로 처리안하면 IP로 접속하는 요청은 재일 위에 선언한 http://172.168.0.2:8080

구성 팁

IP 직접 접근 차단하기

  • 도메인 리버스 프록시를 설정한 경우 도메인으로만 접근하게 하고 싶을 때 사용
  • 이렇게 하면은 무작위 IP 스켄을 통한 DDOS 공격을 어느정도 차단 가능하다
  • 참고로 return 444 는 서버가 아예 없는거 처럼 어떤것도 반환하지 않는다.
    # ip 직접 접근 차단
    server {
        listen 80 default_server;
    	#ipv6
    	listen [::]:80 default_server;
     
    	# 응답 ERR_EMPTY_RESPONSE
        return 444;
    }

WAF (Web Application Firewall) 설정하기

구성법

  • 포트 개방으로 인해 DDOS 공격이나 RCE 공격을 막기위해 nginx 자체적으로 방화벽을 제공해준다

WebSocket 허용하기

  • location 블록에 다음 구문을 추가한다

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
     
    # nginx 에서 websocket이 1분 간격으로 커넥션을 중단함으로 이걸 30일로 설정함
    proxy_read_timeout 30d;
    proxy_send_timeout 30d;

로그 보기

  • 접속로그: var/log/nginx/access.log
  • 애러로그: /var/log/nginx/error.log
  • 만약 위치를 바꾸고 싶다면 nginx.conferror_log 부분과 access_log 부분 수정

서비스 제어

systemctl 사용

# 시작
sudo systemctl start nginx
 
# 중지
sudo systemctl stop nginx
 
# 재시작
sudo systemctl restart nginx

nginx CLI 사용

Docker 환경같이 systemctl가 기본제공되지 않는경우

# 시작
nginx
 
# 중지
nginx -s stop
 
# 재시작
nginx -s reload

HTTPS 인증받기

참고

알아둘 점

  • 인증서는 도메인 마다 각각의 인증서를 발급받아야 한다.

인증서 발급하기

  • 대부분에 기업에서는 DigiCert 인증서를 구매해서 사용하지만 나는 아주 영세하기 때문에 무료 발급 기관인 Let’s Encrypt에 인증서를 사용할꺼임
  • 해당 발급 기관에서는 Certbot이라는 자동 발급툴을 제공하고 있어서 그걸 사용할꺼

CertBot 설치 및 발급

참고자료

  • Let’s Encrypt 인증서는 대략 2달간 유효 하다
  • 그래서 재발급 하는 스케줄링을 추가로 구성해 주는것이 좋다
sudo apt install python3-certbot-nginx
 
sudo certbot --nginx -d <도메인>

nginx.conf 구성

  • 발급을 마치면 발급한 <도메인 이름> 과 Server 블록 server_name 이 일치하는 곳에 인증서및 SSL 설정이 자동으로 구성된다

  • 그걸 적절하게 바꿔서 사용하자

  • 적절히 바꾼 예

    server {
        listen 443 ssl;
    	#ipv6
        listen [::]:443 ssl;
     
    	server_name <도메>;
    	location / {
    		proxy_pass http://172.168.0.3:8080;
    	}
     
    	# HTTPS 인증 부분
        ssl_certificate /etc/letsencrypt/live/fitpin-web-back.kro.kr/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/fitpin-web-back.kro.kr/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    }
     
     
    # HTTP 로 접근시 HTTPS 로 이동하게
    server {
    	listen 80;
    	listen [::]:80;
    	
    	server_name <도메>;
     
    	return 301 <도메>$request_uri;
    }

crontab 재발급 스케줄링 등록

  • 매달 30일 3시에 재발급

    0 3 30 * * certbot renew --renew-hook="sudo systemctl restart nginx"
    

인증서 관리

  • 인증서 확인
    • sudo certbot certificates

인증서 삭제

sudo certbot delete
  • 만약 삭제 후 재발급 하려면 위에 nginx.conf에 HTTPS 인증과 관련된 부분을 말끔하게 삭제해야 함 안그러면 발급할때 오류난다