Apache 서버 사용법에 대해 정리합니다.

인터넷 강의를 정리한거라 범위가 제한적일수도 있습니다.

초보 입장에서 보시고 빠진건 의견 주시면 감사하겠습니다!


1. 아파치 서버 배경지식


웹서버 히스토리

- 연구원 Tim burners Lee가 hypertext 기반 정보를 연구원들 사이어서 공유 & 업데이트 하기 위한 수단을 연구하는 프로젝트를 시작으로 네트워크와 웹 환경에 대한 연구를 진행함

- hypertext idea with TCP and DNS creates the WWW (1989)

- HTML, URI, HTTP : 웹 서버를 이해하기 위한 개념 3대장


Software for Web Server (다음의 요구사항을 만족시켜야 함)

- Web Server: HTTP Server -> Application Server

  - using HTTP Protocol

  - Static content, Dynamic content

  - Must implement the HTTP Protocol

  - example) Apache, Nginx, IIS and others


HTTP는 제일 단순하게 이렇게 작동한다.

Client ---- (HTTP Request)  ---> Web Server

            /index.html 보여줘

       <--- (HTTP Response) ----

            여기 있음, HTML 형식이고 길이는 ...


2. 아파치 구조 파악하기


(1) 아파치 프로세스 제어


Apache enable automatically (시스템 설정)

$ systemctl enable httpd

$ systemctl status httpd


Firewall http and https on (CentOS 7의 방법이므로 OS마다 다시 찾아서 적용해야 함)

$ firewall-cmd --permanent --add-service=http

$ firewall-cmd --permanent --add-service=https

$ firewall-cmd --reload


Find Apache location

$ whereis httpd


Help Apache execution

$ httpd -h


Show Loaded Apache Modules

$ httpd -M


Show Compiled Apache Modules

$ httpd -l


Check if config file location is vaild

$ httpd -t -f /etc/httpd/conf/httpd.conf


All Apache Module's location

$ cd /usr/lib64/httpd/modules


(2) Apache's main location (아파치 프로그램 구성)

$ cd /etc/httpd

- conf    : configuration file's directory

- conf.d  : custom configuration file's directory

- logs    : Apache log directory

- modules : Apache module's location (linked to /usr/lib64/httpd/modules)


3. Apache Configuration

(1) 설정 파일 작성 기초

한줄로 선언하는 설정 명령

+ ServerRoot                 : Apache's root directory

+ Listen                     : Port(+IP Addr) that Apache listen

+ Include *.conf             : 추가 설절파일 포함하여 작동, 설정파일이 존재하지 않으면 에러

+ User/Group                 : OS에서 아파치가 실행되는 계정명

+ ServerAdmin                : 관리자 이메일

+ ServerName                 : 웹 서버의 도메인 이름

+ DocumentRoot               : 웹 서버에서 사용할 resource 의 root 경로

+ ErrorLog                   : 아파치 에러로그 파일의 위치

+ LogLevel                   : 로그 출력 수준 (debug, info, notice, warn, error, crit, alert, emerg)

+ IncludeOptional            : 명시한 추가 설정파일이 실제로 있을 경우에만 포함시켜 작동함


Tag로 선언하는 설정 명령

+ <Directory addr>            : 디렉토리에 대한 접근 설정   *root에 대한 접근은 기본적으로 막혀있다.

  - AllowOverride

  - Require

  - Options

+ <IfModule mod>              : 지정한 모듈이 존재할 경우 추가 설정 정의

+ <File file>                 : 파일에 대한 접근 설정   *보통은 .htaccess와 .htpasswd 파일이 웹에 공유되는 것을 막기 위해 기본 설정 되어 있음


(2) Virtual Host Setting

name based

<VirtualHost *:80>
  DocumentRoot  "/var/www/akademia"
  ServerName  www.akademia.com
</VirtualHost>

port based

* 방화벽 포트 오픈 설정
* conf 생성
Listen 8080

<VirtualHost *:8080>
  DocumentRoot  "/var/www/akademia"
  ServerName  web.akademia.com
</VirtualHost>

Alias Setting (한줄 추가)

Alias /img /var/www/html/images

Redirect Setting (한줄 추가)

Redirect [permanent|temp] /program.html /download.html

Custom Log

https://httpd.apache.org/docs/2.2/ko/mod/mod_log_config.html 참고, 그만큼 옵션이 다양함


(3) Security Basic Settings

httpd.conf

ServerTokens OS->Prod 
ServerSignature On->Off
FileETag None
TraceEnable off

custom conf

Options -Indexes

apache 서비스 계정에 권한

$ sudo usermod -g apache apache
$ sudo chown -R apache.apache /etc/httpd/
$ ls -ld /etc/httpd/
$ sudo systemctl restart httpd

root 외에 설정 파일 접근 차단

$ ps -ef | grep httpd
$ sudo chmod 750 /etc/httpd/conf
$ sudo chmod 750 /etc/httpd/conf.d

Set up TLS/SSL for a free (도메인이 있어야 가능)

$ sudo yum install epel-release
$ sudo yum install mod_ssl python-certbot-apache
$ firewall-cmd --permanent --add-service=https
$ firewall-cmd --reload
$ certbot --apache -d <도메인 명>
$ certbot --renew   # scheduler 설정

Basic Authentication Setting

# custom 설정에 추가
<Directory "/var/www/akademia/admin">
  AuthType Basic
  AuthName "For Authenticated Users"
  AuthUserFile /etc/httpd/password/passwords_file
  Require valid-user
</Directory>

$ httpd -t
$ sudo systemctl restart httpd

(2) passwords_file 생성
$ sudo mkdir /etc/httpd/password
$ sudo htpasswd -c /etc/httpd/password/passwords_file user1

Digest Authentication Setting

# custom 설정에 추가
<Directory "/var/www/akademia/mod">
  AuthType Digest
  AuthName "Private"
  AuthUserFile /etc/httpd/password/digest
  Require valid-user
</Directory>

(2) passwords_file 생성
$ sudo htdigest -c /etc/httpd/password/digest "Private" user3

Access Control

(참고: https://httpd.apache.org/docs/2.4/mod/mod_authz_host.html)
(1) Directory 태그 안에 추가
<RequireAll>
  Require all granted
  Require [not] ip XX.XX.XX.XX
</RequireAll>

.htaccess 설정

(1) Directory 태그 안에 추가
AllowOverride AuthConfig #추가

(2) 지정 위치에 .htaccess 파일 작성
AuthType Digest
AuthName "Private"
AuthUserFile /etc/httpd/password/digest
Require valid-user

웹 서버 anti-virus 설치

$ yum -y install epel-release
$ yum -y install clamav-server clamav-data clamav-update clamav-filesystem clamav clamav-scanner-systemd clamav-devel clamav-lib clamav-server-systemd
(selinux 작동 되어있어야 함)
$ setsebool -P antivirus_can_scan_system 1
$ setsebool -P clamd_use_jit 1
$ vi /etc/clamd.d/scan.conf
$ vi /etc/freshclam.conf
$ freshclam
$ clamscan -r [--(remove|move)] /var/www/akademia/

DoS Attack 방지

$ yum -y install mod_evasive
$ yum -y install mailx
$ vi /etc/httpd/conf.d/mod_evasive.conf
$ tail -f /var/log/messages

4. 기타

(1) Apache MPM (Multi-Processing Modules)

- The worker MPM : multiple child processes * many threads each, Each thread handles one connection at a time
(generally good for high-traffic servers)
- The event MPM : worker with main threads, designed to allow more requests to be served simultaneously by passing off some processing work to supporting threads
- The prefork MPM : multiple child processes * 1 thread each, Each process handles one connection at a time.
(it can be used with non-thread-safe third-party modules, and it is easier to debug on platforms with poor thread debugging support.)

(2) Adjusting httpd.conf (커넥션 관련 옵션)

- Timeout               : sets the number of seconds before data sends to or receives from the client timeout
- KeepAlive             : enables persistent connections on the web server
- KeepAliveTimeout      : the number of seconds Apache wait for a subsequent request before closing the connection
- MaxKeepAliveRequests  : limits the number of requests allowed per connection when KeepAlive is on.


Posted by kevin.jeong.
,

이전 글에서 웹 요청을 위한 HTTP 요청/응답 메시지를 알아보았습니다.

그렇다면 웹 서버에서는 이러한 요청을 어떻게 처리하는 걸까요?


정적인 요청과 동적인 요청, 그 차이는?

자바 웹 개발을 처음 시작할때, Apache Tomcat을 설치하면서 WAS의 역할에 대해 간략하게 배우게 되죠.

WAS의 역할은 동적인 요청을 처리하는 거라고 하는데, 그렇다면 정적인 것과 동적인 것은 어떻게 구분을 할까요?


저도 몇년동안 이걸 어떻게 정의할 수 있을지 고민이 많았습니다만..

핵심은 "정보가 변하는가?" 입니다.

정적인 요청은 한번 위치시켜 놓으면 변하지 않는 정보에 대한 요청인 거고,

(사람의 개입없이 단순히 웹 서버가 작동중일때를 기준)

동적인 요청은 요청의 식별자는 동일해도, 부가적인 정보(HTTP 요청 헤더, 파라미터 변수 혹은 json/xml 형식의 message-body)의 유무나

시간이 지나면서 변하게 되는 데이터인지에 따라

요청할때마다 응답하는 정보가 달라지는 경우를 말하는거죠


그래서 Tomcat같은 WAS는 이런 동적인 요청을 처리하기 위해 HTTP 요청 메시지를 파싱하고,

파라미터나 헤더값, message-body에 따라 동적인 데이터의 저장소 (보통은 DB) 에서 CRUD 같은 지지고볶는 작업을 통해 

가공된 응답을 만들어서 전달하는 것인데요.

(이 부분을 back-end라고 부르죠~)


반면 정적인 요청을 전담하는 웹 서버에서는 요청의 식별자를 요청하는 자원의 상대적인 위치로 인식하고

찾아서 있으면 메시지에 포함하거나 다운로드를 할 수 있도록 응답상태를 Redirect 로 만들어서 보내고,

없으면 응답상태가 403이 되는거죠.


Apache 웹 서버는 이런 정적인 요청을 처리해서 응답하도록 설계/개발된 서버 프로그램이라고 정리할 수 있겠습니다!


정적인 요청과 동적인 요청을 웹서버는 어떻게 구분하지?

아쉽게도 웹서버 자체에서 요청을 받는 시점에 정적인지 동적인지 구분해서 처리할수 있는 방법은 없습니다.

웹 서버는 일단 HTTP 요청 메시지의 URI로 요청 자원을 찾아보고 없으면 설정에 따라 처리할 뿐이죠.


대신 대부분의 웹서버 프로그램들은 WAS와 연동이 가능하도록 플러그인 형태의 모듈을 제공합니다.

이걸 사용하면 웹서버가 먼저 요청을 처리하고 URI에 해당하는 정보 자원이 없으면

이 요청을 WAS에게 넘기는 방식으로 작동합니다.

(아니면 특정 포트를 통해 들어오는 요청은 무조건 WAS에 이관하도록 처리할 수도 있다고 합니다~)


따라서 웹 서버를 본격적으로 다룬다고 하면 설정을 이해할 수 있어야 됩니다.

저도 아직은 미생이지만.. 조만간 Apache 설정법을 정리해볼까 하네요~


번외) Tomcat이랑 다른 WAS도 정적인 요청 다 처리하는데..? 굳이 구분을 왜 하는거야?

..라고 질문하는 분들을 위해

네 맞습니다. 자바 웹 개발 처음 배울때 분명히 tomcat에서 이미지도 처리해주고 css랑 js파일 경로 다 제공해줬죠.

WAS자체만으로도 웹서버로 사용가능한건 맞죠.

다만, 정확히 알아두고 넘어가야 하는 건, WAS로 나오는 서버프로그램들은 Apache 같은 웹 서버의 경량버전을 내포한채로 공개됩니다.

즉, WAS는 사실 동적인 요청을 처리하기 위한 Servlet Container + 경량 웹 서버 모듈인거죠.


자바같이 서버 구현이 가능한 언어에서는 동적인 웹 요청을 처리하기 위한 프로세스를 컨테이너에서 관리하도록 하고,

여기에 웹 서버처럼 작동할 수 있도록 웹 서버의 필수 핵심 기능을 더 붙여서 WAS를 개발한 게 됩니다.

servlet 같은 프로그램 실행 thread의 컨테이너가 WAS의 핵심은 맞지만, WAS == 컨테이너는 엄밀하게 따지면 잘못된거라고 생각되네요.


그래서 WAS에서는 웹 서버에 대한 설정은 깊게 못합니다. 

아예 못한다고 하긴 무리가 있겠지만, 정확히는 웹서버 상의 상당히 많은 설정들이 생략 혹은 default로 박혀버려서

대표적인 몇가지 (HTTPS 및 timeout 정도)를 제외하고는 설정이 불가능 한거죠.


사실 Apache 같은 웹서버를 사용하는 이유라고 하면, 웹으로 유입되는 네트워크 트래픽을 관리하거나

동적인 영역과 정적인 영역을 분리하는게 좋다여서, SI/SM 같은 회사 전산에서는 굳이 필요하지 않을 수도 있습니다.

대신, 웹/모바일 서비스가 회사의 메인인 경우는 트래픽이 많으면 많을 수록 매출로 연결되는데,

안정적인 웹 속도와 사용감을 제공하기 위해서는 웹 서버의 설정이 꼭 필요하고,

실제로도 카카오, 네이버 등의 대형 IT회사에서는 이쪽 전문인력만 따로 뽑아서 키우기도 합니다.


결론은 인터넷을 거쳐 온 후의 서버 측 웹 요청을 중간에 컨트롤할 필요가 있으면 웹서버와 WAS를 분리해서 사용합니다~


Posted by kevin.jeong.
,