[FreeBSD-users-jp 95501] Re: ipfwで特定IP以外の接続を転送したい
Hiroki Sato
hrs at allbsd.org
Wed Apr 1 20:33:47 UTC 2015
佐藤です。
Hiroo Ono (小野寛生) <hiroo.ono+freebsd at gmail.com> wrote
in <CANtk6SgbFQ8AbVPazrLm_KPtK_Hcyvm-N0wAaD7JTfco4_2Ztg at mail.gmail.com>:
hi> 2015年3月31日 1:30 <zen-freebsd-users at suzuki.que.ne.jp>:
hi> > 鈴木@葛飾区です。
hi> > なんか、最初のご質問を私読み違えてますね。。。リモートへの転送と大変な
hi> > 勘違いで。。
hi> >
hi> > fwd 127.0.0.1,2222 なのでローカルへの転送なのでnatを使うまでもなくルー
hi> > ルにマッチすれば2222に転送されるはずですね。。。
hi>
hi> 私もそう思ってはじめはコメントするのを控えたのですが、「BSDカーネルの
hi> 設計と実装」13.4節に
hi> “ホストが複数のアドレスを持っている場合、パケットはその送信先がこれら
hi> のどれかに一致すれば受け入れられる。”
hi> とありますので、127.0.0.1:2222 に届いたけれども、パケットの宛先アドレ
hi> スとポート番号を見て
hi> 192.168.11.3:22 宛のパケットという処理がされているのではないかと思いま
hi> す。
hi> ということで、パケットを書き換える NAPT が必要という指摘は正しいはずで
hi> す。
hi> よくわかっていませんが。
このケースはローカルへの転送ですので、NAPT は必要ありません。
次の条件
- 127.0.0.1:2222 で listen している sshd と、
192.168.11.3:22 で listen している sshd が、それぞれ
同一のホスト (以降ホスト B と呼びます) に存在している
- ホスト B の IPFW の fwd ルールで、192.168.11.3:22 宛のパケットが
127.0.0.1:2222 に転送される
が満たされる場合、別のホスト 192.168.11.2 (以降ホスト A と
呼びます) からの TCP 接続要求は、次のような動作になります。
1. 始点 192.168.11.2:E, 終点 192.168.11.3:22 の
TCP SYN が A から B に送られる。(E は ephemeral port)
2. IPFW がホスト B 上で 1. のパケットを 127.0.0.1:2222 に転送する。
この時、fwd ルールは、パケットの始点・終点アドレスを書き換えないため、
実際には 127.0.0.1:2222 に送られるにも関わらず、
ホスト B のネットワークスタックが socket レベルで認識する
終点アドレスは 192.168.11.3:22 のままです。
3. 2222 ポートで listen している sshd は、パケットを受け取って
accept(2) をコールし、接続用の新しい socket を生成する。
この受け取ったパケットは、192.168.11.2:E -> 192.168.11.3:22 という
始点・終点アドレスとして解釈されるため、ホスト B からの
TCP SYN+ACK の返送は、逆転して 192.168.11.3:22 -> 192.168.11.2:E に
なります。
つまり、接続用の新しい socket には、ピアの始点として
127.0.0.1:2222 ではなく、192.168.11.3:22 が設定されます。
したがって、実際にパケットは 127.0.0.1:2222 に転送されているにも関わらず、
- A->B 方向の通信は 192.168.11.2:E -> 192.168.11.3:22
- B->A 方向の通信は 192.168.11.3:22 -> 192.168.11.2:E
というアドレスにパケットが流れているように見えることになり、
アプリケーションからは、転送の事実は見えません。
sshd などのデーモンは accept した時点で接続用の socket から
通信相手のアドレス・ポート番号を取得しますが、
得られるピアの始点・終点には、127.0.0.1:2222 が現れないということです。
なので、2222/tcp と 22/tcp で待ち受けている 2 つの sshd がホスト B に
あって、始点アドレスを条件に IPFW fwd で振り分けた場合、
外からは、どちらも 22/tcp に接続しているように見えます。
127.0.0.1:2222 で待ち受けているのに、192.168.11.3:22 から通信が
行なわれているように動作するのは奇妙な話のように思えますが、
listen しているアドレスと、accept の時の終点アドレスが
異なっているという状態は、特別なものではありません。
たとえばデーモンが INADDR_ANY (0.0.0.0) で listen している場合、
accept して生成される通信用 socket のピア始点アドレスは
当然ながら 0.0.0.0 ではなく、接続してきた相手のアドレスが使われます。
それとまったく同じです。
Tetsuya Ito <chaltier at agate.plala.or.jp> wrote
in <20150331212326.2783.A7D5A726 at agate.plala.or.jp>:
ch> 結果を纏めますと、
ch>
ch> add 1001 pass tcp from any to any established
ch> add 1002 fwd 127.0.0.1,2222 tcp from not <特定IP> to me 22
ch>
ch> ⇒ 先にestablishedがある場合はNG (22/tcpに接続される)
ch>
ch> add 1001 fwd 127.0.0.1,2222 tcp from not <特定IP> to me 22
ch> add 1002 pass tcp from any to any established
ch>
ch> ⇒ 想定通り特定IP以外は2222/tcpに接続される。
ch>
ch> という結果となりました。
ch>
ch> ただ、ローカルネットの接続まで拒否されてしまうので、ちょっと困ってます。
ch> ローカルネット接続のpassルールをfwdの前に設定するしかないですかね...。
established が先にあると、TCP の最初のパケットだけ 127.0.0.1:2222 に
転送されて、それ以降は 192.168.11.3:22 に送られてしまうため、
動作しないのだと思います。
ローカルネットの接続が拒否される、というのが具体的に
何を指しているのかがよく分からないのですが、
たとえばホスト B 上で "ssh 127.0.0.1" とやった時に
22/tcp ではなく 2222/tcp に接続されてしまうのが困るという話であれば、
to me ではなく to 192.168.11.3 と fwd を限定すれば良いように思います。
-- Hiroki
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-users-jp/attachments/20150402/f8b91299/attachment.sig>
More information about the freebsd-users-jp
mailing list