Ubuntu Server

Nginx 소스 컴파일 설치 및 HTTPS 설정하기 우분투 16.04

우성군 5 2679 0

 

 

1. 기본 설치 경로

 

기본 설치 폴더를 /usr/local/src 로 잡겠습니다. 이 위치는 편한 곳으로 설정하셔도 상관없습니다. 다만 위치 변경시 경로에 주의하시기 바랍니다.

 

cd /usr/local/src

apt-get install build-essential libpcre3 libpcre3-dev zlib1g-dev unzip git

 기본 필수 패키지를 설치합니다.

 

 

2. 클라우드 플레어 SSL 패치 설치 및 ChaCha20 / Poly1305 적용

 

https://github.com/cloudflare/sslconfig 에 주기적으로 패치 파일이 올라옵니다.

 

OpenSSL 이나 Nginx가 업데이트시 파일이 변경되거나, 적용되지 않을 수 있습니다.

 

2016년 10월 30일 현재 Nginx는 1.1.15버전이고, OpenSSL은 1.0.2j 버전 기준입니다.

 

 

git clone https://github.com/cloudflare/sslconfig.git

 

wget -c https://github.com/openssl/openssl/archive/OpenSSL_1_0_2j.tar.gz

 

tar zxf OpenSSL_1_0_2j.tar.gz

 

mv openssl-OpenSSL_1_0_2j/ openssl-1.0.2j

 

rm -f OpenSSL_1_0_2j.tar.gz

 

cd openssl-1.0.2j

 

patch -p1 < ../sslconfig/patches/openssl__chacha20_poly1305_draft_and_rfc_ossl102j.patch

 

cd ../

 

 

3. Nginx 소스 다운로드 및 dynamic tls records 패치하기

 

wget -c https://nginx.org/download/nginx-1.11.8.tar.gz

 

tar zxf nginx-1.11.8.tar.gz

 

cd nginx-1.11.8/

 

patch -p1 < ../sslconfig/patches/nginx__1.11.5_dynamic_tls_records.patch

 

cd ../

 

rm -f nginx-1.11.8.tar.gz

 

4. 인증서 투명성 모듈 설치 (https://www.wsgvet.com/home/488)

 

wget -O nginx-ct-master.zip -c https://github.com/grahamedgecombe/nginx-ct/archive/master.zip

 

unzip nginx-ct-master.zip

 

rm -f nginx-ct-master.zip

 

5. headers-more-nginx-module 설치 (Nginx 버전 숨김 및 이름 변경 가능 - 옵션)

 

참조 : https://www.wsgvet.com/home/493

 

git clone https://github.com/openresty/headers-more-nginx-module

 

6. 브로틀리 압축(ngx_brotli) 설치

 

참조 : https://www.wsgvet.com/home/494

 

apt-get install git python2.7 python-dev brotli libtool autoconf automake 

 

git clone https://github.com/bagder/libbrotli

 

cd libbrotli

 

./autogen.sh

 

./configure

 

make

 

make install

 

cd  ../

 

기본적으로 libbrotli는 /usr/local/lib/libbrotlienc.so.1에 마운트됩니다. 

Nginx 시작시에 찾지 못한다면 /lib 또는 /usr/lib에 soft chain으로 연결하면 해결 될 수 있습니다.

 

https://wangqiliang.com/qi-yong-brotli-ya-suo-suan-fa-ti-gao-xing-neng/

 

위 링크도 참조해보세요.

 

 

7. ngx_brotli 소스 다운로드

 

git clone https://github.com/google/ngx_brotli.git

 

8. Nginx 1.11.8 컴파일 설치

 

기존에 Nginx 패키지 설치한 것이 있다면 완전히 삭제한 후 진행해야 합니다.

 

apt install libperl-dev libpcre3 libpcre3-dev libssl-dev openssl libgd2-xpm-dev libgeoip-dev zlib1g-dev libxslt-dev

기본적으로 필요한 패키지를 설치해줍니다.

 

cd nginx-1.11.8/

 

./configure --sbin-path=/usr/sbin/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/run/nginx.pid --with-openssl=../openssl-1.0.2j --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_perl_module=dynamic --with-threads --with-stream --with-stream_ssl_module --with-stream_realip_module --with-stream_geoip_module=dynamic --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --add-module=../nginx-ct-master --add-module=../headers-more-nginx-module --add-module=../ngx_brotli

 

make

 

make install

 

cd  ../

 

혹시 make 명령어를 내린 후 아래와 같은 에러가 난다면 (참조 : https://github.com/google/ngx_brotli/issues/39#issuecomment-254093378)

 

                -o objs/addon/src/ngx_http_brotli_filter_module.o \

                ../ngx_brotli/src/ngx_http_brotli_filter_module.c

../ngx_brotli/src/ngx_http_brotli_filter_module.c: In function ‘ngx_http_brotli_body_filter’:

../ngx_brotli/src/ngx_http_brotli_filter_module.c:272:9: error: ‘BrotliEncoderInputBlockSize’ is deprecated (declared at /usr/local/include/brotli/encode.h:87) [-Werror=deprecated-declarations]

         ctx->brotli_ring = BrotliEncoderInputBlockSize(ctx->encoder);

         ^

../ngx_brotli/src/ngx_http_brotli_filter_module.c: In function ‘ngx_http_brotli_filter_add_data’:

../ngx_brotli/src/ngx_http_brotli_filter_module.c:498:5: error: ‘BrotliEncoderCopyInputToRingBuffer’ is deprecated (declared at /usr/local/include/brotli/encode.h:95) [-Werror=deprecated-declarations]

     BrotliEncoderCopyInputToRingBuffer(ctx->encoder, size, b->pos);

     ^

../ngx_brotli/src/ngx_http_brotli_filter_module.c: In function ‘ngx_http_brotli_filter_process’:

../ngx_brotli/src/ngx_http_brotli_filter_module.c:534:5: error: ‘BrotliEncoderWriteData’ is deprecated (declared at /usr/local/include/brotli/encode.h:109) [-Werror=deprecated-declarations]

     if (!BrotliEncoderWriteData(ctx->encoder, ctx->last, ctx->flush, &size,

     ^

../ngx_brotli/src/ngx_http_brotli_filter_module.c: At top level:

cc1: error: unrecognized command line option "-Wno-c++11-extensions" [-Werror]

cc1: all warnings being treated as errors

make[1]: *** [objs/addon/src/ngx_http_brotli_filter_module.o] Error 1

make[1]: Leaving directory `/svr-setup/nginx-1.11.8'

make: *** [build] Error 2

configure 명령어에 --with-cc-opt='-Wno-deprecated-declarations' 를 추가해주면 됩니다. 

 

 

./configure --with-cc-opt='-Wno-deprecated-declarations' --sbin-path=/usr/sbin/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/run/nginx.pid --with-openssl=../openssl-1.0.2j --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_perl_module=dynamic --with-threads --with-stream --with-stream_ssl_module --with-stream_realip_module --with-stream_geoip_module=dynamic --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --add-module=../nginx-ct-master --add-module=../headers-more-nginx-module --add-module=../ngx_brotli

최종적으로 위와 같은 명령어가 됩니다. 

 

 

 

9. Nginx 시작 종료 명령어 스크립트 설치

 

git clone https://github.com/Fleshgrinder/nginx-sysvinit-script.git

 

cd nginx-sysvinit-script

 

make

 

#make uninstall   //스크립트 제거 명령어

10. Nginx 설정 

 

nano /usr/local/nginx/conf/nginx.conf

 

http {

include            mime.types;

default_type       application/octet-stream;

 

charset            UTF-8;

 

sendfile           on;

tcp_nopush         on;

tcp_nodelay        on;

 

keepalive_timeout  60;

 

#... ...#

 

# HTTP server signature 바꾸는 부분입니다. Nginx 가리기

#Your's NAS 부분을 원하는 이름으로 바꾸면 됩니다.

# headers-more-nginx-module

server_tokens off;

more_set_headers "Server: Your's NAS";

 

#... ...#

 

gzip               on;

gzip_vary          on;

 

gzip_comp_level    6;

gzip_buffers       16 8k;

 

gzip_min_length    1000;

gzip_proxied       any;

gzip_disable       "msie6";

 

gzip_http_version  1.0;

 

gzip_types         text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;

 

#  ngx_brotli 설정입니다.

brotli             on;

brotli_comp_level  6;

brotli_types       text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;

 

#... ...#

 

include /usr/local/nginx/conf.d/*.conf;

include /usr/local/nginx/sites-enabled/*;

}

위 설정을 보시고, 필요한 부분은 수정해서 사용하면 됩니다. 

 

 

 

11. dhparams 생성 

 

2048 bit 가 기본이고 4096 bit 도 좋습니다. 다만 4096 bit 로 할 경우 생성되는 시간이 매우 오래 걸립니다.

 

mkdir /usr/local/nginx/ssl

 

cd /usr/local/nginx/ssl

 

openssl dhparam -out dhparams.pem 4096

 

12. 세션 티켓키 생성

 

openssl rand 48 > session_ticket.key

 

13. 서버 설정 

 

nano /usr/local/nginx/sites-available

 

server {

#80포트로 접근시 https로 이동

listen 80;

server_name www.wsgvet.com wsgvet.com;

add_header "Cache-Control" "public, max-age=31536000";

location / {

rewrite       ^/(.*)$ https://www.wsgvet.com/$1 permanent;

}

}

 

server {

listen 443 ssl http2;

listen [::]:443 ssl http2;

 

server_name www.wsgvet.com wsgvet.com;

 

root /var/www;

index index.php;

 

#www.wsgvet.com이 아닌 wsgvet.com으로 접근시 www 붙여주기

#참조 : https://www.wsgvet.com/home/513

if ($host != 'www.wsgvet.com' ) {

rewrite ^/(.*)$  https://www.wsgvet.com/$1 permanent;

}

 

#해당 도메인만 퍼가기 허용, 그 이외의 도메인은 퍼가기 불가

location ~* \.(jpg|jpeg|png|gif|mp4|css|js)$ {

log_not_found off;

valid_referers none blocked baum.ga www.wsgvet.com wsgvet.com apms.wsgvet.com data.wsgvet.com pw.wsgvet.com nas.wsgvet.com jt.wsgvet.com mail.wsgvet.com wp.wsgvet.com pogovet.com www.pogovet.com;

if ($invalid_referer) { return 403; }

}

 

#캐시 시간 설정

location ~*.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|cur)$ {

expires max;

log_not_found off;

access_log off;

}

 

#Letencrypt 인증서 생성시 필수

location ~ /.well-known {

allow all;

}

 

charset utf-8;

server_tokens off;

client_max_body_size 100M;

 

location / {

try_files $uri $uri/ =404;

}

 

# Add PHP handler

location ~ [^/]\.php(/|$) {

fastcgi_split_path_info ^(.+?\.php)(/.*)$;

if (!-f $document_root$fastcgi_script_name) {

return 404;

}

try_files $fastcgi_script_name =404;

set $path_info $fastcgi_path_info;

fastcgi_param PATH_INFO $path_info;

fastcgi_index index.php;

include fastcgi.conf;

fastcgi_pass unix:/run/php/php7.0-fpm.sock;

}

 

location ~ /\.ht {

deny all;

}

 

#인증서 투명성 설정 (https://www.wsgvet.com/home/488)

ssl_ct on;

 

# This is your ECDSA certificate

# 하이브리드 인증서 설정하기 (https://www.wsgvet.com/home/492)

ssl_certificate_key /etc/letsencrypt/ecdsa/privkey.pem;

ssl_certificate /etc/letsencrypt/ecdsa/0001_chain.pem;

ssl_ecdh_curve secp384r1; # for ECDSA

ssl_ct_static_scts /etc/letsencrypt/ecdsa/scts;  #ECDSA scts

 

# Letsencrypt 기본 RSA 인증서 (https://www.wsgvet.com/web/179)

ssl_ct_static_scts /etc/letsencrypt/live/www.wsgvet.com/scts;

ssl_certificate /etc/letsencrypt/live/www.wsgvet.com/fullchain.pem;

ssl_certificate_key /etc/letsencrypt/live/www.wsgvet.com/privkey.pem;

 

#OCSP 설정 (https://www.wsgvet.com/home/454)

ssl_trusted_certificate /etc/letsencrypt/live/www.wsgvet.com/chain.pem;

ssl_stapling on;

ssl_stapling_verify on;

resolver 8.8.8.8 8.8.4.4 valid=300s;

resolver_timeout 10s;

 

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

ssl_prefer_server_ciphers on;

 

# 밑 내용은 https://blog.hakase.kr/fix-naver-link-error 여기보고 따라한 것입니다. 

ssl_ciphers EECDH+CHACHA20:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;


 

ssl_session_timeout 1d;

ssl_session_cache shared:SSL:50m;

 

ssl_dhparam /usr/local/nginx/ssl/dhparams.pem;

ssl_session_tickets        on;

ssl_session_ticket_key /usr/local/nginx/ssl/session_ticket.key;

 

#HSTS 설정은 해당 도메인에 접근시 HTTPS로 접속을 강제하는 옵션입니다.

# 밑 옵션을 넣은 후 https://hstspreload.appspot.com  사이트에서 도메인 등록 필요

#정확한 내용을 숙지한 후에 밑에 #을 제거 후 사용하면 됩니다.

#add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

 

#HPKP 설정 (참조 : https://www.wsgvet.com/home/491 )

#정확한 내용을 숙지한 후에 밑에 #을 제거 후 사용하면 됩니다.

#add_header Public-Key-Pins 'pin-sha256="PduLXRpowV4q5wsWHVtMiOTIHusvcWdDHOhG2Hmj/ec="; pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; pin-sha256="Vjs8r4z+80wjNcr1YKepWQboSIRi63WsWXhIMN+eWys="; pin-sha256="qjCCVdtrybQNPEz/7iQTKZbUKE++18Rlsg8JW4O91pA="; max-age=5184000; includeSubDomains';

 

add_header X-Frame-Options SAMEORIGIN;

add_header X-Content-Type-Options nosniff;

add_header X-XSS-Protection "1; mode=block";

 

이제 SSLlabs (https://www.ssllabs.com) 에서 점수를 확인해봅니다.

 

제 홈페이지 점수입니다.

 

 

최종 결과는 여기 스샷 (https://i.imgur.com/IMZywZX.jpg) 에 있습니다.

 

https://www.ssllabs.com/ssltest/analyze.html?d=www.wsgvet.com

 

또는 위 링크를 눌러보시면 됩니다.

, , , , , , , , , , , , , ,

5 Comments
선구자 2016.12.18 10:03  
해당 도메인만 퍼가기 허용
이거 적용해봐야겠네요
응용하면 retrun을 특정 이미지 주소로 리턴할수도 있겠네요
궁금했었는데 좋은 정보 감사드립니다.
우성군의 워드프레스에서 링크타고 왔습니다.
우성군 2016.12.18 13:49  
[@선구자] 넵 맞습니다 ㅎㅎ

그런데 리턴 이미지는 저도 해봤는데 잘 안되더라구요 ㅎ
선구자 2016.12.28 02:50  
사이트 2개는 정상적으로 되는데
한개는 문제가 있는지 403 Forbidden이네요
검색해보니 권한문제라서 퍼미션을 755로 주어도 권한이
주어지지 않는것 같습니다.

ssl은 적용이 잘되는데
내년에 다시 해봐야겠습니다.
좋은 강의 감사드립니다.
주석이 잘되어있어서 쉽게 수정할수 있었습니다.
우성군 2016.12.28 04:36  
[@선구자] 음.. 그렇다면 유저를 www-data 로 주는건 어떨까요?

chown -R www-data ./폴더이름
선구자 2016.12.28 08:40  
[@우성군] 해보겠습니다.감사합니다.
좋은 하루 되세요~~