ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Apache Httpd Configuration 정리
    개발이야기 2021. 8. 16. 21:45

    1. Apache Httpd

    Apache Httpd 는 Apache 재단에서 제공하는 웹서버이다. Tomcat과는 달리 정적인 리소스만을 제공한다. 동적인 리소스를 처리할 수 있는 서블릿 컨테이너(Tomcat 등)과 연결하여 안정적인 웹 서비스를 제공할 수 있다.

    2. Install

    2.1 직접 설치

    리눅스 OS를 사용한다면 패키지 관리 툴을 사용하여 Apache Httpd를 쉽게 설치할 수 있다.

    apt install apache2

    2.2 Docker 사용

    Docker를 사용한다면 다양한 환경에서 Apache 웹서버를 쉽게 띄울 수 있다.

    docker run -d --name="apache" -p 80:80 httpd
    docker run -d --name="apache" -p 80:80 adoreje/httpd

    httpd는 docker hub에 올라간 httpd의 공식 이미지이다. adoreje/httpd는 이미지 경량화를 위해 alpine 리눅스 기반에서 apache httpd 를 설치한 것이다. 자세한 내용은 github 을 참고한다.

    3. Configuration

    3.1 Apache httpd 2.4 default layout

    ServerRoot              ::      /usr/local/apache2
    DocumentRoot            ::      /usr/local/apache2/htdocs
    Apache Config File      ::      /usr/local/apache2/conf/httpd.conf
    Other Config Files      ::      /usr/local/apache2/conf/extra/
    SSL Config File         ::      /usr/local/apache2/conf/extra/httpd-ssl.conf
    ErrorLog                ::      /usr/local/apache2/logs/error_log
    AccessLog               ::      /usr/local/apache2/logs/access_log
    cgi-bin                 ::      /usr/local/apache2/cgi-bin (enabled by default, but some of the bundled scripts are 644)
    binaries (apachectl)    ::      /usr/local/apache2/bin
    start/stop              ::      /usr/local/apache2/bin/apachectl (start|restart|graceful|graceful-stop|stop|configtest)

    Apache 웹서버의 설정파일은 conf 폴더에 있다. httpd.conf 파일에서 여러가지 설정 정보를 관리하며 파일을 기능별로 여러개로 나누고 include하여 사용할 수 있다. 기능별로 나뉜 설정파일은 주로 conf/extra폴더에 위치하며 파일의 이름과 경로 등은 마음대로 설정할 수 있다.

    3.2 기본 설정 정보

    #### httpd.conf ####
    
    Listen 80
    # 기본으로 80포트로 들어오는 요청일 읽는다
    # 다른 포트를 추가로 지정할 수 있다
    
    ServerRoot "/usr/local/apache"
    # 아파치의 홈 디렉토리, 절대경로로 설정한다. 이후에 나오는 대부분의 경로는 ServerRoot의 상대경로로 설정된다.
    
    User apache
    Group apache
    # 홈페이지 서비스를 직접 담당하는 자식 프로세스들의 실행소유자와 소유 그룹에 대한 계정정보
    # 보안을 위해 nobody로 설정하기도 한다.
    
    ServerAdmin root@domain.com
    # 웹 문서 로딩 중 에러 발생 시 보여지는 관리자 메일 주소
    
    DocumentRoot "/var/www/html"
    # 서버 내의 웹문서가 있는 경로
    
    LoadModule auth_basic_module modules/mod_auth_basic.so
    # /usr/local/apache/modules 에 있는 모듈을 동적으로 불러온다
    
    Include conf.d/*.conf
    # conf.d 디렉토리 내의 .conf 파일을 불러온다.
    
    ServerName www.example.com
    # 클라이언트에서 보여주는 호스트 이름
    # 사용중인 도메인이 없다면 IP주소를 입력
    
    Timeout 300
    # 클라이언트에서 300초 동안 아무런 요청이 없을 때 연결을 중지
    
    KeepAlive On
    # 아파치의 한 프로세스가 특정사용자의 지속적인 요청을 처리
    
    MaxKeepAliveRequests 100
    # KeepAlive 가 on일경우에만 유효
    # 사용자의 요청을 처리할 때 100이 넘어가면 프로세스를 종료하고 다른 프로세스가 사용자의 요청을 처리
    # 하나의 프로세스가 지속적으로 요청을 처리하면 메모리 효율 저하 -> 시스템 성능 저하
    
    KeepAliveTimeout 2
    # KeepAlive On인 경우에만 유효
    # 2초동안 요청이 없을 경우 timeout

    3.3 Directives(지시어)

    Related Modules Related Directives
    core <Directory>
    mod_version <DirectoryMatch>
    mod_proxy <Files>
      <FileMatch>
      <If>
      <IfDefine>
      <IfModule>
      <IfVersion>
      <Location>
      <LocationMatch>
      <DomainSet>
      <Proxy>
      <ProxyMatch>
      <VirtualHost>

    <IfDefine>, <IfModule>, <IfVersion> 은 서버가 시작할 때(재시작 포함) 적용된다. 다른 지시어는 request마다 적용된다.

    3.3.1 서버 전체 설정

    • <IfDefine>
    <IfDefine ClosedForNow>
        Redirect "/" "http://otherserver.example.com/"
    </IfDefine>
    
    ===========================================
    서버가 httpd -DClosedForNow 명령어로 실행되어야만 적용된다.
    • <IfModule>
    <IfModule mod_mime_magic.c>
        MimeMagicFile "conf/magic"
    </IfModule>
    
    ============================================
    서버에서 해당 모듈이 있을때만 적용된다. 서버 내에 모듈이 컴파일되어 있거나
    <IfModule>을 호출하기 전 LoadModule을 통해 해당 모듈을 load해야 쓸 수 있다
    • <IfVersion>
    <IfVersion >= 2.4>
        # this happens only in versions greater or
        # equal 2.4.0.
    </IfVersion>
    
    ===========================================
    서버 버전이 2.4 이상일때만 적용된다.

    3.3.2 파일 시스템

    • <Directory>
    <Directory "/var/www/html">
         Options None
         Order allow,deny
         Allow from all
    		 (Deny from all)
    </Directory>
    
    =========================================
    DocumentRoot의 <Directory> 설정이다. Options 설정에 따라 DocumentRoot의파일이 목록화되어 나타날 수 있기 때문에 보안상 None으로 설정한다.
    
    Order는 접근을 통제하는 순서를 나타낸다. allow, deny 순으로 지정하면 allow를 먼저 수행하고 deny를 나중에 수행하라는 의미이다.
    
    Allow from(혹은 Deny from) 뒤에 쓸 수 있는 항목은 다음과 같다.
     - 도메인
     - 호스트 이름
     - 호스트 IP 주소
     - IP 주소의 A.B.C 클래스
     - all (모든 주소)
    • <Files>
    <Files "private.html">
        Require all denied
    </Files>
    
    =========================================
    경로에 상관없이 private.html이라는 파일 모두에 적용된다.

    3.3.3 WebSpace

    클라이언트로 전송되어 화면에 보여지는 부분이다.

    • <Location>, <LocationMatch>
    <LocationMatch "^/private">  
    Require all denied
    ================================================
    */private이 들어간 url 요청을 모두 거부한다.
    <Location "/server-status">
        SetHandler server-status
    </Location>
    
    ================================================
    /server-status 을 호출했을 때 핸들러를 지정한다.
    <Location> 지시어는 파일시스템을 따로 호출해야하는 과정이 필요 없다.

    3.3.4 VirtualHost

    한 서버에서 여러개의 서비스를 호스팅할 때 사용한다.

    • <VirtualHost>
    <VirtualHost 10.1.2.3:80>
      ServerAdmin webmaster@host.example.com
      DocumentRoot "/www/docs/host.example.com"
      ServerName host.example.com
      ErrorLog "logs/host.example.com-error_log"
      TransferLog "logs/host.example.com-access_log"
    </VirtualHost>
    
    ===============================================
    10.1.2.3:80으로 요청이 들어올 경우 적용된다. ip뿐 만 아니라 도메인도 들어올 수 있으며 wildcard(*)를 적용할 수 있다.
    <VirtualHost>마다 ServerName을 지정해주어야 하며 따로 지정해주지 않을 경우
    메인 서버의 ServerName을 상속한다.

    4. 주요 설정

    4.1 WAS 연동

    Apache Httpd와 WAS를 연동하는 방법은 3가지가 있다.

    4.1.1 Tomcat connector(mod_jk)

    Tomcat과 연결하기 위한 전용 모듈이다. AJP/1.3 프로토콜을 사용하며 설정이 조금 복잡하긴 하지만 JkMount 옵션을 이용하여 유연한 설정이 가능하다.

    # 1. 공식 홈페이지에서 최신 버전을 다운로드한다.(현재 최신버전 : 1.2.48)
    wget https://mirror.navercorp.com/apache/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.48-src.tar.gz
    
    # 2. 설치
    tar zxvf tomcat-connectors-1.2.48-src.tar.gz
    cd tomcat-connectors-1.2.48-src/native
    ./configure --with-apxs=/usr/sbin/apxs
    make
    make install
    make install을 완료하면 apache 경로의 modules 폴더에 mod_jk.so 가 복사된다.
    • httpd.conf 설정
    # 모듈 load
    LoadModule jk_module modules/mod_jk.so
    
    # 설정파일 include
    Include conf/extra/mod_jk.conf
    ================================
    경로와 파일 이름은 변경할 수 있다.
    • extra/mod_jk.conf 설정

    폴더와 이름은 변경해도 된다.

    <IfModule mod_jk.c>
      # worker 설정 파일 경로
      JkWorkersFile conf/workers_jk.properties
      
      # jk 공유메모리 파일 위치
      JkShmFile run/mod_jk.shm
      
      # 로그 파일 경로
      JkLogFile logs/mod_jk.log
      
      # 로그 레벨 설정 [debug/error/info]
      JkLogLevel info
      
      # 로그 출력 시 시간 포맷 설정
      JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
      
      ## url pattern 에 따른 connector mapping
      ##JkMountFile conf/uriworkermap.properties
    </IfModule>
    • conf/workers_jk.properties 설정
    worker.list=worker1, worker2
    worker.worker1.port=8009
    worker.worker1.host=server1
    worker.worker1.type=ajp13
    worker.worker1.lbfactor=1
    
    ## server 2
    worker.worker2.port=8009
    worker.worker2.host=server2
    worker.worker2.type=ajp13
    worker.worker2.lbfactor=1
    여기서 설정하는 port는 톰캣에서 사용하는 AJP/1.3 프로토콜에서 사용하는 port를 지정한다. 관련된 설정은 톰캣의 server.xml을 확인한다.
    <Connector protocol="AJP/1.3" port="8009" connectionTimeout="20000" redirectPort="8443" secretRequired="false" URIEncoding="UTF-8" address="0.0.0.0"/>​
    • conf/uriworkermap.properties
    ## Mapping the URI /service1 under worker1
    /service1/*.do=worker1
    /service1/*.jsp=worker1
    
    # /service2 요청으로 들어온 것은 worker2 로 mount
    /service2/*=worker2
    
    # png와 jpg 는 apache 가 처리
    !/service2/*.png=worker2
    !/service2/*.jpg=worker2
    
    ======================================================
    uri 별로 유연한 처리가 가능하다.
    • <VirtualHost> 적용
    <VirtualHost *:81>
        ServerName dgbp.daeguedu.com
        JkMount /* worker1
    </VirtualHost>
    =========================================================
    81번 포트로 들어오는 모든 요청을 worker1로 mount 한다.

    4.1.2 mod_proxy 사용

    reverse proxy로 동작하는 모듈이다.

    • load module
    LoadModule proxy_http_module modules/mod_proxy_http.so
    LoadModule proxy_module modules/mod_proxy.so
    • <VirtualHost> 적용
    <VirtualHost *:8080>
      ServerName was2
      <Proxy *>
        Order deny,allow
        Allow from all
      </Proxy>
    
      ProxyRequests Off
      ProxyPreserveHost On
      ProxyPass / http://10.36.25.73:8080/ retry=1 acquire=3000 timeout=600 Keepalive=On
      ProxyPassReverse / http://10.36.25.73:8080/
    </VirtualHost>
    ========================================================================
    8080로 들어오는 모든 요청을 http://10.36.25.73:8080 로 전달한다.
    
    - ProxyRequests
      On : Forword proxy
      Off : Reverse Proxy
    - ProxyPreserveHost On
      HTTP 헤더의 Host 부분을 유지한다.

    4.1.3 mod_proxy_ajp 사용

    AJP/1.3 프로토콜과 reverse proxy를 결합한 방식이다.

    • <VirtualHost> 적용
    <VirtualHost *:9090>
        ServerName was2
    
        <Proxy *>
    	  Order deny,allow
          Allow from all
      	</Proxy>
    
        ProxyRequests Off
        ProxyPreserveHost On
        ProxyPass / ajp://10.36.25.73:8009/
        ProxyPassReverse / ajp://10.36.25.73:8009/
    </VirtualHost>
    =============================================================================
    reverse proxy와 비슷한 방식으로 적용할 수 있으며 프로토콜을 ajp로 변경하고 ajp에서 사용하는 포트를 적용한다.

    4.2 SSL 적용

    • extra/httpd-ssl.conf
    <VirtualHost _default_:443>
    	DocumentRoot "/usr/local/apache2/htdocs"
    	ServerName www.example.com:443
    	ServerAdmin you@example.com
    	ErrorLog /proc/self/fd/2
    	TransferLog /proc/self/fd/1
    
    	JkMount /* worker1
    
    	SSLEngine on
    	SSLCertificateFile [인증서 파일 경로]
    	SSLCertificateKeyFile [키파일 경로]
    	SSLCACertificateFile [CA인증서 파일경로]
    </VirtualHost>
    • httpd.conf
    # 모듈 load
    LoadModule ssl_module modules/mod_ssl.so
    • mod_proxy 에 적용
    <VirtualHost *:8182>
            ServerName dgbp.daeguedu.com
    
            ServerName dgbp.daeguedu.com
    
            ProxyRequests Off
            ProxyPreserveHost On
            ProxyPass / http://10.36.3.140:8080/ retry=1 acquire=3000 timeout=600 Keepalive=On
            ProxyPassReverse / http://10.36.3.140:8080/
    
            SSLEngine on
            SSLProxyEngine on
            SSLProtocol all -SSLv2 -SSLv3
            SSLProxyProtocol all -SSLv2 -SSLv3
            SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
            SSLProxyCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
            SSLCertificateKeyFile /usr/local/apache//sslFile/server.key.pem
            SSLCertificateFile /usr/local/apache//sslFile/server.crt.pem
            SSLCACertificateFile /usr/local/apache//sslFile/rootca.crt.pem
    
    </VirtualHost>
    ====================================================================
    mod_proxy에 SSL을 적용하고자 하는 경우 SSLProxyEngine 을 활성화한다.

    4.3 HTTPS Redirect

    # 1. rewrite module을 로드한다.
    LoadModule rewrite_module modules/mod_rewrite.so
    
    # 2. Virtual Host에서 80으로 들어온 요청을 443으로 redirect 한다.
    <VirtualHost *:80>
        DocumentRoot "/www/example1"
        ServerName www.example.com
    
        RewriteEngine On
    	  RewriteCond %{HTTPS} !on
    	  RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
    </VirtualHost>
    
    <VirtualHost *:443>
        ServerName www.example.com
        DocumentRoot "/var/www/html"
    
        SSLEngine on
        SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    
        SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
        SSLHonorCipherOrder on
    	
    		SSLCertificateFile [인증서 파일 경로]
    		SSLCertificateKeyFile [키파일 경로]
    		SSLCACertificateFile [CA인증서 파일경로]
    
        ErrorLog logs/example.com-ssl-error_log
        TransferLog logs/example.com-ssl-access_log
        CustomLog logs/ssl_request_log \
            "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    </VirtualHost>
    
    ===========================================================================
    - RewriteEngine
      활성화 여부
    - RewriteCond
      조건 설정. 설정한 패턴과 일치하는 경우 RewriteRule 적용
    - RewriteRule
      실질적인 Rewrite 규칙을 적용하는 지시자
      RewriteRule [input URL] [Return URL]
    * Rewrite Subrutine 지시자
      L : 뒤 구문 여부를 무시하고 그 줄에서 끝낸다.
      R : 무조건 redirect를 적용한다.
      P : proxy를 사용한다.

    댓글

Designed by Tistory.