VirtualBox の Guest 側 CentOS 7 に対してホストから通信可能にする

# 目的・前提

* VirtualBox の Guest 側の Ruby on Rails サーバ等に対して ホスト側のブラウザからアクセスしたい
* DHCP 等で、IPアドレスが変化する状況でも同一のアドレスで通信したい
* ゲストOS は CentOS 7 で、Firewalld を利用している
* ホストOS は Windows 

# 実現方法
## VirtualBox 側でホストオンリーアダプタを設定する

もともと、VirtualBox のゲスト側のインスタンスでは NAT アダプタを使っている。
NAT アダプタを利用する場合、ゲストからインターネット等にはアクセス可能であるが、ホストからゲストにはアクセスできない制限がある。
ホストからゲストにアクセスしたい場合は、別途ホストオンリーアダプタというものを設定する必要がある。
ホストオンリーアダプタの設定について、詳しくは[Using VirtualBox Host-only Networking to run servers in your lap](https://blogs.oracle.com/fatbloke/entry/virtualbox_vms_with_multiple_vnics)に詳しく説明されている。

## Cent OS 7 側の Firewalld の設定を変更する
Cent OS 7 の firewalld では、`public`というゾーンがデフォルトに設定されている。

```
$ firewall-cmd --get-default-zone
public
```

Firewalld には、`public` 以外にも多くのゾーンが最初から設定されている。

```
$  firewall-cmd --get-zones
block dmz drop external home internal public trusted work
```

特にこの中で `trusted` というゾーンはすべての通信を許可する。

```
$ man firewalld.zones
(snip)
       trusted
           All network connections are accepted.
(snip)
```

この `trusted` をホストオンリーアダプタに設定する。

### 一時的に trusted にする

```
$ ip a # 192.168.56 のアドレスが enp0s8 のインタフェースに割り振られていることを確認する

$  firewall-cmd --get-zone-of-interface=enp0s8 # enp0s8 が設定前は、 public ゾーンであることを確認する
public

$ sudo firewall-cmd --zone=trusted --change-interface=enp0s8 # enp0s8 を trusted ゾーンに変更する
success
$ sudo firewall-cmd --reload # 変更を反映する
$  firewall-cmd --get-zone-of-interface=enp0s8 # enp0s8 のゾーンが trusted に変更されたことを確認する
trusted
```

### 今後も永久的に trusted にする

そのインタフェースの UUID を取得する

```
$ uuidgen enp0s8
deadbeaf-dead-beaf-dead-beafdeadbeaf
```
そのインタフェースのネットワークスクリプトを作成する

```
$ sudo cp /etc/sysconfig/network-scripts/ifcfg-enp0s3  /etc/sysconfig/network-scripts/ifcfg-enp0s8
$ sudo vim /etc/sysconfig/network-scripts/ifcfg-enp0s8
NAME 、UUID を適切な値に修正する
ZONE=trusted という記述をファイル末尾に追記する 
```

## Linux 側をホストから名前解決可能にする
Windows 側から簡単に名前解決を可能にするため、 zeroconf プロトコルを使える avahi-daemon をインストールする

```
$ sudo yum install avahi -y
$ sudo vim /etc/avahi/avahi-daemon.conf  # ホストオンリーネットワークだけ avahi を有効にする
(snip) 
#allow-interfaces=eth0 # この行をコメントアウトする
allow-interfaces=enp0s8 # この行を追加する
(snip)
$ sudo systemctl restart avahi-daemon # avahi-daemon を再起動して設定変更を反映する。reload でも良い
```

## Windows 側から名前解決できるようにする
Windows で ZeroConf を使えるようにするため、[Bonjour Print Services](https://support.apple.com/kb/DL999?viewlocale=en_US&locale=en_US) をインストールする。iTunes でも良いが、iTunes をこの目的のためにインストールするのはなにかが違う気がするので Bonjour をインストールする。

## 動作を確認する
### Windows 側からLinux 側に疎通可能かを確認する。

コマンドプロンプトを開いて、下記を実行する

```
>ping centos7.local

centos7.local [fe80::a00:27ff:fe5d:4%11]に ping を送信しています 32 バイトのデータ:
fe80::a00:27ff:fe5d:4%11 からの応答: 時間 =1ms
fe80::a00:27ff:fe5d:4%11 からの応答: 時間 <1ms
fe80::a00:27ff:fe5d:4%11 からの応答: 時間 <1ms

fe80::a00:27ff:fe5d:4%11 の ping 統計:
    パケット数: 送信 = 3、受信 = 3、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 、最大 = 1ms、平均 = 0ms
```

### Ruby on Rails にアクセスできるかを確認する

Cent OS 7 側で 下記のコマンドを実行して、Ruby on Rails のサービスを起動する

```
$ ./bin/rails s -b 0.0.0.0
=> Booting Puma
=> Rails 5.0.0.1 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.6.0 (ruby 2.3.1-p112), codename: Sleepy Sunday Serenity
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
Started GET "/" for 192.168.56.1 at 2016-11-17 18:28:27 +0900
```

Windows 側のブラウザで `http://centos7.local:3000/` にアクセスする

正しくアクセスできれば成功である。

# 後日談

なんとなく、ZeroConf を使ってしまったが、Cent OS 7 側のホストオンリーネットワークの
 IP アドレスは固定できるので、そもそも ZeroConf を使う必要はなかった。
Windows 側で `hosts` ファイルを編集すればそれで十分。

この目的だけではなく、ほかの理由で、ZeroConf をすでに使っている状況であれば、良いかもしれない。

# 参考文献
[Vagrant + rails + CentOS7の組み合わせでゲストOSのlocalhost:3000に接続できない場合](http://qiita.com/kota2_0/items/27530febaf24a3bf285f)