2017-08-04

Synology NAS에 워드프레스 설치하기 (Nginx + PHP-FPM7 + MariaDB)

본 워드프레스는 현재 Synology DS216+II에서 구동되고 있다. 최근에 Synology의 DSM 백엔드를 굳이 건드리지 않고도 Nginx의 설정값을 수정 및 유지하는 방법을 알아내었다. 이걸 알기 전에는 이게 설정이 제대로 안되서 SSL이 일부만 적용되거나 WP Super Cache 설정도 제대로 되지 않는 등 문제가 많았었다. 알아낸 김에 이번에 완전히 제대로 설치 및 설정하였다. 내용을 공유하고자 글을 작성한다. 본 워드프레스 설치기는 DSM 6.1.3-15152 Update 1을 기준으로 작성되었다.

설치할 환경, 워드프레스 및 플러그인

본 글에서 설치할 워드프레스 환경은 다음과 같다.

Synology NAS에 필요한 패키지 설치

Web Station, MariaDB 10, PHP 5.6 및 7.0, phpMyAdmin 그리고 로그센터를 설치한다. 아파치는 설치하지 않는다. 안그래도 다른 서비스도 돌려야 하니 NAS 자원을 최대한 아껴써야하는데 램 많이 잡아먹는 아파치는 그렇게 도움이 되지 않는다. 본인의 경우 램을 8GB짜리로 교체하긴 했지만 Docker쪽에 돌리는게 있어서 좀 아껴쓰는 중이다.

로그센터는 Nginx 로그를 저장하기 위해 필요하다. 서버로부터 받는 로그를 /var/log/ 등의 폴더에 저장해서 쓰면, 에러가 발생할 때 매번 SSH를 통해 접속해서 tail 명령어를 써서 일일히 찾아봐야 한다. 로그센터는 syslog 서버로 사용할 수 있고, Nginx의 로그를 이쪽으로 전송하면 DSM에서 쉽게 로그를 검색해 볼 수 있어 편리하다. 로그센터에서 오류가 발생하면 이메일로 알람을 보내도록 설정할 수도 있어 더더욱 편리하다.

MariaDB 설정하기

MariaDB 10 패키지를 설치했으면 DSM에서 MariaDB 10 아이콘을 눌러 관리자 비밀번호를 설정해준다. 초기에 비밀번호가 설정되어 있지 않기 때문에 반드시 설정해줘야 한다. 위쪽에 MariaDB 패스워드 변경을 눌러 비밀번호 변경을 진행할 수 있도록 한다.

Synology에서의 MariaDB 설정창

설정한 MariaDB 비밀번호를 기억해 두었다가 phpMyAdmin으로 접속하여 이를 이용해 루트 사용자로 로그인한다. phpMyAdmin은 별 다른 설정을 하지 않았다면 http://NAS 주소/phpMyAdmin으로 접속할 수 있다.

phpMyAdmin의 상단 메뉴에서 바로 SQL을 누른다. 다음의 SQL문을 실행하여 wordpress 데이터베이스를 생성한다.

CREATE DATABASE wordpress;

wordpress 데이터베이스가 왼쪽의 목록에 나타났다면, 이번에는 mysql 데이터베이스를 클릭하고 상단 메뉴의 SQL을 선택한다. 다음의 SQL문을 복사해서 수정하고 실행한다. wordpress 데이터베이스를 사용할 유저의 이름과 접속 위치, 비밀번호를 설정해주기 위함이다. root를 그대로 사용해도 되지만 보안을 위해서 이렇게 해주는 것이다.

/* create user '계정아이디'@'접속위치' identified by '패스워드';
 * grant all privileges on wordpress.* to '계정아이디'@'접속위치'; */

create user 'wordpress'@'localhost' identified by 'p@ssword!';
grant all privileges on wordpress.* to 'wordpress'@'localhost';

Wordpress 파일 다운로드

Wordpress.org에 접속하여 최신 Wordpress 압축파일을 다운로드 받는다. 파일 스테이션으로 이를 업로드하고 압축을 푼다. Web Station을 설치하면 web이라는 이름의 공유폴더가 생기는데, 본인은 여기에 wordpress라는 하위 폴더를 만들고 여기에 wordpress php 파일들을 넣었다.

Wordpress.org에서 압축파일을 다운로드 받는다.
web/wordpress에 압축을 풀었다.

가상호스트 설정

Web Station에서 가상호스트를 설정해준다. 호스트 이름에 워드프레스에 사용할 도메인을 입력해주고, 문서루트는 web/wordpress로 설정한다. HTTP 백엔드 서버는 Nginx로, PHP는 7.0으로 선택해 준다. HTTPS를 설정하여 사용할 것인데, 보안을 위해 HSTS를, 전송 최적화를 위해 HTTP/2를 체크해준다.

Synology Webstation 가상 호스트 설정

SSL 인증서 적용

제어판 > 보안 > 인증서로 이동하여 인증서를 발급받고, 구성을 클릭하여 해당 가상호스트에 SSL 인증서를 적용한다. SSL 인증서를 적용하지 않아도 사실 블로그 운영에는 아무 제한이 없지만, 인증서를 적용하면 구글 등의 사이트에서는 검색순위 상위에 노출되는 효과가 있기에 반드시 해주는 것이 좋다. (참조 구글, 웹 사이트 순위 산정에 암호화 반영 “https 적용 권고”)

Synology에서는 Let’s Encrypt를 이용해 3개월마다 자동으로 갱신되는 무료 인증서를 발급받아 사용할 수 있는데, 이에 대한 자세한 방법은 아래의 글들을 참고하자. 본인의 경우 이미 본 블로그를 운영중이라 발급받는 절차를 보여줄 수가 없다.

Nginx 추가 설정

Nginx 사용자 설정값 유지하기 포스트를 참고하여 Nginx 설정을 해주도록 한다. 여기까지만 설정하여 워드프레스에 접속해도 구동은 되는 것처럼 보이지만, Permalink를 포함해 몇가지 기능이 제대로 작동하지 않기 때문에 반드시 Nginx 세부 설정이 필요하다.

WP Super Cache 및 Permalink를 위한 Nginx 설정

추후 설치할 WP Super Cache 플러그인이 제대로 작동할 수 있도록 하기 위해, 그리고 Permalink가 제대로 작동할 수 있도록 하기 위함이다. SSH로 DSM에 접속하여 위에서 설정한 가상호스트용 유저설정 폴더에 user.conf.supercache파일을 만들어주고, 다음의 내용을 붙여넣는다.

# WP Super Cache 설정 시작.
set $cache_uri $request_uri;

# POST 요청시 Super Cache 작동하지 않도록 설정
if ($request_method = POST) {
    set $cache_uri 'null cache';
}

# Get 요청시에 인수가 존재할 경우 Super Cache 작동하지 않도록 설정
if ($query_string != "") {
    set $cache_uri 'null cache';
}

# 다음의 주소로 시작할 경우 Super Cache 작동하지 않도록 설정
# wp-admin, xmlrpc 등을 포함함
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
    set $cache_uri 'null cache';
}

# 로그인한 사용자나 최근에 댓글을 달았던 사람 상대로 Super Cache 작동하지 않도록 설정
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in") {
    set $cache_uri 'null cache';
}

# 1. Permalink가 작동하도록 설정한다.
# 2. 주소가 들어왔을 때 supercache가 가지고 있는 파일이 존재할 경우
#    PHP를 거치지 않고 바로 캐시를 전송시킨다.
location / {
    root   /volume1/web/wordpress;
    index  index.php index.html index.htm;
    try_files /wp-content/cache/supercache/$http_host/$cache_uri/index-https.html $uri $uri/ /index.php?$args;
}

HTTPS로 강제 리다이렉트

사용자 설정폴더에 user.conf.force-https 파일을 만들고, 다음의 내용을 붙여넣는다. 사용자_도메인 부분에는 본인의 도메인을 입력할 수 있도록 한다.

# http로 들어오면 https로 301 리다이렉트
if ($scheme = http){
    return 301 https://사용자_도메인$request_uri;
}

Gzip 전송

클라이언트에 컨텐츠를 전송할 때 Gzip으로 압축하여 보낼 수 있도록 한다. 사용자 설정폴더에 user.conf.gzip 파일을 만들고, 다음의 내용을 붙여넣는다. 아래에 따로 수정할 내용은 없다. WP Super Cache에서 캐시파일을 미리 gz 파일로 압축해주는 설정을 켰을 경우에 gzip_static을 on으로 설정하면, gz파일을 자동으로 검색하여 이를 대신 전송해준다. 반드시 켜도록 하자. CPU 사용량을 줄이고 전송량도 줄일 수 있다.

# GZIP 전송 설정 
gzip on;
gzip_disable "msie6";

gzip_static on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 9;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types
    text/plain
    text/css
    text/js
    text/xml
    text/javascript
    application/javascript
    application/x-javascript
    application/json
    application/xml
    application/rss+xml
    image/svg+xml;

정적 파일 캐시 만료일 설정

스타일, 자바스크립트, 이미지 파일 등 변할일이 별로 없는 정적 파일들의 경우에 대해서 캐시 만료일을 설정해주면, 해당 페이지에 접속했을때 정적파일들을 다시 다운로드 받지 않아 속도가 빨라진다. 전송량을 줄이고 빠른 페이지로딩을 위해 반드시 필요하다. user.conf.cache_expire 파일을 만들고 아래의 내용을 붙여넣자.

location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
    expires 30d;
    add_header Pragma public;
    add_header Cache-Control "public";
}

로깅 설정

로그센터에 Nginx의 로그를 기록할 수 있도록 설정하자. 접속 로그는 안켤수도 있으나 에러 로그는 반드시 켜도록 하자. 에러 로그는 반드시 모니터링하여 수정해야 한다. access_log 혹은 error_log 뒤에 보통은 /var/log/nginx/access.log 처럼 파일 이름을 넣는게 일반적이지만, 다음의 코드에서는 syslog에 대응하는 코드로 작성되어있다. user.conf.logging 파일을 만들고 아래의 내용을 붙여넣자.

#access_log syslog:server=localhost,facility=local7,severity=info,tag=nginx combined;
access_log off;

error_log syslog:server=localhost warn;

문제없이 설정이 되어 있다면 다음과 같이 로그센터에서 Nginx의 에러로그가 잡히는 것을 볼 수 있다. 아래의 로그는 본인이 의도적으로 발생시킨 오류이며 현재 본 워드프레스에는 오류가 없다.

로그센터에 기록되는 Nginx 에러 로그

자세한 Nginx의 syslog 로깅 방법은 Nginx 사이트에서 매뉴얼이 제공되고 있으니 확인하여 세부설정할 수 있도록 하자.

마지막 보안 설정

접근권한 설정을 위한 마지막 설정이다. favicon.ico, robots.txt 파일 등에 대한 접근권한 설정, uploads 폴더 등에 존재할 수 있는 php 파일에 대해 서버차원에서의 직접 접근 금지, 특정 IP를 제외한 로그인 시도 방어 등을 설정한다. user.conf.restriction 파일을 만들고 다음의 내용을 붙여넣는다.

# 파비콘 접속시
# 파일이 발견되든 발견되지 않든 에러로그를 발생시키지 않고
# 발견되더라도 액세스로그를 발생시키지 않는다.
# 필요없으면 제거해도 좋으나 로그가 많이 발생할 것이다.
location = /favicon.ico {
    log_not_found off;
    access_log off;
}

# robots.txt 파일 접속시
# 파일이 발견되든 발견되지 않든 에러로그를 발생시키지 않고
# 발견되더라도 액세스로그를 발생시키지 않는다.
# 또한 모든 경우에 대해 접근을 허용한다.
# 필요없으면 제거해도 좋으나 검색봇에 의한 로그가 많이 발생할 것이다.
location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}

# .htaccess, .htpasswd, .DS_Store 파일 등 .으로 시작하는 파일에 대해서
# 접근할 수 없도록 한다.
location ~ /\. {
    deny all;
}

# uploads, files 폴더 등에 존재할 수 있는 php 파일에 대해서
# 접근할 수 없도록 한다.
location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
}

# wp-admin 경로와 wp-login.php에 대하여
# 특정 IP를 제외하고는 모두 접근 불가로 만든다.
# 불필요한 로그인 시도를 막는다.
# 192.168.0.0/24로 설정하면 내부망에서 접속을 모두 가능하게 한다.
location ~ ^/(wp-admin|wp-login\.php) {
    allow 192.168.0.0/24;
    deny all;
}

DB연동을 위한 wp-config.php 파일 수정

wp-config.php파일을 수정하여 DB연동을 위한 부분을 다음과 같이 수정한다. 앞에서 데이터베이스 이름이나 유저 이름을 wordpress가 아닌 다른것으로 수정했다면 그것을 참고한다.

define('DB_NAME', 'wordpress');
define('DB_USER', 'wordpress');
define('DB_PASSWORD', '암호');
define('DB_HOST', 'localhost:/run/mysqld/mysqld10.sock');

보안을 위한 유니크 키값은 Wordpress.org에서 직접 자동생성을 제공해주는 사이트가 있다. 해당 사이트에 들어가면 다음과 같은 내용을 송출해 줄것이다. 복사하여 wp-config.php파일 내의 해당 부분에 붙여넣도록 하자.

define('AUTH_KEY', '[MH^Y=8&F@ea-deLj6Mp(4=*KDTiRu3SYT5Z|gvZ6 @VyK)+QY<!U;X4#JFUpr_5');
define('SECURE_AUTH_KEY', '`\{\%rv-(|[JhDFpCtDVo_^L-w#k]]!/|BVaku@?/[ 7)_11sk|G?kn_eMSH7o<l!9');
define('LOGGED_IN_KEY', 'L>Zp|wHwN>lUh+n+KJTcEqJy)eZ,$J,G\{\{z5k)(yC$c]tl9,T#7 Yz/@!=LeqtPL');
define('NONCE_KEY', '_|#fX?o9p;)H@\{9GyA1u0!O;F&Z<^!T`XJD_Lae\%I;lRWYwcbFWzixn/9JI,T++W');
define('AUTH_SALT', '|6FvI!P^fk8.ekvzBuB!fJ^|2rb!-iGRK9@+D=PWbl)V@lJ!EkvVx/KSU*}m,zFL');
define('SECURE_AUTH_SALT', ',atK]qaehhq-Qpr*Ji?k4!g3z6p,u)c.?v(_9N\{OO|1TX++4D}W:BPo+vE9X\{e\{]');
define('LOGGED_IN_SALT', ':t+HO0.*b-72LWdPG&b4LdsQ0qn<|=$ek/4BGraX[ujg`8Fi1DSsL!Ctgmfp-sku');
define('NONCE_SALT', '?S+A[a[S9-YtjATu[=4N&t5nE>0)7 JQFHYC*<}Rq3kdL=EG~|Lb|JKo*qyt^U42');

설정 완료!

위의 과정들을 전부 따라했다면 워드프레스 설정은 모두 끝난것이다. 이제 도메인을 통해 사이트에 접속하고 워드프레스를 운영할 수 있도록 하자!

댓글 42

님께 답글 취소
댓글 등록 요청
스팸 댓글을 줄이기 위해 Akismet을 사용하고 있습니다.