- PR -

TFTP通信のソースポートの範囲を指定したい

1
投稿者投稿内容
kei
ベテラン
会議室デビュー日: 2005/03/18
投稿数: 53
投稿日時: 2008-02-13 15:33
keiと申します。

TFTPを使ってファイルの取得を行なう必要があり、色々と試して
いるのですが、TFTPを行なうクライアント側のポート番号を指定
した範囲(1031〜2000)に設定し、ファイル取得を行なうことは
可能でしょうか?理由は、基幹ネットワーク側に制約があるため
です。

何も指定していない現状では、「32829」が自動的に割り振られて
いるようです。(毎回この近辺の数値になっています。)

現状のTFTPコマンドのログ
-----------------------------------------------------------
XX.XX.22.13:クライアント側
XX.XX.22.11:TFTPサーバ側

19:47:08.921198 IP XX.XX.22.13.32829 > XX.XX.22.11.tftp: 37 RRQ "hoge/hogehoge.dat" octet
19:47:08.925181 IP XX.XX.22.11.43974 > XX.XX.22.13.32829: UDP, length 516
19:47:08.925243 IP XX.XX.22.13.32829 > XX.XX.22.11.43974: UDP, length 4
19:47:08.925795 IP XX.XX.22.11.43974 > XX.XX.22.13.32829: UDP, length 516
19:47:08.925824 IP XX.XX.22.13.32829 > XX.XX.22.11.43974: UDP, length 4
19:47:08.926140 IP XX.XX.22.11.43974 > XX.XX.22.13.32829: UDP, length 516
19:47:08.926171 IP XX.XX.22.13.32829 > XX.XX.22.11.43974: UDP, length 4



-----------------------------------------------------------
上記のクライアント側のポート「32829」を「1031〜2000」の範囲に指定して
TFTP通信させたいです。

どなたかご教授願えますでしょうか。


F/A
ぬし
会議室デビュー日: 2006/03/18
投稿数: 312
お住まい・勤務地: Tokyo
投稿日時: 2008-02-13 22:14
おそらく普通にANYポートを使っているだけで、
かつ、接続元ポートを固定化するオプションはtftpには無いようなので、

1)ソースを改変する

2)net.ipv4.ip_local_port_range を変更する

というような方法になると思います。


2)は他にも多々影響が出るとは思いますが…

angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2008-02-13 22:49
こんばんは。
他には、

1') tftpクライアントを自作する

3) UDP通信を中継し、あたかも限定された範囲の接続元ポートを使用したtftp通信を行うかに振舞う、UDPプロキシを作成する

という手もありそうです。

NAT ( Linux の netfilter/iptables ) が使えれば良いのですが、残念ながら無理そうです。
初っ端の通信と、以降の通信で使われるサーバ側ポート番号が異なることで、カーネルが接続状況の追跡を行えないためです。
※ ftp であれば、アプリケーションレベルで追跡するヘルパーモジュールがありますが…

追記:
 実は、tftp_conntrack という tftp通信追跡用のヘルパーモジュールもあるようです…。Googleで若干検索に引っかかります。
 ただ、情報が少ないため、なんとも言えませんが。

[ メッセージ編集済み 編集者: angel 編集日時 2008-02-13 22:53 ]
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2008-02-14 02:27
少し訂正。

手元のlinuxマシンを見たところ、tftpのヘルパーモジュールがちゃんと入っていました。
( FedoraCore1 kernel2.4 )

ip_conntrack_tftp.o と ip_nat_tftp.o とがあります。
なので、tftpクライアント実行側でこれを modprobe して、SNATでソースポートを変換してあげればなんとかなりそうに思います。
kei
ベテラン
会議室デビュー日: 2005/03/18
投稿数: 53
投稿日時: 2008-02-15 09:52
angel様、F/A様

ご回答ありがとうございました。
頂きましたアドバイスを元に、色々と試行錯誤してみたいと思います。

今後とも宜しくお願い致します。
kei
ベテラン
会議室デビュー日: 2005/03/18
投稿数: 53
投稿日時: 2008-02-15 10:38
angel様

「SNATでソースポートを変換する」部分がよくわからないため、具体的な手法を教えて
頂けると嬉しいです。

OSは、Redhat Enterprize ES 4を使っています。

ip_conntrack_tftpをfind検索したら、以下の結果が出ています。
これらの中身については、手を加える必要はないという理解で宜しいでしょうか?
コード:
[root@sstsv6 /]# find * |grep ip_conntrack_tftp
lib/modules/2.6.9-5.EL/kernel/net/ipv4/netfilter/ip_conntrack_tftp.ko
lib/modules/2.6.9-5.ELsmp/kernel/net/ipv4/netfilter/ip_conntrack_tftp.ko
usr/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
usr/src/kernels/2.6.9-5.EL-smp-i686/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
usr/src/kernels/2.6.9-5.EL-i686/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
usr/src/kernels/2.6.9-5.EL-hugemem-i686/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
usr/lib/perl5/5.8.5/i386-linux-thread-multi/linux/netfilter_ipv4/ip_conntrack_tftp.ph
[root@sstsv6 /]# 
[root@sstsv6 /]# more usr/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
#ifndef _IP_CT_TFTP
#define _IP_CT_TFTP

#define TFTP_PORT 69

struct tftphdr {
        u_int16_t opcode;
};

#define TFTP_OPCODE_READ        1
#define TFTP_OPCODE_WRITE       2

#endif /* _IP_CT_TFTP */
[root@sstsv6 /]#
[root@sstsv6 /]# more usr/src/kernels/2.6.9-5.EL-smp-i686/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
#ifndef _IP_CT_TFTP
#define _IP_CT_TFTP

#define TFTP_PORT 69

struct tftphdr {
        u_int16_t opcode;
};

#define TFTP_OPCODE_READ        1
#define TFTP_OPCODE_WRITE       2
#define TFTP_OPCODE_DATA        3
#define TFTP_OPCODE_ACK         4
#define TFTP_OPCODE_ERROR       5

#endif /* _IP_CT_TFTP */
[root@sstsv6 /]#
[root@sstsv6 /]# more usr/src/kernels/2.6.9-5.EL-i686/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
#ifndef _IP_CT_TFTP
#define _IP_CT_TFTP

#define TFTP_PORT 69

struct tftphdr {
        u_int16_t opcode;
};

#define TFTP_OPCODE_READ        1
#define TFTP_OPCODE_WRITE       2
#define TFTP_OPCODE_DATA        3
#define TFTP_OPCODE_ACK         4
#define TFTP_OPCODE_ERROR       5

#endif /* _IP_CT_TFTP */
[root@sstsv6 /]#
[root@sstsv6 /]# more usr/src/kernels/2.6.9-5.EL-hugemem-i686/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
#ifndef _IP_CT_TFTP
#define _IP_CT_TFTP

#define TFTP_PORT 69

struct tftphdr {
        u_int16_t opcode;
};

#define TFTP_OPCODE_READ        1
#define TFTP_OPCODE_WRITE       2
#define TFTP_OPCODE_DATA        3
#define TFTP_OPCODE_ACK         4
#define TFTP_OPCODE_ERROR       5

#endif /* _IP_CT_TFTP */
[root@sstsv6 /]#
[root@sstsv6 /]# more usr/lib/perl5/5.8.5/i386-linux-thread-multi/linux/netfilter_ipv4/ip_conntrack_tftp.ph
require '_h2ph_pre.ph';

no warnings 'redefine';

unless(defined(&_IP_CT_TFTP)) {
    eval 'sub _IP_CT_TFTP () {1;}' unless defined(&_IP_CT_TFTP);
    eval 'sub TFTP_PORT () {69;}' unless defined(&TFTP_PORT);
    eval 'sub TFTP_OPCODE_READ () {1;}' unless defined(&TFTP_OPCODE_READ);
    eval 'sub TFTP_OPCODE_WRITE () {2;}' unless defined(&TFTP_OPCODE_WRITE);
}
1;



あと、modprobe ip_conntrack_tftp実行後の状態を貼りました。
この後、どうすればポート番号をコントロール出来るのでしょうか。
コード:
[root@sstsv6 /]# /sbin/modprobe ip_conntrack_tftp
[root@sstsv6 /]# find * |grep ip_conntrack_tftp
lib/modules/2.6.9-5.EL/kernel/net/ipv4/netfilter/ip_conntrack_tftp.ko
lib/modules/2.6.9-5.ELsmp/kernel/net/ipv4/netfilter/ip_conntrack_tftp.ko
sys/module/ip_conntrack_tftp
sys/module/ip_conntrack_tftp/sections
sys/module/ip_conntrack_tftp/sections/.strtab
sys/module/ip_conntrack_tftp/sections/.symtab
sys/module/ip_conntrack_tftp/sections/.module_sig
sys/module/ip_conntrack_tftp/sections/.bss
sys/module/ip_conntrack_tftp/sections/.gnu.linkonce.this_module
sys/module/ip_conntrack_tftp/sections/.data
sys/module/ip_conntrack_tftp/sections/__versions
sys/module/ip_conntrack_tftp/sections/__ksymtab
sys/module/ip_conntrack_tftp/sections/__ksymtab_strings
sys/module/ip_conntrack_tftp/sections/__kcrctab
sys/module/ip_conntrack_tftp/sections/.rodata.str1.1
sys/module/ip_conntrack_tftp/sections/__param
sys/module/ip_conntrack_tftp/sections/.init.text
sys/module/ip_conntrack_tftp/sections/.text
sys/module/ip_conntrack_tftp/refcnt
sys/module/ip_conntrack_tftp/ports
usr/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
usr/src/kernels/2.6.9-5.EL-smp-i686/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
usr/src/kernels/2.6.9-5.EL-i686/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
usr/src/kernels/2.6.9-5.EL-hugemem-i686/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
usr/lib/perl5/5.8.5/i386-linux-thread-multi/linux/netfilter_ipv4/ip_conntrack_tftp.ph


----------------------------------------------------------------------------

よろしくお願いします。
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2008-02-16 14:10
こんにちは。
引用:
keiさんの書き込み (2008-02-15 10:38) より:
「SNATでソースポートを変換する」部分がよくわからないため、具体的な手法を教えて
頂けると嬉しいです。



前に
引用:
NAT ( Linux の netfilter/iptables ) が使えれば良いのですが、…(略)

と書いたとおり、netfilterの機能を使います。設定コマンドは iptables で。
使い方は manページ等で調べてみてください。

今回の場合、クライアント機上で、
 ・tftp通信のソースポートを1031〜2000の範囲に変換する ( SourceNAT:送信元変換 )
ということになるなので、対象は natテーブルの POSTROUTING チェインになるでしょう。
設定コマンド例としては、

 # iptables \
  -t nat \              … natテーブルが対象
  -A POSTROUTING \          … POSTROUTINGチェインにルール追加
  -p udp \              … UDP通信が対象
  --dport 69 \            … tftp(69)への通信が対象
  -j SNAT \              … SNATを行う
  --to-source 自IPアドレス:1031-2000 … 変換後の送信元情報の指定

といったところでしょうか。

※で、ヘルパーモジュールをロードしている状態なら、tftp通信でポート番号が変わる所まで追跡してNATしてくれる、と考えているわけです。
kei
ベテラン
会議室デビュー日: 2005/03/18
投稿数: 53
投稿日時: 2008-02-20 14:41
angel様

iptables の使い方をご教授いただき、ありがとうございます。
頂きました情報を元に設定したのですが、TFTP通信を成功させることが出来ませんでした。

状況は以下の通りです。

UDPポートフィルターのかかっていないサーバへのアクセスログ(TFTP通信成功する方)
2584バイトのデータ(test.dat)取得が成功する。
サーバ:XXX.XXX.XXX.173
クライアント:hogehoge.jp
コード:
13:15:51.882678 IP hogehoge.jp.32813 > XXX.XXX.XXX.173.tftp:  37 RRQ "test.dat" octet
13:15:51.886361 IP XXX.XXX.XXX.173.54974 > hogehoge.jp.32813: UDP, length 516
13:15:51.886394 IP hogehoge.jp.32813 > XXX.XXX.XXX.173.54974: UDP, length 4
13:15:51.888641 IP XXX.XXX.XXX.173.54974 > hogehoge.jp.32813: UDP, length 516
13:15:51.888661 IP hogehoge.jp.32813 > XXX.XXX.XXX.173.54974: UDP, length 4
13:15:51.889989 IP XXX.XXX.XXX.173.54974 > hogehoge.jp.32813: UDP, length 516
13:15:51.890006 IP hogehoge.jp.32813 > XXX.XXX.XXX.173.54974: UDP, length 4
13:15:51.891353 IP XXX.XXX.XXX.173.54974 > hogehoge.jp.32813: UDP, length 516
13:15:51.891374 IP hogehoge.jp.32813 > XXX.XXX.XXX.173.54974: UDP, length 4
13:15:51.892772 IP XXX.XXX.XXX.173.54974 > hogehoge.jp.32813: UDP, length 516
13:15:51.892789 IP hogehoge.jp.32813 > XXX.XXX.XXX.173.54974: UDP, length 4
13:15:51.893527 IP XXX.XXX.XXX.173.54974 > hogehoge.jp.32813: UDP, length 28
13:15:51.893542 IP hogehoge.jp.32813 > XXX.XXX.XXX.173.54974: UDP, length 4



UDPポートフィルターのかかっているサーバへのアクセスログ(TFTP通信失敗する方)
最初の512バイトのみ取得成功する。(クライアントからのACKがサーバに届かないため、サーバからは何度も先頭の512バイト送信が繰り返されて、最後はタイムアウト終了する。)
サーバ:XXX.XXX.XXX.219
クライアント:hogehoge.jp
コード:
14:21:03.157909 IP hogehoge.jp.32816 > XXX.XXX.XXX.219.tftp:  37 RRQ "test.dat" octet
14:21:03.162029 IP XXX.XXX.XXX.219.48399 > hogehoge.jp.32816: UDP, length 516
14:21:03.162060 IP hogehoge.jp.32816 > XXX.XXX.XXX.219.48399: UDP, length 4
14:21:08.156404 IP XXX.XXX.XXX.219.48399 > hogehoge.jp.32816: UDP, length 516
14:21:08.156471 IP hogehoge.jp.32816 > XXX.XXX.XXX.219.48399: UDP, length 4
14:21:13.156358 IP hogehoge.jp.32816 > XXX.XXX.XXX.219.48399: UDP, length 4
14:21:13.156623 IP XXX.XXX.XXX.219.48399 > hogehoge.jp.32816: UDP, length 516
14:21:13.156667 IP hogehoge.jp.32816 > XXX.XXX.XXX.219.48399: UDP, length 4
14:21:18.156269 IP XXX.XXX.XXX.219.48399 > hogehoge.jp.32816: UDP, length 516
14:21:18.156324 IP hogehoge.jp.32816 > XXX.XXX.XXX.219.48399: UDP, length 4
14:21:23.155941 IP XXX.XXX.XXX.219.48399 > hogehoge.jp.32816: UDP, length 516
14:21:23.156001 IP hogehoge.jp.32816 > XXX.XXX.XXX.219.48399: UDP, length 4
14:21:28.155762 IP hogehoge.jp.32816 > XXX.XXX.XXX.219.48399: UDP, length 4
14:21:33.155900 IP hogehoge.jp.32816 > XXX.XXX.XXX.219.48399: UDP, length 4
14:21:38.157033 IP hogehoge.jp.32816 > XXX.XXX.XXX.219.48399: UDP, length 4



modprobe実行
>/sbin/modprobe ip_conntrack_tftp

iptables設定
>/sbin/iptables -t nat -A POSTROUTING -p udp --dport 69 -j SNAT --to-source XXX.XXX.XXX.XXX:1031-2000

再度、サーバ:XXX.XXX.XXX.219へアクセスした時のログ
コード:
13:20:54.431360 IP hogehoge.jp.1031 > XXX.XXX.XXX.219.tftp:  37 RRQ "test.dat" octet
13:20:54.435404 IP XXX.XXX.XXX.219.48316 > hogehoge.jp.1031: UDP, length 516
13:20:54.435434 IP hogehoge.jp > XXX.XXX.XXX.219: icmp 552: hogehoge.jp udp port 1031 unreachable
13:20:59.432293 IP hogehoge.jp.1031 > XXX.XXX.XXX.219.tftp:  37 RRQ "test.dat" octet
13:20:59.435833 IP XXX.XXX.XXX.219.48317 > hogehoge.jp.1031: UDP, length 516
13:20:59.435855 IP hogehoge.jp > XXX.XXX.XXX.219: icmp 552: hogehoge.jp udp port 1031 unreachable
13:21:04.432430 IP hogehoge.jp.1031 > XXX.XXX.XXX.219.tftp:  37 RRQ "test.dat" octet
13:21:04.435854 IP XXX.XXX.XXX.219.48317 > hogehoge.jp.1031: UDP, length 516
13:21:04.435873 IP hogehoge.jp > XXX.XXX.XXX.219: icmp 552: hogehoge.jp udp port 1031 unreachable
13:21:04.435909 IP XXX.XXX.XXX.219.48318 > hogehoge.jp.1031: UDP, length 516
13:21:04.435928 IP hogehoge.jp > XXX.XXX.XXX.219: icmp 552: hogehoge.jp udp port 1031 unreachable
13:21:09.432564 IP hogehoge.jp.1031 > XXX.XXX.XXX.219.tftp:  37 RRQ "test.dat" octet
13:21:09.435617 IP XXX.XXX.XXX.219.48317 > hogehoge.jp.1031: UDP, length 516
13:21:09.435635 IP hogehoge.jp > XXX.XXX.XXX.219: icmp 552: hogehoge.jp udp port 1031 unreachable
13:21:09.435686 IP XXX.XXX.XXX.219.48318 > hogehoge.jp.1031: UDP, length 516
13:21:09.435700 IP hogehoge.jp > XXX.XXX.XXX.219: icmp 552: hogehoge.jp udp port 1031 unreachable
13:21:09.436372 IP XXX.XXX.XXX.219.48319 > hogehoge.jp.1031: UDP, length 516
13:21:09.436390 IP hogehoge.jp > XXX.XXX.XXX.219: icmp 552: hogehoge.jp udp port 1031 unreachable
13:21:14.432699 IP hogehoge.jp.1031 > XXX.XXX.XXX.219.tftp:  37 RRQ "test.dat" octet
13:21:14.435676 IP XXX.XXX.XXX.219.48318 > hogehoge.jp.1031: UDP, length 516
13:21:14.435694 IP hogehoge.jp > XXX.XXX.XXX.219: icmp 552: hogehoge.jp udp port 1031 unreachable
13:21:14.435733 IP XXX.XXX.XXX.219.48317 > hogehoge.jp.1031: UDP, length 516
13:21:14.435746 IP hogehoge.jp > XXX.XXX.XXX.219: icmp 552: hogehoge.jp udp port 1031 unreachable
13:21:14.435779 IP XXX.XXX.XXX.219.48319 > hogehoge.jp.1031: UDP, length 516
13:21:14.435791 IP hogehoge.jp > XXX.XXX.XXX.219: icmp 552: hogehoge.jp udp port 1031 unreachable
13:21:14.436438 IP XXX.XXX.XXX.219.48320 > hogehoge.jp.1031: UDP, length 516
13:21:14.436455 IP hogehoge.jp > XXX.XXX.XXX.219: icmp 552: hogehoge.jp udp port 1031 unreachable


新たに、icmp 552というパケットがクライアントから送信され、それがサーバに届いていないというエラー内容に変わっています。

UDPポートフィルターのかかっているサーバ側の設定情報(抜粋)
access-list 141 permit udp any eq domain any
access-list 141 permit udp any eq ntp any
access-list 141 permit icmp any any
access-list 141 permit udp any eq snmp any
access-list 141 permit udp any eq snmptrap any
access-list 141 permit udp any eq tftp any
access-list 141 permit udp any any eq tftp
access-list 141 permit udp any range 1031 2000 any

以上のような状態です。
なにか設定等が誤っていますでしょうか。

1

スキルアップ/キャリアアップ(JOB@IT)