最近はクラウド上のサーバーを利用する事も多くなってきた。
サーバーの用意やネットワーク周りの設定はインフラ部門がやってくれるけど、アプリのデプロイ/設定は開発者がする事が多いので、開発メインでやってるエンジニアでも最低限SSHの知識は必要になる。
また、Vagrant等でローカル環境にVMを作成する事もあるので、ローカル環境内でSSHを使用するケースも増えてきた。
というわけでインフラエンジニアじゃなくてもSSHクライアントの知識は必須になってきているので、改めてSSHの再学習をしてみることにした。
SSHとは
暗号や認証の技術を利用して、安全にリモートコンピュータと通信するためのプロトコル。
SSHでは以下の点で従来のTelnetより安全な通信が行える。1
- パスワードやデータを暗号化して通信する。
- クライアントがサーバーに接続する時に、接続先が意図しないサーバーに誘導されていないか厳密にチェックする。
詳しくはWikipediaで
SSHの認証方式
SSHの主要な認証方式としてはパスワード認証方式と公開鍵認証方式がある。
- パスワード認証方式
- パスワード認証方式はデフォルトの認証方式で、ユーザー名とパスワードでログインする方式。
ユーザー名とパスワードは接続先OSのユーザーアカウントの情報が使用される。
- 公開鍵認証方式
- 公開鍵認証方式は公開鍵と秘密鍵の2つの鍵(キーペア)を使用した接続方式。
サーバーに公開鍵、クライアントに秘密鍵を置いて使用する。
公開鍵認証を使うとパスワード入力なしでログインする事が可能になる。
パスワード認証方式はサーバー側で明示的に無効にしていない限り使用できるが、セキュリティ的には脆弱なので無効にしている事も多い。2
公開鍵の仕組みというか考え方については以下が分かりやすいと思う。
妻に公開鍵暗号を教えてみた - 西尾泰和のはてなダイアリー
OpenSSH
SSHプロトコルを使用する為のソフトで、SSHクライアントとSSHサーバーの両方が含まれている。
Linuxではデファクトスタンダードとなっていて、ほぼデフォルトでインストールされている。
WindowsでもCygwinをインストールしたり、Gitに同梱されているGit Bashで使用できる。
OpenSSHの主要コマンド
- ssh
- SSHでリモートホストに接続してコマンドを実行する。
- scp
- SSHを使用してリモートホストとの間でファイルを転送を行う。
- ssh-keygen
- 公開鍵認証方式で使用するキーペアを生成する。
- ssh-copy-id
- 公開鍵をリモートホストに登録するコマンド。環境によってはインストールされていない場合がある。
sshコマンド
sshコマンドはリモートホストに接続してコマンドを実行する時に使用する。
ssh [user@]hostname [command]
- ユーザー名を省略するとクライアントの現在のユーザーが使用される。
- コマンドを指定するとリモートホストに接続したあと指定のコマンドだけ実行してログアウトする。
- コマンドを省略した場合はリモートホストにログインした状態でコマンドプロンプトが表示されるので、任意のコマンドを実行できる。ログアウトしたい時は
exit
。
主要なオプション
- -i identity_file
- 公開鍵認証で使用する秘密鍵ファイルを指定する。デフォルトでは~/.ssh/id_rsaなどが使用される。
- -F configfile
- 設定ファイルを指定する。デフォルトでは`~/.ssh/config`が使用される。
- -p
- ポート番号を指定する。
上記オプションは他のコマンドでもほぼ共通。
scpコマンド
scpコマンドはSSHを使用してリモートホストとの間でファイルを転送を行うコマンド。
scp file1 file2 [user@]hostname[:dir1]
scp [user@]hostname:file1 [user@]hostname:file2 dir1
パスワード認証方式での接続
[vagrant@node1 ~]$ ssh node2 ←node1からSSHでnode2へ接続
The authenticity of host 'node2 (192.168.33.12)' can't be established.
RSA key fingerprint is c4:4d:f9:05:09:31:33:05:cd:99:52:5b:fc:e0:10:b5.
Are you sure you want to continue connecting (yes/no)? yes ←初めて接続するサーバーの場合に確認を求められる。
Warning: Permanently added 'node2,192.168.33.12' (RSA) to the list of known hosts.
vagrant@node2's password: ←パスワードを入力
Last login: Fri Mar 7 16:57:20 2014 from 10.0.2.2
[vagrant@node2 ~]$ ←node2のコマンドプロンプト
[vagrant@node2 ~]$ pwd
/home/vagrant
[vagrant@node2 ~]$ exit
logout
Connection to node2 closed.
[vagrant@node1 ~]$
公開鍵認証方式での接続
キーペアの作成
公開鍵認証で使用するキーペアはssh-keygen
コマンドで生成する。
[vagrant@node1 ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/vagrant/.ssh/id_rsa): ←生成する秘密鍵ファイル名を入力
Enter passphrase (empty for no passphrase): ←パスフレーズを入力
Enter same passphrase again:
Your identification has been saved in /home/vagrant/.ssh/id_rsa.
Your public key has been saved in /home/vagrant/.ssh/id_rsa.pub.
The key fingerprint is:
c4:bf:ba:b6:e0:40:82:8c:29:ca:ee:ae:96:e4:07:c6 vagrant@node1
The key's randomart image is:
+--[ RSA 2048]----+
| |
| . |
| o |
|oo . . |
|*.. . S . |
|+E o . |
|=.o . . . |
|.+ . o ... |
|*+. ..+o |
+-----------------+
パスフレーズは秘密鍵を暗号化するためのもので、パスワード認証方式のパスワードとは別のもの。
パスフレーズを未設定にすることで、以後の接続でパスワード/パスフレーズの入力なしで接続することができるようになる。
公開鍵をサーバーに登録する
ssh-copy-idを使うと、リモートホストの指定ユーザーの~/.ssh/authorized_keys
に公開鍵が追加される。
[vagrant@node1 ~]$ ssh-copy-id node2
vagrant@node2's password:
Now try logging into the machine, with "ssh 'node2'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
ssh-copy-idが使えない場合は、sshコマンドでリモートホストに接続してauthorized_keys
に公開鍵を追加する。
[vagrant@node1 ~]$ cat ~/.ssh/id_rsa.pub | ssh node3 'cat >> ~/.ssh/authorized_keys; chmod 600 ~/.ssh/authorized_keys'
The authenticity of host 'node3 (192.168.33.13)' can't be established.
RSA key fingerprint is c4:4d:f9:05:09:31:33:05:cd:99:52:5b:fc:e0:10:b5.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'node3,192.168.33.13' (RSA) to the list of known hosts.
vagrant@node3's password:
authorizedkeys
は複数の公開鍵を登録するファイルなので、既存の情報を消してしまわないように追加モードで書き込む事。
公開鍵をサーバーに登録した後にsshコマンドで接続すると、パスワードを聞かれずにログインできるようになる。(パスフレーズを設定している場合はパスフレーズを聞かれる)
[vagrant@node1 ~]$ ssh node3
Last login: Fri Mar 7 16:57:20 2014 from 10.0.2.2
[vagrant@node3 ~]$
~/.ssh/内のファイル
- authorized_keys
- 接続を許可する公開鍵を登録しておくサーバー側のファイル。
- config
- SSH接続の情報を書くファイル。
- id_rsa
- ssh-keygenで生成した秘密鍵。
- id_rsa.pub
- ssh-keygenで生成した公開鍵。
- known_hosts
- 過去に接続したことがあるサーバー。
OpenSSHでは~/.ssh/
内のファイルがモード600(ユーザーのみ読み書き可能)でないと使用できない。
~/.ssh/config
~/.ssh/config
にはSSH接続時の情報を定義しておくことができるので、sshコマンドのオプションを省略したり、コマンドラインオプションでは指定できない情報も設定できる。
Host web01
HostName 127.0.0.1
User vagrant
Port 2222
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile /vagrant/.vagrant/machines/default/virtualbox/private_key
IdentitiesOnly yes
LogLevel FATAL
主要な設定項目
- Host
- sshコマンド等で指定するホスト名。
- HostName
- 実際に接続ホストのアドレス。IPアドレスや/etc/hostsに指定したホスト名等を指定する。
- User
- ユーザー名
- Port
- ポート番号
- IdentityFile
- 秘密鍵ファイル
以下のサイトでおそらく全設定項目が確認できる。
OpenSSH 日本語マニュアルページ - SSH_CONFIG
踏み台サーバー/SSHゲートウェイ/SSHプロキシ経由での多段SSH接続
現在使用しているマシンから作業対象マシンに接続したい時に、あるサーバーを経由しないといけないケースがある。
こういう経由しなければならないサーバーの事を「踏み台サーバー」とか「SSHゲートウェイ」とか「SSHプロキシ」とかいう。(以下、踏み台サーバー3)
踏み台サーバー経由で作業対象サーバーにSSH接続する場合、普通にやると先ず踏み台サーバーにsshコマンドで接続して、そこからさらに作業対象サーバーにsshコマンドで接続することになる。
[vagrant@node1 ~]$ ssh node2
Last login: Sun Feb 22 15:39:03 2015 from 192.168.33.11
[vagrant@node2 ~]$ ssh node3
Last login: Sun Feb 22 15:39:09 2015 from 192.168.33.12
[vagrant@node3 ~]$
この接続方法だとコマンドを2回実行するので面倒だし、踏み台サーバー上に秘密鍵を置いたりすることになるため、セキュリティ上あまり好ましくない(らしい)。
こういう時には~/.ssh/config
に多段SSH接続の情報を設定しておくと、踏み台サーバーに秘密鍵を置く必要もなく、コマンド一発で接続できるようになる。
以下はnode2を経由してnode3に接続する設定例。
Host node2
Host node3
ProxyCommand ssh -W %h:%p node2
[vagrant@node1 ~]$ ssh node3
Last login: Sun Feb 22 15:39:48 2015 from 192.168.33.12
[vagrant@node3 ~]$ exit
node2->node3->node4というように複数の踏み台サーバーを経由する設定もできる。
Host node2
Host node3
ProxyCommand ssh -W %h:%p node2
Host node4
ProxyCommand ssh -W %h:%p node3
WindowsでSSHを使用する
Windowsは標準ではSSHが使えるソフトはインストールされていない。
WindowsでSSHを使用するにはいくつかの方法がある。
Linuxコマンドが使える系ソフトを使用する
CygwinやGitをインストールするとOpenSSHが使えるようになる。
ただしLinux版と比較すると動作が若干不安定。
LinuxのVMを作成する
VMWareやVirtualBoxでLinuxのVMを作成してVMからSSHを使用する。
LinuxのOpenSSHを使用するので動作は安定している。
GUI系SSHクライアント
画面上で接続設定をして保存できるので便利。
パスワード認証のパスワードや公開鍵認証のパスフレーズも保存できるので接続時に入力不要になる。
踏み台サーバー経由の接続設定もできるが、複数の踏み台を経由する接続には対応していない。
キーペアの作成も行えるが、Puttyではちょっと特殊なものが作成されるので注意が必要。
-
ネットワーク上のサーバーに接続して作業する場合、10年くらい前まではTelnetを使用することが多かったが、Telnetではパスワードを平文で送信するためセキュリティ上の危険性があった。 ↩
-
Linuxではrootユーザーは必ず存在するしその他のユーザーも個人名やアプリ名(postgresやmongo等)を使う事が多いので発覚しやすい。パスワードも人間が入力するものなので覚えやすい文字列(ユーザー名+1234等)を使う事が多い為、パスワード認証方式を許可しているとセキュリティ的に脆弱になってしまう。 ↩
-
踏み台サーバー/SSHゲートウェイ/SSHプロキシは正確にはそれぞれ役割が違うかもしれないけどよくわかんない。 ↩