[Linux 셸 스크립트] 서버 관리 - 115 웹 접근 감시하기
본문 바로가기
IT 이야기/Linux 셸 스크립트

[Linux 셸 스크립트] 서버 관리 - 115 웹 접근 감시하기

by 찬찬이 아빠 2021. 5. 13.
반응형
  1. 사용 명령어

(1) curl

(2) date

(3) echo

 

 

  2. 키워드 & 사용처

(1) 키워드

웹 감시, 서비스 감시, HTTP 스테이터스 코드

 

(2) 사용처

운용하는 웹 서비스에서 접근 확인을 정기적으로 실행해서 이상 발생 시 경고 통지를 하고 싶을 때 사용합니다.

 

  3. 실행 예제
$ ./web-curlcheck.sh
[2021/05/13 12:12:12] HTTP 스테이터스 이상:HTTP status[503]
ALERT...

 

 

  4. 스크립트

#!/bin/sh

 

# 감시 대상 URL 지정

url="http://www.example.org/webapps/check"       

 

# 현재 시각을 [2021/05/13 12:12:12] 형식으로 조합

date_str=$(date '+%Y/%m/%d %H:%M:%S')         

 

# 감시 URL에 curl 명령어로 접속해서 종료 스테이터스를 변수 curlresult에 대입

httpstatus=$(curl -s "$url" -o /dev/null -w "%{http_code}"     

curlresult=$?

 

# curl 명령어에 실패하면 HTTP 접속 자체에 문제가 있다고 판단

if [ "$curlresult" -ne 0 ]; then         

    echo "[$date_str] HTTP 접속 이상:curl exit status[$curlresult]"

    /home/park/bin/alert.sh

 

    # 400번대, 500번대 HTTP 스테이터스 코드라면 에러로 보고 경고

elif [ "$httpstatus" -ge 400 ]; then           

    echo "[$date_str] HTTP 스테이터스 이상:HTTP status[$httpstatus]"

    /home/park/bin/alert.sh

fi

 

 

  5. 해설

이 스크립트는 웹 서버 접근을 감시해서 이상 발생 시 경고합니다. 이때 이상 발생 시 alert.sh 스크립트를 실행해서 이걸로 알림을 보낸다고 가정합니다.

 

예제에서는 curl 명령어로 HTTP 스테이터스 코드를 확인합니다. 따라서 단순히 웹 서버가 움직이고 있는지 확인하는 것이 아니라 그 위에 동작하는 애플리케이션 상태까지 감시하는 것이 핵심입니다.

 

웹 서비스를 제공하려면 wget 명령어 등으로 HTTP 접속이 되는지만 확인하는 걸로는 부족합니다. 다음처럼 백엔드 데이터베이스에 장애가 발생했을 경우를 살펴봅니다.

백엔드 서버에서 발생한 장애도 포함해서 확인

 

만약 포트 감시만 하면 웹 서버는 정상적으로 TCP 포트 80번으로 접속할 수 있어 데이터베이스 장애 발생을 놓치게 됩니다. HTTP 스테이터스 코드까지 감시하면 웹 서버는 HTTP 스테이터스 코드 500(Internal Server Error) 등을 돌려주므로 애플리케이션이 제대로 동작하지 않는다는 걸 알 수 있습니다.

 

따라서 웹 애플리케이션 감시는 HTTP 스테이터스 코드까지 확인해야 합니다.

 

우선 은 감시 대상 URL을 셸 변수 url에 정의합니다. 여기서 대상 URL은 앞에서 본 백엔드 서버까지 접속하는 애플리케이션 경로를 지정하는 것이 좋습니다.

 

는 date 명령어를 사용해서 현재 시각을 2021/05/13 12:12:12 형식으로 조합해서 경고 표시 시각으로 사용합니다.

 

은 curl 명령어로 HTTP 스테이터스 코드를 취득해서 셸 변수 httpstatus에 대입합니다. curl 명령어는 다양한 옵션이 있지만 여기에서는 다음 세 종류의 옵션을 이용합니다.

명령어 설명
-s slient 모드(침묵 모드). 처리 중 내용을 표시하지 않음
-o 취득한 파일 젖아 경로 지정
-w 명령어 완료 후 출력할 표시 형식 지정

에서는 -w 옵션으로 %{http_code}를 지정해서 HTTP 스테이터스 코드를 출력합니다. 그 외에도 -w 옵션에는 총 걸린 시간이나 내려받기 크기, Content-Type 같은 다양한 값을 지정할 수있습니다.

 

은 curl 명령어 자체의 종료 스테이터스 $?도 셸 변수 curlresult에 대입합니다. 이것은 어떤 네트워크 장애나 URL 지정 실수로 curl 명령어가 실패했을 때 확인하기 위함입니다. curl 명령어 종료 스테이터스는 의 if문에서 확인해서 curl 명령어에 실패했으면 HTTP 접속 에러라고 에러 메시지를 표시하고 alert.sh를 실행합니다.

 

는 HTTP 스테이터스 코드로 정상인지 비정상인지 판별합니다. 일반적으로 HTTP 스테이터스 코드는 400번대 및 500번대가 비정상 코드입니다.

코드 일반적 표시 설명
400 Bad Request 리퀘스트 문제 발생. 존재하지 않늠 메소드 등
403 Forbidden 접근 거부. 서버 설정에 따른 접속 거부 등
404 Not Found 파일이 존재하지 않을 때
500 Internal Server Error 서버 내부 에러. CGI 에러 등
502 Bad Gateway 프록시 서버 등 상위 서버에서 잘못된 응답이 왔을 때
503 Service Unavailable 서버가 바쁘거나 처리를 받을 수 없을 때

예를 들어 503(Service Unavailable)은 서버가 고부하 상태일 때 자주 보게 도비니다. 500(Internal Server Error)은 프로그램에 어떤 버그가 있어서 정상적으로 응답할 수 없을 때도 발생합니다.

 

이런 400번대나 500번대 HTTP 스테이터스 코드가 돌아오면 문제가 발생했다고 봐야하므로 에서 test 명령어 -ge 면산자로 HTTP 스테이터스 코드가 400 이상인지로 판별합니다. 400 이상이면 문제가 있다고 보고 메시지를 출력하고 경고하는 alert.sh를 실행합니다. 이렇듯 HTTP 스테이터스 코드로 비정상인지 판단하는 방법으로 코드값이 400 또는 500 이상인지 확인하는 방법이 일반적입니다.

 

이렇게 하면 웹 서비스 감시가 가능합니다. cron에 등록해서 정기적으로 실행하게 하는 등 상황에 맞춰 사용하기 바랍니다.

 

 

<주의사항>

FreeBSD는 curl 명령어가 기본 설치되지 않습니다. FreeBSD 표준 fetch 명령어로는 HTTP 스테이터스 코드를 취득할 수 없으므로 port로 curl 명령어를 설치하기 발랍니다.

# cd /usr/ports/ftp/curl
# make install

 

웹 서버를 운용하다보면 웹 크롤러나 어떤 악의를 가진 공격자가 이곳 저곳으로 접속해오는 것이 보통입니다. 따라서 접속 로그 파일에서 다수의 404(Not Found)가 발견될 것입니다. 그다지 신경 쓰지 않아도 되지만 공격의 징조를 발견하거나 페이지 링크가 끊긴 걸 확인할 수도 있으므로 접속 로그 파일도 정기적으로 확인하는 것이 좋습니다.

 

 

 

  6. 웹 서비스 감시

자신이 담당하는 시스템이 어느 틈에 정지해버린 경험을 해본 사람이 많이 있을 겁니다. 서버 감시를 하면 이런 상태를 빨리 발견해서 대응할 수 있습니다. 하지만 한마디로 '감시'라고 해도 다양한 수단이 있고 필요한 사항도 서로 다릅니다.

 

여기서는 다음과 같은 구성 예를 통해 셸 스크립트로 감시하는 방법과 적용 방법을 간단히 설명합니다.

웹 애플리케이션 감시

 

이 그림처럼 웹 서비스는 정적 파일을 아파치가 돌려주고, 일부 리퀘스트는 백엔드 애플리케이션으로 보내서 데이터베이스에서 값을 얻어서 동적을로 응답을 돌려줍니다. 즉, 서버 A의 아파치는 웹 서버 겸 리버스 프록시 서버로 동작합니다.

 

여기서 서버 A를 감시하는 방법을 생각해봅니다.

 

  • ping 감시

웹 서버에 ping 명령어를 실행해서 ICMP 패킷 응답으로 서버가 움직이고 있는지 감시합니다. 애플리케이션 상태는 상관없이 서버가 가동 중인가만 감시하므로 사활 감시라고도 부릅니다. 웹 서버 프로세스가 정지했더라도 OS만 기동하고 있으면 정상이라고 판단합니다.

참고 예제 : 예제 114 링크 추가 예정

 

  • 프로세스 감시

서버에서 ps 명령어를 실행해서 프로세스가 가동 중인지 확인합니다. 네트워크 확인은 하지 않으므로 예를 들어 방화벽 설정이 잘못되어서 외부에서 접속하지 못하더라도 정상이라고 정상이라고 판단합니다.

참고 예제 : 예제 111링크 추가 예정

 

  • 로그 감시

서버에 출력되는 로그 파일을 grep 명령어 등으로 분석해서 에러가 출력되는지 확인합니다. 클라이언트 쪽에는 통지가 가지 않는 애플리케이션 내부 에러도 확인할 수 있습니다.

 

  • 포트 감시

TCP나 UDP 특정 포트로 서버까지 도달 가능한지 조사하는 네트워크 감시입니다. 도중 경로 네트워크 장애나 방화벽 설정 오류를 찾습니다. 구체적으로는 nc 명령어를 이용하면 됩니다.

참고 예제 : 예제 61링크 추가

 

  • HTTP 헤더 감시

curl 명령어 -l 옵션을 사용해서 HTTP HEAD 메소드로 웹 서버에 접속 가능한지 확인합니다. 파일 내려받기는 하지 않고 HTTP 헤더만 취득하므로 서버 네트워크 부담이 적습니다.

참고 예제 : 예제 111 링크 추가 예정

 

  • 정적 파일 HTTP 감시

curl 명령어 등으로 파일을 정상적으로 내려받을 수 있는지 감시합니다. 실제로 파일을 내려받기 위해 사용자 환경에 가까운 감시가 가능한데 파일 크기가 크다면 네트워크 부하에 주의해야 합니다.

참고 예제 : 현재 115번 예제

 

  • 정적 애플리케이션 HTTP 감시

curl 명령어 등으로 웹 애플리케이션에 접속해 백엔드 서버에서 자료를 취득해서 결과를 정상적으로 내려받는지 확인합니다 .서비스를 개시해서 운용 단계인 서비스라면 기본적인 감시입니다. 이때 단순히 접속 가능한지만 보는 것이 아니라 HTTP 스테이터스 코드에서 성공, 실패를 판별해야 합니다.

참고 예제 : 현재 115번 예제

 

  • 백엔드 서버 감시

앞에서 본 그림에서 애플리케이션 서버나 데이터베이스 서버에도 감시가 필요합니다. 여기에는 ping 감시나 프로세스 감시 같은 기본 감시 외에도 CPU, 메모리, 디스크 사용량 같은 리소스 감시가 중요합니다.

 

예를 들어 애플리케이션 서버는 메모리를 대량으로 사용하므로 스왑이 발생하지 않는지 감시해야 합니다. 늘 스왑이 발생한다면 디스크 I/O 대기 시간이 늘어나서 서버 로드 평균값(부하)이 커집니다. 결과로 사용자 응답이 늦어집니다.

 

데이터베이스 서버는 데이터베이스 영역의 디스크 사용률이 100%가 되면 데이터베이스 파손 같은 중대한 장애가 발생할 수 있으므로 디스크 사용률 감시는 중요합니다. 또한 데이터베이스는 중요한 시스템이므로 mysql 명령어를 정기적으로 실행해서 MySQL 서버 프로세스에 접속 가능한지 확인하는 DB 접속 감시를 하기도 합니다.

 

  • 운용 단계 감시

포트 감시 등은 낮은 단계의 감시입니다. 예를 들어 서버 방화벽 설정을 하고 있는데 포트 감시가 NG가 되면 잘못된 설정을 넣었다는 걸 바로 알 수 있습니다.

 

서비스 개시 후 '동적 애플리케이션 HTTP 감시'가 갖아 윗 단계이므로 최소한 이 감시는 해둬야 합니다. 그래야지 시스템의 어떤 요소가 장애를 일으켜서 정상적으로 서비스하지 못하는 사태를 빠르게 확인할 수 있습니다 그리고 그 외의 감시도 보조 용도로 해둬야 합니다.

 

막상 장애가 발생했는데 '동적 애플리케이션 HTTP 감시'가 NG면 상황 파악을 위해 더 낮은 단계의 감시 결과를 문제 해결에 활용하면 됩니다. 예를 들어 '프로세스 감시는 정상이지만 포트 감시가 NG'라면 경로에 어떤 네트워크 장애가 발생했거나 방화벽 설정에 문제가 생겨서 TCP 포트 80번이 블록되었다고 판단할 수 있습니다.

 

서버 감시에는 자빅스(Zabbix), 나기오스(Nagios), 무닌(Munin) 같은 오픈 소스 소프트웨어가 널리 사용됩니다. 여러분이 대규모 서비스를 제공한다면 이런 소프트웨어가 도움이 될 것입니다.

 

자빅스

http://www.zabbix.com

 

나기오스

http://www.nagios.org

 

무닌

http://munin-monitoring.org

 

 

참고서적 : 유닉스 리눅스 셸 스크립트 예제 사전

반응형

댓글