torrcのExcludeNodesを変更してTorの接続、ブラウジングを超高速にする方法

Tor は複数のノードを経由することで、とても匿名性を高くしている。だが、匿名性がある程度妥協できる日常のブラウジングに使うにはあまりにも遅い。そのため、匿名性を犠牲にしつつも、高速にする設定を行う。

# torrc の設定
Windowsの場合 `Tor Browser\Browser\TorBrowser\Data\Tor\torrc` ファイルを、
macOSの場合 ~~`~/Library/Application Support/TorBrowser-Data/Tor/torrc` を編集~~ なぜかだめなので、 `Tor Browser.app/Contents/Resources/TorBrowser/Tor/torrc-defaults` を編集(ファイルパスにスペースが入っているので注意)し、

以下のように設定する

```bash
StrictNodes 1
ExcludeNodes {bd},{be},{bf},{bg},{ba},{bb},{wf},{bl},{bm},{bn},{bo},{bh},{bi},{bj},{bt},{jm},{bv},{bw},{ws},{bq},{br},{bs},{je},{by},{bz},{ru},{rw},{rs},{lt},{re},{lu},{lr},{ro},{ls},{gw},{gu},{gt},{gs},{gr},{gq},{gp},{gy},{gg},{gf},{ge},{gd},{gb},{ga},{gn},{gm},{gl},{kw},{gi},{gh},{om},{jo},{hr},{ht},{hu},{hk},{hn},{hm},{kr},{ad},{pr},{ps},{pw},{pt},{kn},{py},{ai},{pa},{pf},{pg},{pe},{pk},{ph},{pn},{pl},{pm},{zm},{eh},{ee},{eg},{za},{ec},{al},{ao},{kz},{et},{zw},{ky},{es},{er},{me},{md},{mg},{mf},{ma},{mc},{uz},{mm},{ml},{mo},{mn},{mh},{mk},{mu},{mt},{mw},{mv},{mq},{mp},{ms},{mr},{au},{ug},{my},{mx},{vu},{fr},{aw},{af},{ax},{fi},{fj},{fk},{fm},{fo},{ni},{nl},{no},{na},{nc},{ne},{nf},{ng},{nz},{np},{nr},{nu},{ck},{ci},{ch},{co},{cn},{cm},{cl},{cc},{ca},{cg},{cf},{cd},{cz},{cy},{cx},{cr},{kp},{cw},{cv},{cu},{sz},{sy},{sx},{kg},{ke},{ss},{sr},{ki},{kh},{sv},{km},{st},{sk},{sj},{si},{sh},{so},{sn},{sm},{sl},{sc},{sb},{sa},{sg},{se},{sd},{do},{dm},{dj},{dk},{de},{ye},{at},{dz},{us},{lv},{uy},{yt},{um},{tz},{lc},{la},{tv},{tw},{tt},{tr},{lk},{li},{tn},{to},{tl},{tm},{tj},{tk},{th},{tf},{tg},{td},{tc},{ly},{va},{vc},{ae},{ve},{ag},{vg},{iq},{vi},{is},{ir},{am},{it},{vn},{aq},{as},{ar},{im},{il},{io},{in},{lb},{az},{ie},{id},{ua},{qa},{mz}
EntryNodes {jp}

ExitNodes {jp}
# ↑日本にExitノードがなくて繋がらない場合、 {jp},{kr},{tw},{hk},{sg} など近い国を入力する
```

と入力する。

# 上記設定の生成方法
`pycountry` と `Set` (集合)を使って、`(すべての国 - ExcludeNodesから取り除く国)` を生成する。

## 前準備

```bash
pip install pycountry
```

## ソースコード

`entry_countries`, `include_countries`, `exit_countries`, `forbid_countries` の設定はお好みで。JPにExitがなくて繋がらない場合、近い国のコードを入れると良いだろう。
それぞれ `EntryNodes`, `ExcludeNodes` のインバース(逆), `ExitNodes` に関係してくる。`forbid_countries` は ExcludeCountries に必ず追加する国。

なお、国コードは2文字の [ISO 3166-1 alpha-2](https://ja.wikipedia.org/wiki/ISO_3166-1) である。 

```py
import pycountry
import pprint
pp = pprint.PrettyPrinter(indent=4)

def concat_sets(countries):
  return ','.join(['{' + r.lower()+'}' for r in countries])

entry_countries = set({
  'JP',
})

include_countries = set({
  'JP',
  #'KR',
  #'HK',
  #'TW',
  #'SG',
  #'PH',
  #'US',
  #'AU',
})

exit_countries = set({
  'JP',
})

forbid_countries = set({
  ## 5-eyes
  #'US',
  #'GB',
  #'CA',
  #'AU',
  #'NZ',
  ## 9-eyes
  #'DK',
  #'FR',
  #'NL',
  #'NO',
  ## 14-eyes
  #'DE',
  #'BE',
  #'IT',
  #'ES',
  #'SE',
  ## 41-eyes
  #'AT',
  #'CZ',
  #'GR',
  #'HU',
  #'IS',
  #'JP',
  #'LU',
  #'PL',
  #'PT',
  #'KR',
  #'CH',
  #'TR',
  ## Dangerous (harmful exit) countries
  #'RU',
  #'UA',
  #'CN',
})

all_countries = set([c.alpha_2 for c in list(pycountry.countries)])

if len(forbid_countries) > 0:
  exclude_countries = forbid_countries
else:
  exclude_countries = all_countries - include_countries

exclude_nodes = concat_sets(exclude_countries)
entry_nodes = concat_sets(entry_countries)
exit_nodes = concat_sets(exit_countries)

print("StrictNodes 1")
print("ExcludeNodes " + exclude_nodes)
if len(entry_nodes) > 0:
  print("EntryNodes " + entry_nodes)
if len(exit_nodes) > 0:
  print("ExitNodes " + exit_nodes)
```

## 実行
```bash
python countrycode.py 

# Macの場合、こうするとクリップボードにコピーされる
# python countrycode.py | pbcopy
```

実行すると、標準出力に設定が吐き出されるので、コピーする

# 理屈
Entry(Guard)ノードに日本のノードだけを使用するようにし、中間ノードとして日本以外のノードを弾くようにし、Exitノードを日本だけにすることで、日本国内だけでTor Circuitが完成され、RTT(Round Trip Time)が減り、高速になる。

# 警告
言うまでもないが、高速なブラウジングとは引き換えに、**匿名性はとても低いものとなる。**

例えばあなたがジャーナリストで重大事案を告発する場合やある組織のメンバーで、その組織の重要な機密を内部告発する場合などにはこの設定は使わず、日常のブラウジング程度の利用にとどめるべきだろう。

また問題として、**JPにExitNodeがない場合は、当然ながら全く接続ができない**ため、いくつかの国をExcludeNodesから削除する(いくつかの国をExitとして許容する)ことをおすすめする。

## レイテンシ比較
速度の比較は意味がないので、レイテンシのみに注目する。

### 上記設定
#### Fast.com 120ms〜

<img width="870" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19148/25045bb7-0f7e-6cd2-da1d-8e114ba542b9.png">

#### Yahoo! Japan 1.86s
<img width="1112" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19148/72f63226-2d70-16c9-4845-0945bfc9de51.png">


### デフォルト
#### Fast.com 805ms〜
<img width="1112" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19148/6c5e3c81-fad4-4981-81fd-3da25fe6293e.png">

#### Yahoo! Japan 7.07s
<img width="1112" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19148/e3f160da-6fd3-545f-7eb5-d161ce4c8468.png">

# おまけ
[Linuxに安全にtorリレーをインストールする方法](https://qiita.com/keiya/items/811dea56bf79c721364f) もご覧ください

## 匿名性+
速度を少し犠牲にし、匿名性を少しあげる。経由する国は日本から出ている[海底ケーブル](https://www.submarinecablemap.com/)で、1hop以内に到達できる場所。

画像はKDDIやGoogleなどによる、日本に接続されている海底ケーブルの一つ "Southeast Asia Japan Cable"
<img width="968" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19148/65dc4a47-d3df-13f5-f8a8-b869e1c2b580.png">
画像：[Southeast Asia Japan Cable (SJC)](https://www.submarinecablemap.com/#/submarine-cable/southeast-asia-japan-cable-sjc)

```py
entry_countries = set({
  'JP',
})

include_countries = set({
  'JP',
  'KR',
  'HK',
  'TW',
  'SG',
  'PH',
})

exit_countries = set({
  'JP',
})
```
## 匿名性++
Entry(Guard)ノードだけをJPにし、速度をある犠牲にし匿名性を上げる。

```py
entry_countries = set({
  'JP',
})

include_countries = set({
  'JP',
  'KR',
  'HK',
  'TW',
  'SG',
  'PH',
})

exit_countries = set({
  'JP',
  'KR',
  'HK',
  'TW',
  'SG',
  'PH',
})
```

## 匿名性+++
速度を犠牲にし匿名性をさらに上げる。

```py
entry_countries = set({
  'JP',
  'KR',
  'HK',
  'TW',
  'SG',
  'PH',
})

include_countries = set({
  'JP',
  'KR',
  'HK',
  'TW',
  'SG',
  'PH',
})

exit_countries = set({
  'JP',
  'KR',
  'HK',
  'TW',
  'SG',
  'PH',
})
```

## 匿名性++++
速度をかなり犠牲にし匿名性をさらに上げる（Torの標準レベル）。Torのデフォルト設定。特に `EntryNodes`, `ExitNodes`, `ExcludeNodes` を指定しない。

## 匿名性++++ & 安全性+ : スパイ協定を結んでいる国をExcludeNodesに追加する場合
あなたが重要な通信をする場合、設定によって速度は低速になるが、この設定を行う。

`forbid_countries` に1つでも国を追加すると、上記プログラムは "除外" モードになり、 `forbid_countries` への通信を一切行わない設定を出力する。

1. `entry_countries`, `exit_countries` を空にする。
2. `forbid_countries` に以下を追加する。

## 5eyes "UKUSA Agreement" を除く場合
[UKUSA協定](https://ja.wikipedia.org/wiki/UKUSA%E5%8D%94%E5%AE%9A)の構成国アメリカ、イギリス、カナダ、オーストラリア、ニュージーランドをTor Circuitから除外するよう設定する。

```py
# 5-eyes
  'US',
  'GB',
  'CA',
  'AU',
  'NZ',
```

- in 2009, the United States proposed to France to join the Five Eyes
    - `'FR'`
- Five Eyes Plus "Like-Minded" Against China and Russia:
    - `'JP'`, `'DE'`
- Israel, Singapore and Japan are collaborating with Five Eyes:
    - `'IL'`, `'SG'`, `'JP'
- In 2013 it was reported that Germany was interested in joining the Five Eyes alliance:
    - `'DE'`

## 9-eyes を除く場合
5-eyesに加え、デンマーク、フランス、オランダ、ノルウェーの4カ国を加える。

[Five Eyes # Other international cooperatives](https://en.wikipedia.org/wiki/Five_Eyes#Other_international_cooperatives)

- consists of the same members of Five Eyes working with Denmark, France, the Netherlands and Norway.

```py
  # 5-eyes
  'US',
  'GB',
  'CA',
  'AU',
  'NZ',
  # 9-eyes
  'DK',
  'FR',
  'NL',
  'NO',
```

## 14-Eyes "SSEUR" を除く場合
9-eyesに加え、ドイツ、ベルギー、イタリア、スペイン、スウェーデンを加える。SSEURとも。

[Five Eyes # Other international cooperatives](https://en.wikipedia.org/wiki/Five_Eyes#Other_international_cooperatives)

- 14 nations officially known as SIGINT Seniors Europe, or "SSEUR".
- consist of the same members of Nine Eyes plus Belgium, Germany, Italy, Spain and Sweden.

```py
  # 5-eyes
  'US',
  'GB',
  'CA',
  'AU',
  'NZ',
  # 9-eyes
  'DK',
  'FR',
  'NL',
  'NO',
  # 14-eyes
  'DE',
  'BE',
  'IT',
  'ES',
  'SE',
```

## 41-eyes を除く場合
- 14-eyesに加え、オーストリア、チェコ、ギリシア、ハンガリー、アイスランド、日本、ルクセンブルク、ポーランド、ポルトガル、韓国、スイス、トルコを加える。

```py
  # 5-eyes
  'US',
  'GB',
  'CA',
  'AU',
  'NZ',
  # 9-eyes
  'DK',
  'FR',
  'NL',
  'NO',
  # 14-eyes
  'DE',
  'BE',
  'IT',
  'ES',
  'SE',
  # 41-eyes
  'AT',
  'CZ',
  'GR',
  'HU',
  'IS',
  'JP',
  'LU',
  'PL',
  'PT',
  'KR',
  'CH',
  'TR',
```


# 参考文献
- https://www.submarinecablemap.com/
- https://ja.wikipedia.org/wiki/UKUSA%E5%8D%94%E5%AE%9A
- https://bestvpn.jp/what-is-5-eyes/
- https://en.wikipedia.org/wiki/Five_Eyes

# 更新情報
- 2022/06/17: ExcludeNodes から `SlowServer` を消去 (これは単なる Nickname としてmanに書いてあるだけであって、遅いサーバーをexcludeするという意味ではなさそう)
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19148/ebc47985-3cad-dec5-5c60-ca2263c04cd7.png)
    - 参考 [Torの ExcludeNodes SlowServer は意味なさそう
](https://qiita.com/keiya/items/51702ce4db4232af753b)