라즈베리파이: Nginx 설치
웹서버(Web Server)란?
웹서버(Web Server)
는 HTTP에 의한 요청(request)을 받아들여 응답(Response)하는 프로그램입니다. 주로 이미지, CSS, Javascript를 포함한 정적인 HTML 문서를 처리합니다.
웹서버에는 아파치(Apache)
와 엔진엑스(Nginx)
등이 있습니다. 아파치는 쓰레드/프로세서 기반의 구조이고 엔진엑스는 이벤트 기반의 구조를 가지고 있습니다.
엔진엑스(Nginx)란?
엔진엑스(Nginx)
는 러시아의 프로그래머인 이고르 시쇼브(Igor Sysoev)가 개발한 동시접속 처리에 특화된 웹 서버 프로그램 입니다.
아파치보다 역사가 오래되지는 않았지만, 아파치가 많은 한계를 보이고 있는 상황에서, 가볍고 높은 성능을 무기로 점유율을 빠르게 늘려나가다 현재는 아파치를 재치고 웹 서버 시장점유율 1위가 되었습니다.
엔진엑스(Nginx)의 기능
정적 페이지를 처리하는 웹서버 역할
웹페이지는 크게 정적 페이지
와 동적 페이지
로 나눠집니다.
정적 페이지는 이미지, CSS, Javascript를 포함한 저장된 HTML 문서를 그대로 전달하는 웹페이지입니다.
반면 동적 페이지는 스크립트에 의해 가공된 데이터를 전달하는 웹페이지입니다.
물론 웹서버가 php같은 서버 사이드 스크립트를 지원하기도 하지만 기본적으로는 정적 페이지를 처리합니다.
리버스 프록시(Reverse Proxy) 역할
프록시(Proxy)
는 클라이언트와 서버 사이에서 데이터를 중계해주는 서버입니다. 여기에는 포워드 프록시(forward proxy)
와 리버스 프록시(reverse proxy)
가 있습니다. nginx는 자체적으로 리버스 프록시 기능을 제공합니다.
포워드 프록시는 클라이언트의 요청을 직접적으로 전달하지 않고 프록시 서버를 통해 간접적으로 요청합니다. 회사의 인트라넷같은 경우 인터넷상의 서버에 요청을 할때 프록시서버를 통해 요청을 하게 됩니다. 클라이언트의 요청을 감독할 수 있고 서버에서는 클라이언트의 신분을 알 수 없어 프라이버시와 보안을 강화할 수 있습니다.
포워드 프록시
리버스 프록시는 그 반대입니다. 서버에서 받은 응답을 프록시 서버를 통해 전달합니다. 클라이언트의 요청을 분산하여 서버의 부담을 줄일 수 있고 클라이언트는 서버의 신분을 알 수 없어 서버 보안을 강화할 수 있습니다.
리버스 프록시
Nginx 설치
우선 명령프롬프트(cmd)를 통해 라즈베리파이에 ssh로 연결합니다.
ssh 연결
> ssh pi@raspberrypi
접속 후 apt를 업데이트 해주세요.
apt 업데이트
$ sudo apt update && sudo apt upgrade -y
apt를 통해 nginx를 설치합니다.
nginx 설치
$ sudo apt install nginx -y
설치후 http://raspberrypi에 접속하면 다음과 같이 기본 웹페이지가 뜹니다.
기본 웹페이지
Nginx 환경설정
Nginx의 환경설정을 튜닝해보겠습니다. 환경설정 파일은 /etc/nginx/nginx.conf
파일입니다. nano 에디터로 해당 파일을 열어봅시다.
/etc/nginx/nginx.conf 편집
$ sudo nano /etc/nginx/nginx.conf
1. 코어(core)
nginx는 메인 프로세스(master)와 작업 프로세스(worker)로 구성되는데, 작업 프로세스가 실질적인 웹서버 역할을 합니다.
- user : 작업 프로세스의 권한을 지정합니다.
- worker_processes : 워커 프로세스 실행 갯수를 지정합니다. 보통 코어 갯수만큼 설정하거나 auto로 적으면 됩니다.
- pid : 마스터 프로세스의 id정보가 저장됩니다.
- include : 다른 파일을 가져옵니다.
2. events 블록
비동기 이벤트 처리 방식에 대한 옵션을 설정합니다.
- worker_connections : 하나의 작업 프로세스에서 처리할 수 있는 접속자 수를 지정합니다.
- multi_accept : 다중 접속의 여부를 지정합니다. 기본값은 off 입니다.
3. http 블록
HTTP 프로토콜을 설정합니다.
- sendfile: sendfile() 함수의 사용여부를 지정합니다.
- tcp_nopush : TCP_CORK 사용 여부를 지정합니다. on인 경우 버퍼가 가득찼을때만 패킷을 전송합니다.
- tcp_nodelay : on인경우 패킷 크기에 상관없이 버퍼에 데이터를 보냅니다.
- keepalive_timeout : 연결을 유지할 수 있는 최대 시간을 지정합니다.
- types_hash_max_size : 도메인 이름 최대 길이를 지정합니다.
- ssl_protocols : 사용할 SSL-TLS 버전을 지정합니다.
- ssl_ciphers : 사용할 알고리즘을 지정합니다.
- ssl_prefer_server_ciphers : SSL-TLS 핸드쉐이크 과정에서 서버 알고리즘을 우선할지 설정합니다.
- gzip : gzip 압축 전송을 사용할지 설정합니다.
- access_log : 접근로그를 기록할 경로를 지정합니다.
- error_log : 에러로그를 기록할 경로를 지정합니다.
- server_tokens : nginx 버전을 나타낼지를 설정합니다. 기본값은 on 입니다.
server_tokens이 on인 경우 response 데이터
server_tokens이 off인 경우 response 데이터
3. server 블록
웹서버를 설정합니다. http 블록에서
/etc/nginx/sites-enabled/*
파일을 include 하고 있기때문에 서버블록은 해당 폴더에 작성하셔도 됩니다. 기본적으로/etc/nginx/sites-available
폴더에 server 블록을 작성하고/etc/nginx/sites-enabled
폴더에는 심볼릭링크를 생성합니다.
- listen : ip와 포트번호입니다. ip는 생략가능하며 default 포트는 80입니다.
- server_name : 도메인 네임입니다. 서브도메인으로 와일드카드 *을 사용가능합니다.
- root : 서버의 루트 경로입니다.
- index : 파일명이 없을때 접근할 기본파일입니다.
- try_files : URI에 일치하는 파일이 없는 경우 제공되는 파일입니다.
- allow : 해당 ip로 오는 요청만 허용합니다.
- deny : 해당 ip로 오는 요청은 거부하고 403 forbidden을 리턴합니다.
- return : 해당 경로로 redirect합니다. URI가 변합니다.
- rewrite : URI 변화없이 내부적으로 해당 경로로 응답합니다.
- proxy_pass : 프록시 서버로 작동합니다.
- location : request URI 매핑을 설정을 합니다. 변경자에 따라 우선순위가 정해져 있는데, 아래 표를 참고하세요.
location 속성
우선순위 | 변경자 | 설명 |
---|---|---|
1 | = | URI와 정확하게 일치합니다. 예) location =/test { } http://localhost/test (일치) http://localhost/test/ (불일치) |
2 | ^~ | URI의 앞부분이 일치합니다. 예) location ^~/t {} http://localhost/test (일치) http://localhost/Test (불일치) |
3 | ~ | 정규표현식과 일치합니다. 예) location ~/Test[0-9]+ { } http://localhost/Test1 (일치) http://localhost/test1 (불일치) |
4 | ~* | 대소문자 구분없이 정규표현식과 일치합니다. 예) location ~*/Test[0-9]+ { } http://localhost/test2 (일치) http://localhost/test (불일치) |
5 | 아무것도 없으면 prefix로 작용합니다. ^~와 같지만 우선순위가 다릅니다. 예) location location /test { } http://localhost/test (일치) http://localhost/Test (불일치) |
4. upstream 블록
upstream 서버를 설정합니다. 클라이언트의 요청을 각 서버에 분배하는 로드밸런싱을 설정합니다. 프록시 서버가 upstream으로 작용합니다.
upstream 블록
upstream <이름> {
<밸런스타입>;
server <host1>:<port1> [파라미터];
...
server <host2>:<port2> [파라미터];
}
로드밸런싱에 대한 내용은 다음에 알아보도록 하고, 이번 글에서는 생략합니다.
Reverse Proxy
Nginx 환경설정을 통해 리버스 프록시를 해보도록 하겠습니다. 예제로 사용하기 위해 node.js로 react 서버를 구축하여 실행시킨 후 http://raspberrypi:3000에 접속하면 리액트 웹어플리케이션에 접속됩니다.
리버스 프록시를 통해 http 프로토콜의 기본 포트인 80으로 요청하면 리액트 웹어플리케이션 서버에 접속되도록 해보겠습니다.
server 블록을 작성해야 합니다. Nginx를 설치하면 /etc/nginx/sites-available/default
파일이 생성되어 기본 server 블록이 작성되어 있습니다. 해당 파일을 수정하겠습니다.
/etc/nginx/sites-available/default 편집
$ sudo nano /etc/nginx/sites-available/default
/etc/nginx/sites-available/default
80번 포트로 요청을 보내면 /var/www/html
폴더를 루트로 하는 페이지가 매핑됩니다. 해당 폴더를 확인하면 index.nginx-debian.html
파일이 하나 있습니다. location 속성을 통해 /
경로를 매핑해두었으며, 해당 경로에 접속하면 인덱스 파일을 응답으로 전송하게 됩니다.
server 블록을 다음과 같이 수정하도록 합시다.
server 블록 수정
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name raspberrypi;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
nginx를 재실행합니다.
nginx 서비스 재실행
$ sudo service nginx restart
http://raspberrypi에 접속하면 리액트 웹어플리케이션에 접속되는 것을 확인할 수 있습니다.
server_name 속성에는 보통 접속할 도메인을 입력합니다. 서브 도메인을 입력해도 되며, 와일드카드(*)를 통해 모든 서브도메인에 대하여 웹서버를 설정 할 수도 있습니다.
proxy_pass 속성에는 리버스 프록시를 위한 포워딩 주소를 입력합니다. 리버스 프록시 서버이므로 root 속성이나 index 속성은 필요하지 않습니다.
80번 포트로 들어오는 요청은 로컬서버의 3000번 포트로 요청을 넘겨주고, 해당 포트에서 오는 응답을 80번 포트를 통해 전송합니다. 클라이언트는 프록시 서버를 통해서 통신을 할 뿐, 웹어플리케이션 서버의 정보를 알 수 없기때문에 서버 보안을 강화할 수 있습니다.