iptables で DNAT と MASQUERADE を組み合わせればできるかなと思い、試しに
iptables -t nat -A PREROUTING -p tcp -d (自分のIP) -j DNAT --to (転送したい宛先アドレス)
iptables -t nat -A POSTROUTING -p tcp -d (転送したい宛先アドレス) -j MASQUERADE
としてみましたが、期待通りに働きませんでした。(クライアントから接続をかけようとするとタイムアウトする)
iptables の使い方が間違っているでしょうか? それとも iptables では不可能で、簡単なデーモンを用意しないと無理でしょうか? その場合、そのような汎用中継デーモンは既に何か存在するでしょうか?
お知恵を貸していただけると助かります。
naruenosekai さんが紹介しているのは Delegate の TCPrelay や UDPrelay を使う方法で、この場合は、任意のプロトコルで中継が出来ます。同様の事は、socat でも出来ます。socat を xinetd から呼び出すようにして、
service サービス名(/etc/services に書かれている名称) { disable = no socket_type = stream wait = no user = root server = /usr/bin/socat server_args = stdin tcp4:宛先のホスト:ポート番号 }
といった具合のファイルを /etc/xinetd.d 以下に作ります。もし、お使いのディストリビューションが、RHEL や CentOS だった場合、socat 自体は rpmforge から取得出来ます。
ただ、Delegate の場合でも socat の場合でも、「このポートに届いたものは中継」ということになるので、任意のポートで、とはいきません。
あと、そもそもパケットのペイロード部分にアドレス情報が入るようなプロトコル(たしか、SIP 関係とか、IPsec 当たりがそうだった気がする)だった場合、ペイロードに入っているアドレス情報とIP ヘッダのアドレス情報に矛盾が発生するとダメというケースもあるので、どんなプロトコルでも、というのは難しいです。
試されている iptables の方法も、何かを加えれば出来そうな気がするのですが、wireshark とかでパケットキャプチャして、実際にどんなパケットが飛び交っているのかを確認すると、解決策が見つかるかもしれません。
マルチプロトコルプロキシーのDeleGateを使うと楽に出来ます。
http://ja.wikipedia.org/wiki/DeleGate
http://www.delegate.org/delegate/
設定方法
http://i-red.info/docs/JF/delegate-mini-howto.html
http://i-red.info/docs/JF/delegate-mini-howto-config.html
http://pyzarlab.s101.xrea.com/delegate/details.html
http://homepage1.nifty.com/yito/anhttpd/faq/delegate.html
あと中継する場合、送信元のIPアドレスやMACアドレスを中継するPCに変更、戻ってきたパケットは逆変換しないと
正しく中継できないと思いますが...
> マルチプロトコルプロキシーのDeleGateを使うと楽に出来ます。
なるほど、ありがとうございます。
サポートされているプロトコルなら間違いなくそれでいけそうですが、
もしかして DeleGate はサポートされていないプロトコルでもいけるでしょうか?
(例えば VNC や ssh といったものを中継したい、という場合など)
> あと中継する場合、送信元のIPアドレスやMACアドレスを中継するPCに変更、戻ってきたパケットは逆変換しないと正しく中継できないと思いますが...
はい、その通りなのです。
なので単なる DNAT だけではダメで、SNAT を組み合わせようとしたのですが、うまくいかなったという次第です。
sshのポートフォワーディングを使えばプロトコルに関係なく、プロキシーできます。
接続元のPC -- 中継Linux -- 目的サーバー
という状態の場合、ポートがTCPの1234番だった場合
接続元PCから、
ssh -N -g -L 1234:目的サーバーのIP:1234 ユーザ名@中継Linux
と実行すると、接続元PCの1234に接続すると、中継Linuxを介して、目的サーバーの1234番に接続できます。
中継Linuxから、
ssh -N -g -L 1234:localhost:1234 ユーザ名@目的サーバー
と実行すると、中継Linuxの1234に接続すると、目的サーバーの1234番に接続できます。
これを使えば、外出先から、自宅のLinuxを介して自宅LAN内のWindowsにVNCで接続もできます。
アイデア次第でいろいろ遊べると思います。
なるほど、そのような手もありますね。ありがとうございます。
naruenosekai さんが紹介しているのは Delegate の TCPrelay や UDPrelay を使う方法で、この場合は、任意のプロトコルで中継が出来ます。同様の事は、socat でも出来ます。socat を xinetd から呼び出すようにして、
service サービス名(/etc/services に書かれている名称) { disable = no socket_type = stream wait = no user = root server = /usr/bin/socat server_args = stdin tcp4:宛先のホスト:ポート番号 }
といった具合のファイルを /etc/xinetd.d 以下に作ります。もし、お使いのディストリビューションが、RHEL や CentOS だった場合、socat 自体は rpmforge から取得出来ます。
ただ、Delegate の場合でも socat の場合でも、「このポートに届いたものは中継」ということになるので、任意のポートで、とはいきません。
あと、そもそもパケットのペイロード部分にアドレス情報が入るようなプロトコル(たしか、SIP 関係とか、IPsec 当たりがそうだった気がする)だった場合、ペイロードに入っているアドレス情報とIP ヘッダのアドレス情報に矛盾が発生するとダメというケースもあるので、どんなプロトコルでも、というのは難しいです。
試されている iptables の方法も、何かを加えれば出来そうな気がするのですが、wireshark とかでパケットキャプチャして、実際にどんなパケットが飛び交っているのかを確認すると、解決策が見つかるかもしれません。
socat はまさに私が求めていたものです! ありがとうございます!
> そもそもパケットのペイロード部分にアドレス情報が入るようなプロトコル…
そうですね。そのようなものは仕方ないと思います。
socat はまさに私が求めていたものです! ありがとうございます!
> そもそもパケットのペイロード部分にアドレス情報が入るようなプロトコル…
そうですね。そのようなものは仕方ないと思います。