ConoHa VPS で サーバ構築

ConoHa VPS 上の Ubuntu 22.4 に Webサーバ と メールサーバ を構築する方法について述べます。
またそれに伴い、ドメインの移行、SSH公開鍵認証、SSL証明書の取得などについても述べます。

ここでは、ConoHaでのサーバ追加時(VPS契約時) に Ubuntu 22.4を選択したものとしています。

お名前.comでドメインを取得する

お名前.comから好きなドメインを取得します。

もちろん、どこで取得してもよいのですが、お名前.comでドメインを取得したものとして進めます。

おすすめなのは .work ドメインです(安いので)。

その他のドメインは、初年度だけ安いドメインが多く、翌年以降値段が跳ね上がることが多いので注意が必要です。 1年近く使った愛着あるドメインを手放すのは悲しいですよね。
今のところ、.workドメインは安定して安いのでお勧めです。

お名前.com で取得したドメインを ConoHa VPS で使えるようにする

お名前.comで取得したドメインはお名前.comのネームサーバとDNSゾーン情報が使われています(当然ですが)。
このままではConoHa VPS から割り当てられたグローバルIPアドレスを、取得したドメインに自動で紐づけることができません。
よって、お名前.com の DNS から ConoHa の DNS に 変更します。

ConoHa VPS にドメインを追加する

ConoHa のコンソール画面で DNS を選んでドメインリスト画面をだし、追加したいドメインを記述します。
(ここでは benkyou.work としています)

まずは自身に割り当てられているIPアドレスが何かを確認します。
(ConoHa VPS を契約するとグローバルIPアドレスが1つ割り当てられます)

メニューの「サーバー」をクリックしてサーバーリストを表示。ネームタグのところのリンクをクリックするとサーバーの詳細画面に進み、そこにIPアドレスなど表示されているのでメモしておきます。
タイトル

次にドメイン設定を行います。
①DNSをクリックしてドメインリスト画面を表示し、ドメインを追加します
タイトル

②右側のペンマークをクリックし、
タイトル

③Aレコードを追加。この時、丸のところに自身に割り当てられてるグローバルIPアドレスを入力します
タイトル

これで、ConoHa側の設定は終了です。

お名前.com のネームサーバ を ConoHa のネームサーバに変更する

次にお名前.comにログインして、メニューからネームサーバの設定を選び、他のネームサーバを利用のラジオボタンにチェックを入れ、ConoHaのネームサーバに置き換えます。
ConoHaのネームサーバーは以下の通りです。

ns-a1.conoha.io
ns-a2.conoha.io
ns-a3.conoha.io

タイトル

以上でDNS情報がお名前.comからConoHaに変更されました。
少し時間をおいてから ping で正しくIPアドレスが返却されることを確認しましょう。

一般ユーザの作成

ConoHa の初期設定で root のパスワードを設定したと思いますが、そのパスワードで ssh ログインが可能です。
が、セキュリティ的にあんまりよくないですよね。パスワードのブルートフォースアタックの標的になりそうです。
一般ユーザを作りrootではsshログインできないようにすれば、少なくともその一般ユーザのアカウントを知らなければ外部からブルートフォースアタックなんてしようがないので、その分、セキュリティ的に堅固になります。
そして root ではログインできないようにする設定は以下の 公開鍵認証を用いたSSH接続の設定 でまとめて行います。

adduserでユーザを追加し、sudoが使えるようにするためにgpasswdコマンドを実行します。
(gpasswdしないとsudoしたときにエラーになります)

# adduser 一般ユーザー名
# gpasswd -a 一般ユーザー名 sudo

これで一般ユーザができました。以降はこのユーザーでsshログインして作業します。

ファイヤーウォールの設定

これから構築するWebサーバやメールサーバ用にポートを開けます。

気を付けないといけないのが、ファイヤーウォールを有効にしたタイミングですべてのポートが「閉じる」ことです。
なので有効にした後、開ける設定をする前に間違ってターミナルを閉じてしまったりしたらもうアウトなのでドキドキしながら作業しましょう。(とかいいつつも実際はConoHaのコンソールからは常に入れるので何とかなりますが)

$ sudo ufw enable

これですべてのポートへのアクセスが遮断されました。

で、以下をオープンします。

sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw allow smtp
sudo ufw allow smtps
sudo ufw allow pop3
sudo ufw allow pop3s
sudo ufw allow imap
sudo ufw allow imaps
sudo ufw allow postfix
sudo ufw allow submission

これにより、ssh、http、https、smtp、smtps、pop3、pop3s、imap、imaps、postfix、submission の wellknown port がオープンされました。
wellknown port じゃないポートを俺は使う!という方は数字を直接指定すればよいです。

例えば ssh の 22 番なんてクラッキングでもっともよくねらわれるポート番号なので、sshは12345とか別のポート番号でやる!という人はsshの設定を22から12345に変えた後、

sudo ufw allow 12345
sudo ufw deny ssh

とすれば12345ポートがオープンされssh(22)がふさがります。

sshサーバ、webサーバ、mailサーバを作るのであればとりあえずはこれでOKです。
ftpなりntpなり追加したいならその都度 allow しないといけません。

確認は、

$ sudo ufw status

でできます。

公開鍵認証を用いたSSH接続の設定

まずは秘密鍵/公開鍵を作ります。

昔はLinuxじゃないと作るの面倒だったのですが、Windows 10にはデフォルトで ssh-keygen.exe というカギを作るアプリが入っているのでらくちんになりました。

もし、C:\Users\(ユーザー名)\.sshディレクトリディレクトリがなかったら先に作っておきましょう。
以下はあるものとしています。また、ユーザー名はuserとしています。

C:>cd C:\Users\user\.ssh
C:\Users\user\.ssh>ssh-keygen.exe -t ecdsa -f id_ecdsa
Generating public/private ecdsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_ecdsa.
Your public key has been saved in id_ecdsa.pub.
The key fingerprint is:
SHA256:aw1tA6FhRQ2aFgnfzz/qWLu8sCLnX+ukMgbVdzxpJmg user@MSI
The key's randomart image is:
+---[ECDSA 256]---+
|      ..++=o     |
|       o.B ..    |
|        *.o. . . |
|       .. E=o B  |
|       .S...*= . |
|      .  . = o   |
|       .  + = o  |
|      . *  X + . |
|       =.==oXo   |
+----[SHA256]-----+

C:\Users\user\.ssh>

これで、C:\Users\user\.sshディレクトリ配下に、
id_ecdsa
id_ecdsa.pub
という2つのファイルができたはずです。

pubとついているほうが公開鍵なのでこれを接続先のサーバーに送ります。
(sftpなりなんなりでアップロードしましょう)

サーバ側で、以下のコマンドを実行します。(公開鍵ファイル:id_ecdsa.pubは ~/.ssh配下にアップロードしたものとしています)

$ cd ~/.ssh
$ cat id_ecdsa.pub >> authorized_keys
$ chmod 600 authorized_keys

これでOKです。

ついでにですが、もう、パスワードでログインできないようにしましょう。

$ sudo vi /etc/ssh/sshd_config

#PasswordAuthentication yes
->
PasswordAuthentication no

さらについでに、rootでのログインは拒否するようにしましょう。

PermitRootLogin yes
->
PermitRootLogin no

sshサーバをリスタートしたらOKです。

$ sudo systemctl restart ssh

Windows側(クライアント側)は pubとついていないほうの秘密鍵ファイル(id_ecdsa)をssh接続に利用するソフトに設定します。

例えばrloginだったら Server New Entry 画面の右下に SSH認証鍵(K)というボタンがあるので押下し、秘密鍵ファイルを選択すればOKです。
(パスワードは秘密鍵を作った時のパスワード)

これで公開鍵認証を用いたSSH接続になります。
パスワード接続をふさいでいるので、秘密鍵ファイルをもっていないとアクセスできず、外部からのハッキングはほぼ不可能でしょう。
(秘密鍵ファイル盗まれたらダメだけどその時点で終わっとる)

Let's Encrypt で SSL証明書の作成

これ、次のWebサーバの構築でApacheの設定をするときに一緒につくります。
ApacheとLet's Encryptが組んでるのか、いい感じのコマンドを用意してくれています。

Webサーバの構築

Apacheをインストールして起動します。

$ sudo apt update -y
$ sudo apt upgrade -y
$ sudo apt install -y apache2

$ sudo a2enmod ssl
$ sudo a2ensite default-ssl

$ sudo systemctl enable apache2

設定ファイルのサーバー名を変更しましょう。
ここではドメイン名は benkyou.work とし、以下、それとして記述していきます。

$ sudo vi /etc/apache2/sites-available/000-default.conf

#ServerName www.example.com
->
ServerName benkyou.work
$ sudo systemctl start  apache2

これで、Webサーバが立ち上がりました。 https://benkyou.work/ にアクセスできることを確認しましょう。

で、アクセスはできたのですが、 "この接続ではプライバシーが保護されません" と表示されますね。
それは証明書が偽物だからです。

Let's Encrypt で SSL証明書 を 作成して Apache の設定ファイルに設定しましょう。
そのための専用パッケージ(python3-certbot-apache)を入れる必要があります。

$ sudo apt install -y certbot python3-certbot-apache

以下のコマンドを実行すると適切なSSL証明書ができてかつApacheの適切なフォルダに格納されます。

$ sudo certbot --apache

いろいろ問い合わせがされますが、Yと答えておけばいいのですが、気を付けないといけないのは、

Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.

これ、Yにするとメールをシェアするとかなんか恐ろしいことが書かれているので、Nにしましょう。

これで証明書ができてかつ適切なフォルダに格納されましたのでApacheを再起動します。

$ sudo systemctl restart apache2

再度、 https://benkyou.work/ にアクセスしても、もう証明書の警告はでないはずです。

メールサーバの構築

Postfix と Dovecot を入れます。

なぜ2つ、と思われるかもしれませんが、Postfix はメールの送信にかかわるサーバになります。
Dovecotは受信にかかわるサーバです。

なので2つ必要なのですね。
Sendmailというサーバは一つで両方やってくれます。いろいろなメールサーバがありますが、ここでは、Postfix と Dovecot を用います。

なお、SSL証明書が必要なのですが、Apacheで作った証明書をそのまま流用します。

上から順番に作業していたら、以下の場所にできているはずです。

/etc/letsencrypt/live/benkyou.work/fullchain.pem
/etc/letsencrypt/live/benkyou.work/privkey.pem

Postfixサーバの構築

まず Postfix をインストールしてサービスを有効にします。

$ sudo apt update -y
$ sudo apt install -y postfix
$ sudo systemctl enable postfix
$ sudo systemctl restart postfix

いっぱい書き換えるところがあるので大変ですが、頑張りましょう。
なお、benkyou.workと書かれているところは当然ですがあなたのドメインにしてください。

main.cfのベースとして用意されている /usr/share/postfix/main.cf.dist を /etc/postfix/main.cf にコピーして編集していきます。

$ sudo cp /usr/share/postfix/main.cf.dist /etc/postfix/main.cf
$ sudo vi /etc/postfix/main.cf
myhostname                   = benkyou.work
mydomain                     = benkyou.work
myorigin                     = $mydomain
mydestination                = $myhostname, benkyou.work, localhost.localdomain, localhost
inet_interfaces              = all
home_mailbox                 = Maildir/
smtpd_banner                 = $myhostname ESMTP
local_recipient_maps         = unix:passwd.byname $alias_maps

mailbox_size_limit           = 0
message_size_limit           = 102400000

disable_vrfy_command         = yes
smtpd_helo_required          = yes
smtpd_sender_restrictions    = reject_non_fqdn_sender, reject_unknown_sender_domain

smtpd_sasl_auth_enable       = yes
smtpd_sasl_security_options  = noanonymous
broken_sasl_auth_clients     = yes
smtpd_sasl_local_domain      = $myhostname
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth

smtpd_tls_cert_file=/etc/letsencrypt/live/benkyou.work/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/benkyou.work/privkey.pem
smtpd_use_tls=yes
smtpd_tls_session_cache_database=btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database =btree:${data_directory}/smtp_scache

あと、 = で終わってるパラメータはそのままにしておくとエラーになるのでコメントアウトします。
(main.cf.distの時点でコメントアウトしておいてほしいのですが(笑))

#sendmail_path =
#newaliases_path =
#mailq_path =
#setgid_group =
#html_directory =
#manpage_directory =
#sample_directory =
#readme_directory =

再起動して、

$ sudo systemctl restart postfix

これでPostfix側の設定は「いったん」終了です。

Dovecotサーバの構築

Postfixよりも変更箇所が多くて大変なDovecotサーバの構築をしましょう。

Dovecotをインストールしてサービスを有効にします。

$ sudo apt install -y dovecot-core dovecot-imapd dovecot-pop3d
$ sudo systemctl enable dovecot
$ sudo systemctl restart dovecot

設定ファイルを更新しますが、まずは念のためまるごとバックアップしておきましょう。

$ mkdir ~/conf_bak/etc/dovecot
$ sudo cp -rf /etc/dovecot/* ~/conf_bak/etc/dovecot/

では、変更です。

■dovecot.conf

$ sudo vi /etc/dovecot/dovecot.conf 

# listen = *, ::
->
listen = *, ::

■10-auth.conf

$ sudo vi /etc/dovecot/conf.d/10-auth.conf

#disable_plaintext_auth = yes
->
disable_plaintext_auth = no

#auth_mechanisms = plain
->
auth_mechanisms = plain login

■10-mail.conf

$ sudo vi /etc/dovecot/conf.d/10-mail.conf

#mail_location = mbox:~/mail:INBOX=/var/mail/%u
->
mail_location = maildir:~/Maildir

■10-ssl.conf

$  sudo vi /etc/dovecot/conf.d/10-ssl.conf

ssl = require
->
ssl = yes

ssl_cert = </etc/dovecot/private/dovecot.pem
->
ssl_cert = </etc/letsencrypt/live/benkyou.work/fullchain.pem

ssl_key = </etc/dovecot/private/dovecot.key
->
ssl_key = </etc/letsencrypt/live/benkyou.work/privkey.pem

■10-master.conf

$ sudo vi /etc/dovecot/conf.d/10-master.conf 

#unix_listener /var/spool/postfix/private/auth {
#    mode = 0666
#}
->
unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
}

inet_listener imap {
    #port = 143
}
inet_listener imaps {
    #port = 993
    #ssl = yes
}
->
inet_listener imap {
    port = 143
}
inet_listener imaps {
    port = 993
    ssl = yes
}

service pop3-login {
    inet_listener pop3 {
        #port = 110
    }
    inet_listener pop3s {
        #port = 995
        #ssl = yes
    }
}
->
service pop3-login {
    inet_listener pop3 {
        port = 110
    }
    inet_listener pop3s {
        port = 995
        ssl = yes
    }
}

service submission-login {
    inet_listener submission {
        #port = 587
    }
}
->
service submission-login {
    inet_listener submission {
      port = 587
    }
}

以上で Dovecot の設定は終了です。再起動しましょう。

sudo systemctl restart postfix dovecot

OP25B 対応

OP25Bというのを聞いたことがありますでしょうか?
あなたのSMTPサーバを踏み台にしてスパムとかをばらまいたりすることです。
いろんな人に迷惑をかけるので知らなかったではすみません。
自身のメールサーバーが不正中継の踏み台に使われないように設定をしましょう。

master.cf の submissionの行(の1行目だけ)をコメントアウトします。

$ sudo vi /etc/postfix/master.cf

# submission inet n       -       n       -       -       smtpd
->
submission inet n       -       n       -       -       smtpd

再起動して設定を反映させます。

sudo systemctl restart postfix dovecot

SMTP over SSL用対応

メールを暗号化させるための手順です。
変更箇所が面倒なので注意して変更しましょう。

$ sudo vi /etc/postfix/master.cf

#smtps     inet  n       -       y       -       -       smtpd
#  -o syslog_name=postfix/smtps
#  -o smtpd_tls_wrappermode=yes
#  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_reject_unlisted_recipient=no
#  -o smtpd_client_restrictions=$mua_client_restrictions
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
#  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING

->

smtps     inet  n       -       y       -       -       smtpd
#  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_reject_unlisted_recipient=no
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
#  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

基本はコメントアウトですが、

#  -o smtpd_client_restrictions=$mua_client_restrictions

はただのコメントアウトではなく、

  -o smtpd_client_restrictions=permit_sasl_authenticated,reject

としなければならないので注意しましょう。

再起動して設定を反映させます。

sudo systemctl restart postfix dovecot

これでメールサーバの設定は完了です。

が、メールのユーザーがいませんので作りましょう。

メールアカウントの追加

ここでは このサイトの管理人となる webmaster (名前なんでもいい) を追加します。

sudo adduser webmaster

...メールアカウントの追加とか言いつつ、ただのユーザー追加ですね。

そうなんです。unixのアカウントを追加すればよいだけなんです(というかそうなるように設定した)
ユーザー追加したら再起動しないと設定が反映されませんのでサーバーを再起動しましょう。

sudo systemctl restart postfix dovecot

これでwebmaster @ benkyou.workが使えるようになりました。

実際にThunderBirdなどに設定してメールの送受信を確認しましょう。

以上です。お疲れ様でした。

2023/09/04 追記

証明書が更新されない問題が発生

Let’s Encryptの証明書が更新されなくなってしまい、Webサーバやメールサーバで証明書不正が起きてしまった。

日付を確認すると有効期限が昨日になっている。

$ sudo certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log

Found the following certs:
  Certificate Name: benkyou.work
    Serial Number:
    Key Type: RSA
    Domains: benkyou.work
    Expiry Date: 2023-09-03 12:22:13+00:00 (INVALID: EXPIRED)
    Certificate Path: /etc/letsencrypt/live/benkyou.work/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/benkyou.work/privkey.pem

先に結論を書くと、ファイヤーウォールでhttp(80)でのアクセスを禁止したのが原因。

Let’s Encryptは証明書の更新の際に、http(80)でサーバにアクセスしてくるので、それができないからエラーになっていた。

dry-runで更新してみると、

$ sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

~

Detail: xxx.xxx.xxx.xxx: Fetching http://benkyou.work/.well-known/acme-challenge/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: Timeout during connect (likely firewall problem)

~

Failed to renew certificate benkyou.work with error: Some challenges have failed.

とでる。以下のように、思いっきりfirewall problemでは?と書いてくれている。

http://benkyou.work/.well-known/acme-challenge/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: Timeout during connect (likely firewall problem)

ファイヤーウォールの設定を確認すると、

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
22/tcp                     ALLOW       Anywhere                  
80/tcp                     DENY        Anywhere 
443                        ALLOW       Anywhere                  
・・・

おもくそDENYになってる。まぁ自分で80をふさいだんだから当然。

ので、http(80)を有効する。

$ sudo ufw allow http
Rule updated
Rule updated (v6)
$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
22/tcp                     ALLOW       Anywhere                  
80/tcp                     ALLOW       Anywhere                  
443                        ALLOW       Anywhere                  
・・・

ALLOWになった。

再度、dry-runで確認。

$ sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/benkyou.work.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Simulating renewal of an existing certificate for benkyou.work

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded: 
  /etc/letsencrypt/live/benkyou.work/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

ばっちり成功。dry-runを外して再度renewを実施し、日時を確認。

$ sudo certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/benkyou.work.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Renewing an existing certificate for benkyou.work
Reloading apache server after certificate renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all renewals succeeded: 
  /etc/letsencrypt/live/benkyou.work/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

$ sudo certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: benkyou.work
    Serial Number: 2
    Key Type: RSA
    Domains: benkyou.work
    Expiry Date: 2023-12-03 01:28:49+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/benkyou.work/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/benkyou.work/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

以上です。念のためApacheとか再起動して終了です。