TrueNAS 워드프레스 설치하기(WordPress, Nginx, PHP, SSL)

이전에 Ubuntu에서 워드프레스를 설하는 방법을 포스팅 했었습니다. 이번에는 TrueNAS 서버에 워드프레스를 설치해 보도록 하겠습니다.

 

FEMP 서버

Ubuntu에 설치했던 구성 그대로 워드프레스를 설치하고자 합니다. 해당 구성을 FEMP 서버(FreeBSD + (E)Nginx + MariaDB + PHP)라고 부릅니다.

각각의 프로그램을 택한 이유는 Ubuntu 워드프레스 설치하기를 참고하시면 됩니다.

MariaDB의 경우 워드프레스 jail에 설치하지 않을 것이며, MariaDB jail을 만들었다고 가정하고 진행하겠습니다. 만약 MariaDB jail을 만들지 않으셨거나, 워드프레스 jail에 MariaDB를 설치하시길 원하신다면 MariaDB jail 구축하기를 참고하여 설치해 주세요.

 

Jail 만들기

  • 이름은 원하시는 대로 설정해 주세요. 저는 Blog로 하겠습니다.
  • Jail Type은 Basejail
  • Auto-start 활성화

으로 설정해 주시고, 나머지 부분은 원하시는 대로 설정해 주세요.

 

Nginx 설치하기

pkg update && pkg upgrade

pkg를 업데이트 해 주고

pkg install nginx

nginx를 설치해 주세요.

sysrc nginx_enable="YES"

nginx를 서비스에 등록하고,

service nginx start

nginx를 시작해 주세요.

nginx가 정상적으로 동작하는지 확인하기 위해서 http://Blog_jail의_IP주소로 접속해 주세요. 그럼 아래와 같은 화면이 보일 것입니다.

만약 안 보이신다면 제대로 설치하셨는지, 잘못된 주소에 들어간 것은 아닌지 확인해 주세요.

 

WordPress, PHP 설치하기

pkg install wordpress php82 php82-dom php82-mbstring php82-filter php82-bcmath php82-exif php82-filter php82-fileinfo php82-pecl-imagick php82-simplexml php82-curl php82-ftp php82-gd php82-gettext php82-iconv php82-mysqli php82-pecl-APCu php82-phar php82-session php82-tokenizer php82-xml php82-xmlwriter php82-zip php82-zlib

WordPress와 PHP8.2 모듈들을 설치하겠습니다. 설치할 것이 많아서 시간이 좀 걸립니다.

chown -R www:www /usr/local/www/wordpress/

WordPress가 설치된 폴더의 권한을 설정해 줍니다.

 

PHP 설정하기

vi /usr/local/etc/php-fpm.d/www.conf

설치가 완료되었으면 php-fpm 설정을 위한 설정파일을 열어주세요.

(.....)
listen = /var/run/php82.sock
(.....)
listen.owner = www
listen.group = www
listen.mode = 0660
(.....)

위와 같이 설정해 주시고, 저장하고 나와주세요.

cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini-production.default
ln -s /usr/local/etc/php.ini-production /usr/local/etc/php.ini

php.ini 파일을 만듭니다.

vi /usr/local/etc/php.ini

php.ini 파일을 수정하기 위해 열어주세요.

(.....)
short_open_tag = On
(.....)
max_execution_tim = 3600
max_input_time = 3600
memory_limit = 256M
(.....)
post_max_size = 128M
(.....)
cgi.fix_pathinfo = 0
(.....)
upload_max_filesize = 128M
(.....)
allow_url_fopen = Off
(.....)
date.timezone = Asia/Seoul
(.....)

위와 같이 php.ini를 수정해 주세요. 그리고 저장하고 나갑니다.

sysrc php_fpm_enable="YES"

php-fpm 서비스를 등록해주고

service php-fpm start

php-fpm을 시작해 줍니다.

 

Let’s Encrypt 설치하기

SSL 연결을 위한 인증서를 발급해 줄 Let’s Encrypt를 설치하겠습니다. 도메인의 경우 Cloudflare에 등록되어 있다고 가정할 것이며, DNS TXT 레코드를 통해서 인증할 것입니다.

도메인이 Cloudflare에 등록되어 있지 않다면, Cloudflare 도메인 등록 및 DNS 설정을 참고하여 등록해 주세요.

pkg install py39-certbot-nginx py39-certbot-dns-cloudflare

Certbot을 설치해 줍니다.

 

Cloudflare DNS 설정

Cloudflare DNS 설정으로 가주세요. 레코드 추가를 눌러서 새로운 레코드를 만듭니다.

형식은 A, 이름은 도메인 주소(저의 경우 bongtae.net), IPv4 주소에는 여러분들의 집의 공인 IP 주소를 입력해주면 됩니다. 프록시는 체크 해제하여 DNS 전용으로 선택해주세요.

또한 새로운 레코드를 만들어서 형식은 CNAME, 이름은 www, 대상은 bongtae.net으로 설정해 주시고 프록시는 체크해제해 주세요.

 

Let’s Encrypt 인증서 발급받기

mkdir /root/.cert
vi /root/.cert/cert.ini

인증 과정에 필요한 정보를 저장해 둘 cert.ini 파일을 만들어 줍니다.

dns_cloudflare_email = mail@example.com
dns_cloudflare_api_key = asdlfkjasldkfasdf32f23rssdf

dns_cloudflare_email에 자신의 cloudflare 계정의 email 주소를 입력해 주세요.

dns_cloudflare_api_key에 api key를 입력해 주세요. Global API Key를 입력하면 됩니다.

chmod -R 400 /root/.cert/

보안을 위해 /root/.cert/를 읽을수만 있도록 설정해 줍니다.

certbot certonly --dns-cloudflare-credentials /root/.cert/cert.ini

Cloud DNS TXT 레코드 인증 모드로 Certbot을 실행해 줍니다.

Saving debug log to /var/log/letsencrypt/letsencrypt.log

How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Obtain certificates using a DNS TXT record (if you are using Cloudflare for
DNS). (dns-cloudflare)
2: Nginx Web Server plugin (nginx)
3: Spin up a temporary webserver (standalone)
4: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-4] then [enter] (press 'c' to cancel):

어떤 방식으로 인증을 진행할 지 묻습니다. DNS TXT 레코드를 이용할 것이므로 1 입력 후 엔터.

Plugins selected: Authenticator dns-cloudflare, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel):

알림용 이메일을 입력하라는 뜻입니다. 자신이 자주 사용하는 이메일을 입력해 줍니다. 그리고 엔터를 눌러주세요.

Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

약관에 동의하라는 메세지입니다. Y 입력 후 엔터.

Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

입력한 이메일로 뉴스레터같은거 보내도 되는지 묻는 메세지입니다. N 입력 후 엔터.

Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c' to cancel):

인증할 도메인을 입력하라는 메세지 입니다.

bongtae.net *.bongtae.net

위와 같이 도메인을 입력해 주세요.

Successfully received certificate.
Certificate is saved at: /usr/local/etc/letsencrypt/live/bongtae.net/fullchain.pem
Key is saved at:         /usr/local/etc/letsencrypt/live/bongtae.net/privkey.pem
This certificate expires on 2022-11-11.
These files will be updated when the certificate renews.

NEXT STEPS:
- The certificate will need to be renewed before it expires. Certbot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal-setup for instructions.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

그럼 위와 같은 메세지가 뜹니다. 해당 메세지에서 인증서가 어디에 저장 되었는 지도 확인할 수 있습니다. 인증서 저장 위치는 나중에 필요하니 메모해 주세요.

 

디피-헬만 키 생성하기

SSL 연결을 위한 디피-헬만 키 교환에서 사용될 키를 생성하도록 하겠습니다.

mkdir /usr/local/etc/cert
openssl dhparam -out /usr/local/etc/cert/dhparam.pem 2048

2048비트 길이의 키를 /usr/local/etc/cert/dhparam.pem에 저장합니다. 시간이 좀 걸릴 수도 있으니 기다려 주세요.

 

Nginx 설정하기

mkdir -p /usr/local/etc/nginx/conf.d

Nginx 설정 파일이 저장될 폴더를 만들어 줍니다.

vi /usr/local/etc/nginx/conf.d/wordpress.conf

wordpress.conf 설정파일을 만듭니다.

server {
    listen 80;
    root /usr/local/www/wordpress;
    index  index.php index.html index.htm;
    server_name  bongtae.net www.bongtae.net;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    root /usr/local/www/wordpress;
    index  index.php index.html index.htm;
    server_name www.bongtae.net;

    ssl_certificate /usr/local/etc/letsencrypt/live/bongtae.net/fullchain.pem;
    ssl_certificate_key /usr/local/etc/letsencrypt/live/bongtae.net/privkey.pem;
    ssl_trusted_certificate /usr/local/etc/letsencrypt/live/bongtae.net/chain.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

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

    return 301 https://bongtae.net$request_uri;
}

server {
    listen 443 ssl http2;
    root /usr/local/www/wordpress;
    index  index.php index.html index.htm;
    server_name bongtae.net;

    ssl_certificate /usr/local/etc/letsencrypt/live/bongtae.net/fullchain.pem;
    ssl_certificate_key /usr/local/etc/letsencrypt/live/bongtae.net/privkey.pem;
    ssl_trusted_certificate /usr/local/etc/letsencrypt/live/bongtae.net/chain.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 30s;

    ssl_dhparam /usr/local/etc/cert/dhparam.pem;

    client_max_body_size 100M;

    autoindex off;
   
    location / {
      try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
      try_files $fastcgi_script_name =404;
      include fastcgi_params;
      fastcgi_pass    unix:/var/run/php80.sock;
      fastcgi_index   index.php;
      fastcgi_param DOCUMENT_ROOT   $realpath_root;
      fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; 
    }
}

각 server 블럭에서 server_name 부분의 도메인을 자신의 서버에 사용할 도메인으로 변경해 주시고, ssl_certificate 부분의 인증서와 키 위치 등을 메모해 둔 Let’s Encrypt 인증서 위치로 변경해 줍니다.

설정을 간단히 설명하면,

  • 80/tcp 포트로 들어온 입력은(HTTP 연결) HTTPS로 바꾸어 줍니다.
  • www.bongtae.net로 들어온 입력은 bongtae.net으로 리다이렉트 해줍니다.

결론적으로, 무조건 HTTPS연결을 이용하게 됩니다. 이것이 보안적인 측면에서도 우수합니다.

 

cp /usr/local/etc/nginx/nginx.conf /usr/local/etc/nginx/nginx.conf.backup

nginx.conf 파일을 수정할 것인데, 안전을 위해 nginx.conf 파일을 백업해 둡니다.

vi /usr/local/etc/nginx/nginx.conf

nginx.conf 파일을 열어주세요.

(.....)
http {
(.....)
    include /usr/local/etc/nginx/conf.d/*.conf;
}

위처럼 파일을 수정해 주시고, 저장하고 나가주세요.

nginx -t

nginx 구성에 오류가 있는지 확인합니다.

nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful

오류가 없으면 위의 문구가 나타납니다. 만약 오류가 발생하면 해당 오류를 수정해 주세요.

service php-fpm restart && service nginx restart

오류가 없는 것을 확인했으면 php-fpm과 nginx를 재시작 해 줍니다.

 

데이터베이스 만들기

iocage console MariaDB

Blog jail에서 나와서 MariaDB jail로 들어가 주세요. MariaDB를 Blog 폴더에 설치하셨어도 아래 과정을 똑같이 하시면 됩니다.

mysql -u root -p

MariaDB를 실행합니다. 비밀번호를 입력해 주세요.

CREATE USER bloguser@'Blog_jail의_IP' identified by 'password';
CREATE DATABASE blogdb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
grant all privileges on blogdb.* TO bloguser@'Blog_jail의_IP';
FLUSH PRIVILEGES;
exit;

bloguser이라는 이름을 가진 유저가 password라는 비밀번호로 Blog jail에서만 접근할 수 있도록 설정합니다.

또한, utf8mb4 문자셋을 가지는 blogdb라는 이름을 가지는 데이터베이스를 만들고, 모든 권한을 bloguser에게 주었습니다.

정리하면 아래와 같습니다.

  • 유저 이름: bloguser
  • 비밀번호: password
  • 데이터베이스 이름: blogdb

따옴표까지 포함해서 명령어를 입력해 주세요.

 

포트포워딩 하기

워드프레스에 접속할 포트를 설정해 줍니다. 원하는 외부 포트의 UDP와 TCP를 모두 Blog jail의 IP와 포트포워딩 해 주세요.

사용하는 포트는 HTTP를 위한 TCP 80번 포트, HTTPS를 위한 TCP 443번 포트 입니다.

Blog jail의 TCP 80, TCP 443번 포트 ↔ 외부망의 TCP 80, TCP 443번 포트

 

WordPress 설정하기

이제 https://도메인_주소로 접속하면 위와 같이 wordpress 설정 화면을 볼 수 있습니다.

워드프레스 설정의 경우 그리 어렵지 않고, 인터넷에 상세하게 나와 있으므로 생략하겠습니다.

설정 중간에 요구하는 DB 서버의 경우 MariaDB jail의 IP를 입력하면 됩니다. 만약 Blog jail에 MariaDB를 설치하셨으면 localhost을 입력하시면 됩니다.

 

마치면서

TrueNAS 서버에 워드프레스를 설치하였으므로 이제 자신만의 블로그를 운영할 수 있습니다.

사용하다가 오류가 발생할 수도 있는데, 이때 편하게 해결하기 위해서는 Blog jail의 스냅샷을 주기적으로 찍고 문제가 발생하였을 때 최신 스냅샷으로 롤백하는게 가장 편할 것입니다. 따라서 안전을 위해서 스냅샷을 주기적으로 찍는 것을 추천드립니다.

답글 남기기