워드프레스 설치 하나씩 따라하기

필자는 처음 CMS(content management system) 시스템(블로그 용)을 구축하고자 할 때, 워드프레스에 대해 알고 있었지만, 자바 개발자로 자바 환경의 CMS 시스템을 우선 검토 했었습니다. 하지만 커뮤니티 지원, 플러그인, 테마, 다양한 호스팅 지원 및 문서(자료) 등을 봤을 때 역시 워드프레스의 대안은 없어 보였으며, CMS라 불리기에는 너무 작게 느껴졌고, 여러 이해 관계자가 존재하는 거대 플랫폼으로 보였습니다.

본 글에서는 워드프레스 설치에 대한 기초 수준의 내용을 다루고 있으며 리눅스(CentOS), MySQL, nginx, php, 워드프레스 및 주요 플러그인 설치를 설명 하겠습니다.

[toc]

소개

워드프레스는 2003년에 PHP 기반의 GPLv2(오픈소스) 라이선스로 개발이 되었으며, 지난 13년 간의 수많은 사용자들로 인해 전세계 26% 이상 웹사이트가 워드프레스로 만들어졌다. 이를 이용해 다양한 웹사이트, 블로그, 웹 애플리케이션 등을 만들 수 있으며, 이는 우리가 이것들을 만드는데 워드프레스를 선택해야 하는 가장 중요한 이유일 것이다. 하지만 많은 사람들이 사용한다는 이유 외의 정말 왜 수많은 사람들이 워드프레스를 사용하게 되었는지 워드프레스의 주요 특징에 대해서 알아보자.

테마

테마는 웹사이트의 외형을 손쉽게 변경할 수 있는 기능이며, 모든 CMS 시스템에는 기본으로 포함되는 필수 기능이다. 하지만 워드프레스의 테마 지원 기능은 조금 특별하다. 단순히 CSS 수정을 벗어나 php, html, 기존 테마 확장 등 다양한 고급 기능을 제공해, 마지 워드프레스로 만들어진 것이 아닌 것과 같이 모든 구조를 변경할 수 있다. 물론 이때쯤 되면, 워드프레스에 대해 깊은 지식을 가지고 있어야 하며, 일반 자바 등의 언어를 가지고 개발하는 것과 별반 다를 것 없는 작업 양이 들 것이다. 다만 처음부터 큰 대형 포탈이 아닌, 소규모로 시작하는 개인 또는 스타트업 회사에게는 몇 시간의 투자로 수많은 기능과 훌륭한 디자인을 가지는 웹사이트를 가지게 되는 멋진 경험을 하게 될 것이다.

themify.me 테마(이미지 출처: https://themify.me/themes)

또 하나 계속 언급하겠지만 가장 중요한 사실은 세계에서 가장 많은 테마를 가지고 있다는 것이며, 이를 지원하기 위한 여러 공개 및 유료 테마 사이트, 디자이너 및 퍼블리쉬어(웹 편집자)가 존재 한다는 것이다. 참고로 워드프레스를 설치, 설정하는 데는 얼마 안 걸린다. 테마를 선택하는데 수 시간을 허비하게 될 것이다. 하지만 제일 재미있는 일이 될 것이나, 너무 테마 선택에 시간을 허비하지 않았으면 좋겠다. 어느 정도 유명해지고, 본인만의 디자인을 가지고 싶을 땐, 어차피 다시 세밀한 작업을 통해 새로운 사이트로 탄생하게 될 것이니까 말이다. 마무리로 유명한 테마 사이트를 소개 하겠다.

더 자세한 내용은 "wordpress theme"로 구글에 검색하기 바라며, medium, brunch와 같은 훌륭한 사이트가 나오길 기대한다.

플러그인

플러그인은 워드프레스의 기본 기능 외에 추가 기능을 제공할 수 있게 도와주며, 세상의 모든 CMS 중에서 가장 많은 플러그인을 제공한다. 수많은 플러그인이 무료로 제공하고 있으며, 유료 플러그인 역시 많다. 몇몇 대표 플러그인들은 뒤에 다루겠지만 플러그인을 통해 비주얼 에디터, SNS(social network service) 연동, 검색 연동(SEO, search engine optimization), 구글 웹사이트 분석, AdSense, 쇼핑몰, 결제, SMS, 기존 게시판 등 나열하기 조차 힘들 정도 많은 플러그인들이 제공된다. 쉽게 말해서 여러분이 생각하는 모든 플러그인들은 존재한 다라고 봐도 좋을 정도이다. 참고로 플러그인 제공은 오픈 소스의 정신을 이어 받아 무료가 많지만 일정 수준의 고급 기능은 유료로 업그레이드를 해야 되는 제공되는 수익 구조로 움직이고 있다.

워드프레스 플러그인 로고(이미지 출처: http://www.wordpressdenver.com/how-many-wordpress-plugins-are-just-too-many/)

마지막으로 꼭 필요한 기능의 플러그인만을 설치하고, 여러 사용자가 접속하는 사이트가 되었을 땐, 관리자 PC에 테스트 환경을 구축하여 미리 테스트하고, 정말 유용한 플러그인지, 이 플러그인으로 인해 사이트가 느려지지는 않는지, 기존 플러그인과 충돌하지는 않는 지를 설치 시 테스트해야 한다.

모바일 지원

안드로이드, iOS, 윈도우폰, 블랙베리 등 수많은 모바일 기기에 반응형 웹으로 자동으로 디자인이 변경된다. 하지만 일부 테마에 따라 모바일에서 디자인이 깨질 수도 있으니 테마를 설치했다면, 꼭 모바일 기기 또는 웹 브라우저의 개발자 도구를 통해 모바일 환경으로 확인 해야 한다.그렇다 하더라도 우리가 모바일 기기와 웹 브라우저를 동시에 제공한다는 것은 노력 대비 엄청난 혁신이 아닐 수 없다.

방응형 웹

(이미지 출처: https://wordpress.org/)

그밖에 기능

그 밖에도 멀티 사용자, 멀티 블로그, 멀티 카테고리, 태깅, RSS 피드 등 여러 수백가지의 기능들이 제공이 된다. 이제부터 워드프레스의 기능 수해를 받기 위해 첫 발을 딛어 보자.

준비 되셨나요! OS 설치 부터 갑니다.

CentOS 설치와 설정

CentOS

지원되는 OS는 윈도우, 리눅스 계열, Max OS 등이 있다. 여기에서는 CentOS 6.8이라는 리눅스 배포판을 사용하도록 한다. 이 영역은 cafe24, 가비아와 같은 곳에서 서버 호스팅을 받는 경우 불필요한 과정이므로 다음 설정으로 넘어가도록 하자. 일반적으로 테스트 환경 구축을 위해 VirtualBox(가상 머신) 환경에서 사용하므로 여기서는 이를 가정으로 하겠다.

CentOS 설치

https://wiki.centos.org/Download 주소에서 6.8 버전의 x86_64 이미지를 받도록 한다. i386과 x86_64는 CPU의 아키텍처를 뜻하는 것으로 근래 나온 서버 또는 PC는 모두 64bit CPU를 사용하므로 x86_64를 선택 한다.

차례대로 따라할 수 있게 화면 캡쳐와 설명을 달아놨으나, 필자의 OS 환경은 영어라 영문 기준의 화면이다. 이점 감안하여 봐주시길 바란다.

http://www.slideshare.net/combineads/centos-68

위 과정으로 워드프레스 서버가 설치 되었다면, sshd를 설치하여, 외부에서 해당 서버로 ssh 접속이 해야 한다.

1
2
3
4
5
6
7
8
# 관리자 로그인
su -
# sshd 설치
yum -y install openssh-server openssh-clients
# 부팅 시, sshd가 구동되게 변경
chkconfig sshd on
# sshd 데몬 시작
service sshd start
1
2
3
4
5
6
7
8
9
10
combine@combine-ThinkPad-T550:~$ ssh 192.168.56.100
ssh: connect to host 192.168.56.100 port 22: Connection refused
combine@combine-ThinkPad-T550:~$ ssh 192.168.56.100
The authenticity of host '192.168.56.100 (192.168.56.100)' can't be established.
RSA key fingerprint is SHA256:BLlJmhDvnDQNQUQF4RSy7rXaLe6VfleQEf00eAfMj3Y.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.56.100' (RSA) to the list of known hosts.
combine@192.168.56.100's password: 
[combine@localhost ~]$ ls
Desktop  Documents  Downloads  Music  Pictures  Public  Templates  Videos

CentOS 설정

설정부터는 일반 서버 호스팅에서도 필요한 항목이다. 여기에서는 기본적인 보안과 워드프레스를 설치하기 위한 추가 Yum 저장소(Repository)를 설정 한다. Yum은 Red Hat 계열의 리눅스에서 제공하는 RPM(Red Hat Package Manager)을 이용한 소프트웨어 관리자를 말하며, 이를 이용해 원격에 저장되어 있는 소프트웨어를 손쉽게 설치할 수 있다. 참고로 Debian 계열에서는 deb를 이용한 소프트웨어 관리자로 APT(Advanced Package Tool)가 있으며, 대표 명령어인 apt-get이라고도 불린다.

여러분의 서버에 ssh를 이용해 root로 다음과 같이 접속이 된다면, ssh 버그에 의해 얼마든지 보안에 위헙을 받을 수 있는 상황이다.

1
2
3
ssh root@192.168.56.100
root@192.168.56.100's password: 
[root@localhost ~]#

만약 접속이 된다면!!! 다음과 같은 과정을 통해 반드시 다음 과정을 통해 방어하도록 하자. root 계정은 관리자 계정으로 해당 서버의 모든 것(패킷 감시, 전체 데이터 삭제, 좀비 서버 등)을 할 수 있다.

사용자 계정 생성

root 계정외의 서버에 별도의 사용자 계정을 생성해 관리해야 한다. 이는 잘 알려진 계정명(root, apache, nginx, mysql 등)을 사용하지 않으므로 보안 취약점을 개선할 수 있다.

1
2
3
4
5
6
7
8
# wpdemo 사용자 계정 추가
[root@localhost ~]# adduser wpdemo
# wpdemo 사용자 계정 비밀번호 변경
[root@localhost ~]# passwd wpdemo
Changing password for user wpdemo.
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.

물론 이렇게 해도 여러 정황을 이용하여 서버에서 사용되는 계정을 파악할 수는 있지만, 최소한의 방어를 위해 설정 한다. 그리고 더불어 내 계정으로 로그인한다는 것이 얼마나 멋있는 일인가?

SSH Daemon 설정

외부에서 ssh를 통해 root 접속이 안 되게 막아야 한다. 다음의 과정을 통해 이를 할 수 있다.

1
[root@localhost ~]# vi /etc/ssh/sshd_config
1
#PermitRootLogin yes

PermitRoot 검색(/PermitRoot)하면, 위와 같은 내용을 볼 수 있다. 이를 다음과 같이 변경한다. 여기서 vi 또는 vim에 대한 설명은 생략 했다.

1
PermitRootLogin no

해당 내용을 정장 후 sshd 서버를 재시작 하면, root 계정으로 로그인이 안 된다. 다음의 명령을 내리기 전에 추가한 사용자(예제에서는 wpdemo) 계정이 접속 가능한지 확인 한다.

1
2
3
4
5
6
7
8
9
combine@combine-ThinkPad-T550:~$ ssh wpdemo@192.168.56.100
wpdemo@192.168.56.100's password: 
Last login: Sun Jul 17 18:55:12 2016 from 192.168.56.1
[wpdemo@localhost ~]$ su -
Password: 
[root@localhost ~]# service sshd restart
Stopping sshd:                                             [  OK  ]
Starting sshd:                                             [  OK  ]
[root@localhost ~]# 

SMTP 설정

HTTP 데몬에서 SMTP를 이용해 메일을 보내기 위해서는 아래와 같은 설정을 해야한다. php에서도 PHPMailer가 메일을 보내기 위해서는 동일한 권한이 필요하다.

1
2
3
4
5
6
7
[wpdemo@localhost ~]$ su -
Password: 
[root@localhost ~]# getsebool httpd_can_sendmail
httpd_can_sendmail --> off
[root@localhost ~]# setsebool -P httpd_can_sendmail 1
[root@localhost ~]# getsebool httpd_can_sendmail
httpd_can_sendmail --> on

해당 설정 시(setsebool) 약 1분정도가 소요될 수 있으므로 절대 멈춘 것이 아니다.

(혹시 이것이 왜 이렇게 오래 걸리는지 또는 추가 설정이 필요한지 아시는 분은 댓글 부탁 드립니다)

Yum 저장소 추가

PHP, nginx, MySQL 5 버전을 설치하기 위한 Yum 저장소를 추가 한다. 여기에서는 CentOS, RHEL 7과 CentOS, RHEL 6에 대해서 모두 다뤘다. 버전에 맞게 사용하면 된다.

1
2
3
4
[root@localhost ~]# yum install epel-release
[root@localhost ~]# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
[root@localhost ~]# rpm -Uvh https://mirror.webtatic.com/yum/el6/latest.rpm
[root@localhost ~]# rpm -Uvh http://repo.mysql.com/mysql-community-release-el6-5.noarch.rpm
1
2
3
4
[root@localhost ~]# yum install epel-release
[root@localhost ~]# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
[root@localhost ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
[root@localhost ~]# rpm -Uvh http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm

워드프레스 관련 소프트웨어 설치

워드프레스가 필요로 하는 소프트웨어는 웹 서비스를 위한 nginx와 php 7, 데이터를 저장하기 위한 MySQL이 필요하다. 여기에서 각 소프트웨어의 역할과 설치 과정을 알아본다.

초기에 개인 또는 스타트업을 대상으로 하는 설명이라 비용을 최소화 하기 위해 최소한의 서버 호스팅을 받는 상황이라 가정 했으며, 메모리 3G, HDD 40G이다. 메모리는 MySQL DB까지 고려했을 때, 최소 3G가 여야 한다.(예상 메모리 사용량 OS: 256M, Web Server: 1G, DB: 1.5G)

PHP 설치

PHP는 서버에서 동적으로 HTML을 구성하기 위한 서버측 스크립트 언어이다. 워드프레스 4.5 버전은 PHP 5.6 이상의 버전을 요구하며, 여기서는 PHP 7 버전을 설치한다. 참고로 PHP 7버전이 5버전에 보다 성능이 크게 개선되었다.

아래는 yum install php70w 으로 설치를 하며, yum search php70w로 설치를 확인하는 과정이다. 중간에 설치 확인 시 'y'를 입력하면 되고, 이후 설치부터는 아래처럼 상세한 yum 설치 정보는 생략 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
[root@localhost ~]# yum install php70w
Loaded plugins: fastestmirror, refresh-packagekit, security
Setting up Install Process
Loading mirror speeds from cached hostfile
epel/metalink                                                                                                                                                                                                                           | 5.3 kB     00:00     
 * base: ftp.daumkakao.com
...
 php70w-common                                                  x86_64                                                  7.0.8-1.w6                                                             webtatic                                                  1.1 M
Transaction Summary
===============================================================================================================================================================================================================================================================
Install       9 Package(s)
Total download size: 7.6 M
Installed size: 28 M
Is this ok [y/N]: y
Downloading Packages:
(1/9): apr-1.3.9-5.el6_2.x86_64.rpm                                                                                                                                                                                                     | 123 kB     00:00     
...
(9/9): php70w-common-7.0.8-1.w6.x86_64.rpm                                                                                                                                                                                              | 1.1 MB     00:02     
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                                          533 kB/s | 7.6 MB     00:14     
...
 From   : /etc/pki/rpm-gpg/RPM-GPG-KEY-webtatic-andy
Is this ok [y/N]: y
Running rpm_check_debug
...
  Verifying  : apr-util-1.3.9-3.el6_0.1.x86_64                                                                                                                                                                                                             9/9 
Installed:
  php70w.x86_64 0:7.0.8-1.w6                                                                                                                                                                                                                                   
Dependency Installed:
  apr.x86_64 0:1.3.9-5.el6_2         apr-util.x86_64 0:1.3.9-3.el6_0.1  apr-util-ldap.x86_64 0:1.3.9-3.el6_0.1  httpd.x86_64 0:2.2.15-53.el6.centos  httpd-tools.x86_64 0:2.2.15-53.el6.centos  mailcap.noarch 0:2.1.31-2.el6  php70w-cli.x86_64 0:7.0.8-1.w6 
  php70w-common.x86_64 0:7.0.8-1.w6 
Complete!
# php70w 설치 확인
[root@localhost ~]# yum search php70w
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
...
php70w-xmlrpc.x86_64 : A module for PHP applications which use the XML-RPC protocol
  Name and summary matches only, use "search all" for everything.

PHP에서 사용하는 추가 모듈을 설치 한다.

1
[root@localhost ~]# yum install php70w-mysql php70w-xml php70w-soap php70w-xmlrpc php70w-mbstring php70w-json php70w-gd php70w-mcrypt

PHP에서 시간과 보안을 위해 기본 설정을 변경한다.

vi /etc/php.ini

1
2
3
4
5
6
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = Asia/Seoul
; http://php.net/cgi.fix-pathinfo
cgi.fix_pathinfo=0

nginx 설치

nginx는 비동기처리 방식의 웹서버로 근래 성능측면에서 우수한 능력을 인정 받아, Apache HTTPD와 더불어 가장 많이 쓰이는 웹서버이다. 다음의 명령어로 설치할 수 있다.

1
[root@localhost ~]# yum install nginx

기본 환경 설정은 아래 설정 파일과 충돌하는 부분(예 root /var/www)이 있으므로 기본 설정을 백업 하고, 신규 설정 파일을 생성한다.

1
2
3
[root@localhost ~]# cd /etc/nginx/
[root@localhost nginx]# mv conf.d conf.d.backup
[root@localhost nginx]# mkdir conf.d

/var/www를 웹 사이트의 홈 디렉토리로 하고, 80번 포트를 수신하게 한다. 도메인은 blog.combineads.co.kr을 사용했으므로, DNS가 아직 등록되지 않은 상황이라면, 클라이언트의 hosts 파일에 해당 도메인을 등록(192.168.56.100 blog.combineads.co.kr) 해 접속 할 수 있다. 마지막으로 fastcgi_pass 는 나중에 다룰 PHP-FPM 설정의 listen 값과 동일해야 한다. 여기서는 unix domain socket이라는 것을 사용했는데, 일반 TCP/IP 포트로 통신하는 것보다 약간의 성능 향상이 있다.

vi /etc/nginx/conf.d/www.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
        listen   80;
        root /var/www;
        index index.php index.html index.htm;
        server_name  blog.combineads.co.kr;
        location / {
                try_files $uri $uri/ /index.html;
        }
        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
              root /usr/share/nginx/www;
        }
        location ~ .php$ {
                try_files $uri =404;
                fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        }
}
1
2
3
[root@localhost ~]# chkconfig nginx on
[root@localhost ~]# service nginx start
Starting nginx:                                            [  OK  ]
1
2
[root@localhost ~]# systemctl enable nginx.service
[root@localhost ~]# systemctl start nginx.service

MySQL 설치

MySQL은 전 세계에서 가장 많이쓰이는 오픈 소스 DB로, MySQL 5.6 이후 버전을 지원한다. MySQL은 현재 오라클에서 주도하고 있으며, 이후 MariaDB라는 새로운 브랜치가 만들어 졌으며, 이는 MariaDB 10 버전이 사용된다. 여기서는 오라클에서 주도하는 MySQL 5.6 버전으로 설치 한다. 개인적인 생각으로 오라클이라는 상용 밴더가 적극 지원하는 버전이라 해당 버전을 사용하며, 현재까지는 크게 차이가 없으나, 향후에는 다른 길을 걸을 것이라 예상 된다.

1
[root@localhost ~]# yum install mysql-server

MySQL의 기본 설정은 초기에는 무리 없이 동작하나 1G의 작은 메모리 환경에서는 적당하지 않다. 최초에는 사용자 접속양이 많치않아 문제가 안 되겠지만, 100명 이상 동접자가 발생하면 문제가 될 수 있다. 다만 대형 포탈처럼 수천명을 처리한다면 전문 엔지니어가 별도의 장비로 튜닝을 해야 한다.

vi /etc/my.cnf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html
[mysqld]
socket = /var/lib/mysql/mysql.sock
datadir = /var/lib/mysql
symbolic-links = 0
skip-character-set-client-handshake
skip-host-cache
skip-name-resolve
skip-external-locking
sysdate-is-now
init_connect = "set collation_connection=utf8_general_ci"
init_connect = "set names utf8"
character-set-server = utf8
collation-server = utf8_general_ci
transaction_isolation = REPEATABLE-READ
sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
event_scheduler = 0
log_bin_trust_function_creators = 1
default-storage-engine = innodb
lower_case_table_names = 1
query_cache_type = 0
query_cache_size = 0
query_cache_limit = 0
back_log = 50
slow_query_log = 1
long_query_time = 1
log_output = FILE
log-warnings = 2
sort_buffer_size = 128K
read_buffer_size = 128K
join_buffer_size = 128K
read_rnd_buffer_size = 128K
max_heap_table_size = 256K
tmp_table_size = 256K
thread_cache_size = 10
wait_timeout = 60
max_connect_errors = 99999
table_open_cache = 4096
max_allowed_packet = 1G
group_concat_max_len = 10485760
open-files-limit = 40960
innodb_print_all_deadlocks
innodb_buffer_pool_dump_at_shutdown = 1
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_instances = 1
innodb_buffer_pool_size = 512MB
innodb_log_buffer_size = 8M
innodb_data_file_path = ibdata1:10M:autoextend
innodb_flush_method = O_DIRECT
innodb_flush_log_at_trx_commit = 1
innodb_doublewrite = 0
innodb_support_xa = 1
innodb_open_files = 20480
innodb_sort_buffer_size = 4M
innodb_log_file_size = 2048M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 60
innodb_file_per_table = 1
innodb_stats_on_metadata = 0
server-id = 1
binlog_format = MIXED
expire_logs_days = 8
max_binlog_size = 300M
binlog_cache_size = 1M
sync_binlog = 0
relay_log_purge = 1
key_buffer_size = 32M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 1G
myisam-recover-options
[mysqldump]
quick
max_allowed_packet = 32M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 256M
sort_buffer_size = 256M
read_buffer = 4M
write_buffer = 4M
[mysqlhotcopy]
interactive-timeout
[mysqld_safe]
open-files-limit = 40960
log-error = /var/log/mysqld.log
pid-file = /var/run/mysqld/mysqld.pid

MySQL 서비스를 기동 시킨 뒤, mysql_secure_installation 명령어를 실행하여 MySQL 보안을 강화 하고, 서비스를 재시작 한다. 초기 mysql root 계정은 빈값으로 엔터를 입력하고, 처음 'Y'를 입력하여, root 계정의 비밀번호를 선택하고, 이후 모두 'Y'를 눌러 보안을 강화 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@localhost ~]# chkconfig mysqld on
[root@localhost ~]# service mysqld start
Starting mysqld:                                           [  OK  ]
[root@localhost ~]# mysql_secure_installation
...
Enter current password for root (enter for none): 
...
Set root password? [Y/n] Y
New password: 
Re-enter new password: 
Password updated successfully!
Reloading privilege tables..
....
Remove anonymous users? [Y/n] Y
...
Disallow root login remotely? [Y/n] Y
...
Remove test database and access to it? [Y/n] Y
...
Reload privilege tables now? [Y/n] Y
...
[root@localhost ~]# service mysqld restart
1
2
3
4
[root@localhost ~]# systemctl enable mysqld.service
[root@localhost ~]# systemctl start mysqld.service
[root@localhost ~]# mysql_secure_installation
[root@localhost ~]# systemctl restart mysqld.service

PHP-FPM 설치

PHP-FPM(FastCGI Process Manager)는 PHP에서 제공하지 않는 몇가지 추가 기능(프로세스 관리, 통계 관리, 안정한 서비스 시작/종료 등)을 제공하므로서, 더 안전하고 빠른 PHP 서비스를 제공 가능하게 한다. 다음의 명령어로 설치 할 수 있다.

1
yum install php70w-fpm

PHP-FPM은 초기에 apache 계정으로 동작하게 설정되어 있는데, 이를 설치한 nginx 계정으로 변경 한다.

vim /etc/php-fpm.d/www.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
; RPM: apache Choosed to be able to access some dir as httpd
user = nginx
; RPM: Keep a group allowed to write in log dir.
group = nginx
...
; listen = 127.0.0.1:9000
listen = /var/run/php-fpm/php-fpm.sock
...
; Default Values: user and group are set as the running user
; mode is set to 0660
;listen.owner = nobody
;listen.group = nobody
;listen.mode = 0660
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
...
1
2
3
[root@localhost ~]# chkconfig php-fpm on
[root@localhost ~]# service php-fpm start
Starting php-fpm:                                          [  OK  ]
1
2
[root@localhost ~]# systemctl enable php-fpm.service
[root@localhost ~]# systemctl start php-fpm.service

방화벽 설정

웹 서비스를 위해 HTTP(80)와 HTTPS(443) 포트를 방화벽에 등록 시킨다.

1
2
3
4
5
6
7
8
9
[root@localhost ~]# iptables -I INPUT -p tcp --dport 80 -j ACCEPT
[root@localhost ~]# iptables -I INPUT -p tcp --dport 443 -j ACCEPT
[root@localhost ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
[root@localhost ~]# service iptables restart
iptables: Setting chains to policy ACCEPT: filter [ OK ]
iptables: Flushing firewall rules: [ OK ]
iptables: Unloading modules: [ OK ]
iptables: Applying firewall rules: [ OK ]
1
2
3
[root@localhost ~]# firewall-cmd --permanent --zone=public --add-service=http
[root@localhost ~]# firewall-cmd --permanent --zone=public --add-service=https
[root@localhost ~]# firewall-cmd --reload

권한 점검

기본으로 설치된 /var/www 디렉토리는 root 권한이다. 그 안에 내용도 크게 필요한 것은 없지만, 백업을 받고 신규로 www 디렉토리를 생성한다. 이때 해당 디렉토리에 권한이 불충분하면 403 forbidden 오류가 발생 한다. 아래 스크립트에서 chcon, httpd_sys_content_t, getsebool, setsebool, httpd_can_network_connect는 생소하다고 느낄 수 있는데, 이는 SELinux라는 리눅스 보안 프로그램에서 사용한다. 근래에 나오는 Red Hat 배포판에는 보안 강화를 위해 기본으로 설치 시작 된다. 자세한 설명은 여기서는 생략하겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost var]# mv www www.backup
[root@localhost var]# mkdir www
[root@localhost var]# chcon -t httpd_sys_content_t www
[root@localhost var]# setsebool -P httpd_can_network_connect 1
[root@localhost var]# getsebool httpd_can_network_connect
httpd_can_network_connect --> on
[root@localhost var]# chown nginx:nginx www
[root@localhost var]# chmod 711 www
[root@localhost var]# ls -Z
...
drwxr-x--x. nginx nginx unconfined_u:object_r:httpd_sys_content_t:s0 www
# PHP에서 세션을 사용할 때 오류를 예방하기 위해 해당 디렉토리 권한 변경.
# 워드프레스의 일부 유명 플러그인들이 PHP의 세션 기능을 사용할 때가 있음.
[root@localhost var]# chown nginx:nginx /var/lib/php

파일 업로드 제한

워드프레스에서 용량이 2MB 이상의 파일을 업로드 할 경우, 오류가 나는데 이는 파일 업로드 제한의 기본 값이 2MB로 되어 있기 때문이다. 여기서는 100MB로 이 제한을 올려주는 작업을 한다.

vi /etc/php.ini

1
2
3
4
5
6
7
8
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 100M
; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; http://php.net/post-max-size
post_max_size = 100M

nginx의 설정에서도 아래와 같이 수정 한다. 이 예제에서는 www.conf를 nginx의 설정 파일로 사용 한다.

vi /etc/nginx/conf.d/www.conf

1
2
3
4
5
server {
        ...
        client_max_body_size 100m;
        ...
}

서비스의 적용을 위해 php-fpm과 nginx를 재시작 한다.

1
2
[root@localhost ~]# service php-fpm restart
[root@localhost ~]# service nginx restart
1
2
[root@localhost ~]# systemctl start php-fpm.service
[root@localhost ~]# systemctl restart nginx.service

설치 검증

PHP와 nginx가 정상 설치되었는지 확인 한다.

1
2
3
4
5
6
[root@localhost ~]# php -v
PHP 7.0.8 (cli) (built: Jun 23 2016 17:01:31) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
[root@localhost ~]# nginx -v
nginx version: nginx/1.0.15

또한 웹에서도 PHP가 정상 동작하는지 확인하기 위해 다음과 같이 test.php 파일을 넣는다. 해당 파일은 보안에 큰 위험이 있는 파일로 테스트가 완료되면, 삭제 한다.

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# cd /var/www/
[root@localhost www]# ls
cgi-bin  error  html  icons
[root@localhost www]# cat > test.php
<?php
phpinfo();
?>
^C
# 웹브라우저에서 확인 후, 반드시 삭제
[root@localhost www]# rm test.php

1

워드프레스 설치

이제 기본적인 워드프레스 설치 환경이 갖춰졌으니, 본격적으로 워드프레스를 설치해보자.

MySQL 사용자 계정 및 DB 생성

워드프레스에서 사용할 DB 사용자 계정 생성 및 권한 설정, DB 스키마 생성을 한다. MySQL의 root 계정을 직접 웹 애플리케이션에서 사용하면, 아주 위험한 보안 문제를 가지고 운영을 하는 것이다. 반드시 추가 사용자 계정을 생성하고, 사용자 계정에는 백업 플러그인을 고려하여 전체 권한을 부여 했다. 아래 예제에서는 wordpress@localhost라는 사용자 계정로 wordpress DB를 생성했는데, 사용자 계정을 combine_wp@localhost 와 같이 일반적이지 않는 값 사용을 권고한다. 참고로 아래 스크립트의 모든 wordpress@localhost 값을 combine_wp@localhost로 변경하면 된다. @뒤에는 IP 또는 호스트명이 사용되는데, 여기서는 단일 서버이므로 localhost를 사용했다. MySQL이 분리가 되는 경우 이부분도 변경되지만, MySQL 보안 및 권한 설정은 여기서 다루지 않겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost ~]# mysql -u root -p
Enter password: 
...
-- 비밀번호를 wp123으로 wordpress 사용자 계정을 생성하며, localhost에서만 접속 가능 함
mysql> CREATE USER wordpress@localhost IDENTIFIED BY "wp123";
Query OK, 0 rows affected (0.01 sec)
-- wordpress DB 생성
mysql> create database wordpress;
Query OK, 1 row affected (0.00 sec)
-- 전체 권한을 wordpress@localhost에게 제공. 백업 플러그인 등에서 DB 관리 기능을 사용
mysql> GRANT ALL ON wordpress.* TO wordpress@localhost;
Query OK, 0 rows affected (0.00 sec)
-- 권한을 적용 함
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> exit
Bye

워드프레스 설치 및 설정

워드프레스 설치 및 SELinux 설정까지 아래 스크립트로 설명을 대신 하겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost ~]# cd ~
[root@localhost ~]# wget https://wordpress.org/latest.tar.gz
[root@localhost ~]# tar zxvf latest.tar.gz wordpress
[root@localhost ~]# rm -rf latest.tar.gzhttp://www.popit.kr/wp-admin/post.php?post=4690&action=edit#
[root@localhost ~]# mv wordpress/ /var/www/wordpress
# 워드프레스의 미디어, 테마 또는 플러그인이 저장되는 디렉토리 생성
[root@localhost ~]# mkdir /var/www/wordpress/wp-content/uploads
[root@localhost ~]# mkdir /var/www/wordpress/wp-content/upgrade
# 신규 디렉토리가 추가 되었으므로 -R(하위 디렉토리까지 포함) 옵션을 주고, 다시 권한 수정
[root@localhost ~]# chown -R nginx:nginx /var/www/wordpress
[root@localhost ~]# chcon -R -t httpd_sys_content_t /var/www/wordpress
[root@localhost ~]# cd /var/www/wordpress/
# 웹 서비스 방지를 위해 상위 디렉토리로 옮김
[root@localhost wordpress]# mv wp-config-sample.php ../wp-config.php

기본 설치는 끝났다. 마지막으로 보안(설정 파일 유출 방어)을 위해 wp-config.php 파일을 워드프레스 홈(/) 디렉토리가 아닌 상위 디렉토리에 위치 시켰다. 위 설명한 nginx 의 설정(www.conf)를 사용했다면, root 디렉토리가 /var/www로 되어 있는데, 이를 /var/www/wordpress로 변경하여, "http://도메인_주소/" 로 워드프레스를 접속할 수 있게 한다.

vi /etc/nginx/conf.d/www.conf

1
2
3
4
5
server {
       ...
       root /var/www/wordpress;
       ...
}

서비스의 적용을 위해 nginx를 재시작 한다.

1
[root@localhost ~]# service nginx restart
1
[root@localhost ~]# systemctl restart nginx.service

wp-config.php를 편집하여, 워드프레스의 DB 및 보안 설정을 한다.

vi /var/www/wp-config.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/** 위 MySQL에 생성한 워드프레스의 사용자 계정과 비밀번호를 넣는다. */
/** The name of the database for WordPress */
define('DB_NAME', 'wordpress');
/** MySQL database username */
define('DB_USER', 'wordpress');
/** MySQL database password */
define('DB_PASSWORD', 'wp123');
/** MySQL hostname */
define('DB_HOST', 'localhost');
/** 워드프레스에서 사용하는 암호화 키로, 각종 사용자 정보 및 워드프레스 시스템 정보를 암호화 할 때 사용. */
/** https://api.wordpress.org/secret-key/1.1/salt/ 이 주소에서 자동 생성. */
/**#@+
 * Authentication Unique Keys and Salts.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
 * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define('AUTH_KEY',         '7)X>ubIU,pUe9OYVfg=k+pmlDXdQ^vP^XA|SPKJ@rFr|75EX)}>p-1OO6JEqlDc}');
define('SECURE_AUTH_KEY',  'w(|2wh~|AB9d[HJ`f7$D.z))AXWH$a<R~U$tqeSdE<8|y;Se%{d<i+Wbp%[v})I%');
define('LOGGED_IN_KEY',    'E4k)!F!M_sEs5[e6[M>4X)VE_aGCK?#~^K=#<rDZp B:)`(d@)`K(76?1CJwb6~U');
define('NONCE_KEY',        '^Wht&olBHLSqDB.75xgD|xdlx^<K+EEkI>(NKSxs@eGahmOd)zo  (fPUsfOCwEk');
define('AUTH_SALT',        'Ug=nFh|u48}r<Ou2m;s-jRZ<1N|:AyDsP&OO|Y5t5[*Y,+8Usp$W)N!j0v.@3Ohd');
define('SECURE_AUTH_SALT', 'L,1cjY<R 7C2w|[56_~4MgKa-`.ma3fM~#p(B=l@U:_|lY;;p-fUL-dWC|<^3+7c');
define('LOGGED_IN_SALT',   '+-NG_)@+^d::n!OQeF)]=,2G-GjN<=(EGC5|fC_W9cB<XH^lNA2=S|.,P$Ht`-^r');
define('NONCE_SALT',       'onoreg&9|-oSJl2NGo/D~f-hB5Ni[9y8,b+w`>(avcIs5+/r/;?Wq46OGt,h?jKd');
/** 워드프레스가 파일 업로드를 할 때 파일 시스템 또는 FTP 등을 이용해 저장하지를 나타내는 값. direct: 직접 사용 */
/** Sets up FS method to direct */
define('FS_METHOD','direct');
/** 테이블의 prefix 값. 워드프레스는 잘 알려져 있다보니, SQL Injection 공격을 막기 위해 아래와 같이 일반적이지 않은 값으로 prefix 생성. */
/**
 * WordPress Database Table prefix.
 *
 * You can have multiple installations in one database if you give each
 * a unique prefix. Only numbers, letters, and underscores please!
 */
$table_prefix = 'dkssud_wp_';

설정이 완료 되었다. 두근거리는 마음으로 해당 도메인을 접속하면 다음과 같은 화면이 나오며, 그림과 같이 단계 별로 설정을 마무리 한다.

1

2

3

마지막으로 워드프레스의 테이블들이 prefix와 함께 잘 생성 되었는지도 확인 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> use wordpress;
Database changed
mysql> show tables;
+------------------------------+
| Tables_in_wordpress          |
+------------------------------+
| dkssud_wp_commentmeta        |
| dkssud_wp_comments           |
| dkssud_wp_links              |
| dkssud_wp_options            |
| dkssud_wp_postmeta           |
| dkssud_wp_posts              |
| dkssud_wp_term_relationships |
| dkssud_wp_term_taxonomy      |
| dkssud_wp_termmeta           |
| dkssud_wp_terms              |
| dkssud_wp_usermeta           |
| dkssud_wp_users              |
+------------------------------+
12 rows in set (0.00 sec)
mysql> 

대쉬보드 설명

아래 첨부된 대쉬보드는 최초 관리자가 접속 시, 보여지는 화면입니다. 해당 대쉬보드는 사용자의 역할에 따라 보여지는 화면이 다릅니다. 관리자는 전체가 보이며, 편집자는 편집자에 맞는 축소된 메뉴 화면이 나옵니다.

4

크게 어려운 내용들이 아니라 메뉴를 한번씩 눌러보시면 그 뜻과 의미를 아실 수 있을 것입니다. 여기서는 간략하게 소개 정도를 하겠습니다.

메뉴명 설명
Dashboard > Home 설치된 워드프레스에서 발생하는 여러 활동 내역 및 지표를 확인
Dashboard > Updates 워드프레스 또는 설치된 플러그인의 버전 업그레이드가 있는지 확인
Posts > 하위 메뉴 글 조회, 쓰기, 카테고리 및 태그를 관리하는 메뉴
Media > 하위 메뉴 이미지, 비디오 및 오디오 등의 미디어를 관리하는 메뉴
Pages > 하위 메뉴 네비게이션 등에 나타나는 페이지로 About 등의 소개 페이지를 관리하는 메뉴
Comments 댓글 관리
Appearance > 하위 메뉴 설치된 워드프레스의 외형에 관련된 내용으로, 테마, 위젯, 메뉴 등을 관리하는 메뉴
Plugins > 하위 메뉴 워드프레스의 플러그인(추가 기능)을 관리하는 메뉴
Users > 하위 메뉴 사용자를 관리하는 메뉴
Tools > 하위 메뉴 워드프레스의 관리자 도구(백업 및 복원) 및 플러그인 관리 기능을 제공하는 메뉴
Settings > 하위 메뉴 설치된 워드프레스의 각종 설정 정보를 관리하는 메뉴

다음 글 안내

테마와 여러 플러그인을 설치하기 전에 기본 기능과 설정에 대해 많이 보고 테스트하고, 익혀야 한다. 그래야 테마 또는 플러그인으로 인해 워드프레스가 어떤 영향을 받았는지 빠르게 파악할 수 있다. 다음 글에서는 테마 적용과 테마를 상속(커스터마이징)한 자식 테마에 대해서 알아 볼 것이다. 또 다른 글로는 운영에 필요한 꼭 플러그인을 소개할 것이고, 이 중 상세한 소개가 필요한 플러그인은 별도 기사로 제공 될 예정이다.

처음에 필자도 워드프레스의 쉬운 설치와 관리 기능에 놀랐지만 테마를 수정하고, 그 안에서 제공되는 수많은 워드프레스의 PHP 함수를 보고 낙담한적이 있었다. 지금 글을 쓰는 시점에도 초심자의 입장(실제로 초심자)에서 하나씩 정리해가며 글을 쓰는 것이고, 이 글로 인해 조금이나마 도움이 되었으면 한다. 또한 본 워드프레스와 관련된 글은 지속 업그레이드 예정이다.

레퍼런스

https://2buntu.com/articles/1513/accessing-your-virtualbox-guest-from-your-host-os/

https://www.digitalocean.com/community/tutorials/initial-server-setup-with-centos-7

https://gistpages.com/posts/phpmailer_smtp_error_failed_to_connect_to_server_permission_denied_13_fix

http://tecadmin.net/install-php-7-nginx-mysql-5-on-centos/

https://fedoraproject.org/wiki/SELinux/apache

긴 글 읽어주셔서 감사합니다. 부족한 점이 많아 이견이 있을 수도 있고, 글과는 다르게 진행이 안 될 수도 있을 것입니다. 그런 내용들은 댓글을 남겨주시면, 성심 것 답변 또는 내용을 보강하겠습니다.

다시 한번 긴글 읽어주셔서 감사합니다.


Popit은 페이스북 댓글만 사용하고 있습니다. 페이스북 로그인 후 글을 보시면 댓글이 나타납니다.