[Linux]Apache 웹 서버(httpd)의 보안 설정을 강화하기(httpd.conf)

여전히 아파치 웹 서버를 많이 사용하고 있지요! 그래서 Apache 웹 서버(httpd)의 보안 설정을 강화하기 위해 알아야 할 환경설정 파일(httpd.conf)의 지시자 및 모듈에 대해 알아보겠습니다. “웹 서비스(httpd) 점검” 글에서도 기본적인 보안 설정 사항을 확인하실 수 있습니다. Apache Version2.4 지시어 목록를 보시면 전체 지시어(Directives)에 대한 설명을 보실 수 있습니다.

  1. 디렉토리에 접근했을 때 자동으로 표시되는 콘텐츠를 제어: DirectoryIndex 인텍스 파일 목록
    디렉터리에 여러 개의 인덱스 파일이 있는 경우, 웹 서버는 리스트된 파일들 중에서 첫 번째로 발견된 파일을 사용합니다.
    # index.html → index.htm → index.php → index.jsp 순서로 사용합니다. 
    DirectoryIndex index.html index.htm index.php index.jsp
    
  2. 디렉터리에 있는 파일 목록을 보이지 않도록 설정: Options Indexes를 제거
    디렉터리 지시자 설정(<Directory />)에서 Options Indexes를 사용하면 웰컴 페이지(index.html, index.jsp 등)가 없을 경우 접근한 디렉터리에 있는 파일 목록을 웹 브라우저에 출력(Directory Listing 공격)하여 불필요한 정보나 중요한 정보가 노출될 수 있습니다.
  3. 심볼릭 링크를 따라가지 않도록 설정: Options FollowSymLinks를 제거
    디렉터리 지시자 설정(<Directory />)에서 Options FollowSymLinks를 사용하면 심볼릭 링크를 따라 갈 수 있기 때문에 불필요한 파일에 접근할 수 있습니다.
  4. 서버 응답 헤더에서 서버 정보를 최소화: ServerTokens Prod
    ServerTockens 지시자를 사용하여 서버 응답 헤더에서 제공되는 서버 정보를 제한할 수 있습니다.(Prod(ProductOnly) < Major < Minor < Min(Minimal) < OS < Full). ServerTokens 지시자를 명시적으로 설정하지 않으면 디폴트 값은 “Full”입니다. 이 경우, Apache 서버는 응답 헤더에 전체 세부 정보를 포함한 서버 정보를 표시하므로, “ServerTokens” 지시자가 명시적으로 선언되어 있는지 확인해야 합니다. 참고로 curl --head hostname 명령어를 사용하면 웹 서버의 정보를 확인할 수 있습니다.
    C:\>curl --head yesxyz.kr
    HTTP/1.1 200 OK
    Server: nginx
    Date: Wed, 31 Jan 2024 22:37:32 GMT
    Content-Type: text/html; charset=UTF-8
    Connection: keep-alive
    Vary: Accept-Encoding
    X-Powered-By: PHP/7.4.5p1
    Vary: Accept-Encoding,Cookie
    Link: ; rel="https://api.w.org/"
    Link: ; rel="alternate"; type="application/json"
    Link: ; rel=shortlink
    
  5. 서버 응답 헤더에서 서버 시그니처 숨기기: ServerSignature Off
    ServerSignature On으로 설정하면 서버 응답 헤더에 Apache 웹 서버의 버전 및 사용 중인 OpenSSL 및 PHP 버전이 표시됩니다. 이 정보는 보안상의 이유로 가리거나 최소한으로 표시하는 것이 권장됩니다.
  6. HTTP 트래이싱을 방지하여 헤더 인젝션 공격 차단: TraceEnable Off
    HTTP 트레이싱(HTTP Tracing)은 클라이언트와 서버 간의 HTTP 통신을 디버깅하고 문제를 해결하기 위해 사용되는 기술로 클라이언트가 요청한 내용을 서버가 그대로 응답함으로써 클라이언트는 자신이 보낸 요청이 어떻게 수정되었는지 확인할 수 있습니다.
    TRACE 메소드를 이용하면 클라이언트가 보낸 헤더를 서버가 그대로 응답하므로, 악의적인 사용자는 서버 응답을 변조하는 헤더 인젝션 공격을 할 수 있습니다. TraceEnable Off 설정을 통해 TRACE 메소드를 비활성화하면 클라이언트가 TRACE 메소드를 통해 서버에게 보낸 요청을 반복해서 보여주지 않습니다. 이를 통해 헤더 인젝션 공격에 대한 대응을 강화할 수 있습니다.
  7. 클라이언트로부터 수신하는 요청의 바디 크기 제한을 설정: LimitRequestBody #_of_bytes
    클라이언트가 서버로 전송하는 HTTP 요청의 본문(body) 크기를 제한함으로써 공격자가 대량의 데이터를 서버로 전송하여 공격하는 경우를 방지하고 서버의 자원 소모를 제어하는 데 사용됩니다(POST나 PUT 메소드). 대량의 데이터를 서버에 전송하는 공격은 서버의 응답 속도를 늦추고, 대역폭을 소모하며, 서버 다운 등의 문제를 유발할 수 있습니다. “0”으로 설정하면 무한대를 의미하며 지정한 크기를 초과하여 요청하는 경우에는 413(Request entity too large) 에러 응답 메세지를 반환합니다. 아래 설정은 본문 크기를 1MB로 제한합니다.
    <Directory "/var/www/html/download">
         LimitRequestBody 1048576 # 1MB = 1024*1024
    </Directory>
    
  8. SSL/TLS 사용하기
  9. mod_security 모듈 사용하기
    아파치 웹 서버에서 사용하는 웹 애플리케이션 방화벽 모듈입니다.
    ModSecurity: TrustWave社에 의해 제공되며 아파치, IIS 웹서버 등을 지원하는 공개 웹 애플리케이션 방화벽(WAF)
    LoadModule security_module modules/mod_security.so
    
    <IfModule mod_security2.c>
        SecRuleEngine On
        SecAuditEngine On
    </IfModule>
    
  10. 클라이언트로부터 요청을 받은 후 응답을 보내기까지 대기하는 시간을 설정: Timeout 20
    기본값은 60초로, 서버가 클라이언트로부터 요청을 받은 후 일정 시간 안에 응답을 보내지 않으면 연결이 종료됩니다.
    클라이언트의 요청으로 서버와 연결된 후, 클라이언트와 웹서버 간에 아무런 데이터 송수신 없이 세션을 유지하는 시간에 대한 타임아웃을 설정하여 연결을 종료합니다.
  11. 클라이언트로부터 온 요청을 읽는 데 걸리는 시간을 제어: RequestReadTimeout header=10-20,minrate=500 body=10,minrate=500
    클라이언트로부터 요청 메세지의 Header와 Body를 모두 수신하는 시간에 대한 타임아웃(초 단위)를 지정합니다.
    주로 느린 DoS 공격으로부터 서버를 보호하기 위해 사용합니다. 위 설정 사항은 Header를 읽는 데 10~20초가 소요되며(Slow HTTP Header DoS 공격 대응, Slowloris), Body를 읽는 데 10초가 소요(Slow HTTP POST DoS 공격 대응, RUDY)됩니다. 최소 요청률은 500 bytes/sec입니다.
  12. Keep-Alive 기능을 사용: KeepAlive On
    한 번의 TCP 연결을 통해 여러 개의 HTTP 요청과 응답을 처리하는 것을 가능하게 합니다. 이것은 웹 서버의 성능을 향상시키고 클라이언트와의 응답 시간을 단축시키는 데 도움이 됩니다. 하지만 이로 인해 서버 리소스가 오래 확보되는 경우가 있을 수 있으므로 공격자가 연결을 끊지 않고 많은 수의 요청을 보낼 수 있습니다.
  13. Keep-Alive 연결의 대기 시간을 설정: KeepAliveTimeout 30
    클라이언트와 서버 프로세스 간에 연결을 지속시키는 동안에 클라이언트의 마지막 요청 이후 다음 요청을 대기하는 시간(초 단위)을 지정합니다. 해당 시간 동안 클라이언트의 추가 요청이 발생하지 않으면 연결을 종료합니다. 만약 이 시간이 너무 길면 서버 리소스를 많이 점유하게 되고, 공격자가 Keep-Alive 연결을 많이 생성하여 서버를 공격할 수 있습니다. 따라서 이 값은 적절히 설정되어야 하며, 너무 짧거나 너무 길지 않도록 유지해야 합니다. 일반적으로 다음과 같은 크기 순서를 가집니다: RequestReadTimeout < Timeout < KeepAliveTimeout
  14. 하나의 Keep-Alive 연결에서 처리할 수 있는 최대 요청 수를 설정: MaxKeepAliveRequests 100
    단일 Keep-Alive 연결을 통해 처리할 수 있는 최대 요청 횟수를 설정합니다. 적절히 설정하면 DDoS 공격을 방지할 수 있습니다. 이 값이 너무 크면 하나의 연결로 많은 수의 요청이 처리되어 서버 리소스가 과도하게 사용될 수 있습니다. 반면에 이 값이 너무 작으면 많은 수의 연결이 생성되어야 하므로 서버의 부하가 증가할 수 있습니다.
  15. 업로드 디렉터리의 URL을 이용한 직접 호출 및 실행을 방지(파일 업로드 취약점 대응): FileMatch 지시자 사용
    악성 스크립트 파일을 업로드한 경우에도 파일명에 .ph, .inc, .lib이 포함된 파일의 접근을 차단합니다.(^:시작 문자열, $:종료 문자열 지정)
    $ vi .htaccess
    <FilesMatch "\.(ph|inc|lib)">
        Order Allow, Deny
        Deny from all
    </FileMatch>
    
    # Apache 2.4 이상에서는 "Require" 지시자가 권장되는 방식입니다.
    <FilesMatch "\.(ph|inc|lib)">
        Require all denied
    </FileMatch>
    
  16. 업로드 디렉터리에서 Server Side Script(webshell)로 실행되지 않도록 설정(파일 업로드 취약점 대응): AddType 지시자 사용
    php, php3, php4, phtml, phps의 파일 확장자를 갖는 파일들의 MIME타입을 text/html 타입으로 재설정하여 악성 스크립트 파일을 업로드한 후 URL을 이용해 직접 호출하여도 Server Side Script로 실행되지 않습니다.
    $ vi .htaccess
    AddType text/html .html .htm .txt .php .php3 .php4 .phtml .phps .in .cgi .pl .jsp .shtml
    
  17. .htaccess파일과 .htpasswd 파일에의 접근 차단: Files 지시자 사용
    .htaccess파일은 인증, 권한 부여, 리디렉션 등과 관련된 설정을 포함하고, .htpasswd 파일은 사용자 이름과 암호를 저장하는 데 사용하므로 사용자의 브라우저에서 열리지 않도록 설정합니다. 웹 서비스(httpd) 점검 페이지를 보시면 .htaccess파일 및 .htpasswd 파일의 사용법을 확인할 수 있습니다. <Files> 지시자보다는 <FilesMatch> 지시자의 사용이 선호됩니다.
    <Files ".ht*">
        Require all denied
    </Files>
    
  18. Order 지시자를 사용하여 디렉토리의 접근 제어 설정
    Order 지시자 뒤에 오는 Deny,Alllow 또는 Allow,Deny 순으로 매칭 검사
    – 매칭되는 항목이 없으면 뒤에 오는 옵션(Deny,Alllow의 경우 Allow)이 디폴트로 적용됨
    ## example.org 도메인에 있는 모든 호스트는 접근이 허용되고, 나머지는 접근이 차단된다
    Order Deny,Allow
    Deny from all
    Allow from example.org
    
    ## example.org 도메인에 속한 호스트 중 foo.example.org를 제외하고 모두 접근 허용, 
    ## 디폴트 옵션이 Deny이므로 example.org 도메인에 없는 모든 호스트는 접근 차단
    Order Allow,Deny
    Allow from example.org
    Deny from foo.example.org
    
    ## foo.example.org은 접근 차단으로 설정하였으나, 
    ## Allow from example.org 설정으로 override되어 foo.example.org도 접속이 허용되고, 
    ## 디폴트 옵션이 Allow이므로 매칭되지 않는 나머지 모든 호스트도 접근 허용. 결과적으로 모든 호스트들의 접속이 허용됨
    Order Deny,Allow
    Allow from example.org
    Deny from foo.example.org
    

You may also like...

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다