CentOS Linux 7 (1708) に公開鍵認証で SSH 接続する最低限の設定を行う

## 0. はじめに
公開鍵認証で SSH 接続する方法・設定方法は、 Google 等で検索すれば多々出てきます。
しかし同方式では本来クライアント側で鍵の生成をするものですが、サーバで生成する記事も多々出てきます。
もちろんサーバ側で鍵の生成していても、正しく・安全に不要データの削除と鍵の転送が行われていれば問題ありません。
また、 OS のバージョンが変わると設定箇所が変わる場合があることがあります。
本 Post では本来実施する操作と設定内容を、個人的なまとめとして記載しています。
これから同方式で SSH 接続する必要がある方は、参考にしてください。

## 1. 本Postを実施するための前提条件
* [環境] CentOS Linux 7 (1708) を minimal でインストールが完了している
* [環境] "yum -y update" コマンドで各パッケージの更新を完了している
* [環境] ssh クライアント (Windows = Teraterm , Mac = Terminal) が導入済み
* [環境] ssh でクライアント (Win,Mac) から 一般ユーザの ID/PWD で接続できる
* [スキル] 一般ユーザの ID で sudo コマンドが実行できる
* [スキル] vi を使ったファイルの編集、保存ができる
* [スキル] ssh クライアントで操作するコマンド操作は、ログを取る癖がついている

## 2.1 公開鍵と秘密鍵を生成 Windows Teraterm 編
1. ssh クライアントとなる Windows マシンで Teraterm を起動
2. メニューバーの [Setup] -> [SSH Keygenerator] で TTSSH Key Generator を起動
3. "Key type" , "Key Bits" はデフォルト (RSA , 2048) で [Generate] をクリック
4. "Key passphrase" , "Confirm passphrase" にパスフレーズを入力
5. [Save public key] , [Save private key] をクリックし、任意の場所に保存
6. public key が id_rsa.pub (公開鍵) , private key が id_rsa (秘密鍵 ) が保存されたことを確認

## 2.2 公開鍵と秘密鍵を生成 Mac High Sierra Terminal 編
1. ssh クライアントとなる Mac で Terminal を起動
2. home ディレクトリ直下に .ssh ディレクトリがなければ、"$ mkdir .ssh" コマンドで作成
3. "$ cd .ssh" コマンドで .ssh ディレクトリに移動
4. "$ ssh-keygen" コマンドを実行
5. "Enter file in which to save the key (/Users/[Mac のユーザ名]/.ssh/id_rsa): " と表示されたら Return
6. "Enter passphrase (empty for no passphrase): " , "Enter same passphrase again: " と表示されたらパスフレーズを入力
7. "$ ls -ltar" コマンドを実行し、 id_rsa.pub (公開鍵) と id_rsa (秘密鍵 ) が作成されたことを確認

## 3.1 公開鍵を SSH サーバに転送 Windows Teraterm 編
1. ssh クライアントとなる Windows マシンで Teraterm を起動
2. SSH サーバに ssh 接続
3. home ディレクトリ直下に .ssh ディレクトリがなければ、"$ mkdir .ssh" コマンドで作成
4. メニューバーの [File] -> [SSH SCP] で上段の "From:" で id_rsa.pub を選択 / "To:" に "~/.ssh" と入力し [Send] をクリックし id_rsa.pub を転送
5. "$ cd ./.ssh" コマンドで .ssh ディレクトリに移動
6. "$ ls -ltar" コマンドを実行し、id_rsa.pub が転送されたことを確認

## 3.2 公開鍵を SSH サーバに転送 Mac High Sierra Terminal 編
1. ssh クライアントとなる Mac で Terminal を起動
2. "cd ./.ssh" コマンドで .ssh ディレクトリに移動
3. "$ scp id_rsa.pub [Username]@[SSH Server's IP or FQDN]:~/.ssh/" コマンドで id_rsa.pub を転送
4. SSH サーバに ssh 接続
5. "$ cd ./.ssh" コマンドで .ssh ディレクトリに移動
6. "ls -ltar" コマンドを実行し、id_rsa.pub が転送されたことを確認

## 4. SSH サーバの設定
1. ssh クライアントから SSH サーバに接続し、一般ユーザの ID/PWD でログイン
2. home ディレクトリ直下に .ssh ディレクトリがなければ、"$ mkdir .ssh" コマンドで作成
3. "$ chmod 700 .ssh" コマンドで .ssh ディレクトリの権限を変更 (所有者のみフルアクセス権あり状態)
4. "$ cd ./.ssh" コマンドで .ssh ディレクトリに移動
5. "$ cat id_rsa.pub >> ./authorized_keys" コマンドを実行 (複数の端末の公開鍵を登録する場合は、 id_rsa.pub を一意のファイル名にし cat コマンドで authorized_keys に追記する)
6. "$ chmod 600 ./authorized_keys" コマンドで権限を変更 (所有者のみ変更権あり状態)
7. "$ rm id_rsa.pub" コマンドで不要データを削除
8. "$ sudo cat /etc/ssh/sshd_config" コマンドで sshd の設定ファイルを編集前状態を保全
9. "$ sudo vi /etc/ssh/sshd_config" コマンドで sshd の設定ファイルを編集 (詳細は次項参照)
10. "$ sudo cat /etc/ssh/sshd_config" コマンドで sshd の設定ファイルを編集後状態を保全
11. "$ sudo sshd -t" コマンドで sshd_config のチェック (エラーが出ないことを確認)
12. "$ sudo systemctl restart sshd" コマンドで sshd を再起動

## 5. sshd_config の設定内容
4か所の変更と1か所の確認を vi で編集し、上書きします。

| No. | 区分 | Before | After | Note |
|---|---|---|---|---|
| 1. | 変更 | "#PubkeyAuthentication yes" | "PubkeyAuthentication yes" | 公開鍵認証を有効化 |
| 2. | 確認 | "AuthorizedKeysFile      .ssh/authorized_keys" | "AuthorizedKeysFile      .ssh/authorized_keys" | 公開鍵のパス指定 |
| 3. | 変更 | "#PermitEmptyPasswords no" | "PermitEmptyPasswords no" | パスワードなしのSSH接続を無効化 |
| 4. |変更 | "#PasswordAuthentication yes" | "PasswordAuthentication no" | パスワード認証を無効化 |
| 5. |変更 | "#ChallengeResponseAuthentication yes" | "ChallengeResponseAuthentication no" | チャレンジレスポンスでの認証を無効化 |

## 6.1 ssh クライアントから秘密鍵を利用し接続 Windows Teraterm 編
1. ssh クライアントとなる Windows マシンで Teraterm を起動
2. SSH サーバに ssh 接続
3. "User name:" に一般ユーザ名を入力 (これまでと同様)
4. "Use RSA/DSA/EDCSA/ED25519 key to log in" のラジオボタンを ON にし、[Private key file:] から id_rsa を選択
5. "Passphrase:" に 鍵生成時に入力したパスフレーズを入力
6. [OK] をクリック

## 6.2 ssh クライアントから秘密鍵を利用し接続 Mac High Sierra Terminal 編
1. ssh クライアントとなる Mac で Terminal を起動
2. "$ ssh -i .ssh/id_rsa [ ユーザ名 ]@[SSH サーバの IP or FQDN]" コマンドを実行
3. "Enter passphrase for key '.ssh/id_rsa': " と表示されたら鍵生成時に入力したパスフレーズを入力

## [参考]sshd_config 全文 Before / After
#### sshd_config (before)

```
#	$OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/bin:/usr/bin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

# 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 ::

HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile	.ssh/authorized_keys

#AuthorizedPrincipalsFile none

#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# 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

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes

# GSSAPI options
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several
# problems.
UsePAM yes

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#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
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# Accept locale-related environment variables
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

# override default of no subsystems
Subsystem	sftp	/usr/libexec/openssh/sftp-server

# Example of overriding settings on a per-user basis
#Match User anoncvs
#	X11Forwarding no
#	AllowTcpForwarding no
#	PermitTTY no
#	ForceCommand cvs server
```

#### sshd_config (after)

```
#       $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/bin:/usr/bin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

# 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 ::

HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin yes
PermitRootLogin no
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes
PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile      .ssh/authorized_keys

#AuthorizedPrincipalsFile none

#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
PermitEmptyPasswords no
#PasswordAuthentication yes
PasswordAuthentication no

# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes

# GSSAPI options
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several
# problems.
UsePAM yes

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#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
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# Accept locale-related environment variables
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

# override default of no subsystems
Subsystem       sftp    /usr/libexec/openssh/sftp-server

# Example of overriding settings on a per-user basis
#Match User anoncvs
#       X11Forwarding no
#       AllowTcpForwarding no
#       PermitTTY no
#       ForceCommand cvs server
```


## 最後に
セキュリティを考慮すれば、ポート番号の変更も実施すべきです。
しかし、本 Post で前提とした環境では SE Linux の設定を変更する必要が出てくるため未実施・未掲載です。
また、root は ユーザ名を変更することで既定のアカウントによる乗っ取り対策を実施しておくことが望ましいと考えています。
各企業でポリシーがあると思いますので、セキュリティポリシーに合わせた環境設計・構築を行いましょう。

Enjoy Linux Life!!