【Vagrantドキュメント意訳】10.ネットワーク

# はじめに

本文章は、Vagrant公式サイト内のドキュメント内の[NETWORKING](https://www.vagrantup.com/docs/networking/)に記載されている内容を意訳に近い形で日本語化したものである。
誤訳が含まれている可能性が十分にあることを踏まえて、参考いただきたい。

# ネットワーク

Vagrantは生成されたVagrant環境へアクセスする為に、転送ポート、公共ネットワークへの接続、プライベート・ネットワークの生成など高度なネットワーク・オプションを提示する。

高度なネットワーク・オプションは複数プロバイダをまたぐ抽象さを定義することを意味する。VagrantfileをVirtualBoxマシンを起動する為に使用することができ、VMWareなどで同じようにふるまうことを、そのVagrantfileに期待することができる。

初めに[基本的な使い方](https://www.vagrantup.com/docs/networking/basic_usage.html)を読み、具体的なネットワークの基本的な事項についての文書を左にあるナビゲーションを追いながら続けること。

## 高度な設定

いくつかのケースにおいて、これらのオプションは上級*すぎる*。もっと最適化することを望んだり、マシンの基礎にあるネットワーク・インタフェースの設定をしたいかもしれない。多くのプロバイダで、これを実現する為に[プロバイダ特有の設定](https://www.vagrantup.com/docs/providers/configuration.html)ができる。どのようなオプションが適用できるかについては、使用しているプロバイダ特有のドキュメントを読むこと。

> 初心者向け：Vagrantのワーク・フローが快適に思え、基礎レベルで動作するさせるべきものに出会うまで、上級ネットワーク・オプションだけを使用することを強く推奨する。不適切な設定が行われた場合、プロバイダ特有のネットワーク設定は、ゲスト・マシンからあなたを即座に締め出すことができる。

# ネットワークの基本的な使い方

Vagrantがどのようにゲスト・マシンをネットワークに接続できるようにするかについて、複数のオプションを提示している。しかし、知っておくべき重要なネットワーク設定のすべてに共通するいくつかのポイントとなるような標準的な使用方法がある。

## 設定

すべてのネットワークは[Vagrantfile](https://www.vagrantup.com/docs/vagrantfile/)の中で、`config.vm.network`メソッド呼び出しを使用することで設定される。例えば、ポート・フォワーディングの定義は以下のようなVagrantfileになる。

```bash
Vagrant.configure("2") do |config|
  # ...
  config.vm.network "forwarded_port", guest: 80, host: 8080
end
```

すべてのネットワークの種類は、上述のように`:forwarded_port`のような識別子をもつ。これに続くのはネットワークの種類ごとに異なる設定引数である。ポート・フォワーディングの場合、2つの数値の引数が期待される。ゲストのポートの後に、ゲストのポートがアクセスすることのできるホスト上のポートを続ける。

## マルチ・ネットワーク

マルチ・ネットワークはVagrantfile内で複数の`config.vm.network`を呼ぶことによって定義される。この正確な意味は、それぞれの[プロバイダ](https://www.vagrantup.com/docs/providers/)をによって異なるが、一般的にはその順番がネットワークを有効化する順番を指定する。

## ネットワークの有効化

ネットワークは、Vagrantfile内で定義されれば`vagrant up`や`vagrant reload`処理の一部として自動的に設定および有効化される。

# ポートの転送

## ネットワーク識別子：`forwarded_port`

Vagrantのポートの転送は、TCPかUDPのいずれかを経由して、ホスト・マシン上のポートにアクセスしたり、ゲスト・マシン上のポートへすべてのデータを転送したりできる。

例えば、ゲスト・マシンがポート80でリッスンしているWebサーバを稼働させている場合に、ホスト・マシンの8080（もしくは任意の）ポートへポート転送の対応付けをすることができる。そして。`localhost:8080`をブラウザで開きWebサイトを閲覧すると、すべての実際のネットワーク・データはゲスト・マシンへと送信される。

## ポートの転送の定義

ポートの転送の設定には2つのパラメータが必要である。ゲスト上のポートとホスト上のポートである。以下に例を示す。

```bash
Vagrant.configure("2") do |config|
  config.vm.network "forwarded_port", guest: 80, host: 8080
end
```

これはホスト上の8080ポートを介してゲスト上の80ポートへアクセスすることができる。

多くのプロバイダにおいて、デフォルトでポートの転送はすべてのインタフェースに対してバインドされている。これは、ネットワーク上のそのほかのデバイスが転送ポートへアクセスできることを意味する。アクセスを制限したいならば、後述する`gest_ip`と`host_ip`の設定を参照のこと。

## オプション・リファレンス

これは、ポート転送に対して適応可能なオプションの、完全な一覧である。`guest`と `host`のオプションのみが必須である。このセクションの末尾で、これらのオプションの使用例の詳細を示す。

* [`guest`](https://www.vagrantup.com/docs/networking/forwarded_ports.html#guest) (整数値) - ホスト上に公開したいゲスト上のポート。これはいずれのポートでもよい。
* [`guest_ip`](https://www.vagrantup.com/docs/networking/forwarded_ports.html#guest_ip) (文字列) - 転送ポートをバインドするゲストのIP。これが設定されていなければ、ポートはすべてのIPインタフェース転送される。デフォルトでは、これは空である。
* [`host`](https://www.vagrantup.com/docs/networking/forwarded_ports.html#host) (整数値) - ゲスト上のポートへアクセスする為に使用する、ホスト上のポート。これは、Vagrantがrootとして稼働（推奨されない）してない限り、1024より大きくなければならない。
* [`host_ip`](https://www.vagrantup.com/docs/networking/forwarded_ports.html#host_ip) (文字列) - 転送ポートをバインドしたいホスト上のIP。これが設定されていなければ、すべてのIPに転送される。デフォルトでは、これは空である。
* [`protocol`](https://www.vagrantup.com/docs/networking/forwarded_ports.html#protocol) (文字列) - "udp"か"tcp"を指定する。転送ポートを通過することを許可するプロトコルを設定する。デフォルトでは"tcp"である。

## ポート転送プロトコル

デフォルトでは、定義されたいかなるポートもTCPプロトコルのみを転送する。オプショナルである3番目のパラメータとして、UDPトラフィックを受け渡すために`protocol: 'udp'`を指定できる。もし、与えたポートが両方のプロトコルで同じポートをリッスンする必要があるならば、それぞれのプロトコルで指定したポートを定義する必要がある。例を示す。

```bash
Vagrant.configure("2") do |config|
  config.vm.network "forwarded_port", guest: 2003, host: 12003, protocol: "tcp"
  config.vm.network "forwarded_port", guest: 2003, host: 12003, protocol: "udp"
end
```

## ポートの衝突と補正

複数のVagrantマシンを稼働した時に、意図せず生成した転送ポートの定義が互いに衝突する(2つの独立したVagrantプロジェクトが8080ポートへ転送するなど）のはよくあることである。Vagrantはこの衝突を検出し、補正するための組み込まれた機構があり、自動的に動作する。

ポート衝突検出は常に実施させる。Vagrantは、トラフィックやコネクションを受け付けるためのホスト上の転送ポートを定義することを許さない。

ポート衝突自動補正は、それぞれの転送ポートに対して、手動で有効化する必要がある。それは、ポート転送が発生したときによく驚いてしまったり、ポートが適切に転送されていないと考えるVagrantユーザを誘発させたりするためである。自動補正は簡単に有効にできる。

```bash
Vagrant.configure("2") do |config|
  config.vm.network "forwarded_port", guest: 80, host: 8080,
    auto_correct: true
end
```

最後の`:auto_correct`パラメータにtrueを設定すると、Vagrantにいかなる衝突に対しても自動的に補正するようにさせる。`vagrant up`または`vagrant reload`の間、Vagrantはすべての衝突の検出や行われた自動補正に関する情報を出力するので、それを感知し適切に対応することが出来るだろう。

# プライベート・ネットワーク

## ネットワーク識別子：`private_network`

Vagrantのプライベート・ネットワークは、グローバルなインターネットからアクセスできる公のものではない、いくつかのアドレスによってゲスト・マシンにアクセスすることができるようにする。一般的には、これは[プライベート・アドレス空間](https://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces)内でマシンがアドレスを得ることを意味する。

同一のプライベート・ネットワーク(通常、同じ[プロバイダ](https://www.vagrantup.com/docs/providers/)を背景に持っている制限もあるが)内の複数のマシンは、そのプライベート・ネットワーク上で互いに通信することができる。

> *ゲスト・オペレーティング・システムのサポートについて。*プライベート・ネットワークは通常、ゲスト・マシン上のネットワーク・アダプタの設定が必要である。この手順はOS毎に異なる。Vagrantは様々なゲスト・オペレーティング・システム上でのネットワークの設定の仕方の知識を持っているが、特に古いもの、または新しいオペレーティング・システムを使用している場合、プライベート・ネットワークは適切に設定されない可能性がある。

## DHCP

プライベート・ネットワークを使用するための最も簡単な方法は、DHCPによって付与されたIPを許可することである。

```bash
Vagrant.configure("2") do |config|
  config.vm.network "private_network", type: "dhcp"
end
```

これは、予約アドレス空間からIPアドレスを自動的に割り当てる。そのIPアドレスはマシンへSSHするための`vagrant ssh`を使用したり、そのIPを見つけるための適切な`ifconfig`などのコマンド・ライン・ツールを使用することで確認することができる。

## 静的IP

マシンに対して静的IPアドレスを指定することもできる。これによって、あらかじめ知っている静的IPアドレスを使用してVagrantが管理しているマシンにアクセスすることができるようになる。静的IP用のVagrantfileは以下のようになる。

```bash
Vagrant.configure("2") do |config|
  config.vm.network "private_network", ip: "192.168.50.4"
end
```

静的IPが同じネットワーク上で、他のどのマシンとも衝突しないことを確認することは、ユーザーにゆだねられる。

IPアドレスは自分の好きなように選ぶことができるが、[予約されたプライベート・アドレス空間](https://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces)から使用するべきである。これらのIPアドレスは、公のIPの宛先とならないことが保証されており、多くのルータは実際に外界に向けてトラフィックが出ていかないようにブロックしている。

いくつかのオペレーティング・システムにおいて、静的IPアドレスに対する追加的な設定、デフォルト・ゲートウェイの設定やMTUの設定など、が適応できる。

> *警告！* システム上のほかのIP空間に重複するようなIPアドレスを選ばないように。これはネットワークの未達を引き起こす。

## IPV6

IPv6による静的IPアドレスを指定することができる。IPv6用のDHCPはサポートされていない。IPv6を使用するには、IPとしてIPv6アドレスを指定するだけである。

```bash
Vagrant.configure("2") do |config|
  config.vm.network "private_network", ip: "fde4:8dba:82e1::c4"
end
```

これはIPアドレスをマシンに割り当てる。/64サブネットの全体は予約されている。IPv6に対して認められている、予約されたローカルアドレスをきちんと使用すること。

`netmask`オプションを変更することで、(デフォルトでは64である)プレフィックス長を変更することもできる。

```bash
Vagrant.configure("2") do |config|
  config.vm.network "private_network",
    ip: "fde4:8dba:82e1::c4",
    netmask: "96"
end
```

IPv6がサポートしていプライベート・ネットワークはVagrant 1.7.5で追加され、すべてのプロバイダに対して動作しないかもしれない。

## 自動設定の無効化

もし、自分自身でネットワーク・インタフェースの設定を手動で行いたいのであれば、`auto_config`で指定することでVagrantの自動設定機能を無効化することができる。

```bash
Vagrant.configure("2") do |config|
  config.vm.network "private_network", ip: "192.168.50.4",
    auto_config: false
end
```

`auto_config`で設定する前にすでに、Vagrant環境を開始しているならば、あるファイルが特定の場所に配置される。それらのファイルを手動で取り除くか、マシンをdestroyまたは再createする必要がある。

そのVagrantによって生成されるファイルはOSに依存する。例えば、多くのLinuxディストリビューションでは、`/etc/network/interfaces`である。一般的に、ネットワーク・インタフェースがそのディストリビューションにおいて通常設定される場所で見つけることができるだろう。

# パブリック・ネットワーク

## ネットワーク識別子:public_network

Vagrantのパブリック・ネットワークはプライベート・ネットワークよりもプライベートではない。そして、そのあいまいな定義のために、正確な意味は実際には[プロバイダとプロバイダ]の間で変化する。考え方としては、[プライベート・ネットワーク](https://www.vagrantup.com/docs/networking/private_network.html)は一般的なパブリック・アクセスをマシンに対して許さないが、パブリック・ネットワークはそれができる。

> *混乱した？* 我々も同じである。通常、パブリック・ネットワークで行われるべきであり、ブリッジ接続をサポートしていないプロバイダでは通常、パブリック・ネットワークへの対応付けを行う他の機能を持っていいないので、パブリック・ネットワークは将来のリリースにおいて、`:bridged`に置き換えられるであろう。

> *警告！* Vagrant Boxはデフォルトで、また、設計上で非セキュアである。パブリック・パスワードの機能や、SSHアクセスに対する非セキュアな鍵ペア、さらにはSSHを介したrootアクセスの可能性など。これらの既知の認証方法を用いて、ネットワーク上のだれでもがそのBoxに簡単にアクセスできる。パブリック・ネットワークを使用するためにVagrantを設定する前に、すべてのセキュリティにかかわる可能性を検討し、セキュリティ・リスクの可能性を確認する為に[デフォルトBoxの設定](https://www.vagrantup.com/docs/boxes/base.html)をレビューすること。

## DHCP

パブリック・ネットワークを使うための最も簡単な方法は、DHCPによるIPアドレスの割り当てを許すことである。この場合、パブリック・ネットワークの定義は非常に簡単である。

```bash
Vagrant.configure("2") do |config|
  config.vm.network "public_network"
end
```

DHCPが使用されたとき、IPはマシンにSSHするために`vagrant ssh`を使用したり、そのIPを見つけるための適切な`ifconfig`などのコマンド・ライン・ツールを使用することで確認することができる。

## デフォルト・ルートを割り当てられたDHCPを使う

いくつかの場合では、デフォルト・ルートが割り当てられたDHCPを変更しないことが要求される。これらの場合、`use_dhcp_assigned_default_route`オプションを指定する。

```bash
Vagrant.configure("2") do |config|
  config.vm.network "public_network",
    use_dhcp_assigned_default_route: true
end
```

## 静的IP

設定に従い、ブリッジされたインタフェースのIPを手動で設定したいと思うかもしれない。これを行うにはネットワークを定義するために:ip節を追加する。

```bash
config.vm.network "public_network", ip: "192.168.0.17"
```

## デフォルト・ネットワーク・インタフェース

一つ以上のネットワーク・インタフェースがホスト・マシン上で得られるならば、Vagrantは仮想マシンがブリッジする先をどのインタフェースにするか選択することを尋ねる。デフォルト・インタフェースはネットワークの定義に`:bridge`節を追加することによって指定することができる。

```bash
config.vm.network "public_network", bridge: "en1: Wi-Fi (AirPort)"
```

適応したいインタフェースを示す文字列は、使用可能なインタフェースと正確に一致している必要がある。もし、それが見つからなければ、Vagrantは使用できるネットワーク・インタフェースの一覧から選ぶように尋ねてくる。

あるプロバイダでは、ブリッジに対するアダプタの一覧を指定することが可能である。

```bash
config.vm.network "public_network", bridge: [
  "en1: Wi-Fi (AirPort)",
  "en6: Broadcom NetXtreme Gigabit Ethernet Controller",
]
```

この例では、一つ目のネットワーク・アダプタが存在し、これがブリッジとして使用される。

## 自動設定の無効化

もし、自分自身でネットワーク・インタフェースの設定を手動で行いたいのであれば、`auto_config`で指定することでVagrantの自動設定機能を無効化することができる。

```bash
Vagrant.configure("2") do |config|
  config.vm.network "public_network", auto_config: false
end
```

シェル・プロビジョナはインタフェースのIPを設定するために使用することができる。

```bash
Vagrant.configure("2") do |config|
  config.vm.network "public_network", auto_config: false

  # manual ip
  config.vm.provision "shell",
    run: "always",
    inline: "ifconfig eth1 192.168.0.17 netmask 255.255.255.0 up"

  # manual ipv6
  config.vm.provision "shell",
    run: "always",
    inline: "ifconfig eth1 inet6 add fc00::17/7"
end
```

## デフォルト・ルータ

設定に従い、デフォルト・ルータを手動で設定したいと思うかもしれない。パブリック・ネットワークを超えてほかのネットワークからVagrant Boxへアクセスする必要があるならば必須である。これを行うにはシェル・プロビジョナ・スクリプトを使用することができる。

```bash
  config.vm.network "public_network", ip: "192.168.0.17"

  # default router
  config.vm.provision "shell",
    run: "always",
    inline: "route add default gw 192.168.0.1"

  # default router ipv6
  config.vm.provision "shell",
    run: "always",
    inline: "route -A inet6 add default gw fc00::1 eth1"

  # delete default gw on eth0
  config.vm.provision "shell",
    run: "always",
    inline: "eval `route -n | awk '{ if ($8 ==\"eth0\" && $2 != \"0.0.0.0\") print \"route del default gw \" $2; }'`"
```

上記はやや複雑であることと、ゲストOS特有であることに注意すること。しかし、よく聞かれる質問であるので、どのように行うべきかの大まかな考え方を記載した。

# 関連記事

* 前の記事：[【Vagrantドキュメント意訳】09.プロビジョニング](http://qiita.com/ringo0321/items/38743442a9abfc3be5b2)
* 次の記事：[【Vagrantドキュメント意訳】11.同期フォルダ](http://qiita.com/ringo0321/items/aec4c543cce63e60a529)