macOSでtorを使ってIP偽装し、pythonで確認する


pythonでスクレイピングをしようと思って、書いていたのですが、
同一IPアドレスから一定の時間アクセスされた場合、しばらくアクセスを拒否します。
みたいなサイトが出てくると、うまくスクレイピングできなくなる可能性があるので、
IPアドレスを偽装して、スクレイピングをしようと思います。

ただしmacOSのみの動作確認なので、特にwindowsはやり方が少し異なると思います。

ちなみに偽装というと悪い印象を持たれますが、悪さをするわけではないです。
もちろん、スクレイピングをする時は、対象のサーバーに負荷をかけない様に、プログラムの実行時間を考えて作ってください。

必要なもの

  • macOS
  • python3
    • requestsライブラリ
    • beautifulsoup4ライブラリ
  • tor

Pythonのインストール

3系をインストールしてください。
(2系でも動くとは思いますが、動作は未確認)

requestsライブラリインストール

pythonから外部URL(API)を呼び出すライブラリです。
javascriptでいうajaxみたいなやつです。

以下のコマンドでインストール

pip install requests

beautifulsoup4ライブラリインストール

requestでテキストを取得した後に、さらに細かい条件をつけて中身をとることができるライブラリです。

pip install beautifulsoup4

tor

匿名通信が可能なtorです。IP偽装にはこちらを使います。
https://www.torproject.org/

以下のコマンドでインストールします。

brew install tor

インストールが終了したら、以下のコマンドを入力

tor

色々と処理が開始されます。
以下の状態となったら完了です。

Jan 28 00:29:59.000 [notice] Bootstrapped 100% (done): Done

次にtorを起動します。

brew services start tor

successfully的な英語が出たらOKです。

pythonプログラミング

ではpythonを書いていきましょう。
今回は、自身のIPアドレスを取得するURLにアクセスして結果を見てみました。

自身のIPアドレスの確認は、以下のサイトで行うことにします。
https://grupo.jp/myip/

test.py

#UTF-8
import requests
from bs4 import BeautifulSoup

get = requests.get('http://httpbin.org/ip').text
soup = BeautifulSoup(get, 'html.parser')
ip = soup.find('table', class_='pubwaku')

print(get)

まずは通常のスクレイピング実行

python test.py

以下の結果が返ってきます。
たくさんHTMLデータが返ってきますが、以下のように、IPアドレスとリモートホストが書かれている場所を探します。

<tr><th>IPアドレス</th><td style="font-size:18px;font-weight:bold;">153.999.999.99</td><td class="commentary">現在、接続されるIPアドレス</td></tr>
<tr><th>リモートホスト</th><td>p554999-************.*****.ne.jp</td><td class="commentary">IPアドレスに紐づけられたホスト名</td></tr>

IPアドレス
153.999.999.99

リモートホスト
p554999-*********.**.ne.jp

※一部変更と伏字にしております。

このままだと普通のスクレイピングになりますが、以下の記述に変更することにより、torを使ったスクレイピングとなります。

test.py

#UTF-8
import requests
from bs4 import BeautifulSoup

get = requests.get('https://grupo.jp/myip/',
                    proxies=dict(http='socks5://127.0.0.1:9050',
                                 https='socks5://127.0.0.1:9050')).text

soup = BeautifulSoup(get, 'html.parser')
ip = soup.find('table', class_='pubwaku')

print(ip)

requestsの中にproxiesの部分を追加。

実行

python test.py

結果を見てみましょう。
再びIPとリモートホストが書かれている場所を探します。

以下の結果が返ってきます。
たくさんHTMLデータが返ってきますが、以下のように、IPアドレスとリモートホストが書かれている場所を探します。

<tr><th>IPアドレス</th><td style="font-size:18px;font-weight:bold;">82.223.99.999</td><td class="commentary">現在、接続されるIPアドレス</td></tr>
<tr><th>リモートホスト</th><td>tornode3.*******.net</td><td class="commentary">IPアドレスに紐づけられたホスト名</td></tr>

IPアドレス
82.223.99.999

リモートホスト
tornode3.*******.net

※一部変更と伏字にしております。

ご覧の様に、IPアドレスももちろん、リモートホストも適当なものになっております。

もう一度test.pyを実行しても、IPアドレスはこのままになります。再度IPアドレスを変更したい場合はtorを再起動します。

再起動

brew services restart tor

test.py実行

python test.py

結果を確認します。

<tr><th>IPアドレス</th><td style="font-size:18px;font-weight:bold;">109.70.999.99</td><td class="commentary">現在、接続されるIPアドレス</td></tr>
<tr><th>リモートホスト</th><td>tor-exit-anonymizer.********.net</td><td class="commentary">IPアドレスに紐づけられたホスト名</td></tr>

IPアドレス
109.70.999.99

リモートホスト
tor-exit-anonymizer.********.net

※一部変更と伏字にしております。

まとめ

いかがでしょうか。
以上の様にIPアドレスの改竄は簡単にできてしまうのです。
ではDoS攻撃に対して、IPチェックは無駄かと言うとそうではないです。
IPアドレスを変更するには、torを再起動させなければならず、再起動もそれなりに時間がかかるのです。
そのため、1秒に何百回も異なるIPアドレスで攻撃することは難しいです。
なので、同一IPアドレスから一定数アクセスがあった場合は、一時的に拒否する、といったプログラムはある程度効果はあります。
ただしDDos攻撃には効果ない

スクレイピングでの無駄なアクセスといたずらはやめましょう。