[Infra 2] NGINX 기초용어/ logging/ ssl

QQQ
nodejs backend
Published in
10 min readFeb 3, 2021

[ #Infra 시리즈 ]
1. 아주 기초적인 배포해보기: EC2 NGINX PM2
[NOW]:2. NGINX와 PM2를 좀더 봐보죠. logging/ ssl(https)
3. 배포를 자동화시켜보죠. CICD “github action”
4. 배포를 또 자동화시켜보죠. “jenkins”

목차

1 . NGINX 기초적인 용어들

  • 지시어
  • 연산자
  • 변수

2 . Nginx logging

3 . Nginx HTTPS 설정하기

Tip: nginx에 문법적으로 오류가 있는지 오타가 있는지 확인할 때는

$ sudo nginx -t 를 이용하여 확인가능합니다. nginx 설정을 바꾸고 재시작하기전에 확인하면 좋습니다.

1. NGINX 기초적인 용어들

지시어

server

Syntax: server { … }
가상서버에 대한 설정을 작성합니다. listen directive로 어떤 서버에 대해 응답할 것인지 설정할 수 있습니다.

server_name

Syntax: server_name name …;

server {
server_name example.com www.example.com;
}

location

Syntax: location [ = | ~ | ~* | ^~ ] uri { … }
들어오는 요청 URI에 대한 설정을 할때 쓰입니다. 우리는 보통 proxy_pass로 전달해줄 때 쓰게 되죠.

“=”

location = /user {
proxy_pass http://login.example.com;
}

=를 붙이게 되면 정확하게 일치하는 URI에만 반응합니다. + 팁으로 "/"으로 가는 요청이 많다면, = /으로 설정해둔다면, 요청을 보다 빠르게 처리할수 있게 됩니다.

root

Syntax: root path;
요청에 대한 root 디렉토리를 설정합니다.

location /i/ {
root /data/w3;
}

위의 코드를 보시면, “/data/w3/i/top.gif” 파일은 /i/top/gif 요청의 응답으로 보내집니다.

try_files

Syntax: try_files file … uri;
Syntax: try_files file … =code;
들어오는 요청에 해당하는 파일이 있는지 확인하고 첫번째로 나오는 파일을 반환합니다. 아무 파일도 검색되지 않는다면 마지막 인자로 설정된 uri, code로 응답합니다.

aio

Systax: aio on | off | threads
비동기 파일 I/P를 가능하게 할지 말지 정합니다. threads 옵션은 파일을 전송함에 있어서 한 프로세스에서 멈추지않고 (block되지않게 하기 위해) 멀티스레딩 방식으로 전달하도록 하는 값입니다.

aio_write

Systax: aio_write on | off;
aio 가 가능할 때 파일 쓰기 작업에서도 가능한지 설정합니다.

alias

Systax: alias path;
들어오는 uri가 변경되서 처리되어야할 때 이용합니다.

location /i/ {
alias /data/w3/images/;
}

위에서 /i/top.gif 요청이 들어오면 /data/w3/images/top.gif의 파일이 전달됩니다. /i//data/w3/images/ 로 변경되어서 처리되었습니다.

error_page

Systax: error_page code … [=[response]] uri;
특정에러에 보여줄 URI를 정의합니다.

error_page 404             /404.html;
error_page 500 502 503 504 /50x.html;

연산자

=

js 의 “==”, “===”와 같다. uri가 같은지 확인.

# uri가 /error와 같으면 error_page를 보여주도록 한다.
location = /error {
proxy_pass 127.0.0.1:3000/error_page
}

!=

=와 반대로 다를때 사용.

~

정규 표현식 패턴을 이용할 때 쓴다.

# .jpg로 끝나는 경로에 대해 반응한다.
location ~ /.jpg$ {
proxy_pass 127.0.0.1:3000/image.jpg;
}

!~

~와 반대되는 연산자이다.

~*

대소문자를 구분하지 않는 정규표현식 패턴이다.

-f

파일이 존재하는지 확인.

-d

디렉토리가 존재하는지 확인.

-e

파일, 디렉토리, 심볼릭 링크가 존재하는지 확인

-x

파일이 존재하고 실행가능한지 확인.

변수

달러표시($)가 붙은 여러 변수를 이용하여 nginx로 전달된 요청에 대한 정보들을 이용할 수 있다.

“http://nginxstudy.co.kr:80/variables?id=123" 이라는 uri이 들어온다면
$host는 nginxstudy.co.kr이 되고, $uri는 /variables 가 된다.

host

요청받은 호스트명

uri

요청받은 URI

args

쿼리스트링이라고 생각하면 된다. 위 uri에선 id=123

디테일한 설명은 https://www.javatpoint.com/nginx-variables

2. Nginx log 남기기

NGINX는 따로 설정해주지 않아도 알아서 로그를 남깁니다. 따로 설정을 해주지 않으면 한 파일에만 계속 저장해주는 게 문제죠.
기본 log설정을 봐봅시다. nginx.conf 파일을 보면 $ sudo vi nginx.conf

server {
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}

아래처럼 적혀있습니다. access_log와 error_log의 경로로 가서 확인해보시면 지금까지의 접근 로그들이 잘 적혀있을 겁니다.
기본 설정에서 더 나아가 우리가 할일은 로그를 [ 1 ] 날짜에 따라 분리시키고, [ 2 ] 당일의 로그를 제외하고는 모두 압축시키는 것입니다. 그리고 [ 3 ]특정 기간을 넘은 파일은 자동으로 삭제되게끔 하겠습니다.

이 모든 일은 Logrotate라는 linux 툴을 이용하면 쉽게 할수 있습니다. logrotate는 이미 리눅스에 깔려있습니다. /etc/logrotate.d로 가셔서 nginx를 위한 로그 설정을 작성하면 됩니다.

$ cd /etc/loglotate.d
$ sudo vi nginx
# /etc/logrotate.d/nginx/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}

logrotate의 중요한 옵션들을 살펴봅시다.

  • daliy, weekly, monthly : 로그 파일을 분할할 시간을 정합니다.
  • missingok : 로그파일을 분실했을 때 에러를 발생시킬지 말지.
  • rotate ’n’ : 저장할 로그파일 갯수
  • compress: 로그 파일을 압축할지.
  • delaycomporess : 최근파일을 제외하고 전부 압축
  • notifempty: 빈 로그파일은 로테이트하지 않음.
  • create 0640 www-data adm: 새 로그파일을 생성하면 640 모드로 생성하고 소유자는 nginx가 됨. *640: 소유자-읽기쓰기, 그룹-읽기, 타인-엑세스불가
  • sharedscripts :
  • prerotate: rotate작업을 마친후 실행할 스크립트를 적는 곳.

위 설정대로 로깅이 작동된다면 nginx 로그는 아래처럼 저장되어집니다.

# /var/log/nginx
access.log access.log.2.gz access.log.4.gz access.log.6.gz
access.log.1 access.log.3.gz access.log.5.gz access.log.7.gz
error.log error.log.2.gz error.log.3.gz error.log.4.gz

3. Nginx https 설정하기

  1. 인증서를 받습니다.
  2. 그리고 nginx 설정파일에서 경로를 설정해주면 됩니다.

1. 인증서를 받습니다.

가비아, cloudflare등 아주 많은 사이트에서 만들어줍니다. 이메일로 cert.pemkey.pem 파일을 받으셔서 /etc/nginx/certificate에 저장합니다. certificate 디렉토리가 없다면 만들어서 저장합니다.

테스트용으로 ssl을 직접 만들 수도 있습니다.

참고:https://techexpert.tips/ko/nginx-ko/nginx%EC%97%90%EC%84%9C-https-%EC%82%AC%EC%9A%A9/

2. nginx에서 몇가지 설정을 합니다.

80포트를 받는 (listen) 설정이 있는 파일로 갑니다. 제 경우에는 /etc/nginx/sites-available/default입니다.

Before: https 가 없던 기존 설정입니다.

server {
listen 80 defalult_server;
listen [::]:80 default_server;

root /var/www/html;
server_name _; location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;

// 80포트로 들어오는 요청을 3000포트로 전달
proxy_pass http://127.0.0.1:3000/;
}

기존 설정은 단순히 80포트로 들어오는 요청을 3000포트로 연결해주는 것이 다였습니다.

After: https(443) 설정이 추가됨.

server {
listen 80 defalult_server;
listen [::]:80 default_server;
return 301 https://$host$request_uri; // ! redirect
// 80 포트로 들어온 요청이 바로 443 port로 가게 됩니다.
server_name _;}server {
listen 443 ssl; // "https" port
server_name ssl_test;
root /var/www/html;

ssl_certificate /etc/nginx/certificate/cert.pem;
ssl_certificate_key /etc/nginx/certificate/key.pem;

location / {
proxy_pass http://127.0.0.1:3000/;
}
}

without HTTPS80 -> 3000 => with HTTPS 80 -> 442 -> 3000

이제부터는 80포트로 들어온 요청을 바로 https로 리다이렉트시킵니다. 그리고 443으로 들어온 요청을 3000포트로 전달합니다.

참고 자료.

생활코딩 nginx: https://opentutorials.org/module/384/4504

SSL 인증서 설치/적용 가이드: https://www.sslcert.co.kr/guides/NGINX-SSL-Certificate-Install

--

--