[Ubuntu 16.04LTS] IP주소 바뀌면 이메일로 통보되게끔 구축 : 구글(Gmail) SMTP 활용

가정용 회선(유동IP)과 DDNS를 활용하고 있습니다.
생각대로라면 IP주소 변경시 DDNS 측에 바로 전달되어 반영되어야 하겠지만, 실제로 써봤더니 지체되는 경우가 있더군요. 가만히 지켜보니 하루 정도 지나서 연결되기도 했습니다(그때까진 사이트 접속 불가.ㅠㅋ).

냉가슴만 앓다가 우연히 아래 글을 읽게 됩니다.
ddns 없이, 자신의 동적ip를 실시간으로 감지하여, 외부에서 접근하기 – 클리앙
=> 세시간마다 체크라? 아이디어가 좋아 보입니다. 그런데 코드가 어렵습니다.(제가 초보라 ㅠㅠ)
그래도 좀 집중해서 보니까 구조가 보입니다. sendmail 프로그램을 쓰는 것 같은데, 저는 sendmail 세팅이 어려워 설치하지 않았었고 메일 전송시 SSL(TSL)을 안쓰면 보안에 취약할 텐데, 지금 SSL까지 구현해 가면서 sendmail 설치한다면 난이도가 꽤 올라갈 것 같았습니다.

좀 더 쉽게 설명된 글을 찾다가
Send Email when IP Address Changes – ariandyblog
발견!! 30분마다 체크라? 나쁘지 않아 보입니다.
따라하면서 문제점까지 해결한 과정을 정리해 봅니다.(ariandyblog 의 내용을 우분투에 직접 적용하니까 사소한 문제가 발생하더군요.)

————————————————-

일단 Gmail 세컨드 계정(발신용)을 하나 만들고, 비밀번호를 어렵게 설정해 둡니다. 이 계정에서 본인의 다른 메일주소로 정보를 보내도록 구축할 겁니다.

터미널 창을 하나 띄웁니다.(단축키 : Ctrl+Alt+T)
sudo apt-get update
sudo apt-get install ssmtp mailutils
위의 명령을 차례로 입력합니다. ssmtp와 mailutils 프로그램을 설치하는 겁니다. 의존성 패키지들을 함께 설치하겠냐고 물을 때도 Y를 눌러줍니다.

/etc/ssmtp/ssmtp.conf 파일을 에디터로 엽니다. 설정 파일을 세팅할 차례예요.
(루트권한이 필요하다면? sudo nautilus 또는 sudo gedit 등등 익숙한 수단을 동원해서 접근하세요.)
주석처리 안 된 라인들 앞에 #을 넣어 전부 주석처리 해주고, 하단에 아래처럼 내용을 작성 후 저장합니다. (줄번호까지 따라 입력하는 실수는 하지 맙시다.)

1
2
3
4
5
6
7
8
9
root=세컨드 구글메일(Gmail) 주소
mailhub=smtp.gmail.com:587
AuthUser=세컨드 구글메일(Gmail) 주소
AuthPass=세컨드 구글메일(Gmail) 비밀번호
UseTLS=YES
UseSTARTTLS=YES
AuthMethod=LOGIN
rewriteDomain=gmail.com
FromLineOverride=YES
cs

(참고로 링크의 글을 보면 587포트는 지메일 SMTP 서버의 TLS 통신용으로 사용됨을 알 수 있습니다. 편하고 안전하죠.)

이제 메일이 잘 보내지나 테스트해 봅시다. 터미널 창에서 아래처럼 입력해 봅니다.
echo “test message” | mail -s “testing ssmtp” yourmail@gmail.com
(yourmail@gmail.com 은 수신 가능한 본인의 메일 주소로 바꿔야 됩니다.)
메일함에 잘 도착했다면…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
# check and send ip address to email
 
MYIP=`wget  q http://checkip.dynu.com | awk F“: “ ‘{print $2}’`;
TIME=`date`;
 
LASTIPFILE=/home/XXXXXX/.last_ip_addr’;
LASTIP=`cat ${LASTIPFILE}`;
 
if [[ ${MYIP} = ${LASTIP} ]]
then
        echo “no IP change!”
else
        echo “New IP = ${MYIP}”
        echo “sending email..”
        echo “Hello\n\nTimestamp = ${TIME}\nIP = ${MYIP}\n\nBye” | \
                /usr/bin/mail “[INFO] New IP” yourmail@gmail.com;
        echo ${MYIP} > ${LASTIPFILE};
fi
cs

▲ 따옴표(유니코드 0022)가 자동서식 적용되면서 다른 따옴표(유니코드 201C)로 바뀌었습니다. 엔터키 왼쪽의 따옴표(유니코드 0022)로 바꿔서 입력해 주세요.

에디터를 하나 열어서 위 코드를 입력 후 원하는 경로+파일명으로 저장합니다(저는 /home/우분투 계정명/emailipaddress.sh 로 했습니다.).
코드에서 붉은색+굵게 표시한 곳은 본인에게 맞게끔 수정해야 합니다. 만약 제가 우분투 계정을 sobi 라고 정해서 쓰고 있다면 /home/XXXXXX/.last_ip_addr 부분을 /home/sobi/.last_ip_addr 라고 바꾸어 적는 겁니다(사실은 .last_ip_addr 이름으로 생성되는 숨김파일의 저장위치를 정하는 것인데, 원하는 경로로 적당히 적어줘도 됩니다.). yourmail@gmail.com 부분도 본인의 메일주소로 바꿉니다.

– 참고 : 코드 내용 파악해보기 –
① bash 스크립트임.
② http://checkip.dynu.com 사이트에서 MYIP 를 받고, 현재 시간(TIME)도 출력하라.
③ LASTIP 는 .last_ip_addr 파일에 있다(파일이 없으면 생성한다.). 이를 LASTIPFILE 라 칭한다.
④ 만약 MYIP = LASTIP 라면 “no IP change!” 메세지를 출력하라. 아니라면 MYIP 값을 출력하고 메일을 보내라.
⑤ MYIP 값을 LASTIPFILE 에 기록하라.
⑥ 끝.

 

이제 이 스크립트 파일을 테스트할 차례입니다. 터미널을 띄워서

bash emailipaddress.sh
라고 쳐봅니다(우분투는 dash 쉘이 기본이라 bash 쉘로 실행할 것을 명시해주는 겁니다. 배경 정보는 https://storycompiler.tistory.com/101 에서 확인해 주세요.)
cat: 블라블라/.last_ip_addr: 그런 파일이나 디렉터리가 없습니다.
라고 뜨면서 IP주소와 메일 보냈다는 메세지까지 뜰텐데요,
실제로 메일함을 보면 현재 IP주소가 메일로 와있을 겁니다. 그리고 nautilus 같은 파일관리자에서 숨긴 파일 보이기 옵션을 체크하고 살펴보면 .last_ip_addr 파일이 생성되어 있을 겁니다.
이제 터미널에서 이렇게 한번 쳐보세요.
./emailipaddress.sh
그러면
bash: ./emailipaddress.sh: 허가 거부
라고 뜰겁니다. 이걸 해결하기 위해서는 터미널에서 아래처럼 쳐주면 되더군요.
chmod u+x emailipaddress.sh
이제 ./emailipaddress.sh 라고 쳐보면 정상적으로 실행되는 것을 확인 가능합니다.

이걸 부팅시+일정 시간마다 자동 실행되도록 할 건데요, 많이들 쓰시는 크론탭(crontab)에 등록 시도하겠습니다. 터미널에서 아래 명령을 쳐보세요.
crontab -e
그리고 맨 밑에 아래처럼 입력 후 Ctrl+X를 눌러 저장+빠져나옵니다.
*/30 * * * * /bin/bash /home/XXXXXX/bin/emailipaddress.sh
30분마다 한번씩 실행하라는 겁니다(저장한 크론탭은 /var/spool/cron/crontabs에 계정명과 같은 이름의 파일로 저장되어 있습니다. 루트계정으로 지정하고 싶다면 root 파일에 내용을 넣으면 되겠죠).
재부팅하여 추이를 지켜봅니다. /var/log/mail.log 파일을 보면 되는데(참고 : 우분투에서 cron 로그는 /var/log/syslog 에서 cron 실행에 대한 부분만 찾아내어 보면 됨.),
잘 돌아가면 그냥 쓰면 되고, 같은 시간에 이메일이 2번 연속 전송되고 메일함에 “Delivery Status Notification (Failure)” 같은 메일들이 쌓여간다면 설정 잘못된 겁니다. 구글 검색해 보니까 ssmtp를 crontab에 세팅할 경우 2중으로 메일이 발송된다는 보고가 이미 있더군요. 제가 이 경우인 듯해서 우회할 수 있는 방법을 찾아봤습니다.

우선 터미널에서
crontab -e
를 친 후 위에서 입력했던 내용을 지우고 빠져나옵니다.
그리고 emailipaddress.sh 파일의 내용을 아래처럼 바꿉니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash
# check and send ip address to email
 
let “loop_time=60*30” #30분마다 반복
 
while :
do
 
MYIP=`wget  q http://checkip.dynu.com | awk F“: “ ‘{print $2}’`;
TIME=`date`;
 
LASTIPFILE=/home/XXXXXX/.last_ip_addr’;
LASTIP=`cat ${LASTIPFILE}`;
 
if [[ ${MYIP} = ${LASTIP} ]]
then
        echo “no IP change!”
else
        echo “New IP = ${MYIP}”
        echo “sending email..”
        echo “Hello\n\nTimestamp = ${TIME}\nIP = ${MYIP}\n\nBye” | \
                /usr/bin/mail “[INFO] New IP” yourmail@gmail.com;
        echo ${MYIP} > ${LASTIPFILE};
fi
 
sleep $loop_time #loop_time 후에 다시 체크합니다
done
cs

이제 에디터로 /etc/rc.local 파일을 수정하여 아래의 내용을 추가하고 빠져나옵니다.
/bin/bash /home/XXXXXX/emailipaddress.sh

재부팅. 터미널 창에서 아래의 명령을 입력해 봅니다.
ps -ef | grep emailipaddress.sh | grep -v grep
root 권한으로 실행되고 있는 emailipaddress.sh 스크립트를 확인할 수 있을겁니다.
(참고로
root     11840  9100  0 15:14 pts/20   00:00:00 sh emailipaddress.sh
이런 식으로 표시된다면 터미널에서
kill 11840
이렇게 입력하면 프로세스를 종료할 수 있습니다.)

저는 이것으로 세팅을 끝냈습니다.

CC BY-NC-ND 4.0