[Linux]쉽게 따라하는 Linux 서버에서 메일 보내기(postfix 사용)

리눅스 서버에서 postfix 패키지를 이용해서 메일 보내기 기능을 설정해 보겠습니다. 메일 보내기 기능을 설치해 놓으면 Daily Health Check Report 등을 이메일로 보낼 수 있으며, crontab과 연결해서 예약 메일 보내기 기능도 구현할 수 있습니다. 여기는 naver 메일의 smtp 서버(smtp.naver.com)과 포트(465)를 이용하겠습니다. 네이버 메일 > 환경설정 > POP3/SMTP 사용함으로 저장해야 합니다.

  1. 메일 서비스 관련 패키지 설치 및 확인
  2. 메일 서버 환경 설정 및 확인
  3. 메일 보내기 테스트
  4. 예약 메일 보내기

 

1. 메일 서버시 관련 패키지 설치 및 데몬 실행

  • postfix, mailx, cyrus-sasl-plain 패키지를 설치합니다.
    $ yum -y install postfix mailx cyrus-sasl-plain
    Last metadata expiration check: 0:01:33 ago on Wed 26 Jul 2023 02:39:35 AM KST.
    Package postfix-2:3.5.8-6.el8.x86_64 is already installed.
    Package mailx-12.5-29.el8.x86_64 is already installed.
    Package cyrus-sasl-plain-2.1.27-6.el8_5.x86_64 is already installed.
    Dependencies resolved.
    Nothing to do.
    Complete!
    
  • `rpm -ql postfix` 명령어로 패키지에서 설치한 파일들을 확인합니다. /etc/postfix/ 디렉토리에 환경설정 파일이 있으며, postfix.service 데몬을 실행시켜야 합니다.
    $ systemctl enable --now postfix.service
    Created symlink /etc/systemd/system/multi-user.target.wants/postfix.service /usr/lib/systemd/system/postfix.service.
    

2. 메일 서버 환경 설정 및 확인

  • /etc/postfix/main.cf이 환경설정 파일입니다. 아래에 있는 지시자들을 등록해야 합니다. 붉은 색 지시자만 수정 또는 추가 등록하면 됩니다. 주석처리(#)된 지시자는 주석처리를 삭제하세요. 설정 완료 후 postconf -n 명령어 또는 postfix check 명령어로 점검하면 잘못되었거나 누락된 설정사항을 확인할 수 있습니다.
    alias_database = hash:/etc/aliases
    alias_maps = hash:/etc/aliases
    command_directory = /usr/sbin
    compatibility_level = 2
    daemon_directory = /usr/libexec/postfix
    data_directory = /var/lib/postfix
    debug_peer_level = 2
    debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin ddd $daemon_directory/$process_name $process_id & sleep 5
    html_directory = no
    inet_interfaces = loopback-only
    inet_protocols = all
    mail_owner = postfix
    mailq_path = /usr/bin/mailq.postfix
    manpage_directory = /usr/share/man
    meta_directory = /etc/postfix
    mydestination = $myhostname, localhost.$mydomain, localhost
    mydomain = centos8
    myhostname = centos8
    myorigin = $mydomain
    newaliases_path = /usr/bin/newaliases.postfix
    queue_directory = /var/spool/postfix
    readme_directory = /usr/share/doc/postfix/README_FILES
    relayhost = [smtp.naver.com]:465
    sample_directory = /usr/share/doc/postfix/samples
    sendmail_path = /usr/sbin/sendmail.postfix
    setgid_group = postdrop
    shlib_directory = /usr/lib64/postfix
    smtp_sasl_auth_enable = yes
    smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
    smtp_sasl_security_options = noanonymous
    smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
    smtp_tls_CApath = /etc/pki/tls/certs
    smtp_tls_security_level = encrypt
    smtp_tls_wrappermode = yes
    smtp_use_tls = yes
    smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
    smtpd_tls_key_file = /etc/pki/tls/private/postfix.key
    smtpd_tls_security_level = encrypt
    unknown_local_recipient_reject_code = 550
    
  • SMTP 서버의 사용자 등록 및 해시 파일 생성
    $ vi sasl_passwd
    [smtp.naver.com]:465 your_id@naver.com:your_passwd
    $ postmap ./sasl_passwd
    $ chown root:root ./sasl_passwd*
    $ chmod 0600 ./sasl_passwd*
    $ ll | grep sasl_passwd
    -rw-------. 1 root root    51 Jul 26 03:13 sasl_passwd
    -rw-------. 1 root root 12288 Jul 26 03:15 sasl_passwd.db
    
  • 종합 권장 /etc/postfix/main.cf 보안 스니펫
    # 1. Information Hiding & Anti-Reconnaissance
    ## Postfix 버전 정보 숨기기 (기본값인 버전 표기를 제거하고 호스트명만 응답, ESMTP: Extended SMTP)
    smtpd_banner = $myhostname ESMTP
    ## VRFY 명령어는 외부에서 VRFY user@domain.com과 같이 메일을 직접 보내지 않고도 특정 계정이 이 서버에 실제 존재하는지 확인할 수 있는 명령어로 
    ## 해커나 스패머가 사전 공격(Dictionary Attack)으로 서버 내 존재 계정 목록을 수집(User Enumeration)하는 데 악용하는 것을 차단합니다.
    disable_vrfy_command = yes
    ## HELO/EHLO 호스트명 필수 요구 (올바르지 않은 접근 차단)
    smtpd_helo_required = yes
    
    # 2. Access Control & Anti-Open Relay
    ## 릴레이 허용 네트워크 (자기 자신 및 신뢰할 수 있는 내부 IP만 지정)
    mynetworks = 127.0.0.0/8 [::1]/128 192.168.0.0/16
    ## 릴레이 제한 (Postfix 2.10 이상 권장 분리 설정)
    smtpd_relay_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_unauth_destination
    ## 수신자 제한 (순서가 중요합니다)
    ## reject_unauth_destination: 앞 두 조건에 해당하지 않는 사용자가 외부 도메인으로 메일을 발송하려고 하면 거부합니다.
    smtpd_recipient_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_unauth_destination,
        reject_invalid_hostname,
        reject_non_fqdn_recipient,
        reject_unknown_recipient_domain
    ## 스패머들이 자주 사용하는 가짜 도메인이나 잘못된 형식의 호스트명 접근을 1차적으로 필터링합니다.
    smtpd_helo_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_invalid_helo_hostname,
        reject_non_fqdn_helo_hostname,
        reject_unknown_helo_hostname
    
    # 3. TLS & SASL Authentication
    ## 외부와 메일을 주고받을 때 TLS 사용 (가능한 경우 적용)
    smtpd_tls_security_level = may
    smtp_tls_security_level = may
    ## 서버 인증서 및 개인키 경로
    smtpd_tls_cert_file = /etc/letsencrypt/live/yourdomain.com/fullchain.pem
    smtpd_tls_key_file = /etc/letsencrypt/live/yourdomain.com/privkey.pem
    ## 취약한 구형 프로토콜(SSLv2, SSLv3, TLSv1, TLSv1.1) 차단 (TLS 1.2 / 1.3만 허용)
    smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
    smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
    smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
    ## SASL 사용자 인증 보안
    smtpd_sasl_auth_enable = yes
    smtpd_sasl_type = dovecot
    smtpd_sasl_path = private/auth
    ## 핵심: TLS 암호화 연결(HTTPS/SMTPS) 상태가 아닐 때는 SASL 로그인 자체를 금지
    smtpd_tls_auth_only = yes
    ## 익명 로그인 및 평문 인증 거부
    smtpd_sasl_security_options = noanonymous, noplaintext
    smtpd_sasl_tls_security_options = noanonymous
    
    # 4. Resource Limits (DoS Protection)
    ## 1회 전송 최대 메일 크기 제한 (예: 20MB)
    message_size_limit = 20971520
    ## 클라이언트당 동시에 연결 가능한 최대 세션 수
    smtpd_client_connection_count_limit = 10
    ## 동일 클라이언트에서 일정 시간 내 생성 가능한 연결 빈도 제한
    smtpd_client_connection_rate_limit = 30
    ## 잘못된 바이트 입력 및 에러 발생 시 세션 즉시 강제 종료 세기
    smtpd_hard_error_limit = 5
    

3. 메일 보내기 테스트

  • postfix 데몬 재시작 및 상태 확인
    $ systemctl restart postfix
    $ systemctl status postfix
    [0m postfix.service - Postfix Mail Transport Agent
       Loaded: loaded (/usr/lib/systemd/system/postfix.service; enabled; vendor preset: disabled)
       Active: active (running) since Wed 2023-07-26 03:20:03 KST; 36s ago
    
    
  • 이메일 보내기 테스트 및 확인
    $ echo "This is the body of the email" | mail -s "This is the subject line" -r your_id@naver.com receiver_email
    $ mailq
    Mail queue is empty
    
  • 메일이 전송되지 않는다면 전송오류로 쌓인 메일큐를 삭제, 설정 재확인 후 postfix 데몬 재시작
    $ mailq | awk '$7~/@/{print$1}' | while read qid; do postsuper -d $qid; done
    $ vi main.cf
    $ postfix check
    $ systemctl restart postfix.service
    

4. 예약 메일 보내기

  • crontab 명령어를 사용해서 보낼 메일을 등록해 놓는다
    $ vi /root/sendmail.sh
    TITLE="subject"
    FR_ADDR="your_id@naver.com"
    TO_ADDR="email1 email2"
    ATTACH="/path/attachment_file"
    BODY="/path/content_file"
    
    mail -s ${TITLE} -a ${ATTACH} -r ${FR_ADDR} ${TO_ADDR} < ${BODY}
    
    $ chmod 755 /root/sendmail.sh
    $ crontab -e
    분 시 일 월 주 /root/sendmail.sh
    

You may also like...

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다