
로깅 구성
이 문서에서는 NGINX Open Source 및 NGINX Plus 에서 오류 및 처리된 요청의 로깅을 구성하는 방법을 설명합니다.
오류 및 요청 처리에 대한 자세한 정보를 로컬 또는 syslog를 통해 로그 파일에 캡처합니다.
목차
1. Error 로그 설정
2. Access 로그 설정
3. Conditional 로깅 활성화
4. 사용 사례: TLS 매개변수 샘플링
5. Syslog에 로깅
1. Error 로그 설정
NGINX는 심각도 Level에 따라 발생한 문제에 대한 정보를 Error 로그에 기록합니다. error_log
지시문은 특정 파일, stderr
또는 syslog
에 로깅을 설정하고 기록할 메시지의 최소 심각도 Level을 지정합니다. 기본적으로 Error 로그는 logs/error.log에 위치하며(절대 경로는 운영 체제 및 설치에 따라 달라집니다), 지정된 심각도 Level 이상의 모든 메시지가 기록됩니다.
아래 구성은 로그에 기록할 오류 메시지의 최소 심각도 Level을 error
에서 warn
으로 변경합니다.
error_log logs/error.log warn;
이 경우 warn
, error crit
, alert
및 emerg
Level의 메시지가 기록됩니다.
Error 로그의 기본 설정은 전역적으로 작동합니다. 이를 재정의하려면 main
(최상위) 구성 컨텍스트에 error_log
지시문을 배치하세요. main
컨텍스트의 설정은 항상 다른 구성 Level(http
, server
, location
)에서 상속됩니다. error_log
지시문은 http
, stream
, server
, location
Level에서도 지정할 수 있으며 상위 Level에서 상속된 설정을 재정의합니다. 오류가 발생하면 오류가 발생한 Level에서 가장 가까운 하나의 Error 로그에만 메시지가 기록됩니다. 그러나 동일한 Level에서 여러 개의 error_log
지시문을 지정하면 지정된 모든 로그에 메시지가 기록됩니다.
Note: 동일한 구성 Level에서 여러 error_log 지시문을 지정하는 기능은 NGINX Open Source 버전 1.5.2에 추가되었습니다.
2. Access 로그 설정
NGINX Plus 는 요청이 처리된 직후 클라이언트 요청에 대한 정보를 Access 로그에 기록합니다. 기본적으로 Access 로그는 logs/access.log에 위치하며, 정보는 미리 정의된 combined 형식으로 로그에 기록됩니다. 기본 설정을 재정의하려면 log_format
지시문을 사용하여 기록된 메시지의 형식을 변경하고 access_log
지시문을 사용하여 로그의 위치와 형식을 지정합니다. 로그 형식은 변수를 사용하여 정의합니다.
다음 예제에서는 미리 정의된 combined 형식을 응답의 gzip 압축 비율을 나타내는 값으로 확장하는 로그 형식을 정의합니다. 그런 다음 이 형식이 압축을 활성화하는 가상 서버에 적용됩니다.
http {
log_format compression '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
server {
gzip on;
access_log /spool/logs/nginx-access.log compression;
...
}
}
로그 형식의 또 다른 예로, 웹사이트 속도 저하가 발생하는 경우 문제를 진단하는 데 도움이 될 수 있는 NGINX와 Upstream 서버 간의 서로 다른 시간 값을 추적할 수 있습니다. 다음 변수를 사용하여 지정된 시간 값을 기록할 수 있습니다.
$upstream_connect_time
– Upstream 서버와의 연결 설정에 소요된 시간$upstream_header_time
– 연결을 설정하고 Upstream 서버로부터 응답 헤더의 첫 Byte를 수신하기까지의 시간입니다.$upstream_response_time
– 연결을 설정하고 Upstream 서버로부터 응답 본문의 마지막 Byte를 수신하기까지의 시간입니다.$request_time
– 요청 처리에 소요된 총 시간
모든 시간 값은 ms(MilliSecond) 단위의 해상도로 초 단위로 측정됩니다.
http {
log_format upstream_time '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"'
'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time"';
server {
access_log /spool/logs/nginx-access.log upstream_time;
...
}
}
결과로 표시되는 시간 값을 읽을 때는 다음 사항에 유의하세요.
- 요청이 여러 서버를 통해 처리되는 경우 변수에는 쉼표로 구분된 여러 값이 포함됩니다.
- 한 Upstream 그룹에서 다른 그룹으로 내부 리다이렉션이 있는 경우, 값은 세미콜론으로 구분됩니다.
- 요청이 Upstream 서버에 도달할 수 없거나 전체 헤더를 수신할 수 없는 경우 변수에 0(Zero)이 포함됩니다.
- Upstream에 연결하는 동안 내부 오류가 발생하거나 캐시에서 응답을 가져오는 경우 변수에 – (Hyphen)이 포함됩니다.
로그 메시지에 대한 버퍼와 이름에 변수가 포함된 자주 사용하는 로그 파일의 Descriptor 캐시를 활성화하여 로깅을 최적화할 수 있습니다. 버퍼링을 활성화하려면 access_log
지시문의 buffer
매개변수를 사용하여 버퍼의 크기를 지정합니다. 그러면 버퍼링된 메시지는 다음 로그 메시지가 버퍼에 맞지 않을 때와 다른 경우
에 로그 파일에 기록됩니다.
로그 파일 Descriptor의 캐싱을 사용하려면 open_log_file_cache
지시문을 사용합니다.
error_log
지시문과 마찬가지로, 특정 설정 Level에 정의된 access_log
지시문은 이전 Level의 설정을 재정의합니다. 요청 처리가 완료되면 현재 Level에서 구성되거나 이전 Level에서 상속된 로그에 메시지가 기록됩니다. 한 Level에서 여러 Access 로그를 정의하는 경우, 메시지는 모든 로그에 기록됩니다.
3. Conditional 로깅 활성화
Conditional 로깅을 사용하면 사소하거나 중요하지 않은 로그 항목을 Access 로그에서 제외할 수 있습니다. NGINX에서 Conditional 로깅은 access_log
지시문의 if
매개변수로 활성화할 수 있습니다.
이 예에서는 HTTP 상태 코드 2xx(Success) 및 3xx(Redirection)가 있는 요청은 제외됩니다.
map $status $loggable {
~^[23] 0;
default 1;
}
access_log /path/to/access.log combined if=$loggable;
4. 사용 사례: TLS 매개변수 샘플링
많은 클라이언트가 TLS 1.3보다 오래된 TLS 버전을 사용합니다. 많은 암호가 안전하지 않다고 선언되었지만 이전 구현에서는 여전히 이러한 암호를 사용하며, ECC 인증서는 RSA보다 뛰어난 성능을 제공하지만 모든 클라이언트가 ECC를 수락할 수 있는 것은 아닙니다. 많은 TLS 공격은 암호 협상 Handshake를 가로채서 클라이언트와 서버가 덜 안전한 암호를 선택하도록 강요하는 ‘중간자’에 의존합니다. 따라서 취약한 암호 또는 레거시 암호를 지원하지 않도록 NGINX Plus 를 구성하는 것이 중요하지만, 그렇게 하면 레거시 클라이언트가 제외될 수 있습니다.
클라이언트로부터 얻은 SSL 데이터를 평가하여 이전 SSL 프로토콜 및 암호에 대한 지원이 제거될 경우 제외되는 클라이언트 비율을 결정할 수 있습니다.
이 예에서 각 클라이언트는 IP 주소와 사용자 Agent의 고유한 조합으로 식별됩니다.
1. SSL 프로토콜 버전($ssl_protocol
), 연결에 사용된 암호($ssl_cipher
), 클라이언트 IP 주소($remote_addr
), 표준 사용자 Agent
HTTP 요청 필드 값($http_user_agent
)이 포함된 사용자 지정 로그 형식 sslparams
를 정의합니다.
log_format sslparams '$ssl_protocol $ssl_cipher '
'$remote_addr "$http_user_agent"';
2. 클라이언트와 해당 사용자 Agent(예: 클라이언트
)의 IP 주소를 보관할 Key-Value 저장소를 정의합니다.
keyval_zone zone=clients:80m timeout=3600s;
3. $remote_addr
및 사용자 Agent
헤더의 각 고유 조합에 대해 $seen
과 같은 변수를 만듭니다.
keyval $remote_addr:$http_user_agent $seen zone=clients;
server {
listen 443 ssl;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
if ($seen = "") {
set $seen 1;
set $logme 1;
}
access_log /tmp/sslparams.log sslparams if=$logme;
# ...
}
4. 이 구성으로 생성된 로그 파일을 확인합니다.
TLSv1.2 AES128-SHA 1.1.1.1 "Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0"
TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 2.2.2.2 "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1"
TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 3.3.3.3 "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:58.0) Gecko/20100101 Firefox/58.0"
TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 4.4.4.4 "Mozilla/5.0 (Android 4.4.2; Tablet; rv:65.0) Gecko/65.0 Firefox/65.0"
TLSv1 AES128-SHA 5.5.5.5 "Mozilla/5.0 (Android 4.4.2; Tablet; rv:65.0) Gecko/65.0 Firefox/65.0"
TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 6.6.6.6 "Mozilla/5.0 (Linux; U; Android 5.0.2; en-US; XT1068 Build/LXB22.46-28) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.10.2.1164 Mobile Safari/537.36"
5. 로그 파일을 처리하여 데이터 확산을 확인합니다.
cat /tmp/sslparams.log | cut -d ' ' -f 2,2 | sort | uniq -c | sort -rn | perl -ane 'printf "%30s %s\n", $F[1], "="x$F[0];'
이 출력에서는 보안성이 낮은 저용량 암호가 식별됩니다.
ECDHE-RSA-AES128-GCM-SHA256 =========================
ECDHE-RSA-AES256-GCM-SHA384 ========
AES128-SHA ====
ECDHE-RSA-CHACHA20-POLY1305 ==
ECDHE-RSA-AES256-SHA384 ==
그런 다음 로그를 확인하여 어떤 클라이언트가 이러한 암호를 사용하고 있는지 확인한 다음 NGINX Plus 구성에서 이러한 암호를 제거할지 결정할 수 있습니다.
5. Syslog에 로깅
syslog
유틸리티는 컴퓨터 메시지 로깅을 위한 표준으로, 단일 syslog 서버에서 여러 장치에서 로그 메시지를 수집할 수 있습니다. NGINX에서 syslog에 대한 로깅은 error_log
및 access_log
지시문에 syslog:
접두사를 사용하여 구성됩니다.
Syslog 메시지를 서버로 보낼 수 있는 server=
도메인 명, IP 주소 또는 UNIX 도메인 소켓 경로일 수 있습니다. 도메인 명이나 IP 주소는 포트와 함께 지정하여 기본 포트인 514
를 재정의할 수 있습니다. UNIX 도메인 소켓 경로는 unix:
접두사 뒤에 지정할 수 있습니다.
error_log syslog:server=unix:/var/log/nginx.sock debug;
access_log syslog:server=[2001:db8::1]:1234,facility=local7,tag=nginx,severity=info;
이 예제에서는 debug
로깅 Level에서 NGINX Error 로그 메시지가 UNIX 도메인 소켓에 기록되고, Access 로그는 IPv6 주소 및 포트 1234
를 사용하는 syslog 서버에 기록됩니다.
facility=
매개 변수는 메시지를 로깅하는 프로그램 유형을 지정합니다. 기본값은 local7
입니다. 사용 가능한 다른 값은 다음과 같습니다. auth
, authpriv
, daemon
, cron
, ftp
, lpr
, kern
, mail
, news
, syslog
, user
, uucp
, local0 … local7
.
tag=
매개 변수는 사용자 정의 태그를 syslog 메시지(예제에서는 nginx
)에 적용합니다.
severity=
매개변수는 Access 로그에 대한 syslog 메시지의 심각도 Level을 설정합니다. 가능한 값은 심각도가 높아지는 순서대로 debug
, info
, notice
, warn, error
(기본값), crit
, alert
, emerg
입니다. 메시지는 지정된 Level과 그보다 더 심각한 Level에서 모두 기록됩니다. 이 예제에서는 심각도 Level error
를 통해 crit
, alert
및 emerg
Level도 기록할 수 있습니다.