Postfixのバウンスログを集計するシェルスクリプト
#!/bin/bash
# ログファイルのパスを指定
LOGFILE="/tmp/sample_maillog.txt"
# 出力ファイル名を生成する関数(ファイル名に日付を付ける)
generate_output_filename() {
local current_date=$(date +%Y%m%d)
echo "bounce_report_${current_date}.txt"
}
# バウンスログを集計してファイルに保存する関数
collect_bounce_logs() {
local logfile=$1
local output_file=$2
# バウンスログを抽出して集計
grep "status=bounced" $logfile | awk '
{
# メールアドレスとバウンス理由を抽出
if ($0 ~ /to=<[^>]+>/) {
match($0, /to=<[^>]+>/);
email = substr($0, RSTART+4, RLENGTH-5);
}
if ($0 ~ /status=bounced.*\((.*)\)/) {
match($0, /status=bounced.*\((.*)\)/, arr);
reason = arr[1];
}
if (email && reason) {
# バウンスメールアドレスと理由をキーにカウント
bounce[email "|" reason]++;
email = ""; reason = "";
}
}
END {
# 一時ファイルに出力する
for (key in bounce) {
split(key, arr, "|");
printf "%-10s | %-30s | %s\n", bounce[key], arr[1], arr[2];
}
}' | sort -nr > $output_file # 回数でソートして出力
}
# メイン処理
main() {
# 出力ファイル名を生成
output_file=$(generate_output_filename)
# バウンスログを集計
collect_bounce_logs $LOGFILE $output_file
# 完了メッセージ
echo "バウンスログの集計が完了しました。出力ファイル: $output_file"
}
# スクリプトの実行
main
こんな感じで出力
54 | user2@example.com | host mail.example.com said: 550 5.1.1 <user2@example.com>: user unknown 51 | user4@example.com | host mail.example.com said: 550 5.1.1 <user4@example.com>: spam detected 49 | user4@example.com | host mail.example.com said: 550 5.1.1 <user4@example.com>: connection timed out 44 | user5@example.com | host mail.example.com said: 550 5.1.1 <user5@example.com>: user unknown 44 | user5@example.com | host mail.example.com said: 550 5.1.1 <user5@example.com>: host not found 44 | user4@example.com | host mail.example.com said: 550 5.1.1 <user4@example.com>: mailbox full 44 | user1@example.com | host mail.example.com said: 550 5.1.1 <user1@example.com>: mailbox full 43 | user3@example.com | host mail.example.com said: 550 5.1.1 <user3@example.com>: spam detected 42 | user3@example.com | host mail.example.com said: 550 5.1.1 <user3@example.com>: user unknown 42 | user1@example.com | host mail.example.com said: 550 5.1.1 <user1@example.com>: user unknown 41 | user4@example.com | host mail.example.com said: 550 5.1.1 <user4@example.com>: user unknown 41 | user2@example.com | host mail.example.com said: 550 5.1.1 <user2@example.com>: spam detected 40 | user2@example.com | host mail.example.com said: 550 5.1.1 <user2@example.com>: host not found 40 | user1@example.com | host mail.example.com said: 550 5.1.1 <user1@example.com>: connection timed out 39 | user5@example.com | host mail.example.com said: 550 5.1.1 <user5@example.com>: mailbox full 39 | user5@example.com | host mail.example.com said: 550 5.1.1 <user5@example.com>: connection timed out 38 | user1@example.com | host mail.example.com said: 550 5.1.1 <user1@example.com>: spam detected 37 | user3@example.com | host mail.example.com said: 550 5.1.1 <user3@example.com>: connection timed out 35 | user5@example.com | host mail.example.com said: 550 5.1.1 <user5@example.com>: spam detected 35 | user4@example.com | host mail.example.com said: 550 5.1.1 <user4@example.com>: host not found 35 | user2@example.com | host mail.example.com said: 550 5.1.1 <user2@example.com>: mailbox full 33 | user3@example.com | host mail.example.com said: 550 5.1.1 <user3@example.com>: host not found 31 | user3@example.com | host mail.example.com said: 550 5.1.1 <user3@example.com>: mailbox full 31 | user1@example.com | host mail.example.com said: 550 5.1.1 <user1@example.com>: host not found 28 | user2@example.com | host mail.example.com said: 550 5.1.1 <user2@example.com>: connection timed out
IAM Identity Center のユーザーへのcloud9共有方法
以下のユーザー条件に該当する人にCloud9環境を共有します。
「 IAM Identity Centerのユーザー」もしくは「IAM Identity Center によって作成された IAM ロール」
通常はIAMユーザーを作成して共有できます。
しかしコントロールタワーなどでユーザー管理している場合はIAMユーザーとは違います。
その場合は以下でユーザーのARNを確認。
1.共有したいユーザーからCloudshellにログインする
2.以下コマンド実行
aws sts get-caller-identity
以下のような出力
{
"UserId": "AROAVAHUIBHHJJNJ:hoge.hogeo",
"Account": "*******",
"Arn": "arn:aws:sts::****:assumed-role/AWSReservedSSO_************/hoge.hogeo"
}
3.ARNをメモ
4.Cloud9のShere設定から取得したARNを入力
これでCloud9環境を共有できます
AWS コスト削減のポイント(自分流)
クラウドのいいとこは使った分だけっていうのはあるけど使った分はしっかり請求されます。
なるべく抑えましょう
コストタグをつける
現状を把握が必要です。 どのリソースがどのくらい費用がかかっているかCost Explorerで明らかにしましょう。 以前はコストタグを付けたときからの費用計算しかできなかったのでしばらく待つ必要ありましたが、最近のアップデートで12ヶ月遡って計算してくれるようになりました。
リザーブドインスタンス、savingplanの活用
基本の木です。EC2はもちろんECS,lambdaも対象になるのでインスタンス立ち上げぱなしの環境はまず購入。 savingplanに関しては7日以内のキャンセルが可能なので購入時のボタンを押す緊張感が若干なくなりました。
AWS が Savings Plans の 7 日間の返品期間と発表
これで一番恩恵を感じられるのはRDSやopenserch serviceじゃないでしょうか。 ただでさえ高いですからその分割引された金額が安く感じます。(ServerlessはRIないので注意) RIだとインスタンススペックの柔軟性がなくなるのがきついなーって場合はあるとおもいます。同じインスタンスタイプ内でスペックを1つ上げる場合は購入したRIは適応されるので損にはならないです。 1つ下げるときは購入した半分は未適応状態になるのでちょっと損です。
インスタンスを夜間停止する
ステージング環境など業務時間だけ触って夜間は触らないような環境は停止したほうが安い場合が多いです。8時起動→20時停止など稼働率50%だとRI契約は高くつきます。 EventBrigeで自動停止・自動起動させるようにしましょう。RDS、ECSなどもできるので忘れずに。
EventBridgeスケジューラを使ってEC2の定期起動/停止を行う方法 | DevelopersIO
スペックの最適化
使用リソースに基づいて各インスタンスのスペックを決めましょう。え?難しい?「AWS Compute Optimizer」に任せましょう。いい感じにしてくれます。 このサービスメモリをデフォルトで見てくれないの改善しないかなぁ。。 古いインスタンスタイプを使用している場合は、最新の同じインスタンススペックに変更するだけで安くなります。 ECSのスペック決めは課題が残る。。
お金のかかる不要リソース削除
「Elastic IP」「ELB」検証だけで立てたものがそのまま残ってる場合が多々あります。こまめに削除しましょう。 Elastic IPも1つづつ課金させるようになってるので注意です。
スナップショットなど数年前に作成したもの残ってないですか?そんなもので今リソースを再構築することないので消しましょう。
ここまでは即効性のある対策。ここからはちょっと手間がかかるかも。
ECSログの吐き出し先
ECSからログの出し方はいくつかありますが一番シンプルで楽なのがCloudwatch logsに出す方法です。しかしログの量によってはとてつもない費用がかかるのがCloudwatch logs。
保管費用もよりも吐き出したときにかかる費用が高いです。東京リージョンでUSD0.76/GBもかかります。
Cloudwatch logsはログ監視もできて便利ですが吐き出すログは取捨選択しましょう。
おすすめはエラーログだけCloudwatch logsに出してそれ以外はS3に放り投げる。
Cloudwatch のメトリクス設定しすぎない
Cloudwatchの監視は標準メトリクスの他にカスタムメトリクスを作って監視項目を設定できます(メモリ監視みたいなの)
カスタムメトリクスの場合無料枠が10個まででそれ以上は監視するたびに費用が発生します。何も考えずにあれこれと数字だけ取ることを目的とした設定をしていると合算したとき高くつくときがあります。ある程度まとまらないとわからない点など注意です。 監視が必要な値に絞りましょう。
まとめ
もともと高いサービスは注意が行きやすいけど、合算したとき人知れず高くなるものは注意が必要ですね。
円安な今気をつけましょう。。
Akamai構成のKeepAlive設定を決めた
AkamaiCDNが前段にあるシステムで後ろに控えるALBやApacheのKeepAlive設定を検証しました。
さらには先日リリースされた以下機能でALBに追加された項目を確認。
項目名は以下の2つが関連する。
「Connection idle timeout」
「HTTP client keepalive duration」
項目の意味合いとしはこんな感じ
実際にはどのような挙動になるのかを確認する
Connection idle timeout
ClientとTargetに対してidle状態(無通信状態)でコネクションを保持する時間
HTTP client keepalive duration
Clientに対してのkeepalive時間
(この時間だけはなにがあろうとコネクションを残しておくということ)
確認手順
ALBに対してtelnetでアクセス
telnet test-local-frt-alb01-1038675640.ap-northeast-1.elb.amazonaws.com 80
telnet test-local-frt-alb01-1038675640.ap-northeast-1.elb.amazonaws.com 80 Trying 54.95.144.247... Connected to test-local-frt-alb01-1038675640.ap-northeast-1.elb.amazonaws.com. Escape character is '^]'. GET / HTTP/1.1 ←入力 Host: localhost ←入力 ←エンター入力 HTTP/1.1 200 OK Date: Tue, 09 Apr 2024 01:26:24 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 12 Connection: keep-alive Server: Apache/2.4.58 (Amazon Linux) Last-Modified: Mon, 08 Apr 2024 09:24:32 GMT ETag: "c-615925f82a5c5" Accept-Ranges: bytes test server
「test server」の表示でるとHTTPアクセス成功
「Connection closed by foreign host.」 の表示が出るまでは同じコネクションで通信していることになる
設定値は以下

確認1
初回アクセスから20秒放置すると「Connection closed by foreign host.」が出力されて切断
確認2
初回アクセスから60秒放置しても切断されず。 120秒放置すると「Connection closed by foreign host.」が出力されて切断
60秒以降120秒までの間にアクセスするとステータス成功した後「Connection closed by foreign host.」が出力されて切断
結果
「Connection idle timeout」は強制的に切断される
「HTTP client keepalive duration」は強制切断はされない
Apache側のkeepaliv値により違いはクライアント側の挙動では確認できず。
ただしALB-Apache間ではコネクションの切断再接続は起きていると想像。
(パケットキャプチャーなどでみると都度都度コネクションの張り直しが発生しているはず)
Akamai含めての設定値

セオリーとしては前段システムのkeepaliveは長く、後ろは短く。
後ろが長いと後ろ側だけ成功してて前には失敗が返ってしまう可能性があるため。
今回はAkamaiでの処理を最優先で発揮させるためにakamai-alb間のコネクションを最大限つなげる
ALBでのHTTPステータスコードとTargetでのHTTPステータスコードを監視しておくことでkeepaliveによる返り値の違いを把握できる。
Organizationsな組織アカウントでCloudwatchグラフを共有したいときにできなかったこと
やりたいこと
モニタリングアカウントを用意して監視を集約したい。 Cloudwatchグラフを作成してモニタリングアカウント経由で組織アカウントのだれでもサクッと見れるようにしたい。
やり方
具体的な設定方法はよくあるものなので以下とか参考に
[Organizations]CloudWatchを別アカウントに共有する際にOrganization account selectorを使ってみた | DevelopersIO
なにができないの?
この設定をしたときに設定したアカウント以外から見たときにグラフの選択肢が出てこなかったのです。
具体的にはここ

他のアカウントからはアカウントの一覧を選択する欄が表示されなかった。
原因
モニタリングアカウントのCloudwatch設定で「アカウントセレクタを有効化」する項目がデフォルトだと何も選択されいない状態だったため
でもこれ設定したアカウントで有効化したんですよ。
どうやらこれはログインしているアカウントユーザー毎の設定でした。 (サポート確認済み)
だから各ユーザー毎に有効化しないといけないです。
どうしたのか
理想としては各ユーザー毎の作業必要なく見れるのがベストです。(無用な問い合わせを避けるためにも)
各アカウントでパブリックなcloudwatchダッシュボード作成して展開するのが無難かなと考え中。
Amazonlinux2023にTeratermから接続できなかった話
謎が溶けました。
弊社環境ではサーバなど構築した際、秘密鍵を作成して開発担当者やチーム内で連携するのですがとある担当者が作成したキーだけ 他のモノが使えない事象が出ていました。
キーを間違えてるのか、キーが壊れているのかなど思ってたのですが作成した担当者は使えてるようです。
ほんとに同じキー?とおもって見てみると作成者は使えて、他の者は使えないキーは同じでした。
弊社の作業PCはwindowsとMACがいます。作成者はMACです。windowsのSSHクライアントはteraterm使ってます。
作成したサーバはAmazonlinux2023です。
そうですね。
原因
Amazonlinux2023の秘密鍵の違いでした。
Amazonlinux2023では「SSH-RSAが無効化」されているためです。 そして新規で「rsa-sha2-256」「rsa-sha2-512」が有効化されています。
teratearm4.0系ではこの無効化されたものを使います。 teratearm5.0系では新規で追加されたものが使えます。
解決策
teratearm5.0に変更
teraterm4.0でも接続できるようにすることはできるがセキュリティ上古いものを有効化する必要がある。 わざわざすることも無いので新しいものに切り替え。
新しいは正義
Zabbix_AgentがAllowRoot=1でrootになれないときに
Zabbxiでログ監視をするときはrootにならないといけないときありますよね。 (ならなくてもいいときもある)
zabbix_agent.confで
AllowRoot=1
としてもAgentがroot実行されずハマりました。