（自分のための覚え書き）FreeBSDとBHIVEとJAILとVLANとIPFWとBRIDGEとVNETと、たくさん！

#manやハンドブックのみではよくわからないので各所からつまみ食いして動作を見ながら記録を残したい。

#せっかちな私のために結論から
vmhyveやiocageを使用するとき、ホスト側サービスは物理NICではなくブリッジにアドレスを付与し、物理NICと同じようにIPFWルールを設定できる。これはIN/OUT,VIA/RECV/XMITの指定が記述の見た目通りの作用が期待できることを意味する。
仮想環境側としてはブリッジのメンバーであるトンネルのホスト側となる仮想NICにはデバイス番号が動的に付き、また（そのように設定しない限り）ブリッジとそのメンバーにホスト側でのIPFWの設定が作用しないので仮想マシン内部のIPFWはその配慮が必要。
さらにブリッジやそのメンバーにフィルタを設定するにしても、何か見落としがない限りホスト側でFWを組むときに動的デバイス名を**個別に**対象にするのはかなり面倒。

それでも仮想マシン側へのフィルタをホスト側で実施したい場合は下記記述を参照し、ブリッジのFWとして設定が可能。

#iocageの覚え書き
コマンド起動時にストレージを総なめにするらしくトラブルなどでマウントしてあるNFSがアクセスできなくなっているとコマンドが止まったかのような遅さになる。パケットフィルタを順次再設定していた時にバックアップ先用のNFSを忘れてて原因追及に無駄に時間がかかった。

#JAIL内部のIPFWについて
ルール自体は個別に扱われるので番号など気にする必要はないのですが、ログがホスト側に出てしまう問題（何か理由があるらしいが不明）があってログ上で混同しないようにルール番号が被らないようにする必要がある。
またJAIL起動時にsecurelevelを3にするとIPFWを設定すること自体ができなくなるので仮想マシン内のrc.confにkern_securelevel_enable="YES"とkern_securelevel=3をいれる。

#インターフェース指定についての覚書
tap*/vnet*など、インタフェース番号をワイルドカードで指定可能。
またrecv tap*,vnet*は一つの名称として扱われる模様。recvを複数指定しても個別とは扱われない模様。
エラーにならないのは何か意味がある、はず。

#ブリッジインターフェースとIPFWの覚え書き（書き直し待ち）
ホストFWを設置するためにIPFWでパケットフィルタを記述するわけですがVLANやJAILやBHYVEなどで複数のサービスを入れてあるとブリッジインターフェースが思わぬ面倒を引き起こす。
フィルタの作用する場所がどこかなのかを意識せずに記述すると連鎖的に次から次に追加のフィルタを入れてしまうので気をつける。特にブリッジインターフェースにフィルタポイントを設定すると着信と転送の二回分ログが残るためフィルタ設定を間違えやすい。
ホスト上に入れたサービスはブリッジインターフェースで待ち受けるので通常のインターフェースのようにブリッジインターフェースに発信/着信フィルタを設定できるが、ブリッジ配下にある仮想系のインターフェースはiocageやvm-bhyveなどの動的設定環境だと命名が変わるので発信方向のフィルタは動的処理が必要になる。めんどくさいので基本的に着信方向のみ設定する。

#ブリッジの何処にIPFWが作用するのかは以下の設定を確認する。
各設定値は基本的に**0 = OFF, 1 = ON**
##IPFWの有効化
###net.inet.ip.fw.enable: 1
IPv4のフィルタを有効にする
###net.inet6.ip6.fw.enable: 1
IPv6のフィルタを有効にする

##IPFWでL2のフィルタ
###net.link.ether.ipfw: 0
L2のパケットを対象とする。実装的にブリッジより上のレイヤーなのでブリッジを通る物は対象にならない。IPFWでIPフィルタの記述のままL2フィルタを記述しなかったら通信が全遮断される。

##ブリッジ上のフィルタポイントやレイヤーを指定
###net.link.bridge.ipfw: 0
これはブリッジ上のIPパケットをIPFWの対象にするフラグ**では無く**、ブリッジを通過するL2のパケットをIPFWの対象とするもの。
###net.link.bridge.ipfw_arp: 0
L2のARPをフィルタ対象とする。net.link.bridge.pfil_onlyipが有効の時、ARPはフィルタされること無く転送（ブリッジ）される。
net.link.bridge.ipfw=1の時、ARPもフィルタに引っかかったのでこの設定の意味は要調査。

###net.link.bridge.pfil_local_phys: 0
物理インターフェースにフィルタポイントを置く。詳細不明。
###net.link.bridge.pfil_member: 0
これが有効の時、jail内部のIPFWのログに変化が見られるので何かしら使い道がある模様。
正直ここまで使う必要はない気もする。

###net.link.bridge.pfil_bridge: 0
ブリッジそのものがフィルタポイントとなる。
inとrecvのみ機能する。vlan&jail&vnetでvlan1-bridge1-vnet1のときIN方向はrecv vlan1でOUT方向はrecv vnet1で指定。どちらもdirectionはinのみ。複数のブリッジがあってもブリッジ自体は指定できない。
またブリッジ自体がフィルタポイントといっても個別のブリッジが一つになるわけではなくちゃんと通信は分けられている（当たり前）

（以下略）
ブリッジメンバから着信(IN)しブリッジが転送(FWD/OUT)する。転送先メンバを指定できない
（A-bridge-BでA->Bをout via B指定しても解釈的にはB->bridgeになるようで機能しない。
応答パケットを指定することは出来るが着信のIN/FWDを別途指定することになる。
recv A keep-stateは機能するがxmit B keep-stateもxmit bridge keep-stateもrecv A xmit B keep-stateもrecv A xmit bridge keep-stateも機能しない）
ブリッジにアドレスを付けてlistenするときはブリッジだけがルールの対象。tap/tunやvnetなどのbhyveやjailはメンバインターフェースを指定可能。
###net.link.bridge.pfil_onlyip: 0
IPパケットのみをフィルタ対象とする。これが有効の場合ARPパケットはフィルタを通らずに転送（ブリッジ）され、またIPv4/IPv6以外のパケットはすべて転送（ブリッジ）されない。

#すべてのサービスに対する前面のFWとして構成する時
% sysctl net.link.ether.ipfw net.link.bridge
net.link.ether.ipfw: 0
net.link.bridge.ipfw: 0
net.link.bridge.allow_llz_overlap: 0
net.link.bridge.inherit_mac: 0
net.link.bridge.log_stp: 0
net.link.bridge.pfil_local_phys: 0
net.link.bridge.pfil_member: 0
net.link.bridge.ipfw_arp: 0
net.link.bridge.pfil_bridge: 1
net.link.bridge.pfil_onlyip: 0
で問題ない。
これは外部との間に設置されたルーターと似た意味がある。
ブリッジを通過する通信すべてにルールを設定できるので国別フィルタなどを一箇所で設置できる。net.link.bridge.pfil_bridgeを使用しない場合は各サービス側にフィルタが必要。
なおセキュリティ的に理解が無ければL2フィルタ設定はしない方が無難。L2の通信はARPだけじゃないしいろいろ引っかかるのですごく面倒。
ただしL2レベルの偽装通信とかのためにL2フィルタのIPFWをJAILに採用したとのこと。

#リモート設定時の注意事項
リモート作業中は自分自身の通信を遮断しないように先頭に静的ルールを入れておくと事故防止になる。
もっと良いのはルーターのVPN経由で対象サーバーのコンソールに接続出来るようにしておく。