Grow up

生活とプログラミング

AnsibleからPostfixを設定してcronからメールを送信する

f:id:knkomko:20210718235123p:plain:w250

はじめに

今回はcronの実行時にメールを送信する機能を使って死活監視を行います。

Postfix や cron の設定は最終的にAnsibleから行えるようにしました。
Ansible は以前に行ったcronの設定を参考にしています。
knkomko.hatenablog.com

Ansible の YAML は以下のリポジトリに保存しています。
github.com

利用環境

・Windows10 Pro
 WSLを使用してAnsibleのplaybookを実行しています

Ubuntu 20.04
 cron を実行するOSです

Postfix とは

メール転送エージェント (Mail Transfer Agent、略称 MTA) の一種です。

cron からメールを送信する為には、メール配信を行うMTA が必要になります。

初めはMTAが無い状態でメール送信を行い、以下のエラーが発生していました。

$sudo cat /var/log/cron.log

Aug 11 07:07:01 ubuntu-cron CRON[378]: (root) CMD (echo 'test')                                                                                              
Aug 11 07:07:01 ubuntu-cron CRON[377]: (CRON) info (No MTA installed, discarding output)  
1. playbook.yml 送信先メールアドレスの編集

job の sample@gmail.com を実在するメールアドレスに変更します。

  - name: Setup cron env
    cron:
      name: MAILTO
      user: root
      job: sample@gmail.com
      env: true
2. playbook.yml ドメイン名の編集

Postfix のインストール前に debconf を使用して設定値を保存しておきます。
debconf を使うとインストール時の設定画面を操作することなく自動で行えます。
今回ドメイン名の設定値は example.com としています。
このドメイン名は実在しなくてもメール送信が可能でした。

  - name: Setup postfix using debconf
    debconf:
      name: postfix
      question: "{{ item.question }}"
      value: "{{ item.value }}"
      vtype: "{{ item.vtype }}"
    with_items:
      - { question: postfix/main_mailer_type, value: "Internet Site", vtype: select }
      - { question: postfix/mailname, value: "example.com", vtype: string }
3. inventry.ini の編集

IPアドレス
 cron を実行するサーバのIPアドレスを変更します。
 今回は 192.168.11.41 に設定しています。
SSH接続ポート番号
 ansible_port でSSH接続のポート番号を接続先に合わせます。
 今回は 22 に設定しています。
SSH接続ユーザー
 ansible_ssh_user でSSH接続のユーザーを接続先に合わせます。
 今回は ubuntu に設定しています。

[target]
192.168.11.41

[target:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_port=22
ansible_ssh_user=ubuntu
4. playbook.yml の実行
$ ansible-playbook -i inventry.ini playbook.yml --ask-pass --ask-become-pass

今回 ansible-playbook を実行した時に以下のエラーが表示されました。

Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host.

管理対象サーバの fingerprint が登録されてないことが原因のようです。
今回 fingerprint の登録が無くても実行できるように ansible.cfg を変更しました。

$sudo vi /etc/ansible/ansible.cfg

# Add ssh_args option "-o StrictHostKeyChecking=no"
#ssh_args = -o ControlMaster=auto -o ControlPersist=60s
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no
5. メール送信の確認

playbook.yml で指定したメールアドレスに送信できていることを確認します。
Postfix で指定したドメインexample.com が送信元として記載されています。
f:id:knkomko:20210812213252p:plain

cron が1分間隔で実行されるため、実行に応じてメールが送信されます。
実行されている cron を確認すると MAILTO にアドレスが指定されています。

ubuntu@ubuntu-postfix:~$ sudo cat /var/spool/cron/crontabs/root                                                                                                                   
[sudo] password for ubuntu:                                                                                                                                                       
# DO NOT EDIT THIS FILE - edit the master and reinstall.                                                                                                                          
# (/tmp/crontabevts3ezv installed on Thu Aug 12 12:28:39 2021)                                                                                                                    
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)                                                                                                         
MAILTO="sample@gmail.com"                                                                                                                                                    
#Ansible: mailtest                                                                                                                                                                
* * * * * bash echo 'test'
cron メール送信ログ

cron からメール送信を行ったログは mail.log に保存されています。

$sudo cat /var/log/mail.log

以下はメール送信に成功したログを抜粋した内容になります。

Aug 12 10:48:12 ubuntu-cron postfix/pickup[14908]: 50FFA390386: uid=1000 from=<ubuntu>                                                                                                                                                                                                                                        
Aug 12 10:48:12 ubuntu-cron postfix/cleanup[14964]: 50FFA390386: message-id=<20210812104812.50FFA390386@example.com>                                                                                                                                                                                                          
Aug 12 10:48:12 ubuntu-cron postfix/qmgr[10365]: 50FFA390386: from=<ubuntu@example.com>, size=280, nrcpt=1 (queue active)                                                                                                                                                                                                     
Aug 12 10:48:12 ubuntu-cron postfix/smtp[14966]: connect to gmail-smtp-in.l.google.com:25: Network is unreachable                                                                                                                                                                                     
Aug 12 10:48:14 ubuntu-cron postfix/smtp[14966]: 50FFA390386: to=<sample@gmail.com>, relay=gmail-smtp-in.l.google.com:25, delay=62, delays=60/0.01/1/0.7, dsn=2.0.0, status=sent (250 2.0.0 OK  253 - gsmtp)                                                                    
Aug 12 10:48:14 ubuntu-cron postfix/qmgr[10365]: 50FFA390386: removed 
postfix 設定ファイル

メール送信等の設定を変更する場合は main.cf から変更を行います。

$sudo cat /etc/postfix/main.cf

手動で main.cf を変更した場合は postfix の再起動が必要です。

$sudo service postfix restart

今回 ansible から設定した内容になります。

# See /usr/share/postfix/main.cf.dist for a commented, more complete version                                                                                                      
                                                                                                                                                                                  
                                                                                                                                                                                  
# Debian specific:  Specifying a file name will cause the first                                                                                                                   
# line of that file to be used as the name.  The Debian default                                                                                                                   
# is /etc/mailname.                                                                                                                                                               
#myorigin = /etc/mailname                                                                                                                                                         
                                                                                                                                                                                  
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)                                                                                                                              
biff = no                                                                                                                                                                         
                                                                                                                                                                                  
# appending .domain is the MUA's job.                                                                                                                                             
append_dot_mydomain = no                                                                                                                                                          
                                                                                                                                                                                  
# Uncomment the next line to generate "delayed mail" warnings                                                                                                                     
#delay_warning_time = 4h                                                                                                                                                          
                                                                                                                                                                                  
readme_directory = no                                                                                                                                                             
                                                                                                                                                                                  
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on                                                                                                         
# fresh installs.                                                                                                                                                                 
compatibility_level = 2                                                                                                                                                           
                                                                                                                                                                                  
# TLS parameters                                                                                                                                                                  
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem                                                                                                                          
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key                                                                                                                         
smtpd_use_tls=yes                                                                                                                                                                 
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache                                                                                                           
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache                                                                                                             
                                                                                                                                                                                  
# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for                                                                                                         
# information on enabling SSL in the smtp client.                                                                                                                                 
                                                                                                                                                                                  
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination                                                                                   
myhostname = ubuntu-postfix                                                                                                                                                       
alias_maps = hash:/etc/aliases                                                                                                                                                    
alias_database = hash:/etc/aliases                                                                                                                                                
myorigin = /etc/mailname                                                                                                                                                          
mydestination = $myhostname, example.com, ubuntu-postfix, localhost.localdomain, localhost                                                                                        
relayhost =                                                                                                                                                                       
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128                                                                                                                         
mailbox_size_limit = 0                                                                                                                                                            
recipient_delimiter = +                                                                                                                                                           
inet_interfaces = all                                                                                                                                                             
inet_protocols = all