【Linux】SSHの認証方式

SSHの認証方法メモ。それぞれファイルがどこにあるとかファイルの内容がたまにわからなくなる。

# SSHの認証方法
SSHの主要な認証方法としてはホスト認証 ⇒ ユーザ認証の順番で行われる。
`ホスト認証`：クライアントが接続しようとしているリモートサーバーが、本当に信頼できるサーバーであることを確認する。
`ユーザ認証`: 次に、リモートサーバーは接続しようとしているユーザーが、本人であることを確認する。

# ホスト認証
Linux等では、ホスト鍵は一般的に `/etc/ssh/ssh_host_rsa_key` という秘密鍵ファイルと `/etc/ssh/ssh_host_rsa_key.pub` という公開鍵ファイルとして保存されており、これらはsshがインストールされる時に生成される。

①クライアントがサーバーに最初に接続したとき、サーバーはその公開ホスト鍵（`/etc/ssh/ssh_host_rsa_key.pub` の内容）をクライアントに送信する。

②クライアントはそれを受け取り、フィンガープリントとしてクライアント側の `~/.ssh/known_hosts`ファイルに保存する。この時点で聞かれる"Are you sure you want to continue connecting" は、この公開ホスト鍵を信頼してよいかどうかの確認。

③次回以降の接続時、クライアントは接続先サーバの公開ホスト鍵が `~/.ssh/known_hosts` 内のフィンガープリントと一致することを確認し、一致すればユーザ認証フェーズへと進む。

`known_hosts` = sshサーバ側の公開鍵の指紋（finger print）が登録されるファイル

```console:
[user01@localhost ~]$ cat .ssh/known_hosts
[user01@localhost ~]$
[user01@localhost ~]$ ssh user02@192.168.0.1
The authenticity of host '192.168.0.1 (192.168.0.1)' can't be established.
ECDSA key fingerprint is SHA256:gpEf8A/H15QkitXXXXXXXXXX/XXXXXXX//xx.
ECDSA key fingerprint is MD5:79:99:1a:3b:b1:bd:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.0.1' (ECDSA) to the list of known hosts.
user02@192.168.0.1's password:

[user01@localhost ~]$ cat .ssh/known_hosts
192.168.0.1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBH9lcnXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/xxxxxxx
[user01@localhost ~]$
```
同IPでVMを再作成したときなどは、接続時に以下のメッセージが出る場合がある。
```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
```
```
ssh-keygen -R 192.168.0.1
```
で指定したホストに属する鍵を取り除くことで、初回接続からやり直すことができる。


# ユーザ認証
リモートホスト（サーバ）が接続を試みているクライアントユーザーが、本当に主張しているユーザーであることを検証するプロセス。主に`パスワード方式`と`公開鍵方式`がある。
パスワード方式はデフォルトの認証方式で、接続先OSのユーザーアカウントの情報(ユーザー名とパスワード)でログインする方式。

## 公開鍵方式の設定
基本的な流れは以下
・クライアントで公開鍵・秘密鍵のペアを作る
・リモートサーバへ公開鍵を送る
・リモートサーバにて公開鍵の内容をauthorized_keysに登録(コピー)する

`authorized_keys` = 接続元のユーザーの公開鍵が登録されるファイル

### ■鍵ペア作成～Authorized_keys登録
```console:
[user01@localhost ~]$ cd .ssh
[user01@localhost .ssh]$ ls
known_hosts

[user01@localhost .ssh]$ ssh-keygen -t rsa -f id_rsa   ##オプションの値はいずれもデフォルト値
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):            ##パスフレーズ。空にすればパスワードを聞かれない
Enter same passphrase again:
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.
The key fingerprint is:
SHA256:8bKxfeGMCpidNDaHXHNqicXXXXXXXXXXXX user01@localhost
The key's randomart image is:
+---[RSA 2048]----+
|       .+..      |
|   . ... = .     |
|    +oo @ +      |
|   .oo+@ X       |
|   . =X S . .    |
|    .*.* * X .   |
|   .o + o X +    |
|  . o. X . .     |
|   oE.X .        |
+----[SHA256]-----+
[user01@localhost .ssh]$
[user01@localhost .ssh]$ ls
id_rsa  id_rsa.pub  known_hosts                       ##鍵ペアが作成されている。※.pubが公開鍵
[user01@localhost .ssh]$
[user01@localhost .ssh]$ scp id_rsa.pub user02@192.168.0.1:~/.ssh/id_rsa.pub
user02@192.168.0.1's password:

id_rsa.pub                                100%  410   403.2KB/s   00:00   ### リモートホストへ公開鍵を転送

[user01@localhost .ssh]$ ssh user02@192.168.0.1
user02@192.168.0.1's password:
Last login: Tue Jul 23 18:26:48 2024 from 192.168.0.10
[user02@remotehost ~]$
[user02@remotehost ~]$ cd .ssh
[user02@remotehost .ssh]$ ls
id_rsa.pub
[user02@remotehost .ssh]$
[user02@remotehost .ssh]$ cat id_rsa.pub >> authorized_keys   ###公開鍵ファイルの内容を追記
[user02@remotehost .ssh]$ ls
authorized_keys  id_rsa.pub
[user02@remotehost .ssh]$
[user02@remotehost .ssh]$ chmod 600 authorized_keys           ###パーミッション変更
[user02@remotehost .ssh]$ rm -rf id_rsa.pub              ###クライアントの公開鍵は削除でOK
```
また、公開鍵の転送からauthorized_keysの登録まで`ssh-copy-id`コマンド使えば自動でやってくれます。
↓の方が楽です。

https://qiita.com/kentarosasaki/items/aa319e735a0b9660f1f0


### ■sshd_config設定
リモートサーバで実施。ファイル群は`/etc/ssh/`ディレクトリにある。

```conf:/etc/ssh/sshd_config
#$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                          ###rootユーザのSSHログイン自体を拒否
PermitRootLogin without-password              ###パスワードを使用したrootユーザのログインを拒否
#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                    ###パスワード認証を有効にする(公開鍵方式の場合はnoにする)

# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no            ###公開鍵方式の場合はno

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

# GSSAPI options
GSSAPIAuthentication no
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                ###SSHポートフォワーディングを有効にする
#AllowTcpForwarding no
#GatewayPorts no
#X11Forwarding yes
X11Forwarding no                      ###X11フォワーディングを無効にする
#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 no
#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をリスタート
```
systemctl restart sshd
```

秘密鍵を指定して接続
```
ssh -i 鍵のファイルパス  ユーザー名@ドメイン -p ポート番号
```
認証に失敗しているときは以下のようなエラーが出る
```
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```
SSHサーバのログは以下のファイルで確認できる。

Debianベースのシステム：`/var/log/auth.log`
Red Hatベースのシステム：`/var/log/secure`

```:/var/log/secure
#公開鍵方式の場合
Jul 26 19:51:45 remotehost sshd[4585]: Accepted publickey for user01 from 192.168.0.1 port 51994 ssh2: RSA SHA256:vv0A3C7VDlOKNfA/XXXXXXXXXXXXXXXXXXXXXX
Jul 26 19:51:45 remotehost sshd[4585]: pam_unix(sshd:session): session opened for user user01 by (uid=0)

#ユーザ・パスワード方式の場合
Jul 26 19:52:03 remotehost sshd[4665]: Accepted password for user10 from 192.168.0.1 port 52006 ssh2
Jul 26 19:52:03 remotehost sshd[4665]: pam_unix(sshd:session): session opened for user user10 by (uid=0)
```
ちなみに
ssh XXX.XXX.XXX.XXX command
でリモートコマンド実行できる。
わざわざログインだけしてコマンド実行するのはやめよう！

以上o。