-
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를 사용한다.
'개발이야기' 카테고리의 다른 글
docker를 활용한 apache-tomcat 이중화 서버 구현 (0) 2021.05.13 Nestjs로 구현하는 Authentication & Authorization(4) (0) 2021.04.11 Nestjs로 구현하는 Authentication & Authorization(3) (3) 2021.04.11 Nestjs로 구현하는 Authentication & Authorization(2) (1) 2021.03.26 NestJS로 구현하는 Authentication & Authorization(1) (0) 2021.03.26