메일 호스팅 업체를 통해 계약된 기관들에 패치내역을 보내주고 있다.

 

근데 오전부터 발신에 대해 모든 동작이 중지했다.

 

서버 엔지니어로 무엇을 봐야할까

메일이 관련된 프로토콜은 SMTP, POP3, IMAP등등이 있다.

SMTP : Simple Mail Transfer Protocol, 이메일 전송 때 사용하는 플로토콜.

POP3 : Post Office Protocol 3, 이메일 수신할때 사용하는 프로토콜.

IMAP: Internet Message Access Protocol, 이메일 수신할때 사용하는 프로토콜이다.

 

네이버, 다음 등 메일을 사용할 때 환경설정을 들어가보면

이렇게 POP3/SMTP 혹은 IMAP/SMTP 조합을 볼수 있다.

이를 보면 SSL이 필요하다고 써져있다. SSL는 다음번에.

 

SMTP는 465 포트

POP3 는 995 포트/ IMAP 은 993 포트를 사용하고 있으니 방화벽에서 차단되는 이력이 있는지 체크해보자.

 

하지만 차단이력이 없는데도 불구하고 메일이 보내지지 않는다.

그렇다면 서버나 웹 페이지의 소스코드의 문제로 생각할수 있다.

 

위에서 한번 언급했듯이, 이 메일 호스팅업체는 SSL을 사용하기 때문에

SSL/TLS 서버 테스트를 하기위해 openssl를 사용해서 테스트 해보자.

 

현재 발신이 안되는 상태이므로 SMTP, 465포트를 사용한다.

[test@mailserver ~]$ openssl s_client -connect smtp.mailhost.co.kr:465
CONNECTED(00000003)
depth=3 C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services
verify return:1
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
verify return:1
depth=0 CN = *.mailhost.co.kr
verify return:1
---
Certificate chain
 0 s:/CN=*.mailhost.co.kr
   i:/C=GB/ST=Greater Manchester/L=Salford/O=Sectigo Limited/CN=Sectigo RSA Domain Validation Secure Server CA
 1 s:/C=GB/ST=Greater Manchester/L=Salford/O=Sectigo Limited/CN=Sectigo RSA Domain Validation Secure Server CA
   i:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority
 2 s:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority
   i:/C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=AAA Certificate Services
 3 s:/C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=AAA Certificate Services
   i:/C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=AAA Certificate Services
---
Server certificate
-----BEGIN CERTIFICATE-----
7clOtTxZSRZ7H39hdjYnvNkL 생략 R52r2dTo++yyFqGwD50LaYDDHZzfuhvQzWBhKqL2
-----END CERTIFICATE-----
subject=/CN=*.mailhost.co.kr
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=Sectigo Limited/CN=Sectigo RSA Domain Validation Secure Server CA
---
No client certificate CA names sent
Peer signing digest: SHA256
Server Temp Key: ECDH, P-384, 384 bits
---
SSL handshake has read 6360 bytes and written 447 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE ~~
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: FAF589A26EB429E 생략
    Session-ID-ctx:
    Master-Key: AAE5F6497D38C66 생략
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - e8 ee d4 41 ed 95 7d d5-cb 68 eb c5 d9 a5 fa 5c   ...A..}..h.....\
    0010 - 43 7c 33 b0 1c 1b 3d bf-08 10 5b 58 79 7f fc 0f   C|3...=...[Xy...
    0020 -
    0030 - 
    0040 - 
    0050 -
    0060 -           생략
    0070 - 
    0080 - 
    0090 - 51 ec 6b 06 44 5d c5 d5-c3 39 56 b6 cf 7c 5e 02   Q.k.D]...9V..|^.
    00a0 - b2 97 48 09 ca 3d f6 7a-18 b0 a1 40 46 e1 4d f2   ..H..=.z...@F.M.

    Start Time: 1741338795
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)

메일서버와의 통신은 정상적으로 된것을 확인했다.

 

그럼 실제로 메일 송/수신 테스트를 해보자.

--- SMTP 서버 통신 테스트 과정 ---

220 mailpx12 ESMTP ready                      # 메일서버에 정상적으로 통신이 되었다.

HELO ourcompany.co.kr                         # [서버 엔지니어가 입력] 회사에 등록된 도메인을 입력한다.
250 mailpx12                                  # 서버가 HELO명령을 수락하였다 

AUTH LOGIN                                    # [서버 엔지니어가 입력] 로그인 인증을 시작하겠다.
334 VXNlcm5h~~~~~~~~~bWU6                     # 서버가 ID를 요구함
YWxsc2                                        # [서버 엔지니어가 입력] 발신전용 메일의 ID를 입력(BASE64로 인코딩 필요)
334 UGFzc3dvcmQ6                              # 서버가 PW를 요구함
Q0ZTY2xvdWQ~~~~~~~~j                          # [서버 엔지니어가 입력] 발신전용 메일의 PW를 입력(BASE64로 인코딩 필요)
235 2.0.0 OK                                  # 인증이 성공적으로 완료됨

MAIL FROM: <onlymail@mail.co.kr>              # [서버 엔지니어가 입력] 발신 전용 메일 주소 입력
250 ok                                        # 서버가 발신자 설정을 수락함
RCPT TO: <serverengineer@mail.co.kr>          # [서버 엔지니어가 입력] 수신 받을 메일주소 입력
250 ok                                        # 서버가 수신자 설정을 수락함

DATA                                          # [서버 엔지니어가 입력] 이메일 내용을 입력하겠다고 선언
354 go ahead                                  # 서버가 이메일 내용 입력을 기다림

Subject: test                                 # [서버 엔지니어가 입력] 이메일 제목을 입력함
                                              # [서버 엔지니어가 입력] 헤더와 본문 사이에 빈 줄 필요(중요!)
test메일 내용입니다                            # [서버 엔지니어가 입력] 이메일 본문 내용
.                                             # [서버 엔지니어가 입력] 단일 점으로 이메일 내용 입력 종료
250 ok 1741339182 qp 944852                   # 이메일이 성공적으로 전송 큐에 추가됨(메시지 ID와 함께)

QUIT                                          # [서버 엔지니어가 입력] SMTP 세션 종료 요청
221 mailhost.co.kr                            # 서버가 연결 종료 확인
[test@mailserver ~]$                          # 쉘 프롬프트로 돌아옴(세션 종료)

 

 

좀 더 사용하기 쉽게 sh로 구현하였다.

touch mailtest.sh
chmod +x mailtest.sh 

#!/bin/bash

# 변수 설정
SMTP_SERVER="smtp.mailserver.co.kr"
SMTP_PORT="465"
FROM_EMAIL="onlymail@mail.co.kr"
TO_EMAIL="serverengineer@mail.co.kr"
USERNAME="메일계정"
PASSWORD="메일비밀번호"
SUBJECT="test"
BODY="test메일 내용입니다"

# Base64 인코딩
USERNAME_BASE64=$(echo -n "$USERNAME" | base64)
PASSWORD_BASE64=$(echo -n "$PASSWORD" | base64)

# OpenSSL로 SMTP 서버에 연결하여 명령 실행
(
  sleep 2
  echo "HELO ourcompany.co.kr"
  sleep 1
  echo "AUTH LOGIN"
  sleep 1
  echo "$USERNAME_BASE64"
  sleep 1
  echo "$PASSWORD_BASE64"
  sleep 1
  echo "MAIL FROM: <$FROM_EMAIL>"
  sleep 1
  echo "RCPT TO: <$TO_EMAIL>"
  sleep 1
  echo "DATA"
  sleep 1
  echo "Subject: $SUBJECT"
  echo ""
  echo "$BODY"
  echo "."
  sleep 1
  echo "QUIT"
) | openssl s_client -connect $SMTP_SERVER:$SMTP_PORT -quiet

방화벽/서버의 문제는 아닌게 입증되었다.

이러면 끝

 

 


근데 궁금하니까 사내 개발소스를 뜯어보자.

ERROR ExceptionResolver /depNtc102/send/sendMail.do [ERROR] : java.lang.NullPointerException
        at com.test.cmm.util.SystemDevCacheUtil.getEnv(SystemDevCacheUtil.java:81)

웹 요청이 /depNtc102/send/sendMail.do 로 들어와서

sendMail 메소드에서 getEnv() 의 Null인 객체를 참조하다 터진거 같다.

 

SVN따기 귀찮은데.. 그냥 여기까지만 봐줘도 되지만 개발소스를 뜯어보자

SystemDevCacheUtil.Java 

public void setEnvList() throws Exception{	
		this.commonSysEnvList=commonService.selectSysEnvList();
	}
~
~
~
public ComSysEnvVO getEnv(String dutDiv, String optnDiv) throws Exception{
    ComSysEnvVO result = new ComSysEnvVO();
    
    for (ComSysEnvVO data : commonSysEnvList){  // 여기서 NullPointerException 발생
        if (data.getOptnDiv().equals(optnDiv) && data.getDutDiv().equals(dutDiv)){
            result = data;
        }
    }
            
    return result;
}

ComSysEnvVO result  부분에서 NullpointerException 부분을 처리하기 위해

public ComSysEnvVO getEnv(String dutDiv, String optnDiv) throws Exception {
    if(commonSysEnvList == null) {
        setEnvList();
    }
    
    ComSysEnvVO result = new ComSysEnvVO();
    
    for (ComSysEnvVO data : commonSysEnvList) {
        if (data.getOptnDiv().equals(optnDiv) && data.getDutDiv().equals(dutDiv)) {
            result = data;
        }
    }
    
    return result;
}

 

setEnvList()부분이 메서드 선언을 가져와서 Null 처리 해주면 될거같다.

+ Recent posts