メールサーバ_DNS関連の学習記録②_SMTPサーバ構築

# SMTP AUTHとは？
メールを送信する際、メールサーバーに「自分が正しい利用者である」ことを証明するための仕組み。
メールを送信する際に利用者の認証を行う。
簡単に言えば、「メールを送る前に、送信者が正しい利用者かどうかを確認する手続きをする。
メールソフト（例：Gmail、Outlook、Thunderbird）を使ってメールを送るとき、ユーザー名とパスワードを使って認証するのがSMTP AUTH。

## なぜSMTP AUTHが必要なのか？
そもそもSMTPは、認証を必要とせず誰でも使えるプロトコルでした。しかし、これには大きな問題があり誰でも自由にメールを送信できるため、不正利用やスパム（迷惑メール）が発生しやすかった問題があった。

SMTP AUTHが導入される前は、例えば悪意のある人が他人のメールアドレスを使ってなりすましメールを送ることも可能で認証がないことで、サーバーを不正に使って大量の迷惑メールを送信することも容易にできていた背景がある。これらの背景がありSMTP AUTHが導入されるようになった。


## SMTP AUTHの流れは下記の4点となる。

①メールを送信：ユーザーがメールソフトでメールを作成し、送信ボタンを押します。
②認証を要求：メールソフトは、送信者が正しい利用者であるかを確認するため、SMTPサーバーにユーザー名とパスワードを送ります。
③認証の確認：SMTPサーバーは、送られてきたユーザー名とパスワードを確認し、正しければメールの送信を許可します。
④メールの送信：認証が成功すれば、SMTPサーバーは受信者のサーバーにメールを送ります。

## SMTP AUTHの主な認証方式
SMTP AUTHにはいくつかの認証方式がある。ここでは、特によく使われる3つの方式について解説する。

## PLAIN（プレーン）認証
PLAIN認証は、最も基本的な認証方式です。この方式では、ユーザー名とパスワードが**平文（暗号化されていない状態）**でサーバーに送信される。
これには、セキュリティ上の大きなリスクがあり、もし悪意のある第三者が通信を傍受してしまうと、ユーザー名とパスワードがそのまま盗まれてしまう可能性があるため、現在ではあまり使われなくなっている。

しかしSSL/TLSという暗号化技術と併用することで、このリスクを軽減できる。SSL/TLSを使えば、データは暗号化されて送信されるため、実質的に安全に利用することが可能である。

## LOGIN認証
LOGIN認証は、PLAIN認証に似ていますがユーザー名とパスワードを分割して送信する。
まず、ユーザー名をサーバーに送信し、次にパスワードを送る。これも暗号化がされていないとセキュリティリスクがあるが、SSL/TLSを使うことで通信を安全に保護できる。

例えば、次のような流れで認証が行われる。

①サーバーが「ユーザー名を送ってください」と要求する。
②ユーザーがユーザー名を送信する。
③サーバーが「パスワードを送ってください」と要求する。
④ユーザーがパスワードを送信し、認証が行われる。

## CRAM-MD5認証
この方式では、ユーザー名とパスワードが直接サーバーに送信されるのではなく、ハッシュ値（暗号化された形式）として送られる。サーバー側では、このハッシュ値を使って正しいパスワードかどうかを確認します。

CRAM-MD5では、サーバーが「チャレンジコード」と呼ばれるランダムな文字列をクライアント（メールソフト）に送信し、クライアントはそのチャレンジコードとパスワードを組み合わせたハッシュ値をサーバーに返す。これにより、パスワードが暗号化されて送信されるため、セキュリティ性のあるメール送信ができる。

実際のCRAM-MD5認証の例として下記のような認証が行われる。

①メール送信準備
　user@example.com から friend@example.net にメールを送るため、ユーザーがメールソフトでメールを作成し、「送信」ボタンを押す。

②SMTPサーバーとの通信（認証の開始）
　メールソフトがSMTPサーバー（例：smtp.example.com）に接続する。
　サーバーは、ユーザーが正当な利用者であるかを確認するため、クライアントに「チャレンジコード」を送信する。このコードは一時的なランダムな文字列。

③チャレンジレスポンスの送信:
　メールソフトは、受け取ったチャレンジコードとユーザーのパスワードを組み合わせて暗号化（ハッシュ化）したレスポンスをSMTPサーバーに送る。
　これにより、パスワードそのものが通信中に盗まれるリスクを軽減できる。

④認証成功
　SMTPサーバーは、受け取ったレスポンスが正しいかどうかを確認する。ユーザー名とハッシュ値を検証し、正しければ「認証成功」となり、メール送信が許可される。

そのほかSMTP認証方式にはサブミッションポートという方法やSCRAM-SHA-1認証方式もある。
・サブミッションポート：メールクライアントからプロバイダを経由する際に25番ポートをブロックしておき587番ポートを通過するように設定する
・SCRAM-SHA-1認証方式：サーバー側に平文のパスワードを保存しない、MD5の場合は使用する必要がある。MD5よりも安全なハッシュアルゴリズムを使用、ソルトを使用する
　※ソルト(salt)は元データ(文字列)に任意の文字列を加えてハッシュ化する手法


# SMTPサーバーの構築
WindowsだとPuTTYを起動し、Host Name に EC2 インスタンスのパブリックIPまたはDNS名を入力する。
Portは22（デフォルトでSSH）に設定する。
左のメニューから「SSH」→「Auth」をクリックし、Private key file for authenticationに先ほど作成した.ppkファイルを指定する。
再び「Session」メニューに戻り、「Open」をクリックする。
接続成功後、ec2-user（または使用するAMIに応じたユーザー名）を入力する。
```
Unable to use key file "C:\Users\user\●●●.ppk" (unable to open file)
login as: ec2-user
Authenticating with public key "imported-openssh-key" from agent

A newer release of "Amazon Linux" is available.
  Version 2023.5.20240722:
  Version 2023.5.20240730:
  Version 2023.5.20240805:
  Version 2023.5.20240819:
  Version 2023.5.20240903:
  Version 2023.5.20240916:
Run "/usr/bin/dnf check-release-update" for full release and version update info
   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'
Last login: Mon Sep  2 23:38:35 2024 from ●●●.●●●.●●●.●●●
```
postfixをインストールする。
```
[ec2-user@ip-●●-●-●●-●● ~]$ sudo apt update
sudo: apt: command not found
[ec2-user@ip-●●-●-●●-●● ~]$ sudo apt install postfix
sudo: apt: command not found
```
sudo: apt: command not found という
エラーメッセージが出た場合、
これは apt コマンドが利用できないことを示す。

このエラーが発生する原因は、
使用しているLinuxディストリビューションが
Debian系（Ubuntuなど）ではなく、
Red Hat系（CentOS、RHELなど）である可能性がある。
Red Hat系ではパッケージ管理システムとして
yum または dnf を使用する。
ほとんどのLinuxディストリビューション（Ubuntu、Debian、CentOSなど）では、Bashが標準のシェルである。
ターミナルを開いて次のコマンドを入力して、現在のシェルがBashであるか確認する。
インストール済みなのかを確認する。
```
[ec2-user@ip-●●-●-●●-●● ~]$ echo $SHELL
/bin/bash
[ec2-user@ip-●●-●-●●-●● ~]$ which bash
/usr/bin/bash

[ec2-user@ip-●●-●-●●-●● ~]$ sudo yum install bash
Last metadata expiration check: 0:13:17 ago on Fri Sep 20 22:39:31 2024.
Package bash-5.2.15-1.amzn2023.0.2.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!
[ec2-user@ip-●●-●-●●-●● ~]$ sudo yum install postfix
Last metadata expiration check: 0:14:58 ago on Fri Sep 20 22:39:31 2024.
Dependencies resolved.
================================================================================
 Package      Arch        Version                        Repository        Size
================================================================================
Installing:
 postfix      x86_64      2:3.7.2-4.amzn2023.0.5         amazonlinux      1.5 M
Installing dependencies:
 libicu       x86_64      67.1-7.amzn2023.0.3            amazonlinux      9.6 M

Transaction Summary
================================================================================
Install  2 Packages

Total download size: 11 M
Installed size: 37 M
Is this ok [y/N]: y
Downloading Packages:
(1/2): postfix-3.7.2-4.amzn2023.0.5.x86_64.rpm   12 MB/s | 1.5 MB     00:00
(2/2): libicu-67.1-7.amzn2023.0.3.x86_64.rpm     44 MB/s | 9.6 MB     00:00
・
・
・
    Release notes:
     https://docs.aws.amazon.com/linux/al2023/release-notes/relnotes-2023.5.20240916.html

================================================================================
Installed:
  libicu-67.1-7.amzn2023.0.3.x86_64    postfix-2:3.7.2-4.amzn2023.0.5.x86_64
Complete!

```
Postfixの設定ファイルは通常、/etc/postfix/main.cf にある。このファイルをテキストエディタで編集する。
```
[ec2-user@ip-●●-●-●●-●● ~]$sudo nano /etc/postfix/main.cf
# http://www.postfix.org/BASIC_CONFIGURATION_README.html etc.
#
# For best results, change no more than 2-3 parameters at a time,
# and test if Postfix still works after every change.

# COMPATIBILITY
#
# The compatibility_level determines what default settings Postfix
# will use for main.cf and master.cf settings. These defaults will
# change over time.
#
# To avoid breaking things, Postfix will use backwards-compatible
# default settings and log where it uses those old backwards-compatible
# default settings, until the system administrator has determined
# if any backwards-compatible default settings need to be made
# permanent in main.cf or master.cf.
#
# When this review is complete, update the compatibility_level setting
# below as recommended in the RELEASE_NOTES file.
#

・
・
・

# INTERNET HOST AND DOMAIN NAMES
#
# The myhostname parameter specifies the internet hostname of this
# mail system. The default is to use the fully-qualified domain name
# from gethostname(). $myhostname is used as a default value for many
# other configuration parameters.
#
#myhostname = mail.example.com
#myhostname = virtual.domain.tld

・
・
・

# The mydomain parameter specifies the local internet domain name.
# The default is to use $myhostname minus the first component.
# $mydomain is used as a default value for many other configuration
# parameters.
#
#mydomain = mail.example.com
# SENDING MAIL

^G Help      ^O Write Out ^W Where Is  ^K Cut       ^T Execute   ^C Location
^X Exit      ^R Read File ^\ Replace   ^U Paste     ^J Justify   ^/ Go To Line
```

設定を保存する。
```
[ec2-user@ip-●●-●-●●-●● ~]$ sudo systemctl restart postfix
[ec2-user@ip-●●-●-●●-●● ~]$ 
```
ファイアウォールでポート25（SMTPのポート）を許可する必要がある。Ubuntuでのファイアウォール設定は以下のコマンドで行う
```
[ec2-user@ip-●●-●-●●-●● ~]$sudo ufw allow Postfix
[ec2-user@ip-●●-●-●●-●● ~]$sudo ufw reload
```
これで外部からのメールの送受信が可能になる。
firewalld をインストールする
```
[ec2-user@ip-●●-●-●●-●● ~]$ sudo yum install firewalld

Last metadata expiration check: 1 day, 2:10:24 ago on Fri Sep 20 22:39:31 2024.
Dependencies resolved.
================================================================================
 Package                     Arch   Version                   Repository   Size
================================================================================
Installing:
 firewalld                   noarch 1.2.3-1.amzn2023          amazonlinux 452 k
Installing dependencies:
 firewalld-filesystem        noarch 1.2.3-1.amzn2023          amazonlinux  11 k

・
・
・

  python3-gobject-base-3.42.2-2.amzn2023.0.3.x86_64
  python3-gobject-base-noarch-3.42.2-2.amzn2023.0.3.noarch
  python3-nftables-1:1.0.4-3.amzn2023.0.2.x86_64

Complete!

[ec2-user@ip-●●-●-●●-●● ~]sudo systemctl start firewalld
```

Postfixを使ってメールを送受信するには、SMTPポート（25番ポート）を開放する必要がある。
```
[ec2-user@ip-●●-●-●●-●● ~]$sudo firewall-cmd --permanent --add-service=smtp
success
[ec2-user@ip-●●-●-●●-●● ~]$
```
その後、ファイアウォールを再読み込みする。
```
[ec2-user@ip-●●-●-●●-●● ~]$ sudo firewall-cmd --reload
success
設定を終えたら、Postfixを再起動して設定を反映する。
[ec2-user@ip-●●-●-●●-●● ~]$ sudo systemctl restart postfix
[ec2-user@ip-●●-●-●●-●● ~]$ telnet localhost 25
-bash: telnet: command not found
telnetコマンドがシステムにインストールされていないのでインストールする。
[ec2-user@ip-●●-●-●●-●● ~]$ sudo yum install telnet
Last metadata expiration check: 1 day, 2:29:33 ago on Fri Sep 20 22:39:31 2024.
Dependencies resolved.
================================================================================
 Package      Architecture Version                      Repository         Size
================================================================================
Installing:
 telnet       x86_64       1:0.17-83.amzn2023.0.2       amazonlinux        64 k

Transaction Summary
================================================================================
Install  1 Package

Total download size: 64 k
Installed size: 121 k
Is this ok [y/N]: y
Downloading Packages:
telnet-0.17-83.amzn2023.0.2.x86_64.rpm          1.1 MB/s |  64 kB     00:00
---------------------------
Total                                           620 kB/s |  64 kB     00:00

・
・
・

Installed:
  telnet-1:0.17-83.amzn2023.0.2.x86_64

Complete!
[ec2-user@ip-●●-●-●●-●● ~]$
```
正常に動作しているか確認する
```
[ec2-user@ip-●●-●-●●-●● ~]$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 ip-●●-●-●●-●●.ap-northeast-1.compute.internal ESMTP Postfix
500 5.5.2 Error: bad syntax
```
正常に動作していることを確認。
しかし500 5.5.2 Error: bad syntaxなるものが出てきた。
220 mail.example.com ESMTP Postfix の応答が表示された場合、
Postfixがポート25で正常に動作していることが確認できている。

次に 500 5.5.2 Error: bad syntax が表示されるのは、
SMTPサーバーが期待している正しいSMTPコマンドを送信しなかったため。
Telnetセッションでは、SMTPプロトコルに従ってコマンドを入力する必要がある。
下記の流れで進めていく。

①HELO コマンドでサーバーに自身を紹介する。
②MAIL FROMコマンドで送信者を指定する。
③RCPT TOコマンドで受信者を指定する。
④DATAコマンドでメールの内容を入力する。
　その次にSubjectを入力し改行して
⑤本文を入力する。「.」を入力してエンターキーを押して送信する。

```
[ec2-user@ip-●●-●-●●-●● ~]$
[ec2-user@ip-●●-●-●●-●● ~]$ HELO example.com
-bash: HELO: command not found
[ec2-user@ip-●●-●-●●-●● ~]$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 ip-●●-●-●●-●●.ap-northeast-1.compute.internal ESMTP Postfix

HELO example.com
250 ip-●●-●-●●-●●.ap-northeast-1.compute.internal
MAIL FROM:mail.enample.com
250 2.1.0 Ok
RCPT TO :●●●●@gmail.com
501 5.5.4 Syntax: RCPT TO:<address>
RCPT TO:●●●●@gmail.com
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
Subject: Test Email
This is a test email.
Here is another line of the email body.
.
250 2.0.0 Ok: queued as C43C497DEF5
```