Module ngx_http_dav_module

Module ngx_http_dav_module The ngx_http_dav_module module is intended for file management automation via the WebDAV protocol. The module processes HTTP and WebDAV methods PUT, DELETE, MKCOL, COPY, and MOVE. This module is not built by default, it should be

nginx.org

 

  • ngx_http_dav_module 모듈은 WebDAV 프로토콜을 통한 파일 관리 자동화를 위한 모듈
  • HTTP 및 WebDAV 메서드 PUT, DELETE, MKCOL, COPY, MOVE를 처리
  • 기본적으로 빌드되지 않으며, --with-http_dav_module 구성 매개변수를 사용하여 활성화 필요

 

create_full_put_path 지시자

  • WebDAV 사양은 이미 존재하는 디렉토리에만 파일을 생성 가능 
  • create_full_put_path 지시자를 통해 필요한 모든 중간 디렉토리를 생성 가능

  • 문맥 : http, server, location
  • 사용 문법
    ## 문법
    create_full_put_path on | off;
  • 사용 예시
    ## 기본 설정
    create_full_put_path off;

 

dav_access 지시자

  • 새로 만든 파일 및 디렉터리에 대한 액세스 권한을 설정 → dav_access user:rw group:rw all:r;
  • 그룹 또는 모든 액세스 권한이 지정되면 사용자 권한은 생략 가능 → dav_access group:rw all:r;

  • 문맥 : http, server, location
  • 사용 문법
    ## 문법
    dav_access users:permissions ...;
  • 사용 예시
    ## 기본 설정
    dav_access user:rw;

 

dav_methods 지시자

  • 지정된 HTTP 및 WebDAV 메서드를 허용
  • 매개변수 off는 ngx_http_dav 모듈에서 처리하는 모든 메서드를 거부 
  • ngx_http_dav 모듈 지원되는 메서드 → PUT, DELETE, MKCOL, COPY, MOVE

  • PUT 메서드로 업로드된 파일은 먼저 임시 파일에 기록된 다음 파일 이름이 변경됨 
  • 버전 0.8.9부터는 PUT 메서드로 임시 파일과 영구 저장소를 서로 다른 파일 시스템에 등록 가능
    1. 서로 다른 파일 시스템에 등록은 이름 변경 작업 대신 두 파일 시스템에 걸쳐 복사된다는 의미 
    2. 특정 위치에 대해 저장된 파일과 client_body_temp_path 지시어로 설정한 임시 파일이 있는 디렉토리를 모두 같은 파일 시스템에 저장하는 것을 추천
  • PUT 방식으로 파일을 만들 때 "Date" 헤더 필드에 수정 날짜(modification date)를 전달하여 수정 날짜를 지정 가능

  • 문맥 : http, server, location
  • 사용 문법
    ## 문법
    dav_methods off | method ...;
  • 사용 예시
    ## 기본 설정
    dav_methods off;

 

min_delete_depth 지시자

    • 요청 경로(request path)의 요소 수(number of elements)가 지정된 수보다 작지 않은 경우 DELETE 메서드가 파일을 제거 가능
    • min_delete_depth 지시자 예시
      ## min_delete_depth 지시자 설정
      min_delete_depth 4;
      
      ## 요청 시 파일 제거 허용
      /users/00/00/name
      /users/00/00/name/pic.jpg
      /users/00/00/page.html
      
      ## 요청 시 파일 제제거를 거부
      /users/00/00
  • 문맥 : http, server, location
  • 사용 문법
    ## 문법
    min_delete_depth number;
  • 사용 예시
    ## 기본 설정
    min_delete_depth 0;

 

'Nginx > Nginx 모듈 학습' 카테고리의 다른 글

ngx_http_auth_basic_module 모듈  (1) 2024.12.15
ngx_http_autoindex_module 모듈  (0) 2024.12.15
ngx_http_hls_module 모듈  (0) 2023.09.24
ngx_http_mp4_module 모듈  (0) 2023.09.24
ngx_http_referer_module 모듈  (0) 2023.09.23

Transfer-Encoding 헤더

  • 안전한 전송을 위해 어떤 인코딩이 메시지에 적용되었는지 수신자에게 알려줌
  • Transfer-Encoding 헤더는 hop-by-hop 헤더로, 리소스 자체가 아닌 두 노드 사이에 메시지를 적용 
  • 다중 노드 연결의 각각의 세그먼트는 Transfer-Encoding의 값을 다르게 사용 가능

    ※ 참고
    • 전체 연결에 있어 데이터를 압축하고자 한다면, Content-Encoding 헤더를 대신 사용하는 것을 추천
    • HEAD 요청에 대한 응답은 GET 요청에 적용될 값을 출력해줌

 

Transfer-Encoding 헤더 지시자

1. chunked

  • Chunked 인코딩 전송방식은 HTTP 1.1에서 사용가능한 스트리밍 데이터 전송 방식
  • 데이터가 일련의 청크(Chunked Message) 내에서 전송
  • Content-Length 헤더는 생략
  • 각 청크의 앞부분에 현재 청크의 길이가 16진수 형태로 오고 그 뒤에는 '\r\n'이 오고 그 다음에 청크 자체가 오며, 그 뒤에는 다시 '\r\n'이 옮
  • 종료 청크는 길이가 0인 것을 제외하면 일반적인 청크와 다르지 않음
  • (비어있을수도 있는) 연속된 엔티티 헤더 필드로 구성된 트레일러(Trailer)가 옮

 

2. compress

  • Lempel-Ziv-Welch (LZW) 알고리즘을 사용하는 형식
  • compress 값의 이름은 알고리즘을 구현한 UNIX compress 프로그램에서 차용된 것
  • compress는 대부분의 UNIX 배포판에서 제외된 압축 프로그램
  • content-encoding에서 compress는 특허 문제로 인해 오늘날 거의 대부분의 브라우저에서 사용되지 않고 있


3. deflate

  • (RFC 1951에 정의된) deflate 압축 알고리즘과 함께 (RFC 1950에서 정의된) zlib 구조체를 사용

 

4. gzip

  • 32비트 CRC를 이용한 Lempel-Ziv coding (LZ77)을 사용하는 형식
  • gzip은 근본적으로 UNIX gzip 프로그램의 형식
  • HTTP/1.1 표준에서 gzip을 content-encoding을 지원하는 서버는 호환성 목적을 위해 x-gzip을 별칭으로 인지할 것을 권고

 

5. identity

  • 압축이나 수정이 없는 정체성 기능을 나타냄 
  • 명시적으로 지정되는 경우를 제외하고 항상 허용 가능한 것으로 간주

 

 

Transfer-Encoding: chunked 헤더 사용 설명

  • Chunked 방식은 전달하려는 컨텐츠의 사이즈가 큰 경우 서버의 처리 지연을 보완할수 있는 방법
  • Transfer-Encoding 헤더는 Chunked 전송방식으로 데이터를 전달하려 할때 주로 사용되는 헤더
  • HTTP 1.1에서는 Content-Length라는 헤더로 전달하고자 하는 컨텐츠의 사이즈 표시 필요
  • 하나의 TCP 커넥션에 여러개의 요청이 가능하기 때문에 클라이언트는 요청마다 전달될 컨텐츠의 데이터 사이즈를 미리 알고 있어야 함 

 

  • Content-Length 헤더로 웹서버에 데이터 처리 과정 → 컨텐츠의 사이즈가 엄청 큰 경우 문제가 발생
    1. 웹서버가 클라이언트의 요청을 받음
    2. 웹서버는 클라이언트에게 전달해 줄 컨텐츠의 사이즈를 먼저 계산 
    3. 계산된 컨텐츠의 전체 사이즈와 함께 데이터를 전달

      ※ 주의
      • 2번 과정에서 컨텐츠의 사이즈가 엄청 큰 경우 문제가 발생 가능
      • 컨텐츠가 큰 경우 전체 사이즈를 계산하는 과정이 오래 걸림 → 클라이언트가 느끼는 지연시간에 반영됨
      • 컨텐츠 사이즈가 큰 경우, 더 효율적인 다른 방식이 필요

 

  • 컨텐츠의 사이즈가 매우 큰 경우 Content-Length 헤더 문제가 발생 가능 → "Chunked" 전송(청크 인코딩; Chunked transfer encoding))
    • Chunked 전송 방식 개념
      • 전체 Chunk를 한번에 주지 않고, Chunked 방식으로 조금씩 조금씩 전송하는 방식
      • 웹서버는 Chunked 방식으로 데이터를 전송하는 경우에는 전체 사이즈를 한번에 계산할 필요가 없음 
      • 보내려는 Chunked만 먼저 클라이언트에게 알리고 데이터를 보냄 → 본문이 동적으로 생성됨에 따라, 서버는 일부를 버퍼에 담은 뒤 한 청크를 크기와 함께 청크 메시지 전송
          
    • Chunked 전송 방식 설명
      • 클라이언트가 이미지를 요청하면, 웹서버는 전체 이미지의 일부분을 전달
      • 전체 이미지의 일부분 사이즈만 알려주면 되기 때문에 전체 사이즈를 계산하지 않아도 됨으로 기존 전송방식의 단점을 극복한 방식
      • 컨텐츠의 마지막 부분을 전송하고 나서는 "0" 을 보내어 데이터가 모두 전송되었음을 알림
      • Chunked 전송방식에는 Content-Length 헤더가 존재하지 않음
         
    • Chunked 방식의 장점
      • 큰 데이터 전송에도 HTTP 연결이 중간에 끊어지지 않게 유지할 수 있음 → HTTP 1.1 연결 유지(Connection: keep-alive, 지속 커넥션)가 활성화
      • Content-Length가 필요 없음 → 크기가 가변적인 데이터 전송에 유리(DB 쿼리 결과를 출력하는 HTML 테이블 / 큰 이미지 등에 사용)
      • 전체 컨텐츠를 생성할 때까지 대기하지 않음
         
    • Chunked 방식을 통해 데이터 전송 과정
      1. Transfer-Encoding: Chunked를 통해 Chunked 전송 방식으로 데이터를 전송할 것을 알림 
      2. Transfer-Encoding: Chunked를 보낸 이후 전송하려는 데이터의 부분적인 사이즈를 16진수로 표시하여 알림
      3. 실제 데이터에 16진수로 표시한 데이터양만큼 보냄 
      4. 위 2~3번 과정을 반복하여 전체 데이터를 전송
      5. 데이터의 마지막 끝부분에 "0" 을 표시하여 데이터 전송이 완료되었음을 알림 
        ### HTTP 응답
        HTTP/1.1 200 OK\r\n
        Content-type: text/plain\r\n
        Transfer-encoding: chunked\r\n
        \r\n
        
        ### 청크 #1
        9\r\n
        HI, Hippo\r\n
        
        ### 청크 #2
        25\r\n
        My name is Hippo. byebye~\r\n
        
        ### 마지막 청크
        0\r\n
        \r\n​
 

 

 

참고 자료 : 분도랑: [HTTP 프로토콜 강좌]#20 HTTP 일반 헤더 II - Transfer-Encoding, Upgrade, Warning, Trailer (withbundo.blogspot.com)

참고 자료 : Transfer-Encoding - HTTP | MDN (mozilla.org)

참고 자료 : 청크 인코딩(Chunked transfer e.. : 네이버블로그 (naver.com)

 

'HTTP > HTTP 헤더' 카테고리의 다른 글

HTTP 프로토콜 Vary 헤더  (0) 2022.06.25
HTTP 프로토콜 server 헤더  (0) 2022.06.25
HTTP 프로토콜 Range 헤더  (0) 2022.06.25
HTTP 프로토콜 Pragma 헤더  (0) 2022.06.25
HTTP 프로토콜 Last-Modified 헤더  (0) 2022.06.25

1. openSSL 사이트에 들어가서 원하는 버전을 다운로드

1.1. 다운로드 경로 : https://www.openssl.org/source/

 

[ Downloads ] - /source/index.html

Downloads The master sources are maintained in our git repository, which is accessible over the network and cloned on GitHub, at https://github.com/openssl/openssl. Bugs and pull patches (issues and pull requests) should be filed on the GitHub repo. Please

www.openssl.org

 

1.2. 원하는 버전에 tar.gz 파일이 다운로드

 

 

2. 다운로드 받은 openssl-X.X.X.tar.gz 파일을 압축 해제(openssl-3.0.13)

## openssl 3.0.13 버전 다운로드
## 형식 tar -xvf openssl-X.X.X.tar.gz
$ tar xvfz openssl-3.0.13.tar.gz

 

 

3. 압축 해체 이후, openssl-X.X.X 폴더 진입(openssl-3.0.13)

## 형식 : cd openssl-X.X.X
$ cd openssl-3.0.13;

 

 

4. openssl-X.X.X 폴더로 진입하여 ls 명령어를 입력, config 실행

4.1. 사용 가능한 패키지들 업데이트 및 필수 패키지 설치

$ sudo apt-get update;
$ sudo apt-get install build-essential -y;​

 

4.2. openssl-X.X.X 폴더 내 ls 명령어 확인

$ ~/openssl-3.0.13# ls
ACKNOWLEDGEMENTS.md  demos        ms                 README-FIPS.md
apps                 doc          NEWS.md            README.md
AUTHORS.md           engines      NOTES-ANDROID.md   README-PROVIDERS.md
build.info           e_os.h       NOTES-DJGPP.md     ssl
CHANGES.md           external     NOTES-NONSTOP.md   SUPPORT.md
config               FAQ.md       NOTES-PERL.md      test
config.com           fuzz         NOTES-UNIX.md      tools
configdata.pm        HACKING.md   NOTES-VALGRIND.md  util
configdata.pm.in     include      NOTES-VMS.md       VERSION.dat
Configurations       INSTALL.md   NOTES-WINDOWS.md   VMS
Configure            LICENSE.txt  os-dep             wycheproof
CONTRIBUTING.md      Makefile     providers
crypto               Makefile.in  README-ENGINES.md

 

4.3. openssl-X.X.X 폴더 내 config 명령어 실행

$ ./config
Configuring OpenSSL version 3.0.13 for target linux-x86_64
Using os-specific seed configuration
Created configdata.pm
Running configdata.pm
Created Makefile.in
Created Makefile

**********************************************************************
***                                                                ***
***   OpenSSL has been successfully configured                     ***
***                                                                ***
***   If you encounter a problem while building, please open an    ***
***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
***   and include the output from the following command:           ***
***                                                                ***
***       perl configdata.pm --dump                                ***
***                                                                ***
***   (If you are new to OpenSSL, you might want to consult the    ***
***   'Troubleshooting' section in the INSTALL.md file first)      ***
***                                                                ***
**********************************************************************

 

 

5. make 명령어를 사용해 소스를 컴파일

5.1. 컴파일(소스파일을 사용자가 실행 가능한 파일로 만들어 주는 과정) 진행(대략 5분 정도 소요)

$ make
...생략...

 

5.2. 컨파일 완료 후 실행 가능한 파일 생성 확인 → 완료 시 아래와 같이 출력

$ make
...생략...
make[1]: Leaving directory '/home/~/openssl-3.0.13'

 

 

6. 실행 가능한 파일 생성 후 설치 진행

$ make install
...생략...
install doc/html/man7/provider-rand.html -> /usr/local/share/doc/openssl/html/man7/provider-rand.html
install doc/html/man7/provider-signature.html -> /usr/local/share/doc/openssl/html/man7/provider-signature.html
install doc/html/man7/provider-storemgmt.html -> /usr/local/share/doc/openssl/html/man7/provider-storemgmt.html
install doc/html/man7/provider.html -> /usr/local/share/doc/openssl/html/man7/provider.html
install doc/html/man7/proxy-certificates.html -> /usr/local/share/doc/openssl/html/man7/proxy-certificates.html
install doc/html/man7/ssl.html -> /usr/local/share/doc/openssl/html/man7/ssl.html
install doc/html/man7/x509.html -> /usr/local/share/doc/openssl/html/man7/x509.html



7. 설치한 openssl 명령어 버전 확인 후 조치

7.1. openssl 명령어 버전 조회 시 에러 메시지 발생

$ openssl version
openssl: /lib/x86_64-linux-gnu/libcrypto.so.3: version `OPENSSL_3.0.9' not found (required by openssl)

 

7.2. 조치 사항

$ echo "/usr/local/lib64" > /etc/ld.so.conf.d/openssl-3-0-13.conf
$ openssl version
OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)

 

 

참고 자료 : [Linux] OpenSSL을 Ubuntu에서 설치하고 업데이트하는 방법 — hyun 공부 학습 공간 (tistory.com)

 

 

  • Ubuntu에서 /etc/resolv.conf 파일이 초기화되는 현상이 발생 → Ubuntu 기본 세팅
  • /etc/resolv.conf 초기화되지 않도록 하기 위해 조치사항

 

1. apt install 패키지 설치를 위해 /etc/resolve.conf에 nameserver 8.8.8.8 추가

$ vi /etc/resolv.conf
...생략...
nameserver 8.8.8.8

 

 

2. resolvconf 패키지 설치

$ apt install resolvconf -y

 

 

3. resolvconf 확인

  • /etc/resolvconf 디렉토리 확인
  • /run/resolveconf/resolv.conf 파일에 소프트링크
    $ ls -al /etc/resolv.conf
    lrwxrwxrwx 1 root root 29 Apr  1 02:44 /etc/resolv.conf -> ../run/resolvconf/resolv.conf​

 

4. head 파일 수정

  • resolve.conf 파일은 위에서부터 읽어들임
  • nameserver 8.8.8.8이 /etc/resolv.conf 파일의 최하단에 위치하면 다른 nameserver 설정의 IP을 먼저 DNS 서버로 사용하고, 위 DNS가 비정상일 경우에 8.8.8.8을 통해 질의함
    $ vi /etc/resolv.conf
    ...생략...
    nameserver 8.8.8.8​

 

5. 서버 재부팅 후 재확인 → 정상적으로 유지 확인

$ vi /etc/resolv.conf
...생략...
nameserver 8.8.8.8​

 

 

참고 자료 : [Solved][Ubuntu18.04] 서버 재부팅시 resolv.conf 초기화되는 문제 해결 :: Devader (tistory.com)

 

  • nginx는 새로 들어오는 모든 요청에 대해 upstream(backend) 서버에 대한 새 연결(incoming request)→ 안전하지만 비효율적
    1. nginx와 upstream(backend) 서버가 연결을 설정하려면 패킷 3개를 교환
    2. nginx와 upstream(backend) 서버가 연결을 종료하려면 패킷 3~4개를 교환

 

  • 트래픽이 많을 경우 모든 요청에 대해 새 연결을 열면 시스템 리소스가 고갈되어 연결을 열지 못 함
  • nginx에서 upstream 서버로 연결하는 경우 source address, destination address, and destination port 는 고정되어 있고 source port만 변수
  • nginx 연경은 source address, source port, destination address, and destination port 4가지 요소로 구성

 

  • nginx에서 upstream 서버와 연결이 닫히면 linux 소켓은 2분 동안 TIME-WAIT 상태가 됨
    • 트래픽이 많으면 사용 가능한 source port가 소진될 가능성이 높아짐 → nginx는 upstream 서버에 대한 새 연결을 열 수 없는 상태가 됨
    • source port가 고갈되는 것을 막기 위해 요청이 완료되면 연결이 닫히는 대신 추가 요청에 사용할 수 있도록 연결을 열어두는 keep-alive 연결을 nginx와 upstream 간에 활성화

 

  • 각 worker process의 캐시에 보존되는 upstream 서버에 대한 idle keep-alive 연결 수를 설정하려면 upstream{} 블록에 keepalive 지시어 사용
    • keepalive 지시어는 worker process가 열 수 있는 upstream 서버에 대한 총 연결 수(total number of connections)를 제한하지 않음
    • keepalive 지시어는 upstream{} 블록에 나열된 서버 수의 두 배로 설정하는 것이 좋음
    • 두배 설정은 nginx가 upstrem 모든 서버와의 keep-alive 연결을 유지하기에 충분히 크며, upstream 서버에 새로 들어오는 연결도 처리 가능하도록 작음
       
    • upstream{} 블록에서 hash, ip_hash, least_conn, least_time, random 지시어를 사용하여 load‑balancing algorithm 을 지정
    • hash, ip_hash, least_conn, least_time, random 지시어가 keepalive 지시어 위에 표시 필요(필수) 

 

  • 요청을 upstream으로 전달하는 location{} 블록에 proxy_pass 지시어와 함께 아래 지시어를 포함
    • nginx는 upstream 서버에 대한 연결에 HTTP/1.0을 사용 → 서버로 전달되는 요청에 Connection: close 헤더를 추가
    • upstream{} 블록에 keepalive 지시어가 있음에도 불구하고 요청이 완료되면 각 연결이 닫힘
    • proxy_http_version 지시어는 nginx가 HTTP/1.1을 대신 사용하도록 지시 → proxy_set_header Connection "" 헤더를 통해서 close 값을 제거함
      proxy_http_version 1.1;
      proxy_set_header Connection "";
       
  • proxy_http_version 지시자
    • 프록시 서버를 위한 HTTP 프로토콜 버전을 설정
    • 기본적으로 버전 1.0이 사용
    • keep-alive 연결 및 NTLM 인증과 함께 사용하려면 버전 1.1을 사용하는 것이 좋음
      구문 :	proxy_http_version 1.0 | 1.1;
      기본 :	proxy_http_version 1.0;
      문맥 :	http, server, location​
       
  • proxy_set_header Connection "" 설정
    • nginx서버에서 upstream으로 요청을 프록시할 때 HTTP 버전을 1.0으로, Connection 헤더를 close로 바꿔서 보냄
    • upstream으로 keepalive 커넥션을 사용하기 위해서는 프록시 HTTP 버전을 1.1로 변경해야 한다고 권장
    • 추가적으로 proxy_set_header Connection "" 설정을 통해 Connection 헤더를 없애주는 설정 진행

    • upstream 서버로 HTTP 버전을 1.0, Connection 헤더를 close으로 전송
    • upstream 서버로 HTTP 버전을 1.1, Connection 헤더를 초기화하여 전송

 

 

참고 자료 : Avoiding the Top 10 NGINX Configuration Mistakes - NGINX

참고 자료 : https://seungtaek-overflow.tistory.com/10

 

  • error_log off 지시문으로는 로깅을 비활성화 불가 → access_log 지시어와 달리 error_log는 off 매개 변수를 사용하지 않음
  • 만약 nginx에 error_log off 지시어를 포함하면 nginx 구성 파일의 기본 디렉토리(/etc/nginx)에 off라는 이름의 에러 로그 파일을 생성됨
     
  • error_log 로그는 nginx의 문제를 디버깅할 때 중요한 정보 소스이므로 비활성화하지 않는 것이 좋지 않음
  • 만약 스토리지가 너무 제한적이어서 사용 가능한 디스크 공간을 모두 소진할 정도의 경우 오류 로깅을 비활성화하는 것이 좋음

  • main 설정에 error_log 지시어 사용 예시
    error_log /dev/null emerg;​

 

  • error_log 지시어
    • 여러 개의 로그를 지정 가능 
    • main configuration 수준에서 로그를 쓰는 것이 명시적으로 정의되어 있지 않으면 기본 파일이 사용
      구문 :	error_log file [level];
      기본 :	error_log logs/error.log error;
      문맥 :	main, http, mail, stream, server, location​
       
  • error_log 지시어의 매개변수
    1. error_log 첫 번째 매개변수
      • 로그를 저장할 파일을 정의
      • stderr 특수 값은 표준 오류 파일(standard error file)을 선택 
      • "syslog:" 접두사를 지정하여 syslog에 로깅하도록 구성 가능 
      • "memory: size" 접두사와 버퍼 크기를 지정하여 순환 메모리 버퍼에 로깅 구성 가능. 일반적으로 디버깅에 사용
         
    2. erorr_log 두 번째 매개변수
      • 로깅 수준을 결정
      • debug, info, notice, warn, error, crit, alert 중 하나가 될 수 있음
      • 로그 수준(Log levels)은 심각도가 높아지는 순서대로 나열
      • 특정 로그 수준(certain log level)을 설정하면 지정된 로그 수준보다 더 심각한 로그 수준의 모든 메시지가 기록됨 → 예시) 오류 로그(error log)는  error, crit 및 alert  메시지가 기록됨
      • error_log 매개 변수를 생략하면 error가 사용

 

  • error_log 지시어는 nginx가 구성을 읽고 유효성을 검사할 때까지 적용되지 않는다는 점에 유의
  • nginx가 시작하거나 구성이 다시 로드될 때마다 구성의 유효성이 검사 → 기본 error log(/var/log/nginx/error.log) 로깅
  • 로그 디렉터리를 변경하려면 nginx 명령에 -e <error_log_location> 파라미터를 포함

 

참고 자료 : Avoiding the Top 10 NGINX Configuration Mistakes - NGINX

 

  • worker_connections 지시어는 nginx의 worker process가 열 수 있는 최대 동시 연결 수를 설정(기본값은 512). 
  • 클라이언트 연결뿐만 아니라 모든 유형의 연결(프록시 서버와의 연결)이 최대 연결 수에 포함 → proxy_pass도 포함
  • worker당 동시 연결 수에는 다른 제한이 있음 → 각 프로세스에 할당된 File Descriptors(파일 설명자)의 최대 수에 대한 OS 제한 
  • 최신 UNIX 배포판에서  File Descriptors(파일 설명자)의 최대 수에 대한 기본 제한은 1024개
  • 가장 작은 규모의 nginx 배포를 제외한 모든 배포에서 worker당 512개의 연결 제한은 너무 작을 수 있음 
  • 이 문제를 해결하려면 기본 구성 컨텍스트에서 worker_rlimit_nofile 지시어를 사용하여 설정

 

  • worker_rlimit_nofile 지시자
    • worker process의 최대 파일 열기 수 제한(RLIMIT_NOFILE)을 변경 
    • Main Process를 다시 시작하지 않고 제한을 늘리는 데 사용
      구문 :	worker_rlimit_nofile number;
      기본 :	—
      문맥 :	main​

 

  • 더 많은 File Descriptors(파일 설명자)가 필요한 이유
    • nginx worker process에서 클라이언트 또는 업스트림 서버로의 각 연결은 File Descriptors를 소비 
    • nginx가 웹 서버로 작동하는 경우, 클라이언트 연결에 하나의 File Descriptors를 사용하고 제공되는 파일당 하나의 File Descriptors를 사용하여 클라이언트당 최소 2개의 File Descriptors를 사용
    • 프록시 서버로 작동하는 경우, nginx는 클라이언트 및 업스트림 서버 연결에 각각 하나의 File Descriptors 사용(2개 사용)하고, 서버의 응답을 임시로 저장하는 데 사용되는 파일에 세 번째 File Descriptors를 사용
    • nginx가 캐싱 서버로 작동하는 경우, 캐시된 응답에 대해서는 웹 서버처럼 작동하고 캐시가 비어 있거나 만료된 경우에는 프록시 서버처럼 작동
    • nginx는 로그 파일당 File Descriptors를 사용하고 Master 프로세스와 통신하기 위해 몇 개의 File Descriptors를 사용 → 일반적으로 몇 개의 File Descriptors 숫자는 연결 및 파일에 사용되는 File Descriptors의 수에 비해 작음

 

  • UNIX는 프로세스당 File Descriptors 수를 설정하는 몇 가지 방법을 제공
    1. nginx를 시작하는 경우 ulimit 명령어
      • ulimit 명령어는 프로세스가 사용하는 자원에 대한 제어 및 관리할 수 있게 해줌
      • ulimit 명령어는 하나의 유저(쉘,프로세스)에 대해서 할당할 자원량의 한계를 정하는 것으로서 리눅스 시스템에서 과부하를 막아주는 방패가 되어 주는 유용한 설정
      • ulimit는 일시적 설정
        $ ulimit -n 65536
         
      • soft와 hard 두 가지 타입
        • soft → 새로운 프로그램을 생성하면 기본으로 적용되는 한도
        • hard → soft 한도에서 최대로 늘릴 수 있는 한도
           
    2. nginx를 서비스로 시작하는 경우 init 스크립트 또는 systemd 서비스 manifest 변수 사용
      $ vi /etc/systemd/system/nginx.service
      [Unit]
      Description=The NGINX HTTP and reverse proxy server
      After=syslog.target network.target remote-fs.target nss-lookup.target
      
      [Service]
      Type=forking
      PIDFile=/run/nginx.pid
      ExecStartPre=/usr/local/nginx/sbin/nginx -t
      ExecStart=/usr/local/nginx/sbin/nginx
      ExecReload=/usr/local/nginx/sbin/nginx -s reload
      ExecStop=/bin/kill -s QUIT $MAINPID
      PrivateTmp=true
      LimitNOFILE=65535
      LimitNOFILESoft=65535
      
      [Install]
      WantedBy=multi-user.target​​
       
    3. /etc/security/limits.conf 파일 → 유저의 프로세스별 file open을 설정
      • /etc/security/limits.conf 파일은 유저의 프로세스별 사용하는 자원에 대한 제어 및 관리할 수 있게 해줌
      • 할당할 자원량의 한계를 정함으로 리눅스 시스템에서 과부하를 막아줌

      • /etc/security/limits.conf 파일은 영구적 설정
        $ vi /etc/security/limits.conf
        
        ## nginx 사용자 계정에 수치를 지정
        nginx   soft  nofile  1048576
        nginx   hard  nofile  1048576
        nginx   soft  nproc   1048576
        nginx   hard  nproc   1048576
        
        ## *를 사용하여 모든 계정에 수치를 지정
        *   soft  nofile  1048576
        *   hard  nofile  1048576
        *   soft  nproc   1048576
        *   hard  nproc   1048576​
       
    4. sysctl.conf 의 file open 확인 및 커널 설정
      • sysctl.conf에서 시스템 전체에 대한 file open 개수를 설정
        $ cat /proc/sys/fs/file-nr
        3072    0       300000
        |         |       |
        |         |       |
        |         |       최대 오픈 파일 디스크립터 수(fs.file-max)
        |        할당되지 않은 파일 디스크립터 수 (2.6 커널에서는 항상 0으로 표기되며 이는 에러 아님)
        할당된 파일 디스크립터 수
         
      • 커널의 fs.file-max 파라미터는 시스템 전체에서 최대로 열 수 있는 파일 개수
      • 커널의 fs.file-max 파라미터는 시스템의 메모리를 KB로 표현한 값의 10%가 적당
      • 커널의 fs.nr_open 파라미터는 하나의 프로세스가 열 수 있는 최대 파일 개수
      • 커널의 fs.nr_open 파라미터는 기본값은 1024*1024 (1048576) → 대부분의 머신에서 충분(Actual limit depends on RLIMIT_NOFILE resource limit.)
         
      • 커널의 fs.file-max 파라미터와 fs.nr_open 파라미터 설정 확인 및 변경
        ## 기존 설정값 확인
        $ sysctl -a | grep fs.file-max
        fs.file-max = 300000
        
        $ cat /proc/sys/fs/file-max
        300000
        
        ## 기존 파라미터 값 수정
        $ vim /etc/sysctl.conf
        fs.file-max = 1048576
        
        ## 설정 값 적용
        $ sysctl -p
        
        
        ## 변경 설정값 확인
        $ sysctl -a | grep fs.file-max
        fs.file-max = 300000
        
        $ cat /proc/sys/fs/file-max
        300000
        
        $ cat /proc/sys/fs/file-nr
        3008    0       1048576

 

  • 시스템 전체에 File Descriptors 수에 대한 제한이 있으며, OS의 sysctl fs.file-max 명령으로 설정 가능
  • nginx를 시작하는 방법에 따라 다르지만, worker_rlimit_nofile은 nginx를 시작하는 방법에 작동
  • 모든 nginx worker process가 사용할 수 있는 최대 파일 설명자 수(worker_rlimit_nofile * worker_processes)가 fs.file-max보다 훨씬 적은지 확인 필요
  • nginx가 사용 가능한 모든 File Descriptors를 사용하는 경우(예: DoS 공격), 문제를 해결하기 위해 컴퓨터에 로그인하는 것조차 불가능해짐

 

 File Descriptor(파일 디스크립터)

  • 리눅스 혹은 유닉스 계열의 시스템에서 프로세스(process)가 파일(file)을 다룰 때 사용하는 개념
  • 프로세스에서 특정 파일에 접근할 때 사용하는 추상적인 값
  • File Descriptor(파일 디스크럽터)는 일반적으로 0이 아닌 정수값을 갖음

 

참고 자료 : 가장 많이 실수하는 NGINX 설정 에러 10가지 - NGINX STORE

참고 자료 : file open 확인 및 커널 설정 : 네이버 블로그 (naver.com)

 

D state란

  • process 상태(STAT)가 D로 표시되는 process는 "uninterruptible sleep" 상태를 의미
  • 일반적으로 I/O에 대해 대기하는 것으로 다른 어떤 일도 할 수 없는 상태 → I/O operation이 완료되기 전까지는 죽은 상태
  • D 상태인 process들은 operation이 완료되어 R/S(Run/Sleep)에 돌아가기 전까지 보통 작은 시간동안(a fraction of a second)만 거기에 있음
     
  • 서버가 I/O 집약적인 작업(intensive operations)을 수행할 때 프로세스가 "D" 상태로 표시되는 것은 정상 
  • 성능이 문제가 되는 경우 디스크의 상태를 확인 필요
  • 펌웨어 및 커널 디스크 드라이버가 업데이트되었는지 확인필요

 

  • process가 D 상태에 빠지는 경우
    1. 연결될 수 없는 NFS나 다른 원격 파일시스템과 통신하려는 경우
    2. 문제가 있는 하드 드라이브에 접근하려는 경우
    3. 비정상적인 device 드라이버를 이용해 하드웨어를 사용하려고 경우

 

  • D state process는 uninterruptible sleep으로 I/O를 대기 중 상태
    • ps 명령어는 uninterruptible sleep의 process에 대해 "D"를 표시 
    • vmstat 명령어는 "blocked" 상태이거나 "waiting on I/O" process를 표시 
    • "D" state Process는 SIGKILL 또는 kill -9를 사용해도 중단할 수 없음 → 서버를 재부팅하거나 I/O가 응답할 때까지 기다려야만 지울 수 있음

 

  • Uninterruptible sleep 상태는 D state의 process로 아무것도 할 수 없는 상태
    • process는 일반적으로 D State를 오래 유지하지 않음
    • D State process가 쌓여 있으면 시스템의 일부 로직이 중단됨
    • ps 명령어에 l 옵션 추가하여 긴 포맷으로 출력 → 우선순위와 관련된 PRI와 NI값 확인 가능  
    • WCHAN 열에는 process가 sleeping인 커널 함수의 이름이 표시
      $ ps axl | awk '$10 ~ /D/'
      F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
      vass     13478  7.2  0.0   1732   624 pts/1    D+   17:36   0:00 find ./​

 

process STAT(프로세스 상태)

  • Linux의 process는 running, sleeping 등 여러 가지 상태가 될 수 있음
  • Running process는 방금 CPU에서 실행 중이고, Sleeping process는 CPU가 켜지거나 다른 이벤트가 발생할 때까지 기다리는 상태를 의미
  • ps 명령어를 사용하면 시스템에서 각 process의 상태에 대한 정보를 얻을 수 있음
     
  • ps 명령어의 STAT 열에 표시
    • 큰 S는 Sleeping을 의미
    • 작은 s는 process이 session leader을 의미 → process가 새로운 session을 생성하면 해당 process는 session leader가 됨(Session Process의 PID = Session ID)
    • 큰 R은 Running을 의미
    • +는 foreground process를 의미
      $ ps a
        PID TTY      STAT   TIME COMMAND
       4975 tty1     Ss+    0:00 /sbin/mingetty tty1
       4976 tty2     Ss+    0:00 /sbin/mingetty tty2
       6202 pts/0    Ss+    0:01 -bash
      10312 pts/1    Ss     0:00 -bash
        639 pts/1    R+     0:00 ps a​

 

참고 자료 : Processes in D state - OpenVZ Virtuozzo Containers Wiki

참고 자료 : [Linux] Uninterruptible sleep 프로세스 상태 D :: TOP GUN (tistory.com)

참고 자료 : Processes in an Uninterruptible Sleep (D) State | Support | SUSE

 

+ Recent posts