[Ubuntu] SSH 접속 시 텔레그램 알람보내기 #3 (명령어로 메시지발송 테스트)

[Ubuntu] SSH 접속 시 텔레그램 알람보내기 #3 (명령어로 메시지발송 테스트)
Photo by Dima Solomin / Unsplash

지난 편을 작성하고서 일이 바빠져서... 글 작성이 너무 늦어져서, 다시 하던 것을 마무리하고자 한다. 아마 이번 편과 다음 편까지 총 4편으로 마무리가 될 것 같다. 사실 중간 과정없이 쉘스크립트만 공유해도 무관한데... 내가 공부했던 과정을 기록하면 다른 사람도 혹시 그 과정에서 얻는 것이 있지 않을까 싶었고, 나도 이걸 기록하면서 얻는 것이 있을 것 같아서이다.


연관 포스트

  1. [Ubuntu] SSH 접속 시 텔레그램 알람보내기 #1 (봇생성편)
  2. [Ubuntu] SSH 접속 시 텔레그램 알람보내기 #2 (메시지발송편)
  3. [Ubuntu] SSH 접속 시 텔레그램 알람보내기 #3 (명령어로 메시지발송 테스트)
  4. [Ubuntu] SSH 접속 시 텔레그램 알람보내기 #4 (최종편)

A. 명령어로 url 호출

리눅스 명령어로 url을 호출 할 수 있는 명령어는 대표적으로(=내가 알고 있는) curl과 wget이 있다. 내 경우에는 URL을 통해서 무언가를 다운받을 경우에는 wget을 주로 사용하고, Restful API와 같은 특정 URL을 호출하는 경우에는 curl을 사용하는 편이다.[1]

지난 문서와 동일한 메시지를 curl 명령어로 전송해보면...

$ curl https://api.telegram.org/bot57412121:AAEF-Zjsdlsd-----YPk/sendMessage?chat_id=5545034869&text=test
[1] 1859
$ {"ok":false,"error_code":400,"description":"Bad Request: message text is empty"}
[1]+  Done                    curl https://api.telegram.org/bot57412121:AAEF-Zjsdlsd-----YPk/sendMessage?chat_id=5545034869
$

curl에 단순히 URL 전체[2]를 붙여넣으니 전송이 안된다. 참고문서 2를 보면서 명령어를 손봐야한다.

일단, 위 에러내용을 보니 정상적으로 get 방식으로 전달한 파라미터가 잘 전달되지 않은 것으로 보아서 분리해본다.

$ curl -d 'chat_id=55450--869&text=test' https://api.telegram.org/bot57412121:AAEF-Zjsdlsd-----YPk/sendMessage

위 명령어를 실행하니 아래와 같은 json 형태의 반환값(웹브라우저에서 보였던 값)이 보이고, 메시지도 정상적으로 발송되었다.

{"ok":true,"result":{"message_id":5,"from":{"id":6215--8963,"is_bot":true,"first_name":"simplism-ssh-alarm","username":"simplism_ssh_alarm_bot"},"chat":{"id":55450--869,"first_name":"SIMPLISM","type":"private"},"date":1690266482,"text":"test"}}

  1. 참고문서 1을 보면 자세한 내용을 확인 할 수 있다. ↩︎

  2. 참고로 위 url은 API Token을 임으로 변형한 것이므로 정상적으로 실행되지 않는다. ↩︎

처음 curl 명령어를 실행했을 때는 실패했지만, 두번째 get파라미터를 -d 옵션으로 분리하고서는 정상적으로 메시지 발송에 성공했다!

B. 조금 더 복잡하게

프로그래밍으로 치면, 이제 ==Hello World!==만 끝난 것이다. 단순하게 login과 같은 띄어쓰기도 안되어있는 메시지만 보낼꺼라면 저걸로 충분하지만... 난 좀 더 많은 정보를 메시지에 담고 싶었다.

  1. SSH 세션이 열린 서버의 호스트명과 IP주소
  2. 접속한 사용자계정과 IP주소
  3. 접속한 시간

일단 최소 위의 3가지 정보는 메시지에 담고 싶었다.

예를 들어 아래처럼...

simplism-beebox(192.168.0.11) ssh session open! (user=simplism, ip=192.168.0.3, datetime=2023-07-25 (Tue) 15:07:22)

위와 같은 메시지를 받으면, 어떤 리눅스 서버(hostname, server ip)에 누가(user), 언제(datetime), 어디서(client ip) 접속했는지 바로 알 수 있으니까!

C. 메시지를 위한 정보수집

이제 메시지 발송에 포함되는 정보들을 수집할 방법을 찾아보자

01) 서버의 호스트명과 IP주소

$ echo $(hostname)
simplism-beebox
$ echo $SSH_CONNECTION
192.168.0.3 14693 192.168.0.11 22
$ echo $SSH_CONNECTION | awk '{print $3}'
192.168.0.11
$

호스트명은 hostname이라는 명령어의 결과로 출력이 가능하니 간단하고... SSH 서버의 IP주소는 가장 간단하게 SSH 세션이 열리면 SSH_CONNECTION이라는 환경변수에 클라이언트 IP, 클라이언트 Port, 서버 IP, 서버 Port 정보가 저장된다. 그 중에서 3번째의 값이 서버 IP주소이므로 awk 명령어를 이용해서 추출해준다.

$ netstat -an | grep ESTA | grep :22
tcp        0      0 192.168.0.11:22         192.168.0.3:14693      ESTABLISHED
$

netstat명령어로 확인해보면 IP와 Port정보가 나와서 비교해보니 일치한다.

02) 클라이언트 IP주소 및 사용자명

$ echo $SSH_CONNECTION | awk '{print $1}'
192.168.0.3
$ echo $USER
simplism
$

클라이언트 IP주소는 서버 IP주소와 동일하게 SSH_CONNECTION 환경변수에서 추출하고, 사용자명은 USER 환경변수에 저장되니 해당 값에서 추출한다.

03) 접속시간

접속시간은 date 명령을 원하는 포맷(읽기 편한 형태)으로 바꿔서 출력한다.

$ echo $(date +"%Y-%m-%d (%a) %H:%M:%S")
2023-07-25 (Tue) 15:49:35
$

D. 스크립트 파일을 만들자!

이제 단일 명령어로 끝낼 수 있는 수준은 넘었으니.. 쉘스크립트 파일을 만들어보자.

$ vi LoginAlarm.sh

이제 간단한 형태로 스크립트를 만들어보면...

#/bin/sh

NOW=$(date +"%Y-%m-%d (%a) %H:%M:%S")
SERVER_IP=$(echo $SSH_CONNECTION | awk '{print $3}')
CLIENT_IP=$(echo $SSH_CONNECTION | awk '{print $1}')
SERVER_INFO=$(hostname)'('$SERVER_IP')'

API_URL=https://api.telegram.org/bot
API_TOKEN=57412121:AAEF-Zjsdlsd-----YPk
API_METHOD=sendMessage
API_FULLURL="$API_URL$API_TOKEN"/"$API_METHOD"
API_CHATID=55450--869

MSG="<b>$SERVER_INFO</b> ssh session open! (user=$USER, ip=$CLIENT_IP, datetime=$NOW)"
DAT="{\"chat_id\":\"$API_CHATID\",\"text\":\"$MSG\",\"parse_mode\":\"html\"}"

curl -X POST -H "Content-Type: application/json" -d "$DAT" $API_FULLURL

위 내용 중에서 주요 라인을 설명하면...

  1. API_TOKEN : 이 부분은 본인이 봇파더에게 받은 봇의 API TOKEN을 넣어준다.
  2. API_CHATID : 이 부분도 이전 문서에서 확인한 나의 Chat ID를 넣어준다.
  3. DAT : Telegram API를 호출할 때, 보다 다양한 값을 입력하기 위해서 JSON 형태의 데이터를 만들었다. JSON 데이터의 키(Key)를 표현하기 위해서 "(쌍따옴표)를 넣어야하는데, 키(Key)의 쌍따옴표는 앞 부분에 (backslash, 역슬래시)를 넣어서 Escape Character 처리를 해줘야 정상적으로 인식된다. 추가적으로 Bold와 같은 텍스트 강조를 위해서 parse_mode 값에 html이라는 값을 넣어줬다.

사실 위 스크립트를 만들기까지 Telegram 공식 API 문서를 열심히 읽었다.. 그 내용을 다 옮길 수가 없더라.. 더 많은 텔레그램 API와 관련된 내용은 텔레그램 API 문서를 확인해보는 것이 좋을 것 같다.

이제 스크립트 파일을 저장하고...

$ chmod u+x LoginAlarm.sh

실행이 가능하도록 퍼미션을 조정한 다음에...

$ ./LoginAlarm.sh
{"ok":true,"result":{"message_id":6,"from":{"id":6215--8963,"is_bot":true,"first_name":"simplism-ssh-alarm","username":"simplism_ssh_alarm_bot"},"chat":{"id":55450--869,"first_name":"SIMPLISM","type":"private"},"date":1690269331,"text":"simplism-beebox(192.168.0.11) ssh session open! (user=simplism, ip=192.168.0.3, datetime=2023-07-25 (Tue) 16:15:30)","entities":[{"offset":0,"length":16,"type":"bold"},{"offset":16,"length":12,"type":"url"},{"offset":16,"length":12,"type":"bold"},{"offset":28,"length":1,"type":"bold"},{"offset":67,"length":12,"type":"url"}]}}

실행했을 때 ok 값이 true로 나온다면 성공이다!

E. 마치면서..

이제 만든 쉘스크립트에 몇 가지 기능을 손을 보고... SSH 세션이 열릴 때 실행되도록 설정만 하면 된다. 여기까지 따라왔다면 아마 뒷 부분은 어렵지 않을 것 같다.

일단, 포스트가 너무 길어지니까 여기서 마무리하고 다음 편에서 마무리 해보겠다!

F. 참고문서

  1. [Linux] wget, curl 차이, 우노, 운호(Noah), 2021/04/21
  2. curl로 REST API 테스트, 기록만이살길, 기록만이살길, 2021/03/28

Read more

[Linux] Mariadb Docker container 설치

[Linux] Mariadb Docker container 설치

A. 사용환경 * OS : Rocky Linux 9.5 (Blue Onyx) * Docker : 28.0.4 * Portainer : 2.27.3 LTS B. 시작하기 전에... 어떤 소프트웨어를 사용하더라도 보통 Database는 거의 필수로 필요한 편이다.(요즘엔 SQLite도 많이써서... DB서버가 없어도 되긴하지만 어쨌든!) 업무적으로 사용할 소프트웨어들을 몇개 검토해봤는데, 대부분이 MySQL, Mariadb, PostgreSQL이더라. 일단, 바로 설치해서 사용해볼

By simplism
[Linux] Docker에 Portainer 설치

[Linux] Docker에 Portainer 설치

A. 사용환경 * OS : Rocky Linux 9.5 (Blue Onyx) * Docker : 28.0.4 B. Portainer란? docker를 사용할 때 명령어 기반으로 사용해도 되지만... 여전히 GUI는 필요하다.(ㅎㅎ) Portainer를 간단하게 설명하면 docker 관리소프트웨어(웹기반)정도로 이해해도 된다. Portainer 공식 홈페이지에서 확인해보면 기능이 아주 많은 것 같은데... 사실 나의 경우에는 아주 단순한 기능만

By simplism
[Linux] Rocky Linux 9에 Docker 설치

[Linux] Rocky Linux 9에 Docker 설치

사용환경 1. Hardware : VMware 2. OS : Rocky Linux 9.5 (Blue Onyx) A. 시작하기 전에.. Docker 테스트를 위해서 VMware에 가상서버를 생성하고 Rocky Linux를 설치했다. 개인적으로는 Ubuntu를 선호하는 편인데, 회사에서 사용할 서버라서 다른 사람들과 같이 사용하기 위해서 RHEL이나 RHEL과 호환되는 배포판을 선택해서 사용하는 편이다. B. Docker 설치 전 작업 01. OS

By simplism