環境
クライアント側
- Windows 10
- Tera Term
- WinSCP
- 適当なテキストエディタ
サーバ側
やること
SSHの接続を公開鍵認証方式にして、接続ポート番号を22→50022に変更します。
- パケットフィルタで新規ポート追加
- ファイアウォールで新規ポート追加
- SELinuxで新規ポート追加
- sshd_configの設定変更
- SSH接続ポート番号変更
- 認証方式を公開鍵認証に変更
- その他セキュリティ向上
- 不要ポートの設定削除
まずは初期設定で接続
OSインストール時に設定したパスワードで、ポート22番にrootユーザで接続できるか確認します。サーバのIPアドレスは、さくらのVPSのコントロールパネルのサーバ→ネットワーク情報のアドレス欄からコピーできます。Tera Term でも WinSCP でも接続できることを確認します。
パケットフィルタの設定変更
カスタムOSインストールでCentOSをインストールしたので、「パケットフィルタを利用しない」になっていました。そして、ポート32767番までしか設定できないようなので、ここでは使わないことにします。利用する場合は32767以下の番号で追加すればいいでしょう。あと、一通りの設定が終わるまでは22番は削除しないように。設定が終わって、すべてOKになったら一番最後に22番を閉じます。
ファイアウォールの設定変更
現在の状態を確認
$ sudo firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1 eth2
sources:
services: dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
services: dhcpv6-client ssh
というところで、sshが開いています。
ssh-alt (50022番) の追加
上記のsshの設定をコピーして番号だけを50022にして適用することでssh-altというサービスとして50022番を開放します。
設定ファイルのコピー
$ sudo cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh-alt.xml
ssh-alt.xml を編集
$ sudo vi /etc/firewalld/services/ssh-alt.xml
<port protocol="tcp" port="50022"/>
firewalldの設定に追加、反映
$ sudo firewall-cmd --add-service=ssh-alt --permanent
success
$ sudo firewall-cmd --reload
success
$ sudo firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1 eth2
sources:
services: dhcpv6-client ssh ssh-alt
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
これで、ssh-alt (ポート50022) がfirewalldで開放されました。
SELinuxの設定変更
現在の状態を確認
$ getenforce
Enforcing
SELinuxが有効であることが分かります。
semanageコマンドのインストール
SELinuxの設定を変更するためのコマンドであるsemanageコマンドをインストールします。これは policycoreutils-python パッケージに含まれているので以下のようにインストールします。
$ sudo yum install -y policycoreutils-python
SELinuxが許可しているポート番号を確認
$ sudo semanage port --list
長いリストが出てきます。grepでsshだけフィルタリングすると、
$ sudo semanage port --list | grep ssh
ssh_port_t tcp 22
22番だけ許可されていることが分かります。
SELinuxのポリシーにポートを追加
$ sudo semanage port --add --type ssh_port_t --proto tcp 50022
$ sudo semanage port --list | grep ssh
ssh_port_t tcp 50022, 22
これで、50022番がsshのポートとして追加されました。
sshd_configの設定変更
設定ファイルである /etc/ssh/sshd_config
を編集します。
SSH接続ポート番号変更
の部分のコメントを外し、49152~65535番くらいのプライベートな番号をつけておけばいいと思う。
Port 50022
ここまでの設定を反映して、sshdを再起動して、50022番で接続できるか確認してみる。
sshd_configの構文に誤りがないかチェックするコマンドを実行します。
$ sudo sshd -t
何もエラーが出なければOKです。sshdを再起動します。この時いま開いているターミナルを閉じないように。もし、再起動後ログインできなくなったら、コンソールから入らなくてはいけなくなります。
$ sudo systemctl restart sshd
再起動後、Tera Term と WinSCP で変更後のポート番号でアクセスできたらOKです。
認証方式を公開鍵認証に変更
鍵の生成
ここでは、Tera Term で鍵のペアを作成します。メニューの「設定」→「SSH鍵生成」を選びます。鍵の種類はRSA、ビット数は4096で「生成」をクリックします。鍵の生成が終わったら、公開鍵 (id_rsa.pub) と秘密鍵 (id_rsa) をそれぞれ保存します。ここではパスフレーズは空でいいです。
公開鍵の転送
SCPで公開鍵 (id_rsa.pub) をVPSに転送します。ログインユーザのホームディレクトリの直下 (~/
) の .ssh
に (なければ作成)、そこに転送します。その後、id_rsa.pub ファイルを authorized_keys ファイルにマージします。
$ mkdir ~/.ssh # .sshディレクトリがない場合
$ cd ~/.ssh
$ cat id_rsa.pub >> authorized_keys
$ rm -f id_rsa.pub
パーミッションの確認
.ssh
ディレクトリは700、authorized_keys
ファイルは600である必要があります。
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys
sshd_configの設定変更
のコメントを外して
PubkeyAuthentication yes
にする。
PasswordAuthentication yes
を
PasswordAuthentication no
にする。
sshdの再起動と接続確認
$ sudo sudo sshd -t
$ sudo systemctl restart sshd
sshd再起動後、パスワード認証ではなく、公開鍵認証でログインできたらOKです。
その他セキュリティ向上
sshd_config を編集してきます。
LoginGraceTime
を
LoginGraceTime 20
にして、ユーザが20秒以内にログインを成功させないと接続を切るようにする。
PermitRootLogin
を
PermitRootLogin no
にして、rootユーザでログインできないようにする。
MaxAuthTries
を
MaxAuthTries 3
にして、1度の接続で3回までのパスワードの間違いを許可することにします。
MaxSessions
を
MaxSessions 5
にして、最大同時接続数を5にします。
PermitEmptyPasswords
を
PermitEmptyPasswords no
にして、空のパスワードを許可しないことにします。
GSSAPIAuthentication
GSSAPIAuthentication yes
を
GSSAPIAuthentication no
にして、GSSAPI認証は使わない。
MaxStartups
を
MaxStartups 5:75:10
として、非認証の接続が5を超えると75%の確率で拒絶をはじめて10を超えると全て拒否します。
AcceptEnv
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
を
つぃて、サーバ側へ、環境変数を渡さないようにする。
AllowUsers
AllowUsers *@*.jp
を追加して、特定ユーザからのみ接続を受け入れる。ここでは .jp ドメインのみ受け入れ (自分が使っているプロバイダは全て .jp ドメインのため)。
暗号アルゴリズム
Ciphers aes256-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-gcm@openssh.com,aes128-ctr,chacha20-poly1305@openssh.com
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
MACs umac-128-etm@openssh.com,umac-64-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128@openssh.com,umac-64@openssh.com,hmac-sha2-512,hmac-sha2-256
を追加して、弱いアルゴリズム使わわないようにする。
sshdの再起動と接続確認
$ sudo sudo sshd -t
$ sudo systemctl restart sshd
不要ポートの設定削除
新しいポートで接続できることが確認できたら、初期設定の22番ポートを無効にします。
SELinuxのポリシーから削除
SELinuxのポリシーから22番ポートをSSHの定義から外すことは上手くいかない模様。以下の削除コマンドでエラーが出てしまう。ただ、firewalldやパケットフィルタで22番を塞ぐのでセキュリティには問題はないです。
$ sudo semanage port --delete --type ssh_port_t --proto tcp 22
ValueError: Port tcp/22 is defined in policy, cannot be deleted
firewalld でssh (22番) を閉じる
sshのサービス (ssh.xml) を外す。
$ sudo firewall-cmd --remove-service=ssh --zone=public --permanent
success
$ sudo firewall-cmd --reload
success
sshが外れているか確認する。
$ sudo firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: dhcpv6-client ssh-alt
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
services
からsshが消えました。
パケットフィルタで22番の設定を削除する
さくらのVPSのパケットフィルタ利用している場合は、SSH (22番) のフィルタを削除する。
以上で、SSH接続が22番のパスワード認証から50022番の公開鍵認証になりました。