CentOS 6.x 에서 웹서버(nginx+php-fpm+MYSQL) 구성하기 TLS v1.3 지원 및 SSL LABS A+

Zzori/ 9월 2, 2020/ 웹서버 구성/ 0 comments

CentOS 6.x 버젼에서 yum(rpm) 기반으로 웹서버를 간단하게 구성하는 방법입니다. 문서 작성 시점에서 기준 버젼은 nginx : 1.18.0(TLS v1.3지원), php-fpm : 7.3.22, MySQL(MariaDB) : 10.4.14 입니다. 추가적으로 

– MySQL(MariaDB) 저장소 추가 : CentOS 6.x 버젼은 10.4 버젼까지만 지원합니다. 아래 경로에 파일을 생성하고 아래 내용을 넣는다.
vi /etc/yum.repos.d/MariaDB.repo

# MariaDB 10.4 [Stable] CentOS repository list - created 2020-09-06 11:21 UTC
# https://mariadb.org/download-test/
[mariadb]
name = MariaDB
baseurl = https://ftp.harukasan.org/mariadb/yum/10.4/centos6-amd64
gpgkey=https://ftp.harukasan.org/mariadb/yum/RPM-GPG-KEY-MariaDB
gpgcheck=1

추가한 저장소를 업데이트하고 MariaDB-Server 패키지를 설치한다.

yum update
yum install -y MariaDB-server

MariaDB 서버를 시작합니다. (OS 재기동시에는 자동으로 기동이 되도록 설정 되어 있습니다. 확인 : chkconfig –list | grep mysql)

/etc/init.d/mysql start

MySQL root 계정 패스워드를 변경합니다.

mysql_secure_installation

Nginx 설치 : 기본 저장소나 nginx repo 가 아닌 별도의 repo 를 통해 설치하겠습니다.

yum -y install https://repo.aerisnetwork.com/pub/aeris-release-6.rpm
yum install nginx-more

설치된 버젼은 아래와 같습니다. (OpenSSL 1.1.1g 기반으로 빌드되어 TLS v1.3 지원합니다.)

nginx 서버 시작은 아래와 같은 방법을 통해 중지 및 기동이 가능합니다. 디폴트 설정으로 OS 재기동시 nginx 서버가 자동으로 시작되게 되어 있습니다.

service nginx start/stop

/etc/init.d/nginx start/stop

다음은 마지막으로 PHP(php-fpm) 를 설치하겠습니다. PHP도 외부 repo 를 사용하여 설치합니다. 현재 PHP 7.3.xx 버젼을 지원하고 있습니다.

rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-6.rpm
yum install yum-utils yum-config-manager --enable remi-php73
yum install php php-cli php-common php-fpm php-mysql php-gd php-xml php-opcache

nginx + php-fpm + mysql 설치는 모두 완료되었습니다. ssl 인증서를 적용하기 위해서 추가적으로 certbot 을 설치하겠습니다. 아래의 명령어를 통해 설치하고 나오는 화면에서 y 를 눌러 설치하여 주세요.

wget https://dl.eff.org/certbot-auto && chmod 700 certbot-auto && ./certbot-auto

사전 준비작업으로 DNS설정을 centos6.zzori.com 의 A레코드(IP는 해당서버)와 CAA 레코드를 아래처럼 설정해주세요. 아래화면은 cloudflare 기준입니다.

다음 certbot-auto 로 ssl 인증서를 발급하겠습니다. 도메인은 centos6.zzori.com 으로 하겠습니다. 방화벽 설정에서 80포트와 443포트는 미리 오픈하여 주시기 바랍니다. 이메일 주소와 기타 질문사항에 대해서는 y를 입력하여 주시면 됩니다. dhpram.pem 은 ssllabs 에서 A이상을 받기 위해 필수로 해야 합니다.

service nginx stop
./certbot-auto certonly --standalone --rsa-key-size=4096 -d centos6.zzori.com
service nginx start

# 서버사양에 따라 시간이 많이 소요될 수 있음.
openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

지금까지 필요한 소프트웨어들을 설치하였고 이제 설정에 들어가겠습니다.
먼저 nginx 설정입니다. vi /etc/nginx/fastcgi_params 파일을 아래와 같이 하여 줍니다.

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_NAME        $fastcgi_script_name;
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  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

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;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;
# 아래 내용 추가
fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  PATH_TRANSLATED    $document_root$fastcgi_path_info;
fastcgi_param  PATH_INFO          $fastcgi_path_info;

그리고 virtual host 설정도 해줍니다.
웹페이지 경로는 /home/zzori/www 기준으로 설정하였고 해당 경로를 미리 만들어주세요.(저의 경우엔 zzori 계정을 만들고 아래에 www 디렉토리를 생성하였습니다. 그리고 index.php 파일을 생성하여 <?php phpinfo(); ?> 내용을 추가합니다.)
vi /etc/nginx/conf.d/vhosts/centos6.zzori.com.conf

server {
    listen       80;
    server_name  centos6.zzori.com;

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

server {
    listen       443 ssl http2;
    server_name  centos6.zzori.com;
    root   /home/zzori/www;

    server_tokens off;

    add_header X-Frame-Options SAMEORIGIN;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    charset utf-8;

    #set same size as post_max_size(php.ini or php_admin_value).
    client_max_body_size 10M;

    ssl_certificate "/etc/letsencrypt/live/centos6.zzori.com/fullchain.pem";
    ssl_certificate_key "/etc/letsencrypt/live/centos6.zzori.com/privkey.pem";
    ssl_dhparam "/etc/ssl/certs/dhparam.pem";

    # Enable HSTS. This forces SSL on clients that respect it, most modern browsers. The includeSubDomains flag is optional.
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header Content-Security-Policy "upgrade-insecure-requests" always;

    # Set caches, protocols, and accepted ciphers. This config will merit an A+ SSL Labs score.
    ssl_session_cache shared:SSL:20m;
    ssl_session_timeout 10m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE+AESGCM:DHE+AESGCM:ECDHE+RSA+SHA256:DHE+RSA+SHA256;
    ssl_ecdh_curve secp521r1:secp384r1;

    access_log /var/log/nginx/centos6.zzori.com.access.log main;
    error_log  /var/log/nginx/centos6.zzori.com.error.log error;

    location / {
        index  index.php index.html;
    }

    # Allow Lets Encrypt Domain Validation Program
    location ^~ /.well-known/acme-challenge/ {
        allow all;
    }
    # Block dot file (.htaccess .htpasswd .svn .git .env and so on.)
    location ~ /\. {
        deny all;
    }

    # Block (log file, binary, certificate, shell script, sql dump file) access.
    location ~* \.(log|binary|pem|enc|crt|conf|cnf|sql|sh|key|yml|lock)$ {
        deny all;
    }

    # Block access
    location ~* (composer\.json|composer\.lock|composer\.phar|contributing\.md|license\.txt|readme\.rst|readme\.md|readme\.txt|copyright|artisan|gulpfile\.js|package\.json|phpunit\.xml|access_log|error_log|gruntfile\.js)$ {
        deny all;
    }

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location = /robots.txt {
        log_not_found off;
        access_log off;
    }

    # Block .php file inside upload folder. uploads(wp), files(drupal), data(gnuboard).
    location ~* /(?:uploads|default/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_read_timeout 300;
        fastcgi_pass unix:/var/run/php-fpm/zzori.sock;
        fastcgi_index index.php;
        fastcgi_buffers 64 16k; # default 8 4k

        include fastcgi_params;
    }
}

다음으로 php-fpm 설정을 하도록 하겠습니다. 계정별로 pool 을 만들어 설정하였습니다.
vi /etc/php-fpm.d/zzori.conf

[zzori]
user = zzori
group = nginx

listen = /var/run/php-fpm/zzori.sock
listen.owner = zzori
listen.group = nginx

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35

php_admin_value[session.cookie_httponly] = 1
php_admin_value[session.use_strict_mode] = 1

; save std error to /var/log/php7.3-fpm.log
catch_workers_output = yes

; save slow process
slowlog = /var/log/php-fpm.zzori.slow.log
request_slowlog_timeout = 10

; php only timeout
php_admin_value[max_execution_time] = 30

; all timeout (php+mysql+exec+fopen+...) (use it carefully.)
;request_terminate_timeout = 90

;php_admin_value[post_max_size] = 25M
;php_admin_value[upload_max_filesize] = 25M

php_admin_value[session.name] = "MY_SESSION_ID"
php_value[session.save_path] = /home/zzori/.php-session

;access.log = /var/log/php-fpm.zzori.access.log
;access.format = "%t %{REMOTE_ADDR}e \"%m %r%Q%q\" %s %f TIME:%{mili}dms MEM:%{kilo}MK CPU:%C%%"

php_admin_flag[log_errors] = on
php_admin_value[error_log] = /var/log/php-fpm.zzori.error.log

;php_admin_value[memory_limit] = 128M
;php_admin_value[max_input_time] = 90
;php_admin_value[max_input_vars] = 3000

여기까지 모든 설정이 완료되었습니다.
이제 nginx, php-fpm 데몬을 기동하여 웹페이지를 확인해보겠습니다.
URL : https://centos6.zzori.com

service nginx restart
service php-fpm restart

웹접속 화면 확인

그리고 추가적으로 ssllabs 에서 A+ 등급을 확인할 수 있습니다.

Share this Post

Leave a Comment

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
*
*