「IBM i エンジニア不在でもDXはできる」実践編
日本アイ・ビー・エム株式会社が毎月開催しているIBM Powerユーザーのための自由な語り場「IBM Power Salon」(月1回、第二水曜日の朝9時から開催)をご存じでしょうか?
https://www.ibm.com/blogs/systems/jp-ja/ibm-power-salon/
「IBM Power Salon」は、さまざまな課題に取り組まれていらっしゃるお客様と、課題解決へのお手伝いができるビジネス・パートナー様、ソリューション・ベンダー様が、一同に会して情報交換を行うための場として開催されており、2021年11月の第1回から、2023年2月末までに15回開催されております。中でも、お客様ご自身による事例講演は毎回大好評を博しています。
2022年12月14日に開催された第13回では、「IBM i エンジニア不在でもDXはできる」と題して株式会社 松沢書店様をゲスト講師としてお迎えし、既存IBM i環境を見事に活用し、DXを実現された素晴らしい事例についてお話いただきました。
とはいえ、1時間の講演時間では語りきれなかった詳細は、きっと他のIBM i ユーザーの方にも参考になるはず!ということで、松沢書店 システム部部長の山口様に課題解決の方法について具体的に解説いただきます。
第1回は、Power Salonで紹介された8つの課題のうち、「要望:得意先より伝票データを決まったフォーマットで送信してほしい。」という課題に対して、IBM i からの出力をPostfix + Gmailでメール送信する方法についてご説明頂きます。
(編集部)
第1回:IBM i にあるデータをPostfix+Gmailを使用して
SMTP認証+TLSでメール送信をする
システム部
山口 昌一
前書き
こちらの記事はIBM PowerSalonでご紹介させていただいた「PHPクエリでメールを送信したい」を少し掘り下げたものになります。最初にハードルを下げさせて下さい。筆者はIBM iに詳しいわけでもLinuxに精通しているわけでもございません。非エンジニアからシステム担当になり、いきなりmakeしてdnfしてsudoしてSBMJOBしてという、「全部知っていますよね?」前提のWebのドキュメントと格闘中です。ですので、誤った認識があればご指摘頂ければと思います。どうか暖かい目で読んで頂ければ幸いです。
目的と概要
当社ではオムニサイエンス社のPHPQUERY+Postfix+Gmailを使用して、IBM i上のデータをスケジュールに応じて顧客にメール送信をしております。
当初の目的は納品伝票をスケジュールに従い複数顧客に送信する事でした。しかしながら、昨今のメールに対する企業のセキュリティ強化もあり、SMTP認証※1やTLS※2が求められる様になり、port25でそのまま送ってしまっては安全性や認証の問題でメールが届かなくなったり迷惑メールになったりしてしまいます。そこでpostfixからGmailにリレー(メールを転送)しGmailのセキュリティと認証を利用し安全に送信します。
更に困った事に、password付ZIPファイルがスキャン出来ない事により、禁止する企業も多くなってきました。当社ではPHPクエリを使用してpassword付ZIPを添付しておりました。もちろんpass無にすれば良いだけの話ですが、今はOSSで大変便利なものが出ており、送信したメールに添付があればWebストレージにアップし、WebストレージのURLとログインpassが記載されたメールが宛先に送られるサービスがございます。
今回の記事では、まず1.Postfix+Gmailを使用して転送する方法、次回は2.Postfix+Gmail+SaMMA+nextcloudを使用して添付ファイルをWebストレージにアップし共有させる方法を解説いたします。弊社ではPHPQUERYをいう製品を利用してデータ抽出を行っておりますが、PHPQUERYを導入していない方でも可能な設定になっております。PHPQUERYの設定に関しましては最後に記載致します。
1. 添付なしメール送信の場合(今回取り上げる内容):
IBM i +(PHPQUERY)+Postfix+Gmailを使用しIBM i からメール送信。
2. 添付ありメール送信の場合(第二回で説明予定):
IBM i +(PHPQUERY)+Postfix+Gmail+SaMMA+nextcloudを使用し添付ファイルをクラウドにアップロード。
添付なしメール送信の場合:
IBM i +Postfix+Gmail設定
(1) :Gmailの設定
Gmailのアカウントが無い場合は作成して下さい。このアカウントにメールをリレーし、このアカウントから宛先にメールが送られます。
作成後、もしくはアカウントが存在する場合「Google アカウント」を検索してログインして下さい。
左側の「セキュリティ」をクリック「2段階プロセス」をオンにします。
「開始」で進みます。
設定後「2段階プロセス」がオンになります。
次に「アプリパスワード」を選択します。
「アプリを選択」から「その他(名前を入力)」を選択します。
Postfixで使用しますので、PostfixやLinuxなど自分でわかる任意の名前を入力し「生成」して下さい。
パスワードが生成されますのでメモ等に保存しておいてください。
後ほどPostfixの設定で利用致します。
(2):Postfixのインストールと設定
当社環境:
Linux : CentOS8 stream
Postfixをインストール
[root@localhost ~]# dnf install -y postfix
※以下からは#以降のコマンドのみ表記致します。
インストールされていない依存関係は全てインストールしますのでオプションに「-y」を指定します。
Postfix自動起動を設定:
systemctl enable postfix
設定ファイルを変更:
念のためバックアップを取ります。
設定ファイルは
/etc/postfix/main.cf
コピーします
cp -p /etc/postfix/main.cf /etc/postfix/main.cf.bk
-pはパーミッションと所有者とタイムスタンプを保持します。
リレーするGmailのアドレス、パスを保持するファイルを作成します。
sudo vi /etc/postfix/relay_password
relay_passwordは任意の名称で問題ございません。
[smtp.gmail.com]: 587 ○○@○○メールアドレス : パスワード
上記を追記してください。viを開いたら「i」を押下してINSERTモードにして記述してください。 抜けるときは「ESC」「:wq」で上書き保存できます。間違ってしまったら「:q!」 で編集したものをキャンセル出来ます。
メールアドレスとパスワードは先ほどGmailで設定したものになります。
postmapコマンドでrelay_password.dbを作成します。Postfixが拡張子dbを参照するため作成します。
postmap /etc/postfix/relay_password
viでmain.cfの最終行にsasl※3の設定とTLSの設定を追加します。
sudo vi /etc/postfix/main.cf
main.cfの最終行なのでviであればノーマルモード(開いたまま)で「shift+g」を押せば 最終行に飛びます。
reayhost = [smtp.gmail.com]:587 smtp_sasl_auth_enable = yes #smtp_use_tls = yes smtp_sasl_password_maps = hash:/etc/postfix/relay_password smtp_sasl_security_options = noanonymous smtp_sasl_tls_security_options = noanonymous smtp_sasl_mechanism_filter = plain
smtp_use_tls = yesは
smtp_tls_security_level = may
の記述が736行目あたりにあればコメントアウトしておいて問題ございません。
(viでノーマルモード時に「:set number」とすれば行番号を表示します。)
Postfix2.3以降からはsmtp_tls_secrity_levelで設定します。TLSの設定は後ほど致します。
smtp_sasl_password_maps=の右側は先ほどpostmapを実行した「relay_password」を指定して下さい。
ローカルのサーバーからのみのメールを許可する設定をします。
IBM i がPostfixと同じローカルネットワーク上にある場合
283行目あたりのmynetworksをコメントアウトします。
メールを送信するIBM i のIPを指定してします。
例えばIBM i のIPが192.168.34.230だった場合は、
mynetworks = 192.168.34.230/32, 127.0.0.0/8
にします。
他のサーバーからも送りたい場合はネットマスクの指定を/24にする等で任意に対応下さい。
IBM i からは様々なアドレスでメールが来る事も想定できます。認証をしていないアドレスで送信されては弾かれてしまいます。
そこで、認証されているアドレスに送信元の名前を変更する設定をします。
sender_mapsファイルを作成します。(名前は任意です。)
sudo vi /etc/postfix/sender_maps
以下の内容を記述します。
/^.*$/ test@○○.○○
正規表現でどんな文字列が来ても送信者はtest@○○.○○に置き換えるという意味です。
test@○○.○○ は先ほどの手順1で作成したGmailのアドレスです。
設定ファイルを編集します。
sudo vi /etc/postfix/main.cf
以下を追記します。
local_header_rewrite_clients = permit_mynetworks sender_canonical_classes = envelope_sender sender_canonical_maps = regexp:/etc/postfix/sender_maps
sender_canonical_mapsには先ほど設定したsender_mapsを指定いたします。
ファイヤーウォール設定:
port25を開けて置きます。
現状を確認します。
firewall-cmd --list-all
port25が開いてなければ開けます。
sudo firewall-cmd --add-port=25/tcp --zone=public --permanent sudo firewallcmd reload
Postfixを再起動:
念のため再起動して設定を反映します。
sudo systemctl restart postfix
reloadでも良いのですが、上手く反映しない場合があるのでrestartしておきます。
ログ:
ログは以下にあります。
stail /var/log/maillog
上手くいかない時はご確認下さい。
PostfixからGmailへのリレー間でのTLS設定:
設定ファイルを編集します。
sudo vi /etc/postfix/main.cf
736行目あたりのsmtp_tls_security_level = mayの下に
以下を追記します。
smtp_tls_CAfile = /etc/pki/tls/cert.pem smtp_tls_loglevel = 1
smtp_tls_CAfileはCentOSに最初から入っています。
smtp_tls_security_level = mayは、リレー先のサーバーがTLSに対応していない場合は暗号化せずに送るという意味です。相手はGmailなので強制的に暗号化するencryptでも良いかと思います。
念のため有効期限を確認します。
openssl x509 -noout -dates -in /etc/pki/tls/certs/ca-bundle.crt
当社環境では2030年でしたのでそのままです。切れている場合は更新してください。(更新については今回は触れません。)
また、メールサーバーからGmailまでのTLSを使用しなくても送信は可能ですので、期限が切れていた場合はとりあえずは上記2行をコメントアウトしておいても良いでしょう。
上手く適用が出来てればログに以下の文が書かれます。
Trusted TLS connection established to smtp.gmail.com
以上でPostfixの設定は終了です。
(3):IBM i メールの設定
当社環境
IBM i : Version 7 Release 4
IBM i でメールを送信するには、ユーザープロファイルを作成し、更にSMTPユーザーの作成が必要です。△△@○○.CO.JPという送信者を作成し、その送信者でメールが送信されます。
Postfixをインストールしたサーバーの別名を設定:
CFGTCP
実行
10 TCP/IP ホスト・テーブル項目の処理
実行
IPアドレス:PostfixをインストールしたサーバーのIP ホスト名:後ほど使うホスト名になります。通常サーバーの名前を入れますが、後ほどホスト名からこのIPを呼ぶだけなので、ご自身が理解できる名前であれば何でも構いません。
ユーザー作成:
CRTUSRPRF
F4で任意に設定、今回はTESTというユーザープロファイル
SMTPアトリビュートの変更、送信元ドメインの設定
送信元ドメインの設定(第二回添付ありメール送信の場合で使用、添付がなければそのままで問題ございません)
CHGSMTPA ALIASDMN('ドメイン')
実行
ドメインは、○○.CO.JPや○○.COMというメール送信時の送信元
△△@○○.CO.JP
の@の後ろの部分になります。△△はユーザープロファイルでありSMTPユーザーになります。この後設定していきます。
ALIASDMNの確認は
RUNQRY *N QUSRSYS/QATMSMTP
実行
上記ファイルの中より下あたりに
0001 ○○.CO.JP
インデックス ドメイン名
という形式で書き込まれています。
設定しない場合は
CFGTCP
の12で設定されているドメインが使用されます。
SMTPユーザーを追加します:
WRKSMTPUSR
F4
*ALL
SMTPユーザーがいれば表示されます。いなければOPTに1を入れて以下の画面に遷移します。
ユーザープロファイル:先ほど追加したユーザープロファイル名
SMTPメールボックス別名:上記と同じもの
ドメインインデックス:QATMSMTPに書き込まれていた0001というインデックス
他は*DFT(Default)で問題ございません。
WRKDIRE(Work Directry Entry)で過去に設定している場合はその設定が自動的に入ります。
上記の様に送信者のアドレスが設定できれば成功です。
TEST@○○.○○でメールを送信する準備が出来ました。
例えばTEST2@○○.○○からメールを送信したい場合は、CRTUSRPRFでTEST2というユーザープロファイルを作成しWRKSMTPUSRでTEST2をSMTPユーザーに追加し、○○.○○というドメインをCHGSMTPA ALIASDMNで変更する流れになります。
上記設定はややこしい所もあるので、上手くいかない場合は記事最後に送信メールアドレス設定を抜粋したものを「IBM i 設定補足」として記載しておきますのでそちらもご確認下さい。
メールの送信テスト:
CHGSMTPA FWDHUBSVR('Postfixを入れたサーバー名')
例
CHGSMTPA FWDHUBSVR('POSTFIX')
FWDHUBSRV(forward hub server)により、POSTFIXにメールを送信することが出来ます。
ENDTCPSVR SERVER(*SMTP) STRTCPSVR SERVER(*SMTP)
念のためSMTPサーバーを止めてから起動しておきます。FWDHUBSRV自体は実行すればすぐ反映されます。
SBMJOB CMD(SNDSMTPEMM RCP(('ATESAKI@test.com')) SUBJECT('TEST') NOTE('TEST')ATTACH(('/IFSDIR/GAZOU.PNG' *PNG *BIN))) USER(作成したユーザー)
実行
SBMJOB(submit job):job名をつけて指定のユーザーで実行できるコマンドです。
CMD:SNDSMTPEMMコマンドを丸々書きます。
USER:今回作成したユーザーを入れます。今回ならUSER(TEST)別途ログアウトして、そのユーザーでログインすればSBMJOBは使用しなくてもSNDSMTPEMMだけでそのユーザーで送信されます。
SNDSMTPEMM:メール送信コマンドです。
RCP(recipent): メールの宛先です。
SUBJECT: タイトルです。
NOTE:本文です。
ATTACH:添付ファイルが置いてあるIFS(integrated file system)
IFSにファイルを置く場合はFFFTP等を使用し、IBM i のIPを指定して接続しておいて下さい。
成功すると「Eメールの送信が成功しました。」と表示されます。
エラーの場合のログ確認:
ログをスプールに吐き出します。吐き出したいスプールを事前にESCで設定しておいて下さい。
TRCTCPAPP APP(*SMTPCLT) TRCFULL(*STOPTRC)
実行
SBMJOBCMD(SNDSMTPEMM RCP(('ATESAKI@test.com')) SUBJECT('TEST') NOTE('TEST')ATTACH(('/IFSDIR/GAZOU.PNG' *PNG *BIN))) USER(作成したユーザー)
先ほどのコマンドを実行
TRCTCPAPP APP(*SMTPCLT) SET(*OFF) TITLE('SMTP OUTBOUND')
実行
TRCTCPAPP(trace tcp application)
でSNDSMTPEMMを挟んであげることで、ログをスプールに吐き出せます。
WRKSPLF
WRKSPLF
実行もしくは、ESCからスプールを確認します。
※ログは小文字が含まれますのでエミュレータのホストコードページは「939」に設定してください。
上記の様なログが吐き出されますので、上手くいかない場合はご確認下さい。
メールのヘッダ確認:
上手くメールが届いていたら、メールのヘッダも確認します。
メールソフト:Thunderbird
右上のハンバーガーメニューより「表示」→一番下の「メッセージのソース」
これでメールのヘッダが確認出来ます。送信者が上記で設定したものになっており、Gmailの認証が使われている事もわかります。
Google Transport Security:TLSです。
Authentication-Results:SMTP認証です。
X-Google-Original-From:送信元です。
以上でIBM i からのメール送信は完了です。
(4):PHPQUERYのメール設定
PHPQUERYにログインします。
「管理」→「メールサーバー」
SMTPサーバー: Postfixの入っているサーバーのIP
ポート:25
差出人アドレス:なんでも構いません。Postfixのsender_mapsで指定されているアドレスでGmailにリレーされます。
※1 SMTP認証(Simple Mail Transfer Protocol authentication)
電子メールを送信する際にSMTPサーバーが送信者の身元を確認するための認証方式です。
Postfixでも何も設定しなければ認証無しで適当なアドレスでメールを送信できてしまいます。今回の事例でGmailのアカウントとパスを作成いたしました。Postfixで正しいパスを設定し、sender_mapsでGmailのユーザーを指定することで、私は間違いなくこのGmailユーザーで送信していますという認証になります。
※2 TLS (Transport Layer Security)
ネットワークにおける通信のセキュリティを確保するための暗号化プロトコルの一つです。
メールの送信者と受信者の間で通信が行われる際に暗号化する事によって、通信を傍受されても暗号化されているので、内容は保護されます。
今回の設定は図のCentOSからGmailへの→の上のTLSの設定になります。Gmailから宛先に対してはGmailが行ってくれております。
※3 SASL(Simple Authentication and Security Layer)
クライアントとサーバー間の認証プロセスをセキュアに行うためのフレームワークです。
SASL認証を使用すると、IDとパスワードが暗号化され、クライアントとサーバーの間での認証プロセスがより安全になります。
Postfixの設定ではsmtp_sasl_で始まっている箇所で設定しています。
IBM i 設定補足
IBM i から
TEST@○○.○○
上記アドレスでメールを送信するには、ユーザープロファイルとSMTPユーザーの作成が必要です。
&9312;ユーザープロファイル作成
TESTという名前でユーザープロファイルを作成することによってTEST@○○.○○でメール送信が可能です。
TEST2@○○.○○で送信する場合はTEST2のユーザーを作成する必要があります。
===> CRTUSRPRF
F4 実行
F10追加のパラメーターで特殊権限に*SECADMを追加して下さい。
(設定値はWRKUSRPRFで他ユーザーを確認し任意に設定してください。)
&9313;エイリアスドメインの設定
TEST@○○.○○の○○.○○部分を設定します。
===> CHGSMTPA ALIASDMN(‘○○.○○’)
実行
===> RUNQRY *N QUSRSYS/QATMSMTP
実行で追加されたエイリアスドメインが確認できます。
000034 0000000
000035 0000000
000036 0000000
000037 0000000
000038 0001 ○○.○○
000039 0000
000040 0000
当社実行では38行目にインデックス ドメインという形で
0001 ○○.○○が確認できます。
後ほどこのインデックス0001を使用します。
&9314;SMTPユーザー作成
こちらを作成することによって
TEST@○○.○○
でメールを送信することが可能になります。
===> WRKSMTPUSR
F4 実行
このまま実行
OPTに1を入れて実行
ユーザープロファイルに先ほど作成したユーザープロファイル
SMTPメールボックス別名にユーザープロファイルと同じ値
ドメイン・インデックスには②で作成されたインデックス0001をキーにして○○.○○を取ってくるため
「1」と入力。
他の値は*DFTで問題ございません。
再度
===> WRKSMTPUSR
実行で
ユーザー OPT プロファイル Eメール・アドレス TEST TEST@○○.○○
と表示されれば送信メールアドレスの登録は完了です。
次回は今回の設定にSaMMAとnextcloudを追加して、添付ファイルを送信すればWebストレージにアップしてくれる非常に便利な仕組みを紹介致します。
この記事を執筆中に単純な疑問として、SMTPサーバーがあるならそこからGmailにリレーしてしまえばいいのでは?と考えました。公式にもGmailやOutlookでリレーする記事がございました。こちらはまだ手を付けておりませんので、もし上手くいけばいつか機会があればご紹介致します。