[Infra] 시리우스 3편 - NginX 닌 누꼬...??

Bronze_Yun·2025년 5월 21일

Sirius

목록 보기
3/5
post-thumbnail

이전 글에서는 시리우스 팀의 돌돌 프로젝트 CI/CD에 대해 상세히 기술하였습니다. CD가 잘 기억나지 않으신 분들은 한번 보고 오셔도 좋을것 같아요~ 이번글에서는 CD를 통해 서버에 배포를 했으면 구동을 해야겠죠? 또한 사용자들이 안전한 통신을 위해 HTTPS와 무중단 배포를 위한 로드밸런서 역할을 해줘야합니다. AWS의 ALB 서비스를 통해 편하게 진행 할 수있지만 비용 문제도있고 NginX에 대해 공부를하고싶어 도입하게 되었습니다.


NginX란 🤔

3-Tier-Architecture 구조를 보면 Web-Was-DB로 이루어져있습니다. 거기서 WEB을 담당을 하는데요. Web Server이기에 정적 파일을 제공을 하는 역할을 하기도하고 Reverse Proxy를 두어서 Was에 대한 트래픽 부하를 줄이는 로드밸런서 역할을 합니다.


Forward-Proxy 🤔

클라이언트와 인터넷 사이에 위치한 프록시 서버를 포워드 프록시라고합니다.

포워드 프록시의 이점은 아래와 같습니다.

  • 클라이언트 보안
  • 캐싱
  • Ip 보안

클라이언트 보안

보안을 강화 할 수 있습니다. 예를 들자면 공공기관, 회사 등 내부 사설망을 쓰는 곳에서 특정 사이트에 대한 접속을 막기 위해 포워드 프록시에 특정 서버에 대한 요청을 막도록 설정을 해놓습니다. 그러면 클라이언트가 요청을 했을 때 프록시 서버를 타고 그 규칙에 해당되면 인터넷에 접근이 안되겠죠.

캐싱

정적 파일을 제공해주기에 구글 사이트를 들어가면 빨리 구글 로고나 검색 창 등 정적 파일을 캐싱을 해놓았기에 빠른 조회가 가능합니다. 그래서 누군가가 이에대한 요청을 이미 했으면 다른 사람은 이전 사람이 이미 조회한 파일을 캐싱해놓았기에 바로 조회하죠

Ip 보안

사용자들의 요청을 프록시 서버를 거쳐서 오기에 프록시 서버에서는 필수적인 데이터만 제공해서 사용자들의 Ip 정보는 숨깁니다. 그래서 Ip 추적을 해도 프록시 서버에 대한 Ip만 보이게됩니다.


Reverse Proxy 🤔

인터넷과 Was 사이에 위치한 프록시 서버를 리버스 프록시라고합니다.

리버스 프록시의 이점은 아래와 같습니다.

  • 로드밸런서
  • 서버 보안
  • SSL

로드밸런서

사용자들의 요청이 많을 때 서버 하나 트래픽을 모두 전달하면 서버가 터질 가능성이 높습니다. 그래서 여러개 서버를 두고 앞에 리버스 프록시를 두면 리버스 프록시가 트랙필을 각 서버에 맞게 분할 시키는 로드밸런서 역할을 합니다.

서버 보안

서버 앞에 리버스 프록시가 위치해있기에 사용자가 리버스 프록시에 요청을 하면 리버스 프록시는 다시 서버에 요청을 하고 응답 후 사용자는 다시 리버스 프록시의 응답을 받기에 서버의 ip가 아닌 리버스 프록시의 ip만을 알 수 있습니다.

SSL

Was 서버에서 SSL 적용이 가능하지만 서버가 무거워지고 비용도 많이 나갑니다. 그래서 프록시 서버에서 SSL을 통한 암호 및 복호화를 거치기에 Was의 부담을 줄일 수 있습니다.


프로젝트에서 겪은 일들 🤔

ec2에 NginX 설정한다고 바빠서 중간 과정에 대한 이미지를 첨부하는 걸 잊어버렸습니다...😭😭😭 하지만 기억은 나니 글로라도 기록을 하겠습니다.

SSL 설정 🤔

Certbot에서 인증서를 발급을 했습니다. 무료지만 인증서를 3달마다 갱신을 해줘야한다는 불편한점이 있지만 무료이기에 사용했습니다.

  • SSL을 발급 받고 도메인에 설정하기 위해서는 미리 NginX가 설치가되어있어야합니다.
  • 도메인을 구매를 하고 example.com 자리에 그대로 사용하면 오류가 발생하실겁니다. 해당 도메인을 Route53 or 가비아에서 DNS 설정을 해주고 이를 서버 Ip와 등록해야합니다. 그리고 해당 도메인을 example.com 자리에 넣어서 인증서를 연결해야합니다.

인증서 발급이 성공하면 아래와 같이 .pem 키가 생깁니다.

NginX의 설정 파일 🤔

map $http_origin $cors_origin {
        default "";
        "http://localhost:3000" $http_origin;
        "http://프론트_개발_서버" $http_origin;
        "https://프론트_개발_서버" $http_origin;
}

server {
	root /var/www/html;
	index index.html index.htm index.nginx-debian.html;
	include /etc/nginx/conf.d/service-url.inc;
	server_name 백엔드_개발_서버;
	location / {
		if ($cors_origin != "") {
                    add_header 'Access-Control-Allow-Origin' $cors_origin always;
                    add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PATCH, PUT' always;
                    add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type' always;
		    add_header 'Access-Control-Allow-Credentials' 'true' always;
                }
                if ($request_method = 'OPTIONS') {
                    add_header 'Access-Control-Allow-Origin' $cors_origin;
                    add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PATCH, PUT, OPTIONS';
                    add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type';
		    add_header 'Access-Control-Allow-Credentials' 'true';
                    add_header 'Content-Length' '0';
                    add_header 'Content-Type' 'text/plain charset=UTF-8';
                    add_header 'Access-Control-Max-Age' 1728000;
                    return 204;
		}
		proxy_pass $service_url;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header user-agent $http_user_agent;
	}
    listen [::]:443 ssl ipv6only=on;
    listen 443 ssl;
    ssl_certificate 백엔드_개발_서버의 fullchain.pem 경로;
    ssl_certificate_key 백엔드_개발_서버의 privkey.pem 경로;
    include options-ssl-nginx.conf 경로;
    ssl_dhparam ssl-dhparams.pem 경로;
}

server {
    if ($host = 백엔드_개발_서버) {
        return 308 https://$host$request_uri;
    }
	listen 80;
	listen [::]:80;
	server_name 백엔드_개발_서버;
    return 404;
}

server {
    server_name localhost;
    listen 80;
    listen [::]:80;
    include /etc/nginx/conf.d/service-url.inc;
    location / {
            proxy_pass $service_url;
    }
}
  • map을 통해 환경변수를 매핑합니다.
  • localhost와 프론트 서버에 대해서만 Cors를 허용합니다.
  • HTTP로 접속을 해도 HTTPS를 사용하도록 강제 리다이렉션을 통해 보안을 강화합니다.
  • preflight 캐싱(1728000초 = 20일) 설정을 통해 OPTIONS 요청에 대한 최적화된 응답을 합니다.
  • 리버스 프록시로 사용하여 클라이언트 요청을 $service_url 변수로 지정된 백엔드로 전달합니다.
  • 개발용 서버와 로컬 개발 환경을 동시 지원합니다.
  • IPv4와 IPv6 모두 지원합니다.

참고

https://inpa.tistory.com/entry/NETWORK-%F0%9F%93%A1-Reverse-Proxy-Forward-Proxy-%EC%A0%95%EC%9D%98-%EC%B0%A8%EC%9D%B4-%EC%A0%95%EB%A6%AC

https://velog.io/@coastby/Nginx-SSL-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0

profile
정답이 꼭 정답이 아니다.

0개의 댓글