nakashima723 / P2Pcrwlr

P2Pクローラ
https://twitter.com/nakashima723
Other
0 stars 0 forks source link

証拠ピースの収集方法 #14

Open nakashima723 opened 1 year ago

nakashima723 commented 1 year ago

証拠としてファイル断片を収集するときは、ピースを1つだけダウンロードし、そのピースを他のピースとは合成せずに保存する必要があります。

GPT-4からは以下のようなコードが提案されました(動作未検証です)

import libtorrent as lt
import time
import random

# 1. libtorrentをインポートし、セッションを作成
ses = lt.session()

# 2. トレントファイルを追加し、情報を取得
info = lt.torrent_info("my_torrent_file.torrent")
h = ses.add_torrent({"ti": info, "save_path": "./"})

# 3. ダウンロードするランダムなピースを指定
random_piece_index = random.randint(0, info.num_pieces() - 1)
h.piece_priority(random_piece_index, 7)
h.set_sequential_download(False)

for i in range(info.num_pieces()):
    if i != random_piece_index:
        h.piece_priority(i, 0)

# 4. ダウンロードの完了を待つ
print(f"Downloading piece {random_piece_index}...")

while not h.have_piece(random_piece_index):
    s = h.status()
    print(f"Progress: {s.progress * 100:.2f}%")
    time.sleep(1)

print("Download complete.")
ses.remove_torrent(h)

実際には、この動きを「各監視対象ファイルごと」「その中に記録されているIPごと」に行う必要があります。 ・接続先のIPを指定するにはどうするか ・対象IPがSeederならこれで問題がないが、Leecherの場合は大丈夫なのか (ランダムな位置のピースを指定しても、持っていなければ落とせないのでは?) といった点も検討が必要です。

04/02追記:対象はSeederだけでも問題ないかも(Seederをぜんぶ潰せればファイル共有はほぼ成立しないので)

取得した時刻はピースファイル自体のタイムスタンプを参照することもできますが、実用上はそのときのSeed状態やComlete数とあわせて、別途ログファイルに記録しておくのがよさそうです。

tenax66 commented 1 year ago

証拠としてファイル断片を収集するときは、ピースを1つだけダウンロードし、そのピースを他のピースとは合成せずに保存する必要があります

この前提を把握していなかったのですが、証拠ピースは「各監視対象(著作物)・各IPアドレスにつきひとつ」あれば事足りるのでしょうか? それとも多ければ多いほどいいみたいな世界観なんでしょうか。

nakashima723 commented 1 year ago

あ、よく読むと特定IPからの継続的なピース収集は認定要件に含まれていないですね。クロスワープ社のシステム試験の記述と混同してました。失礼しました 認定要件:https://www.telesa.or.jp/vc-files/consortium/provider_hg_TechReq20160222.pdf クロスワープ社の試験:http://www.ccif-j.jp/shared/pdf/BitTrrentreport.pdf

なぜこの機能が欲しかったかというと、ひとつのIPについて複数のピースを集めておけば「そのIPがどれくらいの期間にわたって、ファイルを送信可能状態にしていたか」が明確になり、「より長期間にわたって送信している悪質なシーダー」を検出するのに役立つからです。 数が問題というより、期間を検出したいので、特定のIPから10分おきに1ピースだけ集めるような機能があると望ましいわけです。

証拠収集システムの全容は

(1)少なくとも1度はファイル全体をダウンロードする (2)その後はシード状態である各IPから、少なくとも1ピースをダウンロードし、送信可能状態にあることを確定する (3)より悪質なシーダーを特定したい場合、10日程度にわたって検出済みのIPからピースを収集する

 ※上記それぞれの段階で、接続先のメタ情報や時刻を正確に記録していく

といった感じで考えています。

優先順位としては掲題の機能は必須ではないので、先に以下のメタ情報の取得の仕方を確認していくのがよさそうです。

発信元ノード(ユーザの PC 等)のIPアドレス,ポート番号,ファイルハッシュ値,ファイルサイズ,ダウンロード完了時刻等

情報の記録方式についてはこちらで検討しておきます。 というか、ちょっと弁護士先生にも意見をうかがった方がいいのかもしれません。

nakashima723 commented 1 year ago

ピースファイル収集時のログ、フォーマット案を以下に書いておきます。 ログファイルの保存場所は evidence>torrent>各ファイル名のフォルダ>各IP_ポート番号 のフォルダ です。 (フォルダがまだ存在しない場合は、新しく作ります)

123.456.789.000_ポート番号_ファイル名.log

中身:

123.456.789.000_ポート番号_ファイル名
証拠収集開始時刻:2023-01-01_22-42-15-32
=====================================
ピース00001 完了時刻:2023-01-01-22_42-15-32 状態:Seed Complete数:3123
=====================================
ファイルハッシュ:dasfdtuogqbawuioherioawhoeioajskdnasklndajnn912781827489q3eqwijedtuogqbawuioherioawhoeioajskdnasklndajnn91278dtuogqbawuioherioawhoeioajskdnasklndajnn91278dtuogqbawuioherioawhoeioajskdnasklndajnn91278dtuogqbawuioherioawhoe......

「ファイルハッシュ」は各記録用フォルダ内にある、対象のtorrentファイルから取得したものです。ファイル名がまったく同じ別ファイルも存在しうるので、取り違え防止です。

同じIP・ポート番号のユーザーから複数のピースファイルが収集できた場合、

=====================================
ピース00001 完了時刻:2023-01-01_22-42-15-32 状態:Seed Complete数:3123
ピース00002 完了時刻:2023-01-01_22-52-17-18 状態:Seed Complete数:3124
=====================================

のように記録が増えていきます。

各ピースファイルの名称は(可能な場合)「00001_123.456.789.000_ポート番号_ファイル名」のようにします。時刻はピースが保存された時刻そのものになるので、自明です。

元torrentの対象ファイル名がすごく長い場合は文字数オーバーになるので、元ファイル名部分は200文字程度に切っておく必要があります。

nakashima723 commented 1 year ago

・検討 各IPに対するピース収集時に毎回Complete数を取得していると、トラッカーへのアクセスが過大だとみなされる可能性があります。 Complete数の取得はピース収集とは別のモジュールとし、対象ファイル1つごとに10分おき程度にとどめておいてもいいかもしれません。

nakashima723 commented 1 year ago

UI含めて、証拠採取コア部分の動作方針が固まってきました。 各ファイルに対して、「証拠採取を開始」ボタンを押したときの動きは以下のような形で考えています。

(1)ファイル全体をDLする前に、現存するシーダーの各ノードからピースファイルを1つずつ収集する。同時に、ノード別(IP別)のピース保存用フォルダとログファイルを、対象ファイル・フォルダ内に生成する。

(2)ノード数が20に達するか、10分経過したら収集をいったん停止する。

(3)停止後、ファイル全体のDLを行う。

(4)DLが完了したら、(1)で収集したノードから優先して、ピースを再度収集する。    取得ずみノードで現存していないものがあった場合は、取得済みのノード以外からもピースを収集する。

(5)以降も、過去に取得したノードを優先して探索しつつ、そのノードがすでに存在しない場合は新しいノードを探し、収集対象に加えていく。これを各ファイル毎に、10分おきに繰り返す。

(6)ピース収集は、ユーザーが設定した日数(初期設定では10日間)で一旦終了する。

可能な場合は、上の処理を収集中のファイルごとに、並行して走らせます。 このあたりはしばらく私は触らないので、やりたい方がいればお任せします。「やるぜ」と宣言してから取り掛かってもらえると安全です。

tenax66 commented 1 year ago

シーダーのリストアップについて確認です。

(1)ファイル全体をDLする前に、現存するシーダーの各ノードからピースファイルを1つずつ収集する。同時に、ノード別(IP別)のピース保存用フォルダとログファイルを、対象ファイル・フォルダ内に生成する。

このステップに関しては「現存するシーダーのリスト」が既にあることを前提としており、その後は

(5)以降も、過去に取得したノードを優先して探索しつつ、そのノードがすでに存在しない場合は新しいノードを探し、収集対象に加えていく。これを各ファイル毎に、10分おきに繰り返す。

で収集対象に加わったものが「現存するシーダーのリスト」に追加されていくという理解でよいでしょうか。

nakashima723 commented 1 year ago

そうですね、リストが既にあるというか、以下のような動きを考えています。

(1)libtorrentで「このファイルのピースを1つ、いずれかのシーダーからDLしろ」と指定します。

(2)適当なシーダーのノードからピースをDLします。    この時点で、対象ファイルの証拠フォルダ下に、そのノード専用の証拠フォルダを生成します。    そこにピースを格納します。

(3)ログファイル「IP_ポート番号_ファイル名.log」を生成し、最初の1行として以下のように書きます。    「ピース00001 完了時刻:2023-01-01_22-42-15-32 状態:Seed」

(4)続けて、もうひとつピースをDLします。このとき、すでに証拠フォルダが存在するIPのノードは避けます。

(5)2~3を繰り返します。証拠フォルダの数が規定数に達するか、一定時間が経過したら終了です。

どのノードをすでに対象にしたかは、別途リスト(ログファイル)を作るのではなく、ファイル別フォルダ内に「各ノード専用の証拠フォルダが存在するかどうか」で判定してください。証拠フォルダの一覧そのものをリストとする想定です。

tenax66 commented 1 year ago

了解しました。

別途リスト(ログファイル)を作るのではなく、ファイル別フォルダ内に「各ノード専用の証拠フォルダが存在するかどうか」で判定してください

特にリスト作成を避ける理由は何かありますか?

nakashima723 commented 1 year ago

実在するフォルダだけを参照する実装にしておけば、Dropboxなどのファイル・フォルダ変更履歴と照合しやすくなり、証拠能力が高まるかなと思いまして。

nakashima723 commented 1 year ago

あ、あと証拠フォルダ・ファイルの数が膨大になる可能性があるので、できるかぎり新規ファイルの生成や読み書きを減らしたいです。

nakashima723 commented 1 year ago

メモ:検討の結果、IPv6アドレス(コロンを含む)はそのままだとフォルダ名に使えず、正規化と変換がだるすぎるので普通にリストを作ることになりました。

tenax66 commented 1 year ago

@nakashima723 ログファイル出力機能の開発に着手したのですが、情報として以下を教えてもらってもよいでしょうか?

・Seed Complete数とは何を指しているか。 ・Seed Complete 数を収集する理由は何か。

nakashima723 commented 1 year ago

サンプルにある「状態:Seed」の部分は、接続先のピアがSeederなのかLeecherなのかを取得して、それを記録することを考えていましたが、考えてみると送信可能状態にしているのがファイルの一部であれ全体であれ、ファイル共有に寄与していることには変わりないので、記録する必要はないかもしれません。(GW明けに平野先生に聞いてみます) なので、この部分の処理についてはとりあえずナシで結構です。

Complete数」はその時点で(このアプリのユーザー以外も含めて)そのファイルが何回、DL完了しているかを取得し、記録しています。このデータはトラッカーサーバーが持っているはずです。

このデータは賠償請求額の算定に使います。たとえば最初にIPを検出した時点で100だったComplete数が10日後に15000になっていたら、そのIPは少なくとも14900件のファイル共有について、有責であるという証拠にできます。 Complete数はWeb上のインデックスサイト(Nyaaなど)にも記載されていますが、インデックスサイトが消滅した場合には確認できなくなってしまうので、ログとして記録しておく必要があります。

Complete数について、あまり頻繁にトラッカーサーバーに問い合わせるのは望ましくないという意見もありました。どの程度から「頻繁」といえるのか分からないのですが、もしIP別に取得するのは多すぎる(またはアプリ側の処理としても時間がかかる)ということなら、Complete数のログは各IPごとではなく、各ファイルごとに10分おき位で取得し、ファイル別のログに記録する処理にするべきかもしれませんので、この点についても検討してみてください。

tenax66 commented 1 year ago

あ、「状態」と「Complete数」でしたか。お恥ずかしい…… 内容については了解です。検討・開発を進めておきます。

tenax66 commented 1 year ago

そういえば、

あまり頻繁にトラッカーサーバーに問い合わせるのは望ましくない

この指摘が記載されているサイトってどこかにありますか? 理由を把握しておきたいです。

Complete数のログは各IPごとではなく、各ファイルごとに10分おき位で取得し、ファイル別のログに記録する処理にするべき

確かに、complete数は各ピアに紐づくものではなくファイルのやりとり全体に関わるものなので、ピア単位で取得する必要はない(別処理にすべき)という考え方はひとつあるかもしれません。検討しておきます。

nakashima723 commented 1 year ago

問い合わせ間隔については、他のトピックについて調べたときにChatGPTが吐いた内容で見たものだったと思います。あらためて聞いてみると、以下のような回答を得ました。

Bittorrentのトラッカーサーバーに、あるファイルのComplete数を問い合わせる処理を行いたいのですが、一般的にその頻度についてはどの程度まで許容されると考えられますか。

BitTorrentのトラッカーサーバーは、ピアとシードの情報を提供し、ファイルのダウンロードとアップロードを助ける役割を担っています。あるファイルのComplete数(完了したダウンロードの数)を問い合わせることは、トラッカーの通常の機能の一部ですが、問い合わせの頻度には注意が必要です。

過度の問い合わせは、トラッカーサーバーに負荷をかけ、他のユーザーの体験に悪影響を与える可能性があります。通常、トラッカーに接続する際にアナウンス間隔(announce interval)という情報が提供され、これが適切な問い合わせの間隔となります。この間隔は通常、数分から数十分程度です。

ただし、トラッカーサーバーによっては、問い合わせの頻度に制限が設けられている場合があります。そのため、トラッカーのドキュメントや利用規約を確認し、適切な問い合わせの頻度を守ることが望ましいです。また、必要以上に問い合わせを行わないよう、自動化されたスクリプトやアプリケーションを適切に設定することも重要です。

Complete数のようにannounce interval が設定されている情報は、ファイルそのものをダウンロードするための処理と比べて、あまり頻繁に問い合わせるべきではないものと考えるべきでしょうか。

はい、その通りです。Complete数などの統計情報は、ファイルのダウンロードやアップロードの進行状況に関連しない情報のため、それらを頻繁に問い合わせる必要性は低いと言えます。announce intervalは、ピア間でのファイルのやり取りに関する情報を更新するために使用されるものであり、通常はその間隔でトラッカーに接続して情報を更新することが望ましいです。

また、サーバーに負荷をかけることなく情報を取得する方法があれば、それを利用することも検討してください。例えば、一部のトラッカーは、APIを提供しており、APIを通じて統計情報を取得することができます。このようなAPIを利用すれば、サーバーに負荷をかけずに情報を得ることができる場合があります。

トラッカーサーバーのannounce intervalを確認する、一般的な方法を教えてください。

BitTorrentのトラッカーサーバーのannounce intervalを確認する一般的な方法は、トラッカーからの最初のレスポンスを解析することです。announce intervalは、トラッカーから提供される情報の中に含まれています。

import libtorrent as lt
import time

# トレントファイルのパスを設定
torrent_path = "path/to/your/torrent/file.torrent"

# libtorrentのセッションを作成
ses = lt.session()

# トレントファイルを追加
info = lt.torrent_info(torrent_path)
h = ses.add_torrent({"ti": info, "save_path": "./"})

# トレントのダウンロードを開始
h.resume()

while not h.is_seed():
    s = h.status()

    # トラッカーのステータス情報を取得
    tracker_status = h.status().handle.trackers()

    for tracker in tracker_status:
        # トラッカーのURLとannounce intervalを表示
        print("Tracker URL:", tracker.url)
        print("Announce Interval:", tracker.next_announce.total_seconds())

    # 更新間隔を適切に設定
    time.sleep(5)

この例では、まずlibtorrentのセッションを作成し、トレントファイルを追加しています。次に、トレントのダウンロードを開始し、トラッカーのステータス情報を取得しています。各トラッカーのURLとannounce intervalが表示されます。この例では、更新間隔を適切に設定するために、time.sleep(5)を使用しています。

この方法を使用する際は、適切なトレントファイルのパスを設定し、必要に応じて保存先や更新間隔を調整してください。また、この例ではダウンロードが完了するまでループが続きますが、実際のアプリケーションで使用する場合は適切な終了条件を設定してください。

tenax66 commented 1 year ago

了解です。chatGPTの回答ということであれば、そもそも正しいのかというところから調べておきます。

一般論としては、ピース一回のダウンロードごと(早くとも十数秒に一回ぐらい?)にサーバーにアクセスするぐらいであれば「過大」とは言わないかなという気がします。complete数を取得する処理が特別重い可能性はありますが。

nakashima723 commented 1 year ago

crawler > collector.py https://github.com/nakashima723/P2Pslyr/commit/150039d51f96f7b84fda0165d45d3e9d74eb0d61#diff-7510708c7e49c58fc94b503bb8c3f92823b0c82388adaad006a9db92f42fee1b で、内部に「.process」を含む証拠フォルダ1件に対して ピース収集を実行するようにしてみましたが、うまくピースをダウンロードできませんでした。 本体ファイルはダウンロード済みです。

私の方のファイアウォールの設定などが悪い可能性もあるのですが、そちらではどうでしょうか?

以下のようなログがprintされます。10件程度のピアに対して実行してみても、ピースのダウンロードまで成功することはありませんでした。

peers: [('126.142.211.84', 34229), ('59.14.39.51', 59624), ('60.128.197.209', 15157), ('138.199.39.174', 1852), ('153.139.182.10', 38937), ('115.21.50.163', 41134), ('61.193.128.198', 62248), ('133.204.4.160', 11345), ('106.155.2.69', 51619), ('153.151.144.185', 44802)]
INFO:torrent.client:([('0.0.0.0', '126.142.211.83'), ('126.142.211.84', '126.142.211.84'), ('126.142.211.85', '255.255.255.255')], [('::', 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')])
INFO:torrent.client:0.00% complete (down: 0.0 kB/s, up: 0.0 kB/s, peers: 0)
INFO:torrent.client:0.00% complete (down: 0.0 kB/s, up: 0.0 kB/s, peers: 0)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (http://nyaa.tracker.wf:7777/announce)[127.0.0.1:6881] v1 skipping tracker announce (unreachable) "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (http://nyaa.tracker.wf:7777/announce)[192.168.0.8:6881] v1 banned by IP filter "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (udp://tracker.openbittorrent.com:80/announce)[192.168.0.8:6881] v1 banned by IP filter "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (udp://tracker.openbittorrent.com:80/announce)[127.0.0.1:6881] v1 skipping tracker announce (unreachable) "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (udp://tracker.opentrackr.org:1337/announce)[127.0.0.1:6881] v1 skipping tracker announce (unreachable) "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (udp://tracker.opentrackr.org:1337/announce)[192.168.0.8:6881] v1 banned by IP filter "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (http://anidex.moe:6969/announce)[192.168.0.8:6881] v1 banned by IP filter "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (http://anidex.moe:6969/announce)[127.0.0.1:6881] v1 skipping tracker announce (unreachable) "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (udp://open.stealth.si:80/announce)[127.0.0.1:6881] v1 skipping tracker announce (unreachable) "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (udp://open.stealth.si:80/announce)[192.168.0.8:6881] v1 banned by IP filter "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (udp://exodus.desync.com:6969/announce)[192.168.0.8:6881] v1 banned by IP filter "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (udp://exodus.desync.com:6969/announce)[127.0.0.1:6881] v1 skipping tracker announce (unreachable) "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (udp://tracker.torrent.eu.org:451/announce)[127.0.0.1:6881] v1 skipping tracker announce (unreachable) "" (1)
WARNING:torrent.client:DLRAW.NET-Yusha no Kuzu vol 01-04.rar (udp://tracker.torrent.eu.org:451/announce)[192.168.0.8:6881] v1 banned by IP filter "" (1)
INFO:torrent.client:0.00% complete (down: 0.0 kB/s, up: 0.0 kB/s, peers: 0)
INFO:torrent.client:0.00% complete (down: 0.0 kB/s, up: 0.0 kB/s, peers: 0)
INFO:torrent.client:0.00% complete (down: 0.0 kB/s, up: 0.0 kB/s, peers: 0)
INFO:torrent.client:0.00% complete (down: 0.0 kB/s, up: 0.0 kB/s, peers: 0)
INFO:torrent.client:0.00% complete (down: 0.0 kB/s, up: 0.0 kB/s, peers: 0)
INFO:torrent.client:0.00% complete (down: 0.0 kB/s, up: 0.0 kB/s, peers: 0)
INFO:torrent.client:0.00% complete (down: 0.0 kB/s, up: 0.0 kB/s, peers: 0)
INFO:torrent.client:0.00% complete (down: 0.0 kB/s, up: 0.0 kB/s, peers: 0)
WARNING:torrent.client:Max retries exceeded
nakashima723 commented 1 year ago

上記のエラー(banned by IP filter)については、トラッカー自体のアドレスを許可リストに含めることによって解決しました。 ダウンロードの成功率はまちまちですが、10件やって全部ダメということは稀なようです。

このあと、ピースのダウンロード処理については並列化して処理することを試してみます。 ダウンロードの成功率については、ピアの健全性が保証されていない以上こんなものと考えてこのままにしてもいいのですが、試しに接続試行の時間・回数をもう少し粘ったバージョンも作ってみます。