SSHの認証?公開鍵認証でしょ?
個人でVPS使う分には運用面とかでは問題ない
大規模な場合どうするんだ…みたいな疑問
ユーザーごとに公開鍵登録するの面倒スギィ
LDAP?構築面倒...

公開鍵認証
たぶん大半の人が使ってる
サーバーに公開鍵を登録
クライアントは秘密鍵で認証
割愛

証明書認証
公開鍵認証で使用している公開鍵を認証局が署名
認証局の公開鍵を持つホストは証明書を使用して認証を行う

利点
ユーザーの公開鍵をいちいち登録しておく必要がない
ユーザーに有効期限を設定できたり, ログイン禁止(証明書失効)が可能
CAの鍵ペアを作成(CA)
ユーザーの公開鍵に署名するのに使用
 $ ssh-keygen -f ca-key
$ ls
ca-key ca-key.pub
CAの鍵ペアを作成(CA)
鍵ペアを作成(クライアント)
$ ssh-keygen -f id_rsa
$ ls
id_rsa id_rsa.pub
出来上がった公開鍵をCAに提出
提出された公開鍵に署名(CA)
-s 署名に使う秘密鍵(CAの秘密鍵)
-I 鍵識別子. 自由につけれる. 証明書が利用されるとログに残る
 $ ssh-keygen -s ca-key -I KEYID id_rsa.pub
他にもログインユーザの指定や証明書の有効期限も設定可能
id_rsa-cert.pubが出来上がる(CA)
certが付いているので証明書であることがわかる
 $ ls
id_rsa id_rsa.pub id_rsa-cert.pub
内容を確認(CA)
Extensionsには利用できる機能一覧が表示される
 $ ssh-keygen -L -f id_rsa-cert.pub 
id_rsa-cert.pub:
        Type: ssh-rsa-cert-v01@openssh.com user certificate
        Public key: RSA-CERT SHA256:RcQbKKqIhgBzL8qA3gSf6CR3I3j/9Xy4pNz1MnWneac
        Signing CA: RSA SHA256:LwfyPd/G1dra0Egnh8YZ0QPmdwR5MiufJtEZkCOw2KM
        Key ID: "KEYID"
        Serial: 0
        Valid: forever
        Principals: (none)
        Critical Options: (none)
        Extensions: 
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc

証明書認証のみを行う設定(サーバー)
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
AuthorizedKeysFile /etc/ssh/ca-key.pub
ログイン(クライアント)
証明書は自動的に使用される
 $ ssh -i id_rsa REMOTEHOST
鍵識別子がログに残る
Jul 4 07:44:19 ALCOTT sshd[1480]: Accepted publickey for mrtc0 from 192.168.1.115 port 35212 ssh2: RSA-CERT ID KEYID (serial 0) CA RSA f5:f9:b8:32:40:2b:2f:77:b0:92:26:98:39:78:6e:44

ホストベースド認証
サーバーがクライアントマシンを認証する
クライアント側設定
/etc/ssh/以下に各種鍵ペアが生成される
 $ sudo ssh-keygen -A
ssh-keysign
秘密鍵はroot以外読み取れないために一般ユーザーはホストベースド認証を行えない
そこでssh-keysignとよばれるsetuidされたコマンドが用意されている
/etc/ssh/ssh_configに EnableSSHKeysign yes を追加
クライアント側設定
$ cat /etc/ssh/ssh_config
...
EnableSSHKeysign yes
HostbasedAuthentication yes
サーバー側設定
sshd_configにHostbasedAuthentication yesを設定
/etc/ssh/ssh_known_hostsに「クライアントマシン名 公開鍵」を登録
 192.168.1.118 ssh-rsa ABCD...
IgnoreUserKnownHosts no の場合はログインユーザーの公開鍵DBから読み込まれる
~/.ssh/known_hosts

サーバー側設定(任意)
ログイン許可するユーザーを設定する場合
 $ cat /etc/ssh/shosts.quiv
192.168.1.118 mrtc0


複数要素認証
OpenSSH-6.2からAuthenticationMethodsを使うことができる
複数の認証方式を組み合わせることができる
公開鍵認証+パスワード認証みたいなことが可能
公開鍵認証+パスワード認証
$ cat /etc/ssh/sshd_config
...
PubkeyAuthentication yes
PasswordAuthentication yes
AuthenticationMethods publickey,password
複数のパターンを組み合わせ
AuthenticationMethodsの値をスペースで区切ると複数パターンから認証可能
公開鍵認証orパスワード認証 + ホストベースド認証
公開鍵認証に失敗してもパスワード認証が通ればOK
 AuthenticationMethods publickey,hostbased password,hostbased
公開鍵認証失敗後パスワード認証
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Trying private key: /home/mrtc0/.ssh/id_rsa
debug1: Trying private key: /home/mrtc0/.ssh/id_dsa
debug1: Trying private key: /home/mrtc0/.ssh/id_ecdsa
debug1: Next authentication method: password
mrtc0@192.168.1.117's password:


AuthorizedKeysCommand
鍵認証を行う時にユーザの公開鍵を探すプログラムが指定できる
LDAPやDBへ接続して公開鍵を取得することが簡単に
MySQLに公開鍵を登録
mysql> select * from authorizedkeys;
+------------+--------------------------------------+
| username | publickey |
+------------+--------------------------------------+
| mrtc0 | ssh-rsa AAAAB ... 0sFdu mrtc0@arch |
| mrt-k | ssh-rsa AAAAB ... PUoe1 mrt-k@ubuntu |
+---------------------------------------------------+
鍵検索スクリプトと設定
$ cat /usr/local/bin/findkeymysql.sh

/usr/bin/mysql -ussh authorizedkeys -sNe "select publickey from authorizedkeys where username='$1'"
$ cat /etc/ssh/sshd_config
...
AuthorizedKeysCommand /usr/local/bin/key.sh
AuthorizedKeysCommandUser %u
Googleが提供するワンタイムパスワードを使用する
PAMのモジュールとして提供されている
libpam-google-authenticatorをインストールしておく
Pluggable Authentication Module
認証モジュール
PAMのAPIを通してPAMモジュールに認証処理を任せれる
必要なモジュールを組み合わせることで柔軟な認証を設定可能
長いので割愛
サーバー側の設定
$ cat /etc/ssh/sshd_config
...
PasswordAuthentication no
ChallengeResponseAuthentication yes
UsePAM yes
サーバー側の設定
デフォルト4行の上に追記
UNIXパスワードの前にOTPが聞かれる
 $ cat /etc/pam.d/sshd
 auth required pam_google_authenticator.so
 auth required pam_unix.so
 auth required pam_env.so
サーバー側の設定
ログインするユーザーのホームディレクトリにルールやシークレットキーを保存
スクラッチコードは安全なところに
 $ google-authenticator
   Do you want authentication tokens to be time-based (y/n) y
   <Here you will see generated QR code>
   Your new secret key is: xxxxxxxxxxx
   Your verification code is 1234567
   Your emergency scratch codes are:
     xxxxxxxx
     xxxxxxxx
     xxxxxxxx
     xxxxxxxx
     xxxxxxxx

   Do you want me to update your "/home/username/.google_authenticator" file (y/n) y

   Do you want to disallow multiple uses of the same authentication
   token? This restricts you to one login about every 30s, but it increases
   your chances to notice or even prevent man-in-the-middle attacks (y/n) y