티스토리 뷰

개요

  • Apache HTTP Server는 그 자체로서도 굉장한 역사를 자랑하는 웹 서버이면서, 특히 PHP로 제작된 프로젝트의 기반 웹 서버로 전세계적으로 널리 사용되고 있다. 이번 글에서는 CentOS 6에서 Apache HTTP Server(httpd), mod_php, PHP 7.x.x를 설치하는 방법을 안내한다.

Apache HTTP Server, PHP 7 설치

  • PHP 7은 아래 순서로 설치한다. 패키지를 설치할 외부 저장소로 신뢰도가 높은 IUS를 선택했다.
# 저장소 캐시 초기화
$ sudo yum clean all

# EPEL 저장소 설치
$ sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm

# IUS 저장소 설치
$ sudo rpm -Uvh https://centos6.iuscommunity.org/ius-release.rpm

# IUS 저장소에서 PHP 7 패키지 설치
$ yum --enablerepo=ius install mod_php71u php71u-cli php71u-devel php71u-json php71u-xml php71u-process php71u-mbstring php71u-mcrypt php71u-pdo php71u-mysqlnd php71u-opcache
  • mod_php71u는 아래 패키지를 설치한다. httpd 패키지는 기본 저장소의 구버전에 의존한다.
apr-util-ldap x86_64 1.3.9-3.el6_0.1 base
httpd x86_64 2.2.15-59.el6.centos
httpd-tools x86_64 2.2.15-59.el6.centos
php71u-common x86_64 7.1.4-1.ius.centos6

설정 확인

  • 아래와 같이 Apache, mod_php, PHP 설정을 확인한다.
# Apache HTTP Server 버전 확인
$ httpd -v
Server version: Apache/2.2.15 (Unix)

# Apache HTTP Server 설정 확인
$ sudo nano /etc/httpd/conf/httpd.conf
Listen 80
DocumentRoot "/var/www/html"

# mod_php 설정 확인
$ sudo nano /etc/httpd/conf.d/php.conf
LoadModule php7_module modules/libphp7.so

# PHP 설정 확인
$ sudo nano /etc/php.ini

Apache 서비스 시작

  • 아래와 같이 Apache 서비스를 시작한다. 기본 설정을 바꾸지 않았다면 HTTP 80 포트로 서비스가 시작된다.
# httpd 서비스 시작
$ sudo service httpd start

# 부팅시 httpd 서비스가 자동 실행되도록 설정
$ sudo chkconfig httpd on
  • 서비스에 등록하지 않고 사용할 경우, 위 방법을 통한 서비스 제어는 불가능하다. 아래와 같이 apachctl 바이너리를 직접 제어해야 한다.
# 현재 설정된 httpd.conf 파일의 문법 오류를 검사
$ sudo /usr/local/apache/bin/apachectl -t
Syntax OK

# Apache를 무중단으로 재시작, 문법 오류 또한 사전 검사
$ sudo /usr/local/apache/bin/apachectl -k graceful

# Apache를 시작
$ sudo /usr/local/apache/bin/apachectl -k start

# Apache를 중지
$ sudo /usr/local/apache/bin/apachectl -k stop

.htaccess 허용

  • 각 디렉토리에 위치한 .htaccess 파일 설정을 활성화 하려면 httpd.conf 파일을 아래와 같이 수정한다.
$ nano /etc/httpd/conf/httpd.conf
<Directory "/var/www/html">
    AllowOverride All
</Directory>

$ service httpd restart

Xdebug 확장 모듈 설치

  • 원격 개발 서버에 Xdebug 확장 모듈을 설치하면 개발환경에서 편리하게 브레이크 포인트를 걸면서 디버깅이 가능하다.
$ yum install php71u-pecl-xdebug

$ nano /etc/php.d/15-xdebug.ini
zend_extension=xdebug.so
xdebug.remote_autostart = 1
xdebug.remote_connect_back = 1
xdebug.remote_enable = 1
xdebug.remote_mode = req
xdebug.remote_port = 9000

$ service httpd restart
  • 이제 PhpStorm에서 디버깅을 설정할 차례이다.
1. Run -> Web Server Debug Validation -> Validate 클릭하여 원격 서버의 Xdebug가 정상 작동하는지 확인
2. Run -> Break at first line in PHP Scrips 체크
3. Run -> Start Listening for PHP Debug Connections 실행
이제 F9를 누르며 브레이크 포인트 단위로 디버깅이 가능
  • 추가적으로 REST API을 디버깅하려면 매 요청시 2가지를 추가해야 한다. 첫번째는 URL에 붙는 요청 파라메터에 XDEBUG_SESSION_START=PHPSTORM을 추가한다. 두번째는 요청 헤더 쿠키에 XDEBUG_SESSION=PHPSTORM을 추가한다.

POST 요청 바디 로그 적재

  • mod_dumpost 모듈을 설치하면 POST 요청 바디를 로그 파일로 남길 수 있다. 설치 및 설정 방법은 아래와 같다. [관련 링크]
# 추가 모듈 설치를 위한 Apache 개발 패키지 설치
$ sudo yum install httpd-devel gcc

# mod_dumpost 설치
$ cd /opt
$ sudo git clone https://github.com/danghvu/mod_dumpost
$ cd mod_dumpost
$ sudo make
$ sudo make install

# mod_dumpost 환경 설정
$ sudo nano /etc/httpd/conf/httpd.conf
LoadModule dumpost_module     /usr/lib64/httpd/modules/mod_dumpost.so

LogLevel info

<IfModule dumpost_module>
    DumpPostMaxSize 1024
    DumpPostHeaderAdd Content-Type
    DumpPostLogFile /usr/local/apache/logs/dumpost.log
</IfModule>

# 로그 파일 생성 후 권한 부여, 생성하지 않을 경우 자동으로 적재되지 않음
$ sudo touch /usr/local/apache/logs/dumpost.log
$ sudo chmod 777 /usr/local/apache/logs/dumpost.log

# 로그 로테이션 정책 설정, 매일 자동으로 배치 실행
$ sudo nano /etc/logrotate.d/dumpost
/usr/local/apache/logs/dumpost.log {
    daily
    dateext
    rotate 30
    copytruncate
    missingok
}

# 로그 로테이션 테스트, 실제 실행하지는 않음
$ sudo logrotate -df /etc/logrotate.d/dumpost

# 로그 로테이션 즉시 실행
$ sudo logrotate -vf /etc/logrotate.d/dumpost

# Apache 재시작
$ sudo /usr/local/apache/bin/apachectl -k start

# 로그 조회
$ tail -f /usr/local/apache/logs/dumpost.log
$ tail -f /usr/local/apache/logs/dumpost.log | grep -A 3 "POST"

Apache 로그 Graylog 전송

  • Apache는 기본적으로 외부로부터의 요청 로그를 로컬 파일에 기록한다. 생성되는 로그를 Graylog에도 전송하면 훨씬 고도화된 로그 조회 및 시각화가 가능하다. 방법은 아래와 같다. [관련 링크] 로그 적용시 HTTP(<VirtualHost *:80> 디렉티브 내부에 설정) 및 HTTPS(<VirtualHost *:443> 디렉티브 내부에 설정)에도 모두 적용하는 것을 잊지 말도록 한다.
# Apache GELF UDP 로그 설정 추가
$ sudo nano /etc/httpd/conf/httpd.conf
<IfModule log_config_module>
    # Apache 기본 로그 포맷
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    # Graylog GELF 로그 포맷을 새로 생성
    LogFormat "{ \"version\": \"1.1\", \"host\": \"%V\", \"short_message\": \"%r\", \"timestamp\": %{%s}t, \"level\": 6, \"_request_user_agent\": \"%{User-Agent}i\", \"_request_ip_address\": \"%a\", \"_request_total_bytes\": %O, \"_request_method\": \"%m\", \"_request_path\": \"%U\", \"_request_query_string\": \"%q\", \"_http_referer\": \"%{Referer}i\", \"_process_time_ms\": %{ms}T, \"_response_status\": %>s, \"_web_server\": \"Apache\" }" graylog
    # Apache 기본 로그 저장소
    CustomLog "logs/access_log" combined
    # Graylog 서버로 GELF 로그를 UDP 전송
    CustomLog "|/usr/bin/nc -u graylog.example.com 12201" graylog
</IfModule>

# Apache 재시작
$ sudo service httpd restart
  • 위 설정을 통해 Apache의 모든 액세스 로그는 아래와 같은 형식으로 원격지의 Graylog 서버로 전송되어 조회가 가능해진다.
{
    "source": "api.foobar.com"// 요청을 수신한 서버명, httpd.conf에 명시된 ServerName, %V
    "_request_ip_address": "222.111.222.111" // 요청 IP 주소 (리버스 프록시 감안 안됨), %a
    "_request_ip_address": "222.111.222.111" // 요청 IP 주소 (리버스 프록시 감안됨), %{X-Forwarded-For}i
    "_request_total_bytes": 10380 // 총 요청 바이트 크기, %O
    "_request_method": "GET" // 요청 메써드, %m
    "_request_path": "/v1/foobar" // 요청 URI, %U
    "_request_query_string": "?abc=def" // 요청 쿼리스트링, %q
    "_process_time_ms": // 처리 소요 시간, %{%d/%b/%Y:%T}t-%{msec_frac}t, 2.2.30 이전 버전에서 사용
    "_process_time_ms": // 처리 소요 시간, %{ms}T, 2.2.30 버전부터 사용
    "_response_status": 200 // 응답 상태 코드, %>s
}
  • 이제 Apache가 실시간 전송하는 GELF UDP 로그를 수신할 차례이다. System -> Inputs -> Select Input: GELF UDP -> Launch New Input을 차례로 실행하여 새로운 인풋을 생성한다.

트러블슈팅: HTTPS 적용시 메모리 누수 문제 해결

  • ApacheHTTPS 적용 후 메모리 누수가 발생할 수 있다. 아래와 같이 설정하면 해결된다. [관련 링크]
# 현재 세션에 대해 임시로 설정
$ export NSS_SDB_USE_CACHE=YES

# 전체 세션에 대해 영구적으로 설정
$ sudo nano /etc/environment
NSS_SDB_USE_CACHE=YES

# Slab 오브젝트 캐시 초기화
$ sudo echo 3 > sudo /proc/sys/vm/drop_caches

# Apache 재시작
$ sudo /usr/local/apache/bin/apachectl -k graceful

트러블슈팅: Handshake alert : unrecognized_name

  • ApacheSSL 인증서를 적용 후 클라이언트(주로 Java) 측에서 요청시 Handshake alert : unrecognized_name 오류가 발생할 수 있다. 와일드 카드(멀티 도메인) 형태의 인증서를 설치할 경우 발생하는 문제로 Apache에서는 환경 설정에서 ServerName, ServerAlias 설정을 생략하지 않고 빠짐 없이 정확하게 명시하면 문제가 해결된다. [관련 링크1] [관련 링크2]

참고 글

댓글
댓글쓰기 폼