Vagrant で作った VM にやってはいけない2つのこと

## 1. 自前の公開鍵「だけ」を設置する

### やっちゃうと起きること

* `vagrant up` 等の実行のたびにパスワード入力が必要になる
* `vagrant up` 等が実行できなくなる

### 詳細

使用する box ファイルにもよるのかもしれませんが、`vagrant up` や `vagrant halt` 等のコマンドは内部的に「公開鍵認証による VM への SSH 接続」を行っているようです。その際に使用している秘密鍵のありかは、VM が立ち上がっている状態で `vagrant ssh-config` すると確認できます。

```bash
$ vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/megane42/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL
```

下から3行目、 IdentityFile という欄がそれですね。

そして、それと対になる公開鍵が自動的に VM 上に生成されています。vagrant ユーザのホームディレクトリ配下 (`~/.ssh/authorized_keys`) に置いてあります。

この公開鍵を消し去ってしまうと、当然ながら公開鍵認証に失敗します。sshd のデフォルト設定では、「公開鍵認証に失敗した場合、パスワード認証を試みる」という挙動をとるため、`vagrant up`等の実行のたびにパスワードの入力が求められます（ユーザ名/パスワードの両方とも「vagrant」）。

```
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 => 2222 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
Text will be echoed in the clear. Please install the HighLine or Termios libraries to suppress echoed text.
vagrant@127.0.0.1's password:vagrant   # <=== ここ！！！
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => /Users/megane42/chef-repo
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: to force provisioning. Provisioners marked to run always will still run.
```

もっと面倒なケースが、事前に sshd の設定をして、パスワード認証をオフにしていた場合です。この場合、一度ログアウトしてしまうと、以下のようにログインできなくなってしまいます。こうなってしまったら、使用する秘密鍵を自前のものに設定し直しましょう（[参考](http://qiita.com/t_732_twit/items/2303a0c3f27c288382c5#1-4)）。

```
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 => 2222 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
    default: Warning: Authentication failure. Retrying... # <=== ここでコケ続ける！
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
^C==> default: Waiting for cleanup before exiting...
Vagrant exited after cleanup due to external interrupt.
```

### 起こりうるシーン（筆者の体験談）

* chef のレシピで公開鍵設置まで自動化しようとした際に、勢い余ってこの公開鍵を消し去ってしまった。

### 対策

* vagrant ユーザ用にデフォルトで用意されている公開鍵は削除しない
* `vagrant xxx` 系のコマンドが使用する秘密鍵を自前のものに設定し直す

## 2. sudo にパスワードが必要な設定にする

### やっちゃうと起きること

`vagrant up` 等が実行できなくなる

### 詳細

前述の通り、`vagrant up` や `vagrant halt` 等のコマンドは、まず ssh で VM に接続し、そのあと VM 内で一連の処理（プロビジョニング等）を実行しているようです。この「一連の処理」には sudo 権限が必要な処理も含まれています。そのため、 vagrant ユーザがパスなしで sudo できる設定にしておかないと、実行中にエラーが発生して中断してしまいます。

```
$ vagrant halt
==> default: Attempting graceful shutdown of VM...
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

shutdown -h now

Stdout from the command:



Stderr from the command:

sudo: no tty present and no askpass program specified
```

この場合でも `vagrant ssh` はできるはずなので、落ち着いて再度ログインし、`/etc/sudoers` や `/etc/sudoers.d/vagrant` を設定し直しましょう。

### 起こりうるシーン（筆者の体験談）

* 本番の Web サーバを模した VM 設定にするために、 sudo にパスワードが必要な設定にしていた

### 対策

* vagrant ユーザが「パスなしsudo」できるように sudoers を設定する
* 本番サーバーと vagrant とで sudoers の設定を変えられるようなレシピにしておく
    * nodes やら environment やらで

## 参考
http://docs.vagrantup.com/v2/boxes/base.html