本稿では CentOS 7 上の sshd の待ち受けポート番号を変更する方法について解説します。 本稿では、例として変更後のポート番号が 20022 になるように解説します。
前提知識
CentOS 7 には、セキュリティのために SELinux とファイアウォール (firewalld) がインストールされており、許可していないポート番号でのプロセスの起動と、許可していないポート番号へのアクセスを禁止しています。 このことから、単純に sshd の待ち受けポート番号の設定を変更しても、sshd を起動できない、もしくは接続することができません。
- SELinux : 許可していないポート番号でのプロセス起動を禁止している。
 - ファイアウォール : 許可していないポート番号へのアクセスを禁止している。
 
本稿ではこの事も加味して、sshd の待ち受けポート番号を変更する方法について解説します。
作業手順
本稿での主な手順は以下の通りです。
手順
- SELinux の設定を変更する。
 - ファイアウォールの設定を変更する。
 - sshd の待ち受けポート番号を変更する。
 - 22番ポートを無効にする。
 
1. SELinux の設定を変更する
それでは SELinux の設定変更について解説します。
1-1. SELinux の状態を確認する
 まずは、お使いの CentOS 7 における SELinux の状態を確認しましょう。 getenforce コマンドで現在の SELinux の状態を確認できます。
# getenforce
Enforcing
SELinux が有効になっていると Enforcing と表示されます。 もし無効の場合は Disabled もしくは Permissive と表示されます。 (SELinux が無効になっている場合において「SELinux を有効にすべきか?」の判断は別の話題なので、本稿では触れません。 SELinux が無効になっている場合は、次のファイアウォール設定に進んでください。)
1-2. semanage コマンドをインストールする
SELinux の設定を変更するためには semanage というコマンドを利用するのが便利なのですが、CentOS 7 のデフォルトではインストールされていない場合があります。 semanage コマンドは policycoreutils-python というパッケージに含まれるコマンドなので、次のように yum コマンドで policycoreutils-python をインストールします。
# yum install policycoreutils-python
policycoreutils-python パッケージのインストールが完了すれば semanage コマンドが利用できます。
1-3. SELinux が許可しているポート番号を確認する
semanage コマンドを利用すると、SELinux のポリシーを表示することができます。 次のように port 引数を与えることで、許可しているポートを一覧表示することができます。
# semanage port --list
しかし、このままだと結果が多すぎてわかりづらいので、今回の設定対象である ssh だけに表示を絞るようにして、もう一度 semanage コマンドを実行します。 すると、今度は ssh_port_t という行だけ表示されます。
# semanage port --list | grep ssh
ssh_port_t                    tcp      22
結果の通り、TCP の22番ポートだけが許可されていることがわかります。
1-4. SELinux のポリシーにポート番号を追加する
 ここで行いたいのは、上記の semanage port –list コマンドの結果に、新しい待ち受けポートとしたい 20022 を追加することです。 ポリシーにポート番号を追加するのも semanage コマンドでできます。 次のようにコマンドを実行します。
# semanage port --add --type ssh_port_t --proto tcp 20022
コマンドの実行完了後に再び semanage port –list コマンドを実行すると、今度は 20022 番ポートが追加されたことがわかります。
# semanage port --list | grep ssh
ssh_port_t                    tcp      20022, 22
備考
これで SELinux のポリシーに 20022 番ポートの設定が追加されたので、22番ポートの設定を削除したいところですが、そもそもの目的である sshd のポート番号の設定が終わっていないので、今の時点では22番ポートの設定は残しておきます。 本稿の最後でまとめて22番ポートの設定を削除します。
2. ファイアウォール (firewalld) の設定を変更する
さて次はファイアウォール (firewalld) の設定を変更します。
2-1. ファイアウォールの状態を確認する
まずはお使いの CentOS 7 でのファイアウォールの状態を確認します。 次のように systemctl コマンドを実行します。
# systemctl status firewalld
  ● firewalld.service - firewalld - dynamic firewall daemon
    Active: active (running) since Mon 2017-05-01 15:09:59 UTC; 2s ago
(略)
コマンドの実行結果の Active の値が active (runnning) となっていれば、ファイアウォールが有効になっています。 逆に inactive (dead) となっている場合は無効になっています。 (もしファイアウォールが無効になっているようであれば、次の sshd の設定に進んで構いません。)
2-2. 公開されているサービス(ポート)を確認する
それでは、ファイアウォールがインターネットに向けて公開しているサービスを確認してみましょう。 次のようにコマンドを実行します。
# firewall-cmd --list-services --zone=public --permanent
dhcpv6-client ssh
 上の例では、dhcpv6-client と ssh のサービスが公開されていることがわかります。 ここで表示されたサービス名「ssh」は、じつは /usr/lib/firewalld/services/ に設定があります。 フォルダ内の ssh.xml を開いてみると、次のようになっています。
<?xml version="1.0" encoding="utf-8"?>
  <service>
    <short>SSH</short>
    <description>Secure Shell (SSH) is a protocol ...</description>
    <port protocol="tcp" port="22"/>
</service>
port に 22 と書かれているのがわかります。 この記述によって、ファイアウォールで公開するポート番号を決めているというわけです。
2-3. 公開するポートを追加する
 それでは、公開するポート番号を追加しましょう。 上で確認した /usr/lib/firewalld/services/ の ssh.xml を変更すればいいのかと思うかもしれませんが、違います!
 CentOS 7 の firewalld では、/usr/lib/firewalld/ はシステムの初期設定を保存しておくディレクトリと位置付けており、ユーザーがカスタマイズした設定は /etc/firewalld/ 内に配置するようにデザインされています。 よって、設定を変更した ssh.xml は /etc/firewalld/services/ に設置する必要があります。
POINT
- /usr/lib/firewalld/ はシステム初期設定の保存場所
 - /etc/firewalld/ はユーザーが変更した設定の保存場所
 
 次のような操作で /etc/firewalled/services/ に ssh.xml を設置します。 まずは、/usr/lib/firewalld/ 配下のファイルをコピーします。
# cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/
ssh.xml をコピーしたら、以下のように編集します。 20022番のポート番号の設定を追加します。
<?xml version="1.0" encoding="utf-8"?>
  <service>
    <short>SSH</short>
    <description>Secure Shell (SSH) is a protocol ...</description>
    <port protocol="tcp" port="22"/>
    <port protocol="tcp" port="20022"/>
</service>
これで設定が完了しましたので、次のコマンドで firewalld に設定を再読み込みさせます。
# firewall-cmd --reload
備考
SELinux と同様、22番ポートの設定を削除したいところですが、そもそもの目的である sshd のポート番号の設定が終わっていないので、今の時点では22番ポートの設定は残しておきます。 本稿の最後でまとめて22番ポートの設定を削除します。
3. sshd の待ち受けポート番号を追加する
さて、やっと目的の sshd の待ち受けポート番号の変更です。 sshd の設定は、ファイル /etc/ssh/sshd_config に記載されています。 この sshd_config ファイルを変更します。
sshd_config に次のような行があります。 行の先頭に「#」が付いておりコメントアウトされていますので、実質は設定として無効の状態になっています。 そのため、デフォルトの22番ポートで sshd が待ち受けているわけです。
#Port 22
この行を次のように変更して保存します。
Port 22
Port 20022
このようにすることで、22番と20022番の2つのポートで待ち受けるようになります。 sshd を再起動して設定を読み込み直しましょう。
# systemctl restart sshd
これで、sshd のポート番号の追加は完了です。 SSHクライアントでポート番号に 20022 を指定して接続してみてください。 無事に接続できたでしょうか?
4. 22番ポートを無効にする
さて、ここまでで20022番ポートで SSH 接続ができるようになりましたので、22番ポートが不要になりました。 最後に SELinux, Firewalld, sshd の22番ポートの設定を無効化します。 20022番ポートに SSH 接続した状態で以下の作業を行います。
4-1. SELinux のポリシーから削除する
 上で SELinux のポリシーにポート番号を追加したときと同様に、semanage コマンドを利用します。 ポートを追加した時と似たコマンドですが、今度は –delete オプションを指定することでポート設定を削除できます。
# semanage port --delete --type ssh_port_t --proto tcp 22
コマンドの実行が終わったらポリシーの設定内容を確認してみます。 次の例のように、今度は20022番だけが表示されます。
# semanage port --list | grep ssh
ssh_port_t                    tcp      20022
これで SELinux の設定は完了です。
4-2. ファイアウォール (firewalld) から削除する
 前述の通り、firewalld の設定は /etc/firewalld/services/ssh.xml に記述しました。 ssh.xml から22番ポートを設定している行を削除して、次のようにします。
<?xml version="1.0" encoding="utf-8"?>
  <service>
    <short>SSH</short>
    <description>Secure Shell (SSH) is a protocol ...</description>
    <port protocol="tcp" port="20022"/>
</service>
これで設定が完了しましたので firewalld に設定を再読み込みさせます。
# firewall-cmd --reload
これでファイアウォール (firewalld) の設定も完了です。
4-3. sshd の設定を変更する
 最後に sshd の設定を変更します。 前述の通り、/etc/ssh/sshd_config を修正します。 Port 22 と記述された行を削除して、Port 20022 と書かれた行だけにします。
Port 20022
sshd_config を修正したら、次のコマンドで sshd を再起動させます。
# systemctl restart sshd
これで sshd の設定も完了です。
動作確認
これで22番ポートが利用できなくなったはずです。 SSH クライアントから接続を試みてください、今度は接続できないはずです。
おわりに
本稿では CentOS 7 において sshd の待ち受けポートを変更する方法について解説しました。 皆様のお仕事のお役に立てれば幸いです。 もし誤りなどありましたらお知らせください。



