You cannot see this page without javascript.

ubuntu nginx

Linux 조회 수 2547 추천 수 0 2015.12.22 22:26:20

Nginx

공식사이트는 http://nginx.org/ 이다. 엔진엑스 라고 부른다.

Igor Sysoev (이고르 시소에브) 라는 러시아 개발자가 개발했으며, 이 소프트웨어의 주요 개발 목표는 “동시접속 처리에 특화된 웹서버 프로그램” 이다.

 

- Nginx 가 Apache 보다 동시접속 처리에 좋은 이유

Nginx 는 Apache 에서 널리 사용되는 기능만 구현하였다. 즉 기능이 많지 않다. 동작이 단순하다.

Nginx 자체는 별로 많은 연산을 하지 않는다. 주로 전달자 역할만 하며 이런 이유로 Reverse Proxy Tool 이라고도 부른다.

 

- Nginx 와 Apache 중 어떤 웹서버를 선택해야할까?

당신의 취향이다.

둘은 분명히 장단점이 있다. 다 되는 Apache 를 선택할 것이냐, 동시접속처리를 잘하는 Nginx를 선택할 것이냐는  본인의 판단에 달려있다.

다만 동시연결수 250이상 (동시접속자 환산 500명정도?) 라면 반드시 Nginx 를 선택하여야 할 것이다.

 

 

PHP-FPM

NginxPHP 를 해석할 수 없기 때문에 외부 프로그램의 도움을 받아야 한다.

PHP-FPMNginx 로 부터 전달 받은 경로의 PHP 파일을 실행시키고 그 실행 결과를 Nginx 에게 반환하는 독립 실행 프로그램이다.

 


이제 실제로 세팅해 보도록 하겠다.

이 글은 Ubuntu 14.04 LTS (코드네임 : Trusty) 기준으로 작성되었다.

 

1) 쉘 기본 언어값 변경

서버 운영중에 문제가 발생했을 때 구글링을 할 수 있게 하는 기초작업이다.

쉘의 기본 언어값영어로 변경하도록 하자.

크게 달라지는 것은 없고 오직 쉘 메세지영어로 바뀐다.

# apache2

이미 영어메시지가 출력된다면 1번을 건너뛰고 2번 단계로 넘어가도록 하자.

스크린샷 2015-12-09 오후 11.39.48 스크린샷 2015-12-09 오후 11.40.03

< 그림 : 동일한 서버. 쉘 언어값만 다름. >

 

# vi /etc/default/locale
LANG="en_US.UTF-8"
LANGUAGE="en"

한줄만 써도 되는데, 쉘 언어값이 바뀌지 않으면 두줄을 적도록 하자.

스크린샷 2015-12-09 오후 8.08.56

스크린샷 2015-12-09 오후 8.10.51

다시 로그인 해 보면 값이 적용된 것을 알 수 있다.

 

2) 리눅스 버전체크

#uname -a
Linux 133-130-98-222 3.16.0-51-generic #69~14.04.1-Ubuntu SMP Wed Oct 7 15:32:41 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

 

3) Ubuntu 버전체크

#cat /etc/issue
Ubuntu 14.04.3 LTS

스크린샷 2015-11-29 오후 2.08.46

4) 하드용량체크

# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        49G  1.6G   45G   4% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
udev            2.0G   12K  2.0G   1% /dev
tmpfs           396M  392K  395M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            2.0G     0  2.0G   0% /run/shm
none            100M     0  100M   0% /run/user

스크린샷 2015-11-29 오후 2.11.46

49 - 1.6 이 왜 45 인지 이해가 가지 않지만, 아무튼 위의 서버에서 현재 사용가능한 용량은 45GB 이다.

 

5) 메모리 체크

# free -m
             total       used       free     shared    buffers     cached
Mem:          3952        194       3758          0         13        105
-/+ buffers/cache:         76       3876
Swap:         1020          0       1020
 

3952M의 전체메모리중 현재 194M을 사용하고 있고 3758M가 비어있다.

스크린샷 2015-11-29 오후 2.18.14

 

6) CPU 코어수 확인

cpu정보 프로세스를 읽어서 processor 항목이 몇개인지 갯수를 셉니다.

# cat /proc/cpuinfo | grep processor | wc -l

스크린샷 2015-04-08 오전 12.42.54

위의 사진은 6 core 를 뜻합니다.

한번 정도는 다음의 명령어를 확인해 보세요. CPU 정보를 알 수 있습니다.

#cat /proc/cpuinfo | grep processor
#cat /proc/cpuinfo

스크린샷 2015-11-29 오후 2.19.37

 

7) 현재 운영체제에 설치되어 있는 프로그램 최신버전 패치

APT 목록 갱신

APT란 Advanced Packaging Tool 을 뜻합니다.

우리는 apt 라는 우분투에 내장된 프로그램을 이용해서 프로그램을 쉽게 설치/제거 할 수 있습니다.

 

패키지 목록 갱신.

#apt-get update

 

현재 운영체제에 설치되어있는 프로그램 최신버전 패치

#apt-get upgrade

 

8) 시스템 시간 설정

이것을 하지 않으면 클라우드 서버 사업자가 미리 지정해 둔 지역의 시간을 불러올 것이다. (한국은 Seoul, 일본은 Tokyo, 그외에는 GMT.)

물론 초기 설치할 때 Asia/Seoul 을 설정했다면 이 작업을 할 필요는 없다. 하지만 또 한다고 해서 문제되지는 않는다.

- 데비안 패키지 재설정 TimeZone Data 를 실행한다.

#dpkg-reconfigure tzdata

GUI 환경이 나올 텐데, 순서대로 Asia - Seoul 을 선택하면 된다.

 

v1

스크린샷 2015-11-29 오후 2.25.42

이 서버의 시각은 현재 한국기준(KST) 2015년 11월 29일 14:24:53 이다.

 

9) Hostname 설정

이 서버에 이름을 정하는 것이다. 이름을 잘 정해 두어야 나중에 다중 서버작업을 할 때 헷갈리지 않는다.

v3

위의 뜻은 “li599-115 서버에 root 사용자” 라는 뜻이다.

서버 이름은 FQDN(Fully Qualified Domain Name)을 쓰는 것이 좋다.

참고로 라엘이의 이 블로그 서버의 hostname은 blog.lael.be 이다.

 

#vi /etc/hostname

빈 파일일 건데(또는 기존 hostname이 쓰여있을것임.) 원하는 이름으로 바꾼다.

권장하는 단어는 이 서버에 연결될 대표 도메인이다. 예를 들어 blog.lael.be 같은 것.

 

적용한다.

#hostname -F /etc/hostname

 

서버에 재 접속하면 적용된 것을 확인 할 수 있을 것이다.

스크린샷 2015-10-08 오전 2.31.05

hostname 값은 서버작업자에게 서버이름을 알려주는 역할을 하며, 아무 의미없는 글자를 적어도 된다.

일부 sendmail 같은 프로그램에서 다른 서버와 통신시 사용하기도 한다.

 

- hostname 을 FQDN 으로 설정하는 것을 권장하지만, 외부와 연결이 없는 서버이거나 자신이 쓰고 싶은 이름이 있다면 (팀명이나, 회사명, 서비스명 등) 그것으로 해도 된다.

예를 들어 myserver1, new1111 같이 자신이 하고 싶은대로 정했다고 한다면, 서버의 /etc/hosts 에 해당 이름을 등록해두도록 하자.

127.0.0.1    myserver1

스크린샷 2015-10-17 오전 12.51.37

 

추가) 메일 발송프로그램 설치하기

많은 프로그램에서 mail() 함수를 사용한다. 이 함수는 서버에 sendmail 에게 메일발송을 요청한다.

메일문의, 가입시 환영메일, 비밀번호 찾기 메일, 이메일인증 등 널리 사용된다. 서버가 메일 발송을 할 수 있게 sendmail 을 설치하자.

# apt-get install sendmail

이것은 오직 웹사이트에서 메일을 보내기 위한 것이다.

아이디@당신의도메인.com 같은 것을 하고 싶다면 절대로 직접 구축하려고 하지 말고 구글앱스, 네이버웍스, 도메인 구입처, 클라우드 메일호스팅 을 사용하도록 하자.

 

10) APT 소스리스트 파일에 Nginx, PHP, MariaDB 저장소 추가

이 글에서는 Nginx, PHP, MariaDB 를 모두 최신버전으로 설치할 것이다.

우분투 공식 저장소에는 stable 버전만 존재한다. stable 버전이란 “기능추가 없이 보안과 안정성 패치만 하는 버전” 을 뜻한다.

최신버전을 설치하기 위해서 APT 소스리스트 파일에 최신버전이 담겨있는 저장소를 추가해주어야 한다.

 

# vi /etc/apt/sources.list

 

파일 맨 끝에 다음의 줄 추가. (더블클릭하면 전체 선택됨)

1
2
3
4
5
6
# Nginx
deb http://nginx.org/packages/mainline/ubuntu/ trusty nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ trusty nginx
 
# MariaDB
deb http://ftp.osuosl.org/pub/mariadb/repo/10.1/ubuntu trusty main

스크린샷 2015-12-09 오후 7.52.32

 

- 각 저장소 보안키 다운로드 후 시스템에 등록

보안키 정보는 /etc/apt/trusted.gpg 에 저장된다.

 

nginx 보안키 다운로드 후 적용.

# cd /root
# wget http://nginx.org/keys/nginx_signing.key
# apt-key add nginx_signing.key
# rm nginx_signing.key

 

MariaDB 보안키 다운로드 후 적용.

# apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db

 

PHP 저장소 추가 및 보안키 등록

여기서는 ppa(Personal Package Archive)라는 개인패키지 저장소를 이용할 것이다.

ondrej 사용자의 php-7.0 저장소를 사용할 것이다.

ondrej 는 Debian 에서 일하고 있으며, Ubuntu 제작자 중 한명이다.

 

스크린샷 2015-12-12 오후 4.16.58

< Debian이나 Ubuntu에서 가끔 이분의 이름을 볼 수 있을 것이다 >

 

보안키/etc/apt/trusted.gpg.d/ondrej-php-7_0.gpg 에 저장되고

저장소 추가 구문/etc/apt/sources.list.d/ondrej-php-7_0-trusty.list 에 저장된다.

# add-apt-repository ppa:ondrej/php-7.0

스크린샷 2015-12-10 오전 1.06.07

엔터키 한번 눌러주면 된다. (맥의 경우 return 키)

 

추가된 보안키 목록 보기

# apt-key list

스크린샷 2015-12-10 오전 1.09.22

nginx 저장소키, mariadb 저장소키, Ondřej Surý 님의 개인저장소(Launchpad PPA)키가 등록되어 있는 것을 알 수 있다.

 

- APT 소스패키지 정보 업데이트

신규 저장소를 추가하였고, 저장소키도 등록했으니, APT 패키지 정보를 갱신해보도록 하자.

# apt-get update

 

10) Nginx 설치

스크린샷 2015-11-29 오전 11.23.00

<https://en.wikipedia.org/wiki/Nginx>

글 작성일인 2015년 12월 10일 현재 최신버전은 1.9.8 이다.

 

- Nginx 설치

Nginx 공식 저장소에서 배포하는 최신버전을 설치해 보도록 하자.

# apt-get install nginx

 

자동으로 설치되고, 실행되고, 재부팅시 자동실행 되게 설정된다.

 

- nginx 버전체크

# nginx -v

스크린샷 2015-12-10 오전 12.06.00

당신의 버전은 이것보다 높을 것이다.

또는 언제든지 #apt-get update#apt-get upgrade 하면 최신버전으로 업그레이드 된다.

 

- 동작여부를 직접 확인해본다.

웹브라우저를 켜고 http://123.456.123.456 (서버의 아이피) 에 접속해보자.

 

스크린샷 2015-12-01 오전 1.13.47

Welcome to nginx! 문구가 뜨면 정상이다. (이 파일의 위치는 /usr/share/nginx/html/index.html 이다.)

 

11) PHP-FPM 설치

- PHP7-FPM 최신버전 설치

# apt-get install php7.0-fpm

 

- 콘솔 PHP 버전확인

# php -v

 

- PHP-FPM 프로그램 버전확인

ondrej 님이 왜 패키지명php7.0-fpm 이라고 해두고, 실행파일명php-fpm7.0 으로 정했는지 이해가 가지 않지만, 아무쪼록 php-fpm7.0 파일을 실행해 보도록 하자.

# php-fpm7.0 -v

스크린샷 2015-12-10 오전 1.14.03

- 널리쓰이는 PHP 모듈 설치

mcrypt 는 PHP-FPM 설치할 때 함께 설치되니 따로 설치하지 않는다. 중복설치가 가능한데 중복설치할 경우 PHP 콘솔명령 실행시 warning 메시지가 나타나게 된다.

# apt-get install php7.0-gd php7.0-curl

설치가 완료되면 자동으로 PHP-FPM 프로그램을 재시작 한다.

 

11-2) PHP Default timezone 설정하기.

이 값을 설정하지 않으면 시스템 timezone 을 사용합니다.

PHP Default timezone 을 설정하는 것은 필수는 아니지만 매우 권장하는 작업입니다. 설정해주세요.

# vi /etc/php/7.0/fpm/php.ini

 

date.timezone 값을 찾아서 주석을 제거하고 시간을 설정해주세요.

스크린샷 2015-07-30 오전 10.57.25

이 값을 찾아서

 

스크린샷 2015-07-30 오전 10.57.49

이렇게 변경.

 

# service php7.0-fpm restart

 

스크린샷 2015-07-30 오전 11.01.06

phpinfo 페이지에서 Default timezone 이 설정되어 있으면 정상.

 

 

12) MariaDB 설치

스크린샷 2015-11-29 오후 11.39.02

<https://en.wikipedia.org/wiki/MariaDB>

 

당연히 MariaDB 10.1 을 설치할 것이다.

# apt-get install mariadb-server-10.1 mariadb-client-10.1

설치시에 데이터베이스 root 사용자의 비밀번호를 설정할 수 있다.

설치와 동시에 MariaDB 가 실행되며, 재부팅시에도 자동 시작되도록 설정된다.

 

서비스 상태확인

# service mysql status

스크린샷 2015-12-04 오후 10.23.37

 

PHP-FPM 에 DB 연동관련 모듈설치

# apt-get install php7.0-mysql

 

13-1) 기본 언어셋 설정(중요)

이 단계를 건너뛰면 DB가 latin1 으로 생성되며 추후 DB작업에 문제가 생길 수 있다.

# vi /etc/mysql/my.cnf

 

(vi 에디터 사용방법을 모른다면 ftp 클라이언트를 사용하여 서버에 로그인 후 해당파일을 수정하고 덮어쓰기한다.)

 

[mysqld] 항목에 다음 2 줄을 추가한다.

character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

 

스크린샷 2015-04-08 오전 1.19.05

 

변경사항 적용

#service mysql restart

 

 

14) Nginx 와 PHP-FPM 연결

현재 상태에서 Nginx 프로그램은 기본적으로 nginx 사용자 권한으로 실행되고,

PHP-FPM 프로그램은 기본적으로 www-data 사용자 권한으로 실행된다.

둘의 사용자 권한을 www-data 로 일치시키자. 이 사용자는 운영체제 설치시 자동으로 생성되는 특수목적 사용자이다.

nginx 의 설정값만 바꾸면 된다.

 

- Nginx 사용자 권한 변경

# vi /etc/nginx/nginx.conf

첫줄의 user  nginx; 를 user  www-data; 로 바꿉니다.

# service nginx restart

스크린샷 2015-12-12 오후 4.46.51

 

 

- Nginx 에서 PHP 확장자에 대해서 PHP-FPM 프로그램으로 요청을 전달하게 설정하기

# vi /etc/nginx/conf.d/default.conf

 

과정 설명

#1. 기본 값에서 주석 제거

#2. 커스텀 에러페이지 구문 제거

#3. Nginx - PHP-FPM 구문 추가 (https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/) 참조

 

결과적으로 다음의 구문을 적용하시면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
    listen       80;
    server_name  localhost;
    root   /usr/share/nginx/html;
 
    location / {
        index  index.php index.html;
    }
 
    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        if (!-f $document_root$fastcgi_script_name) {
            return 404;
        }
 
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

 

# fastcgi_params  도 가이드대로 변경 (https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/)

# vi /etc/nginx/fastcgi_params

아래와 같이 변경

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
fastcgi_param   QUERY_STRING            $query_string;
fastcgi_param   REQUEST_METHOD          $request_method;
fastcgi_param   CONTENT_TYPE            $content_type;
fastcgi_param   CONTENT_LENGTH          $content_length;
 
fastcgi_param   SCRIPT_FILENAME         $document_root$fastcgi_script_name;
fastcgi_param   SCRIPT_NAME             $fastcgi_script_name;
fastcgi_param   PATH_INFO               $fastcgi_path_info;
fastcgi_param   PATH_TRANSLATED         $document_root$fastcgi_path_info;
fastcgi_param   REQUEST_URI             $request_uri;
fastcgi_param   DOCUMENT_URI            $document_uri;
fastcgi_param   DOCUMENT_ROOT           $document_root;
fastcgi_param   SERVER_PROTOCOL         $server_protocol;
 
fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;
fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;
 
fastcgi_param   REMOTE_ADDR             $remote_addr;
fastcgi_param   REMOTE_PORT             $remote_port;
fastcgi_param   SERVER_ADDR             $server_addr;
fastcgi_param   SERVER_PORT             $server_port;
fastcgi_param   SERVER_NAME             $server_name;
 
fastcgi_param   HTTPS                   $https;
 
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param   REDIRECT_STATUS         200;

 

- Nginx 재시작

# service nginx restart

 

15-1) 연동테스트1

# vi /usr/share/nginx/html/phpinfo.php

 

1
2
<?php
phpinfo();

 

웹브라우저에서 다음을 입력해서 phpinfo 페이지를 보도록 하자.

http://111.222.333.444/phpinfo.php

 

스크린샷 2015-12-10 오전 1.53.53

<이 페이지에서 컨트롤+F 누르고 “nginx” 와 “php-fpm” 단어로 검색해본다>

 


 

15-2) 연동테스트2

nginx 와 php-fpm , 그리고 mariadb 를 모두 사용하는 프로그램을 실행시켜보자.

phpmyadmin 공식사이트 : https://www.phpmyadmin.net/

 

설치 못하시는 분이 꽤 있으셔서 따로 설치법을 적습니다.

여러 설치방법이 있겠지만 저는 다음과 같이 설치합니다.

 

압축해제 프로그램 설치

# apt-get install unzip

 

압축파일 다운로드

# cd /usr/share/nginx/html

 

스크린샷 2015-12-13 오전 11.22.36

# wget https://files.phpmyadmin.net/phpMyAdmin/4.5.2/phpMyAdmin-4.5.2-all-languages.zip

 

압축해제

# unzip phpMyAdmin-4.5.2-all-languages.zip

 

폴더 이름변경

# mv phpMyAdmin-4.5.2-all-languages dbmyadmin

 

다운받은파일 삭제

# rm phpMyAdmin-4.5.2-all-languages.zip

 

http://111.222.333.444/dbmyadmin/

 

스크린샷 2015-12-12 오전 10.35.09

 

- 재부팅

복잡한 세팅이 끝났으니 한번 숨을 고르고 가자.

# reboot

재부팅 후에 phpinfo 페이지와 phpmyadmin 가 잘 실행된다면 “재부팅이 가능한 서버” 라고 볼 수 있다.

 


16) 웹 사이트 구동예제

원래 표준명령어는 useradd 이지만, ubuntu는 사용하기 좋게 adduser 를 지원한다.
리눅스 관련 서적을 보면 둘다 계정생성용 명령어라고 되어있다.
쉬운 설정을 위해 adduser를 사용

다음의 예제에서는 php7.kr 이라는 사용자(user) 와 웹주소(ServerName) 사용예제를 설명합니다.

각자 본인의 도메인으로 변경해서 실행하세요.

#adduser php7.kr --force-badname

 

(참고로 위와 반대동작을 하는 계정삭제 명령어는 다음과 같다. (계정을 삭제하고 홈디렉토리도 삭제함)

#userdel -r php7.kr
 

보통 웹루트는 홈디렉토리에 하지 않습니다.
저는 주로 www 디렉토리를 사용합니다.사용자변경 후 www 디렉토리를 생성하고 빠져나오기

#su -l php7.kr
#mkdir www
#exit

 

- php pool 파일 만들기 및 nginx server 구문을 추가하기

PHP-FPM Pool 파일 작성
# vi /etc/php/7.0/fpm/pool.d/php7.kr.conf

자주 쓰이는 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
[php7.kr]
 
user = php7.kr
group = php7.kr
 
listen = /run/php/php7.kr.sock
 
listen.owner = php7.kr
listen.group = www-data
 
pm = dynamic
pm.max_children = 9
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
 
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
 
;php_admin_value[memory_limit] = 128M
;php_admin_value[max_execution_time] = 120
;php_admin_value[max_input_time] = 300
 
;php_admin_value[post_max_size] = 25M
;php_admin_value[upload_max_filesize] = 25M

 

Nginx server 구문 작성
# vi /etc/nginx/conf.d/php7.kr.conf

워드프레스 Nginx 설정예제 https://codex.wordpress.org/Nginx 페이지를 많이 참조했습니다.

 

- 일반적인 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
40
41
42
43
44
45
46
47
48
49
# Copyleft Lael's World (http://blog.lael.be/post/2600)
# Nginx, PHP-FPM template.
# Template 1. Normal PHP Site.
 
server {
    listen       80;
    server_name  php7.kr www.php7.kr my-second-domain.net;
    root   /home/php7.kr/www;
 
    access_log /var/log/nginx/php7.kr.access.log;
    error_log  /var/log/nginx/php7.kr.error.log warn;
 
    location / {
        index  index.php index.html;
    }
 
    # Block dot file (.htaccess .htpasswd .svn .git .env and so on.)
    location ~ /\. {
        deny all;
    }
 
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }
 
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
 
    # Block .php file inside upload folder. uploads(wp), files(drupal, xe), data(gnuboard).
    location ~* /(?:uploads|files|data)/.*\.php$ {
        deny all;
    }
 
    # Add PHP handler
    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        if (!-f $document_root$fastcgi_script_name) {
            return 404;
        }
 
        fastcgi_pass unix:/run/php/php7.kr.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

 

- 워드프레스, 드루팔, 코드이그나이터, 라라벨 등 일 때

위의 예제 설정값에서 index.php 파일이 요청을 받도록 한줄만 더 추가해주면 됩니다.

스크린샷 2015-12-15 오후 10.07.27

 

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
# Copyleft Lael's World (http://blog.lael.be/post/2600)
# Nginx, PHP-FPM template.
# Template 2. WordPress, Drupal, CodeIgniter, Laravel.
 
server {
    listen       80;
    server_name  php7.kr www.php7.kr my-second-domain.net;
    root   /home/php7.kr/www;
 
    access_log /var/log/nginx/php7.kr.access.log;
    error_log  /var/log/nginx/php7.kr.error.log warn;
 
    location / {
        index  index.php index.html;
        try_files $uri $uri/ /index.php?$args;
    }
 
    # Block dot file (.htaccess .htpasswd .svn .git .env and so on.)
    location ~ /\. {
        deny all;
    }
 
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }
 
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
 
    # Block .php file inside upload folder. uploads(wp), files(drupal, xe), data(gnuboard).
    location ~* /(?:uploads|files|data)/.*\.php$ {
        deny all;
    }
 
    # Add PHP handler
    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        if (!-f $document_root$fastcgi_script_name) {
            return 404;
        }
 
        fastcgi_pass unix:/run/php/php7.kr.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

nginx 및 php-fpm 재시작.

실제 운영중에는 되도록 reload 명령어를 사용하되, 원하는 변경이 되지 않으면 restart 를 하도록 하자.

# service nginx reload
# service php7.0-fpm reload

 

17) 보안설정

- PHP 가 아닌 파일 실행 차단 (이미 적용되어 있음. 취약하지 않음.)

위의 세팅에는 2중 보안이 되어있기 때문에 취약하지 않다.

nginx 에서 한번 필터링을 하고(if 구문), php-fpm 에서 한번 더 확장자 검사(PHP 5.3.9 이상버전은 .php 만 실행됨)를 한다.

 

https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/ 가장 하단의 Note 항목을 참조하세요.

http://php.net/manual/kr/install.fpm.configuration.php 페이지의 security.limit_extensions 항목을 참조하세요.

 

- 기본 사이트 차단

어느 하나의 웹 호스트로 해당되지 않으면 default 파일로 연결된다.

이것을 아예 차단해 보자. 즉 유효한 도메인의 요청이 아니면 응답을 하지 않는다.

 

# vi /etc/nginx/conf.d/default.conf
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
server {
    listen       80 default_server;
    server_name  localhost;
    root   /usr/share/nginx/html;
 
    # Deny all except me.
    if ($remote_addr != 123.456.123.456) {
        return 444;
    }
 
    location / {
        index  index.php index.html;
    }
 
    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        if (!-f $document_root$fastcgi_script_name) {
            return 404;
        }
 
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

 

# service nginx reload

 

그 외에 딱히 중요한 보안 이슈는 없는듯 하다.

 

옵션) 방화벽 적용하기.

* 접속자의 IP 가 고정되어 있으면 아래와 같이 방화벽 세팅을,
웹호스팅 서비스와 같이 접속자의 IP를 특정할 수 없으면 fail2ban 을 (http://blog.lael.be/post/858#fail2ban) 사용하세요.

저의 경우 몇대의 단독 VPN 서버가 있으며(즉 어느 위치에 있든지 고정IP 로 활동할 수 있음) 해당 IP 를 방화벽 예외로 설정해 두곤 합니다.

당연한 이야기지만 Ubuntu 에도 방화벽이 있습니다.
무척 당연한 이야기지만 방화벽을 사용하면 서버 보안이 매우 많이 향상됩니다.

현재 방화벽 설정 보기. (List)

#iptables -L

스크린샷 2015-12-15 오전 1.58.42

INPUT (서버로 들어오는 것 관리), FORWARD (서버에서 내부망으로 연결관리;잘 안씀), OUTPUT (서버에서 나가는 것 관리)
로 이루어져 있다.

보통 FORWARD와 OUTPUT은 건들이지 않고 INPUT 만 수정한다.
policy ACCEPT 라는 뜻은 아무 조건도 해당하지 않았을 때 ACCEPT 하라는 것이다.

먼저 현재 방화벽 설정을 파일로 저장한다. 언제든 현재의 상태로 되돌릴 수 있기 위해서 이다.

#cd ~
#mkdir firewall_rules
#cd firewall_rules
#iptables-save > 151214.rules                 현재 날짜 쓰세요.

이제 방화벽을 복구해 보자.

#iptables-restore < 151214.rules
#iptables -L

>>설정 시작.
규칙 : 아이피 111.222.111.222 에 대해서 destination port 가 22 이면 ACCEPT 하여라.

#iptables -A INPUT -s 111.222.111.222/32 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT

아이피 바꾸지 마시고 위의 예시 (111.222.111.222) 그대로 입력하세요.

#iptables -L

스크린샷 2015-12-15 오전 2.04.49

 

이제 현재 상태에 대해서 방화벽 설정파일을 다시 생성해보도록 하자.

#iptables-save > 151214.rules

 

FTP나 vi, cat 으로 해당 151214.rules 를 열어보자.

열고나서 코드의 뜻을 대충 해석해보아라. (간단하다.)

하단 *filter 부분에

-A INPUT -s 111.222.111.222/32 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT

가 보이는가?

 

여러분은 이곳에 아래의 코드를 집어넣어야 한다.

순서가 중요하다. IF-ELSE 같이 동작하기 때문에 조건에 맞으면 바로 지정된 동작을 한다.

211.105.192.168 아이피만 지정하고 싶을 때 -> -s 211.105.192.168/32

211.105.192.* 아이피 그룹을 지정하고 싶을 때 -> -s 211.105.192.0/24

211.105.*.* 아이피 그룹을 지정하고 싶을 때 -> -s 211.105.0.0/16

목적지 포트가 22번(ssh) 포트일 때 -> -dport 22

목적지 포트가 80번(http) 포트일 때 -> -dport 80

목적지 포트가 443번(https) 포트일 때 -> -dport 443

 

아래는

1. 이미 연결된 것은 허용

2. ping 허용

3. loopback 허용

4. 111.222.111.222 의 22번 포트 접근 허용

5. 123.111.123.111 의 22번 포트 접근 허용

6. 80 포트 접근 허용 (-s 옵션이 없으므로 누구나 허용)

7. 차단

8. FORWARD 차단

의 코드이다.

아까 생성한 .rules 파일을 열어서 아래의 코드를 그림과 같이 코드를 추가하여라. 이때 반드시 당신의 아이피를 추가하여라.

추가가 잘못되어도 어차피 1번의 조건에 의해서 당신의 연결이 끊기지는 않겠지만 새로운 연결은 차단될 것이다.

 

1
2
3
4
5
6
7
8
9
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -s 111.222.111.222/32 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -s 123.111.123.111/32 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited

스크린샷 2015-01-23 오전 2.18.26

#iptables-restore < 151214.rules
#iptables -L

!!!반드시 현재 쉘 연결을 끊지 말고!!!

현재 연결은 1번 조건에 의해서 반드시 허용이기 때문에 괜찮다.

 

새로 연결창 띄워서 테스트해 보아라.

만약 원하는대로 동작하지 않는다면 다시 .rules 파일을 수정하고 iptables-restore 하여라.

방화벽 설정이 머리가 아프다면

# iptables -F

초기화 하고 내일 다시 시도해 보아라.

 

이 설정은 재부팅이 되면 초기화 된다.

설정을 지속시키도록 하자.

iptables-persistent 설치

스크린샷 2015-01-23 오전 3.13.35

#apt-get install iptables-persistent

Yes (엔터), Yes (엔터)

 

/etc/iptables 라는 폴더가 생성되고

rules.v4, rules.v6 가 생성된다.

 

부팅시 실행되는 파일을 갱신하자.

#iptables-save > /etc/iptables/rules.v4

 

ipv6 차단하기

#vi /etc/sysctl.conf

맨 밑에

1
2
3
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

추가.

 

설정파일 적용

#sysctl -p

 

검사

#cat /proc/sys/net/ipv6/conf/all/disable_ipv6

1 이면 disable 된 상태이다.

스크린샷 2015-12-15 오전 2.19.35
재부팅

#reboot

 

Cloud Init Bug로 인해 일부 클라우드에서 문제가 발생할 수도 있습니다.

일부 Cloud Hosting 에서 의 IPv6 를 Disable 한 경우, 또는 아무것도 하지 않아도 cloud-init-nonet error 가 뜨면서 IP 정보를 가져오지 못하는 경우가 있습니다. (ConoHa 클라우드 및 KS클라우드에서 확인 했음.)

이 경우 ipv6 dhcp 관련 구문을 주석처리 해 주어야 합니다.

# vi /etc/network/interfaces

스크린샷 2015-12-15 오후 3.39.09

 

재부팅

#reboot

 

재부팅 후에 방화벽 규칙이 유지가 되면 성공이다.

#iptables -L

 

끝.

List of Articles
번호 제목 글쓴이 날짜 조회 수

XE Login