(2020年10月改変)
本投稿は CentOS 7.8 (2003) で更新しました。
はじめに
CentOS 7 を お名前.com VPS にインストールしたときの手順をご紹介します。
VPSプランは2ギガメモリプランです。
12ヶ月まとめ払いならば1ギガメモリプランとさほど金額差はありませんのでおすすめです。
記事では CentOS 7 インストールから各種さまざまなサーバーアプリケーションのセットアップまでを複数に渡ってご紹介したいと思います。
- CentOS 7 でサーバー構築(インストール編)
- CentOS 7 でサーバー構築(論理ボリュームマウント編)
- CentOS 7 でサーバー構築(ユーザー作成~SSH開通編)
- CentOS 7 でサーバー構築(パッケージ管理編)
今回はネットワーク設定を行い、外部からSSH接続ができるようにしたいと思います。
これまでの作業は外部ネットワークに繋がっていませんでしたので、お名前.com VPS コントロールパネル上のコンソールかシリアルコンソール接続で行っていました。
ネットワーク接続してあげないとサーバーとして意味ないので、接続してあげます。
また、ユーザーを作成した後は各自SSHで接続できるようにする必要がありますので、SSHサーバーの設定も行います。
設定作業は前回から引き続きシリアルコンソール接続にて root ユーザーでログインして行います。
ユーザーの種類とSSH設定におけるポリシーを決める
SSH接続を設定しますので、少なからずセキュリティリスクを背負うことになります。より良いサーバー運用をしていく中で、攻撃を回避するための施策は重要です。
今回は以下のようにポリシーを決めて作業を進めたいと思います。
- ユーザーは管理者ユーザーと一般ユーザーに分けて作成する。
- 管理者ユーザーはroot昇格が可能である。(一般ユーザーは不可)
- rootはSSHでログイン禁止とする。
- SSHのポートは22ではなく別ポートに変更する。
- SSHのログイン認証は共通鍵認証とし、パスワード認証は禁止とする。
ユーザーを作成する
ユーザーを作成します。管理者ユーザーがroot昇格可能という制御を pam 認証を利用することで解決します。具体的には、pam 認証設定で pam_wheel.so モジュールを有効にして、wheel グループに所属しているユーザーだけがroot昇格できるようにするというものです。
よって、管理者ユーザーと一般ユーザーの違いは、wheel グループの所属有無だけで表現します。
以下のコマンドで suzuki という管理者ユーザーを作成します。
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# useradd suzuki
[root@localhost ~]# gpasswd -a suzuki wheel
ユーザ suzuki をグループ wheel に追加
[root@localhost ~]# passwd suzuki
ユーザー suzuki のパスワードを変更。
新しいパスワード: (パスワードを入力)
新しいパスワードを再入力してください: (パスワードを確認入力)
passwd: すべての認証トークンが正しく更新できました。
[root@localhost ~]#
useradd コマンドでユーザーを作成します。
gpasswd コマンドで suzuki を wheel グループに追加しています。
passwd コマンドで suzuki のパスワードを設定します。
同じ手順で他のユーザーも作成できます。
rootに昇格する必要の無いユーザーは wheel グループに所属させないようにします。
pam_wheel.so モジュールの有効化
wheel グループに所属しているユーザーが root昇格できるように/etc/pam.d/su 設定ファイルを編集して pam_wheel.so モジュールを有効にします。
[root@localhost ~]# vi /etc/pam.d/su
# %PAM-1.0
auth sufficient pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
# auth sufficient pam_wheel.so trust use_uid
# Uncomment the following line to require a user to be in the "wheel" group.
# auth required pam_wheel.so use_uid
auth substack system-auth
auth include postlogin
account sufficient pam_succeed_if.so uid = 0 use_uid quiet
account include system-auth
password include system-auth
session include system-auth
session include postlogin
session optional pam_xauth.so
↓ 6行目のコメントを外す。
# %PAM-1.0
auth sufficient pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
# auth sufficient pam_wheel.so trust use_uid
# Uncomment the following line to require a user to be in the "wheel" group.
auth required pam_wheel.so use_uid
auth substack system-auth
auth include postlogin
account sufficient pam_succeed_if.so uid = 0 use_uid quiet
account include system-auth
password include system-auth
session include system-auth
session include postlogin
session optional pam_xauth.so
開いているポートを閉める
ネットワークを開通するまえに、デフォルトで開いているポートをしめてしまいます。
ネットワーク開通後にちゃんとセキュリティ確保してから改めて開けるようにします。
firewall-cmd コマンドで空いているポートを確認します。
[root@localhost ~]# firewall-cmd --list-all
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@localhost ~]#
firewall-cmd は名前のとおり、ファイヤーウォールの設定を行うコマンドです。
firewall-cmd --list-all で、現在の設定を一覧で確認できます。
services: dhcpv6-client ssh
services に dhcpv6-client ssh が表示されていますので、これらのサービスが利用しているポートが開いていることがわかります。
dhcpv6-client は、Ipv6 を利用するならば必要のようですが、とりあえずいらないので永久に閉めます。
ssh は、後ほどちゃんと設定してから開けるので、一時的に閉めます。
[root@localhost ~]# firewall-cmd --permanent --remove-service=dhcpv6-client
success
[root@localhost ~]# firewall-cmd --permanent --remove-service=ssh
success
[root@localhost ~]# firewall-cmd --reload
success
[root@localhost ~]#
[root@localhost ~]# firewall-cmd --list-all
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@localhost ~]#
services から表示がなくなりましたので、ポートがすべて閉じました。
ネットワークを開通する
ポートをすべて閉めましたので、この時点でネットワーク開通します。
ネットワークの設定は、nmcli コマンドで行います。
まずは現状の確認。
[root@localhost ~]# nmcli device
DEVICE TYPE STATE CONNECTION
eth0 ethernet 切断済み --
lo loopback 管理無し --
[root@localhost ~]#
eth0 が 切断状態なので接続します。
[root@localhost ~]# nmcli connection modify eth0 connection.autoconnect yes
状態確認。
[root@localhost ~]# nmcli device
DEVICE TYPE STATE CONNECTION
eth0 ethernet 接続済み eth0
lo loopback 管理無し --
[root@localhost ~]#
接続しました。
connection.autoconnect yes としているので、以後は自動で接続されます。
パッケージ管理 yum でパッケージ更新
ネットワーク接続できるようになったので、各種設定を行う前にシステムにインストール済のパッケージを更新しておきます。
[root@localhost ~]# yum update
...
(色々途中経過が表示されます。)
...
Is this ok [y/d/N]: (y を入力して Enter)
わらわらとリストが出ていて、インストールの是非を問われるので y で Enter します。
ちなみに y 押すのも面倒くさいという方は -y オプションをつけて実行すれば勝手に y したことになります。
更新途中で再度是非を問われることがあるかもしれませんが、yで進めれば良いです。
SSHの設定
SSHの設定は、/etc/ssh/sshd_config で行います。SSH規定のポート番号は22番ですが、外部からの不正アクセスを回避するために変更します。プライベートポートとして利用可能なポート番号の範囲は、49152 ~ 65535 なので、49022 を採用したいと思います。
SSHでのrootログインも禁止にしてしまいます。パスワード認証も禁止にして共通鍵認証のみで接続するようにします。
/etc/ssh/sshd_config の設定を行います。
[root@localhost ~]# vi /etc/ssh/sshd_config
- ポート番号変更(22 → 49022)
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
# Port 22
# AddressFamily any
# ListenAddress 0.0.0.0
# ListenAddress ::
Port のコメントを外して、ポート番号を 49022 に変更します。
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
Port 49022
# AddressFamily any
# ListenAddress 0.0.0.0
# ListenAddress ::
- rootログイン禁止
# LoginGraceTime 2m
# PermitRootLogin yes
# StrictModes yes
# MaxAuthTries 6
# MaxSessions 10
PermitRootLogin のコメントを外して、設定値を no に変更します。
# LoginGraceTime 2m
PermitRootLogin no
# StrictModes yes
# MaxAuthTries 6
# MaxSessions 10
- パスワード認証無効化
# To disable tunneled clear text passwords, change to no here!
# PasswordAuthentication yes
# PermitEmptyPasswords no
PasswordAuthentication yes
# Change to no to disable s/key passwords
# ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no
PasswordAuthentication の設定値を no に変更します。
# To disable tunneled clear text passwords, change to no here!
# PasswordAuthentication yes
# PermitEmptyPasswords no
PasswordAuthentication no
# Change to no to disable s/key passwords
# ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no
ついでにSSH接続でなにも操作しないときに短時間で切断されないように対策しておきます。
# UseLogin no
# UsePrivilegeSeparation sandbox
# PermitUserEnvironment no
# Compression delayed
# ClientAliveInterval 0
# ClientAliveCountMax 3
# ShowPatchLevel no
# UseDNS yes
# PidFile /var/run/sshd.pid
# MaxStartups 10:30:100
ClientAliveInterval のコメントを外して、設定値を 15 に変更します。
# UseLogin no
# UsePrivilegeSeparation sandbox
# PermitUserEnvironment no
# Compression delayed
ClientAliveInterval 15
# ClientAliveCountMax 3
# ShowPatchLevel no
# UseDNS yes
# PidFile /var/run/sshd.pid
# MaxStartups 10:30:100
ClientAliveInterval は秒数を指定します。上記設定の場合15秒毎に最大3回の応答確認を行い、SSH接続でなにも操作していないときに短時間で接続が切れることを防止します。
最大3回という設定値は ClientAliveCountMax が関わっておりコメントアウトされていますが、デフォルト値が 3 なのでデフォルト値のままとしています。
/etc/ssh/sshd_config の設定が完了したので、sshd の設定をリロードしておきます。
sshd はSSHで接続するためのデーモンプロセスです。
[root@localhost ~]# systemctl reload sshd
ファイヤーウォールの設定
SSHのデフォルトポート番号 22 を 49022 に変更しましたので、ファイヤーウォールの設定も変更します。
ネットワーク開通前に閉じた ssh というサービスのポートは 22 なので、49022 用の ssh サービスを作成します。
ssh サービスの定義ファイルは /usr/lib/firewalld/services/ssh.xml にありますので、これをコピーして 49022 用の ssh サービス定義ファイルを作成します。
[root@localhost ~]# cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh-49022.xml
元の定義ファイルをコピーしたので、内容を編集します。
[root@localhost ~]# vi /etc/firewalld/services/ssh-49022.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>SSH</short>
<description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encc
rypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. Youu
need the openssh-server package installed for this option to be useful.</description>
<port protocol="tcp" port="22"/>
</service>
ポート番号を 49022 に変更します。
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>SSH</short>
<description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encc
rypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. Youu
need the openssh-server package installed for this option to be useful.</description>
<port protocol="tcp" port="49022"/>
</service>
49022 ポート版の ssh サービスを有効にします。
[root@localhost ~]# firewall-cmd --permanent --add-service=ssh-49022
success
ファイヤーウォール設定をリロードしておきます。
[root@localhost ~]# firewall-cmd --reload
success
これでSSHの設定は完了です。
SSH用の鍵ペア生成
SSH接続でパスワード認証を無効化したので、公開鍵認証で認証を行う必要があります。
接続元となるPC上で公開鍵と秘密鍵のペアを作成します。
鍵ペアは OpenSSH に含まれている ssh-keygen コマンドを利用して作成します。
OpenSSH は、今やWindows10に標準装備されているので非常にお手軽に利用できるようになって良いです。
Windows10の OpenSSH をインストールする方法は、私の別記事「Windows10 に OpenSSH インストール」を御覧ください。
作業はコマンドプロンプトまたは、PowerShellで行います。
昨今、暗号化アルゴリズムはいつ解読されてしまうか分からないので、できるだけ暗号強度の強い方式を採用したいと思います。
とりあえず私が問題ないと思っている3種類を紹介だけしておきます。どれを採用するかは各自のご判断で、、
RSA
RSAは短い鍵長は推奨されませんので、私は 4096bit で作成するようにしています。
少なくとも 2048bit 以上の鍵長で作るほうが良いと思います。
PS C:\Users\suzuki> ssh-keygen -t rsa -b 4096 -C "suzuki@xxxxxx"
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\suzuki/.ssh/id_rsa):
Enter passphrase (empty for no passphrase): (パスフレーズ)
Enter same passphrase again: (パスフレーズ確認)
Your identification has been saved in C:\Users\suzuki/.ssh/id_rsa.
Your public key has been saved in C:\Users\suzuki/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:OhAgi6VynLpw3ERwPwtncK80s3mW48F/ir45z2tgE2w suzuki@xxxxxx
The key's randomart image is:
+---[RSA 4096]----+
|. +.+ . |
|.* = + . |
|= + + O.. |
|.+ o * XE. |
|o o o =.S. |
|.o . =++ |
|. o..o. . |
| ..+.o |
| .===. |
+----[SHA256]-----+
PS C:\Users\suzuki>
-t rsa は暗号形式が RSA であることを示しています。
-b 4096 は鍵長が 4096bit であることを示しています。
-C "suzuki@xxxxxx" はコメントですので、必須ではありませんが私は鍵内容を判断できるように (ユーザー名)@(サーバー名) というルールで付与しています。
ECDSA
ECDSAは楕円曲線DSAと呼ばれる暗号アルゴリズムです。
PS C:\Users\suzuki> ssh-keygen -t ecdsa -b 521 -C "suzuki@xxxxxx"
Generating public/private ecdsa key pair.
Enter file in which to save the key (C:\Users\suzuki/.ssh/id_ecdsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\suzuki/.ssh/id_ecdsa.
Your public key has been saved in C:\Users\suzuki/.ssh/id_ecdsa.pub.
The key fingerprint is:
SHA256:CT88nHtnSlyVXcRjMhbSulciO2oh5RUH4AJmF9hD5cU suzuki@xxxxxx
The key's randomart image is:
+---[ECDSA 521]---+
| +++ooo+o..oo|
| o.ooo .E.* =o|
| ...o = * o|
| =.+ + o . |
| S . = o |
| . B = . |
| o * = |
| = + |
| . . |
+----[SHA256]-----+
PS C:\Users\suzuki>
-t ecdsa は暗号形式が ECDSA であることを示しています。
-b 521 は鍵長が 521bit であることを示しています。
-C "suzuki@xxxxxx" はRSAのときと同じくコメントです。
Ed25519
Ed25519はエドワーズ曲線DSAと呼ばれる暗号アルゴリズムです。
PS C:\Users\suzuki> ssh-keygen -t Ed25519 -C "suzuki@xxxxxx"
Generating public/private Ed25519 key pair.
Enter file in which to save the key (C:\Users\suzuki/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\suzuki/.ssh/id_ed25519.
Your public key has been saved in C:\Users\suzuki/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:k8tdiX8usQAscPEg1RTNsDGNtu8DfTJhtWQklvgrWu0 suzuki@xxxxxx
The key's randomart image is:
+--[ED25519 256]--+
| ..++*Ooo. |
| ...o===.+ |
| o ooo + . |
| . +.+... |
| .S*.oo |
| .++Ooo |
| oo=.=.o. |
| . E oo |
| . .. |
+----[SHA256]-----+
PS C:\Users\suzuki>
-t Ed25519 は暗号形式が Ed25519 であることを示しています。
-C "suzuki@xxxxxx" はRSAのときと同じくコメントです。
Ed25519は鍵長が 256bit 固定ですので、鍵長指定 -b は不要です。
いずれの方法でも、鍵ペアの生成に成功すると、フィンガープリントと randomart と呼ばれるものが表示されます。randomart は鍵情報を視覚化したものです。
そして、鍵ペアは暗号方式によってファイル名は違いますがいずれの方法でも C:\Users\suzuki\.ssh フォルダー配下に秘密鍵と公開鍵が生成されます。(※出力先ファイルパスをデフォルトとした場合)
例えば、RSAだとデフォルトファイル名で下記のように出力されます。
秘密鍵:C:\Users\suzuki\.ssh\id_rsa
公開鍵:C:\Users\suzuki\.ssh\id_rsa.pub
公開鍵は後ほどサーバーへ転送します。
ちなみに暗号強度でいうと、恐らく「Ed25519 > ECDSA > RSA」だと思います。たぶん。。
なので個人的にはEd25519を利用するのが良いかなと考えています。
公開鍵転送
公開鍵をサーバーに転送する必要があります。
シリアルコンソール越しに該当ユーザーの公開鍵格納場所へ配置しますので、基本的にこの作業はサーバー管理者が行うことになります。
公開鍵ですので、サーバー管理者に見えても得に問題ありません。
秘密鍵は絶対に他者に見られてはいけませんので、今回のような作業を実施する際は必ず各クライアント端末で鍵ペアを作成して公開鍵だけをサーバー管理者経由で設定してもらう運用が良いかと思います。
公開鍵を配置する該当ユーザーのホームディレクトリで作業しますので、su (ユーザー) して cd してホームディレクトリに移動しておきます。
[root@localhost ~]# su suzuki
[suzuki@localhost root]$ cd
[suzuki@localhost ~]$
ホームディレクトリに .ssh ディレクトリを作成します。
パーミッションは 700 にして自ユーザーだけがアクセス可能な権限にセットします。
[suzuki@localhost ~]$ mkdir .ssh
[suzuki@localhost ~]$ chmod 700 .ssh
[suzuki@localhost ~]$
次に .ssh ディレクトリ内に authorized_keys ファイルを設置して公開鍵を登録します。
公開鍵はテキストなので、vi コマンドでシリアルコンソール越しにコピー&ペーストで転送します。
authorized_keys ファイルの権限は自ユーザーのRead Onlyにする必要があるので、600 に変更します。
[suzuki@localhost ~]$ vi .ssh/authorized_keys
(ファイル内は公開鍵の内容を記載)
[suzuki@localhost ~]$ chmod 600 .ssh/authorized_keys
SSH接続テスト
クライアント端末から公開鍵認証でSSH接続ができるかテストします。
今回はEd25519で作成した公開鍵をサーバーに登録してますので、Ed25519の秘密鍵を使用して接続します。
PS C:\Users\suzuki> ssh suzuki@xxx.xxx.xxx.xxx -p 49022 -i ~/.ssh/id_ed25519
The authenticity of host '[xxx.xxx.xxx.xxx]:49022 ([xxx.xxx.xxx.xxx]:49022)' can't be established.
ECDSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[xxx.xxx.xxx.xxx]:49022' (ECDSA) to the list of known hosts.
Enter passphrase for key 'C:\Users\suzuki/.ssh/id_ed25519':
Last login: Thu Oct 1 07:12:22 2020
Last login: Thu Oct 1 07:12:22 2020
[suzuki@localhost ~]$
SSH接続できました。
初回接続は接続先ホストを信頼するかどうかを問うてくるので、yes にしておきます。
known_hosts にホストキーが登録されるので、以後は聞かれません。
秘密鍵のパスフレーズを聞かれるので、鍵ペアを作成したときに使用したパスフレーズを入力します。
一旦 exit してSSH接続を切断し、再度接続してみますが今度はパスフレーズをわざと間違えてみます。
PS C:\Users\suzuki> ssh suzuki@xxx.xxx.xxx.xxx -p 49022 -i ~/.ssh/id_ed25519
Enter passphrase for key 'C:\Users\suzuki/.ssh/id_ed25519':
Enter passphrase for key 'C:\Users\suzuki/.ssh/id_ed25519':
Enter passphrase for key 'C:\Users\suzuki/.ssh/id_ed25519':
suzuki@xxx.xxx.xxx.xxx: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
PS C:\Users\suzuki>
当然SSH接続はできませんが、もしパスワード認証が有効な場合は公開鍵認証が失敗したあとにパスワード入力を求められます。
今回はパスワード認証をOFFにしているので、公開鍵認証が失敗するとそのままSSH接続は失敗するということで、設定が正しくされていることがわかります。
今回の作業はこれで完了です。
さいごに
ボリュームのある作業でしたが、無事にSSH接続ができるようになりました。
サーバーメンテナンスはリモート作業が基本なので、SSH接続は必須です。
しかしながら、セキュリティ面をしっかり考慮していないといつのまにか攻撃者に乗っ取られていましたという自体にもなりかねませんので、セキュリティ面のポイントをしっかり押さえて設定しておくことが重要かと思います。
今回は、認証方法を公開鍵認証のみとしたことで下記のメリットがあります。
- パスワードがネットワーク上へ流れない。
- 秘密鍵が無いと接続すらできない。
- 秘密鍵自体もパスフレーズが無いと利用できない。
公開鍵暗号で使用する暗号アルゴリズムも高いものを採用していますので、より高いセキュリティが得られたのでは無いかと思います。