中繼節點維護者

  • 請勿使用Ubuntu的套件庫中所提供的軟體套件,因為這些套件不會被定期更新,如果您使用它們的話,將會缺少重要的穩定性和安全性修補。
  • 可透過下列指令來確定您的Ubuntu系統版本:
     ‪$ lsb_release -c
    
  • 使用root權限將下列幾行資訊寫入/etc/apt/sources.list中,並記得將「version」替換成您在上一步驟中查到的版本:
     deb https://deb.torproject.org/torproject.org version main
     deb-src https://deb.torproject.org/torproject.org version main
    
  • 透過執行下來指令來加入簽署該套件數位簽章的gpg金鑰:
     ‪$ curl https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | sudo apt-key add -
    
  • 執行以下指令來安裝洋蔥路由並驗證其數位簽章:
     ‪$ sudo apt-get update
     ‪$ sudo apt-get install tor deb.torproject.org-keyring
    

洋蔥路由可以使用動態IP位址正常運行。 只要把torrc設定檔裡的「Address」項目那行保留空白,這樣洋蔥路由就會自動偵測位址了。

不, 如果您的出口節點的網路連線引起執法單位的關注,那麼相關單位可能會扣押您的電腦。 基於這個理由,最好不要在家中架設出口節點或使用您家中的網路線路。

相對的,可以考慮在支持洋蔥路由專案的商業機構中架設出口節點。 請幫您的出口節點設定一個獨立的IP位址,而且不要讓您自己的網路流量通過它。 當然,您也應該要避免在出口節點的電腦主機上,存放任何敏感或個人資訊。

如果您的洋蔥路由中繼節點使用的記憶體超過您的預期,可以嘗試以下方式來降低該使用率:

  • 如果您是使用Linux系統的話,有可能是遭遇到了在Glibc的malloc函式裡的記憶體碎裂臭蟲。 也就是說,當洋蔥路由程式將記憶體釋放回作業系統後,出現破碎的記憶體空間,故難以被再度利用。 目前 Tor tarball套件包裡有預載 OpenBSD版本的 malloc 函式,此版本的函式較少發生記憶體碎裂的問題(但是代價就是中央處理器的使用率會比較高)。 您可以透過這個設定,來要求 Tor 程式使用此版本的malloc函式:./configure --enable-openbsd-malloc
  • 若您架設的是較高速的中繼節點的話,那就會有很多條TLS的連線同時開通,此時OpenSSL的內部緩衝區就會佔用掉大量的記憶體空間(每個網路接套約須38KB的空間)。 我們已有特別針對OpenSSL程式進行修補過,讓它會更積極的釋放出緩衝區記憶體空間。 若您把OpenSSL更新到1.0.0或更新的版本,洋蔥路由行程就會自動識別並且啟用該功能。
  • 如果您還是無法控制記憶體使用量的話,可以考慮調降中繼節點的額定頻寬。 對外廣播較低的可用頻寬值可以減少吸引到的使用者,進而就會降低中繼節點主機的負載量。 請參閱主頁的MaxAdvertisedBandwidth設定項目。

總而言之,高速的洋蔥路由中繼節點通常都會使用較多的主記憶體空間,因此它在運行狀態中佔用掉500-1000MB的記憶體空間是很常見的現象。

如果您的節點允許出口連線的話,那有些使用者透過您的中繼節點連上的網路服務,會建立回向連線以取得更多關於您的資訊。比如說,有些IRC伺服器會建立回向連線到您的identd連接埠以記錄哪個使用者已建立連線。(這種行為對它們來說其實沒有用,因為洋蔥路由並不會揭露這些資訊,但是它們的服務還是會嘗試。)還有一種可能的情況是,當使用者透過您的節點連上IRC伺服器或網站等標的時,可能會引起其他使用者的注意,它們會想了解更多該使用者所使用的路由資訊。

另一個可能的原因是,有些專門掃描尋找開放代理伺服器的人會發現,有些洋蔥路由中繼節點會將Socks連接埠暴露在網路上,我們建議您將您的Socks連接埠綁定限制於本地端網路。

不論無何,您都應該要隨時關注自身的安全,請參閱洋蔥路由中繼節點安全性以取得更多的相關建議。

很好,這就是為什麼我們會實作出口節點政策的功能。

每個洋蔥路由中繼節點都可以設定自己的出口政策規則,用來指定要接受或者拒絕什麼樣的外接連線。 這個出口政策規則會跟隨著目錄清冊一起被派送到每個洋蔥路由客戶端程式裡,因此客戶端程式在建立迴路時,會自動避免將不願意作為出口節點的中繼節點串接在迴路末端。 因此每個中繼節點的架設者都能夠依據自身的狀況進行評估,以便決定自己的主機要允許什麼樣的連線服務以及連接上什麼樣的主機。 若您要使用預設的出口節點政策的話,請參閱可能遭遇的問題,並且也建議您參閱由Mike Perry撰寫的將架設出口節點所可能遭遇的騷擾最小化

預設的出口節點政策會允許通往大多數熱門的網路服務的連線(例如普通網頁瀏覽),但是會限制某些可能被濫用的情況(例如電子郵件),或者是可能會讓洋蔥路由網路超載的連線(例如封鎖檔案分享協定的預設埠號)。 您可以透過編輯 torrc 檔案來變更出口策略。 如果您想要盡可能的避免被濫用的機會,可以將它設定為「reject *:*」。 這個設定值的意思是,您的中繼節點只會被用來轉送洋蔥路由網路內的連線,不會被用來轉接至外部的普通網站或網路服務。

如果您想要允許通往外部的網路連線的話,請確定您主機的域名解析功能正常(亦即可以正常轉譯網路位址)。 如果有某些網路資源是您的主機無法連接上的(例如您所在的網路防火牆會過濾阻擋),那麻煩請在您的出口節點政策裡,將它明確標注為拒絕,否則洋蔥路由的使用者將會連帶受到影響。

我們希望的是能夠擁有相對穩定的網路連線品質,且其上行與下行的頻寬分別都至少有10 Mbit/s (Mbps)以上,若您擁有這樣的網路環境的話,請考慮架設洋蔥路由中繼節點

即使您的網路可用頻寬不到10 Mbit/s,也仍然可以架設支援Obfs4的洋蔥路由橋接中繼站來貢獻洋蔥路由網路,這種中繼節點只要有1 MBit/s以上的頻寬即可。

洋蔥路由軟體猜測自身IP位址的方式,是先查得該電腦本身的主機名稱,再去解析該名稱的位址,有時候是因為主機本身的/etc/hosts設定檔裡仍然記錄舊的IP位址造成的。

If that doesn't fix it, you should use the "Address" config option to specify the IP address you want it to pick. If your computer is behind a NAT and it only has an internal IP address, see the following Support entry on dynamic IP addresses.

然而,如果您擁有多個位址的話,或許可以調整「OutboundBindAddress」的設定值,這樣可以讓所有外部連線中所暴露出來的IP位址,就是您希望讓外界網路看見的位址。

目前洋蔥路由已可以部份支援IPv6,我們也鼓勵中繼節點的架設者,若您所使用的網路環境支援IPv6的話,可以在torrc設定檔裡啟用IPv6功能。 然而以現階段而言,洋蔥路由的中繼節點仍然必須要使用IPv4位址,還沒辦法完全只用IPv6來架設洋蔥路由中繼節點。

如果是新架設的中繼節點的話,請再等一段時間。 洋蔥路由軟體是依據頻寬主管機構廣播的資訊,再利用推估模式來決定要使用哪些中繼節點的,這些主管機構會去量測您的中繼節點的可容載量,然後才會漸漸的將流量導入您的中繼節點,直到它達到最佳負載量為止。 對於新架設的中繼節點生命週期,在這篇部落格貼文有較詳細的深入解說。 若您的中繼節點已經上線運行一段時間,但是仍然有問題的話,可以試著在洋蔥路由中繼節點的郵件通訊清單尋求協助。

If you're using Debian or Ubuntu especially, please use the Tor Project's repository, so you can easily receive updates. In addition, using the package provides other conveniences:

  • Your ulimit -n gets set to a high number, so Tor can keep open all the connections it needs.
  • The package creates and uses a separate user, so you don't need to run Tor as your own user.
  • The package includes an init script so Tor runs at boot.
  • Tor can bind to low-numbered ports, then drop privileges.

您可以依照下面這份教學,在Windows系統中架設中繼節點:

只有在您能夠讓它24/7不停運行的情況下,再來架設Windows中繼節點。 若您無法保證做到的話,使用Snowflake會是一個貢獻洋蔥路由網路的較好方式。

在中繼搜索中,如果中繼過載,中繼暱稱旁邊將顯示黃色小點。 那就表示下列的負載指標裡,至少有一項被觸發了:

請注意,當中繼節點發生負荷超載的情況時,即使負載量降回正常範圍內,也要等72小時後其顯示狀態才會恢復至正常。

若發現您的中繼節點出現負荷超載現象時,麻煩請進行以下處置:

  1. https://status.torproject.org/ 查詢「洋蔥路由網路」分類裡的任何已知問題。

  2. 請考慮針對網路、記憶體以及中央處理器的使用量,調整sysctl設定

  3. 請考慮啟用MetricsPort以了解實際情況。

調整網路、記憶體以及中央處理器的sysctl設定

TCP連接埠號耗盡

若您遇到TCP連接埠被耗盡的情況,請考慮擴增本地端可用埠號的範圍。 您可藉由此法來調整

# sysctl -w net.ipv4.ip_local_port_range="15000 64000"

或者

# echo 15000 64000 > /proc/sys/net/ipv4/ip_local_port_range

請記住,如上所述,調整的 sysctl在重啟時丟失,而不是永久的。 為了永久有效,需將其添加到 /etc/sysctl.conf/etc/sysctl.d/中的檔案。

MetricsPort

想要了解 Tor 中繼和 Tor 網絡的運行情況,提供並可訪問中繼指標是至關重要的。 從 0.4.6+ 開始,中繼超載資訊被加入到中繼描述符中,但直到 Tor 0.4.7.1-alpha 之後,才提供底層中繼指標的接口:指標接口。

正在啟用 MetricsPort

通過 torrc 配置選項MetricsPort,Tor 提供指標端口的訪問。

重要的是要明白, 對 Tor 網路用戶,公開暴露 Tor MetricsPort 是為危險的,因此該端口默認不啟用,而且其訪問必須受到訪問政策的約束。 因此當開啟這個連接埠時請特別小心謹慎,並且務必在完成除錯後將它關閉。

假設你是運行了 Tor 中繼的伺服器上的唯一用戶。 可以在 torrc 文件中添加以下內容來啟用指標端口:

MetricsPort 127.0.0.1:9035
MetricsPortPolicy accept 127.0.0.1

然後使用以下命令可輕鬆獲取指標:

# curl http://127.0.0.1:9035/metrics

預設為 Prometheus 格式。

注意: 該伺服器上的每個用戶都能夠訪問上述例子中的中繼指標。 通常,可通過MetricsPortPolicy 設置嚴格的訪問政策,並考慮使用作業系統防火牆功能進行深度防禦。

關於 MetricsPortMetricsPortPolicy更詳細的解釋,請參閱 tor 的 man 頁面。

MetricsPort 輸出

以下示例為MetricsPort 啟用後生成的輸出(刪去了所有與擁塞控制有關的指標,因為我們仍然需要穩定該接口):

# HELP tor_relay_connections Total number of opened connections
# TYPE tor_relay_connections gauge
tor_relay_connections{type="OR listener",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="OR listener",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="OR listener",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="OR listener",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="OR",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="OR",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="OR",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="OR",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Exit",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Exit",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Exit",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Exit",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Socks listener",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Socks listener",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Socks listener",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Socks listener",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Socks",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Socks",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Socks",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Socks",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Directory listener",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Directory listener",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Directory listener",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Directory listener",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Directory",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Directory",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Directory",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Directory",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Control listener",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Control listener",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Control listener",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Control listener",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Control",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Control",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Control",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Control",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Transparent pf/netfilter listener",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Transparent pf/netfilter listener",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Transparent pf/netfilter listener",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Transparent pf/netfilter listener",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Transparent natd listener",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Transparent natd listener",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Transparent natd listener",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Transparent natd listener",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="DNS listener",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="DNS listener",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="DNS listener",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="DNS listener",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Extended OR",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Extended OR",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Extended OR",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Extended OR",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Extended OR listener",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Extended OR listener",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Extended OR listener",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Extended OR listener",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="HTTP tunnel listener",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="HTTP tunnel listener",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="HTTP tunnel listener",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="HTTP tunnel listener",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Metrics listener",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Metrics listener",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Metrics listener",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Metrics listener",direction="received",state="opened",family="ipv6"} 0
tor_relay_connections{type="Metrics",direction="initiated",state="opened",family="ipv4"} 0
tor_relay_connections{type="Metrics",direction="initiated",state="opened",family="ipv6"} 0
tor_relay_connections{type="Metrics",direction="received",state="opened",family="ipv4"} 0
tor_relay_connections{type="Metrics",direction="received",state="opened",family="ipv6"} 0
# HELP tor_relay_connections_total Total number of created/rejected connections
# TYPE tor_relay_connections_total counter
tor_relay_connections_total{type="OR listener",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="OR listener",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="OR listener",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="OR listener",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="OR listener",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="OR listener",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="OR",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="OR",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="OR",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="OR",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="OR",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="OR",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Exit",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Exit",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Exit",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Exit",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Exit",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Exit",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Socks listener",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Socks listener",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Socks listener",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Socks listener",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Socks listener",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Socks listener",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Socks",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Socks",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Socks",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Socks",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Socks",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Socks",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Directory listener",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Directory listener",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Directory listener",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Directory listener",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Directory listener",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Directory listener",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Directory",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Directory",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Directory",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Directory",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Directory",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Directory",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Control listener",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Control listener",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Control listener",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Control listener",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Control listener",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Control listener",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Control",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Control",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Control",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Control",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Control",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Control",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Transparent pf/netfilter listener",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Transparent pf/netfilter listener",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Transparent pf/netfilter listener",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Transparent pf/netfilter listener",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Transparent pf/netfilter listener",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Transparent pf/netfilter listener",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Transparent natd listener",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Transparent natd listener",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Transparent natd listener",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Transparent natd listener",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Transparent natd listener",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Transparent natd listener",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="DNS listener",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="DNS listener",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="DNS listener",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="DNS listener",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="DNS listener",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="DNS listener",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Extended OR",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Extended OR",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Extended OR",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Extended OR",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Extended OR",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Extended OR",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Extended OR listener",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Extended OR listener",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Extended OR listener",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Extended OR listener",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Extended OR listener",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Extended OR listener",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="HTTP tunnel listener",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="HTTP tunnel listener",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="HTTP tunnel listener",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="HTTP tunnel listener",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="HTTP tunnel listener",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="HTTP tunnel listener",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Metrics listener",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Metrics listener",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Metrics listener",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Metrics listener",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Metrics listener",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Metrics listener",direction="received",state="rejected",family="ipv6"} 0
tor_relay_connections_total{type="Metrics",direction="initiated",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Metrics",direction="initiated",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Metrics",direction="received",state="created",family="ipv4"} 0
tor_relay_connections_total{type="Metrics",direction="received",state="created",family="ipv6"} 0
tor_relay_connections_total{type="Metrics",direction="received",state="rejected",family="ipv4"} 0
tor_relay_connections_total{type="Metrics",direction="received",state="rejected",family="ipv6"} 0
# HELP tor_relay_flag Relay flags from consensus
# TYPE tor_relay_flag gauge
tor_relay_flag{type="Fast"} 0
tor_relay_flag{type="Exit"} 0
tor_relay_flag{type="Authority"} 0
tor_relay_flag{type="Stable"} 0
tor_relay_flag{type="HSDir"} 0
tor_relay_flag{type="Running"} 0
tor_relay_flag{type="V2Dir"} 0
tor_relay_flag{type="Sybil"} 0
tor_relay_flag{type="Guard"} 0
# HELP tor_relay_circuits_total Total number of circuits
# TYPE tor_relay_circuits_total gauge
tor_relay_circuits_total{state="opened"} 0
# HELP tor_relay_streams_total Total number of streams
# TYPE tor_relay_streams_total counter
tor_relay_streams_total{type="BEGIN"} 0
tor_relay_streams_total{type="BEGIN_DIR"} 0
tor_relay_streams_total{type="RESOLVE"} 0
# HELP tor_relay_traffic_bytes Traffic related counters
# TYPE tor_relay_traffic_bytes counter
tor_relay_traffic_bytes{direction="read"} 0
tor_relay_traffic_bytes{direction="written"} 0
# HELP tor_relay_dos_total Denial of Service defenses related counters
# TYPE tor_relay_dos_total counter
tor_relay_dos_total{type="circuit_rejected"} 0
tor_relay_dos_total{type="circuit_killed_max_cell"} 0
tor_relay_dos_total{type="circuit_killed_max_cell_outq"} 0
tor_relay_dos_total{type="marked_address"} 0
tor_relay_dos_total{type="marked_address_maxq"} 0
tor_relay_dos_total{type="conn_rejected"} 0
tor_relay_dos_total{type="concurrent_conn_rejected"} 0
tor_relay_dos_total{type="single_hop_refused"} 0
tor_relay_dos_total{type="introduce2_rejected"} 0
# HELP tor_relay_load_onionskins_total Total number of onionskins handled
# TYPE tor_relay_load_onionskins_total counter
tor_relay_load_onionskins_total{type="tap",action="processed"} 0
tor_relay_load_onionskins_total{type="tap",action="dropped"} 0
tor_relay_load_onionskins_total{type="fast",action="processed"} 0
tor_relay_load_onionskins_total{type="fast",action="dropped"} 0
tor_relay_load_onionskins_total{type="ntor",action="processed"} 0
tor_relay_load_onionskins_total{type="ntor",action="dropped"} 0
tor_relay_load_onionskins_total{type="ntor_v3",action="processed"} 0
tor_relay_load_onionskins_total{type="ntor_v3",action="dropped"} 0
# HELP tor_relay_exit_dns_query_total Total number of DNS queries done by this relay
# TYPE tor_relay_exit_dns_query_total counter
tor_relay_exit_dns_query_total 0
# HELP tor_relay_exit_dns_error_total Total number of DNS errors encountered by this relay
# TYPE tor_relay_exit_dns_error_total counter
tor_relay_exit_dns_error_total{reason="success"} 0
tor_relay_exit_dns_error_total{reason="format"} 0
tor_relay_exit_dns_error_total{reason="serverfailed"} 0
tor_relay_exit_dns_error_total{reason="notexist"} 0
tor_relay_exit_dns_error_total{reason="notimpl"} 0
tor_relay_exit_dns_error_total{reason="refused"} 0
tor_relay_exit_dns_error_total{reason="truncated"} 0
tor_relay_exit_dns_error_total{reason="unknown"} 0
tor_relay_exit_dns_error_total{reason="tor_timeout"} 0
tor_relay_exit_dns_error_total{reason="shutdown"} 0
tor_relay_exit_dns_error_total{reason="cancel"} 0
tor_relay_exit_dns_error_total{reason="nodata"} 0
# HELP tor_relay_load_oom_bytes_total Total number of bytes the OOM has freed by subsystem
# TYPE tor_relay_load_oom_bytes_total counter
tor_relay_load_oom_bytes_total{subsys="cell"} 0
tor_relay_load_oom_bytes_total{subsys="dns"} 0
tor_relay_load_oom_bytes_total{subsys="geoip"} 0
tor_relay_load_oom_bytes_total{subsys="hsdir"} 0
# HELP tor_relay_load_socket_total Total number of sockets
# TYPE tor_relay_load_socket_total gauge
tor_relay_load_socket_total{state="opened"} 0
tor_relay_load_socket_total 0
# HELP tor_relay_load_tcp_exhaustion_total Total number of times we ran out of TCP ports
# TYPE tor_relay_load_tcp_exhaustion_total counter
tor_relay_load_tcp_exhaustion_total 0
# HELP tor_relay_load_global_rate_limit_reached_total Total number of global connection bucket limit reached
# TYPE tor_relay_load_global_rate_limit_reached_total counter
tor_relay_load_global_rate_limit_reached_total{side="read"} 0
tor_relay_load_global_rate_limit_reached_total{side="write"} 0

我們來說明一下這幾行文字代表的意義:

tor_relay_load_onionskins_total{type="ntor",action="dropped"} 0

當中繼節點開始出現「丟失」訊息時,通常是中央處理器或記憶體相關的問題造成的。

遺憾的是 Tor 是單線程的 除了 處理“洋蔥皮”時. 所謂的「洋蔥表皮」是指在每條迴路中,需要針對每個「洋蔥包覆層」進行的加解密運算處理。

當 Tor 在針對包覆層進行處理時,會將其運算作業交付給執行緒池負責。 因此當這個執行緒池遇到記憶體或中央處理器資源吃緊的情況時,有可能會開始丟失掉須處理的運算工作,進而觸發了負荷超載狀態。

當您的伺服器運算資源有限時,這種情況就有可能會發生。

tor_relay_exit_dns_error_total{...}

“*_dns_error_total” 領域的任何計數器(成功查詢的除外)都表明可能存在 DNS 相關的問題。 然而,我們在 0.4.7 的發佈週期中意識到,DNS 錯誤的噪音太大,且包含太多的假陽性,不可用於超載報告。 因此,從 0.4.6.9 和 0.4.7.4-alpha 開始,我們不再將其用於此目的。然而,為了便於中繼營運者瞭解中繼發生了什麼,仍然保留了 DNS 指標。

DNS 超時問題和錯誤只適用於出口節點。

tor_relay_load_oom_bytes_total{...}

而 OOM的指示訊息通常是由記憶體造成的。 您的中繼節點可能需要增加記憶體,或者也有可能是有記憶體洩漏的問題。 若您發現洋蔥路由程式有記憶體洩漏的現象,麻煩請將問題通報至洋蔥路由的GitLab,或者是直接寄發電子郵件至洋蔥路由中繼節點的郵件論壇

洋蔥路由有內建OOM管理模組,當它可用的總記憶體空間使用量達75%時,此訊息就會被觸發。 因此,假設洋蔥路由程式的可用記憶體總量是2GB的話,當它已使用1.5GB時,會自動開始進行記憶體釋放。 此時就會被視為是負荷超載狀態。

針對可用記憶體總量的估算,洋蔥路由程式會以啟動時MaxMemInQueues的設定值為準,如果此值未被設定的話,那它就會針對主機裡的總記憶體量以下列演算法來求算出來:

    if RAM >= 8GB {
      memory = RAM * 40%
    } else {
      memory = RAM * 75%
    }
    /* Capped. */
    memory = min(memory, 8GB) -> [8GB on 64bit and 2GB on 32bit)
    /* Minimum value. */
    memory = max(250MB, memory)

要避免進入負荷超載的狀態,我們建議若是使用64位元的電腦架設中繼節點的話,那至少要安裝2GB的主記憶體。 如果能夠安裝到4GB當然是更好,當然,盡可能的加大記憶體是有利無害的。

您或許也會發現,Tor 的OOM訊號也有可能會被作業系統觸發。 因為 Tor 在啟動時,會以整個系統所擁有的記憶體總量去估算其可用量,而當系統中已經有執行許多佔用大量記憶體的程式時,它就會耗用掉過多的記憶體空間。 在這種情況下,即使洋蔥路由程式本身沒有偵測到記憶體不足的情況,作業系統也仍會呼叫並觸發洋蔥路由的OOM訊號。

tor_relay_load_socket_total

如果打開的 socket 端口數量接近或等於可用的總數,那麼這就表明,中繼 socket 端口快要用盡了。 解決方式就是增加洋蔥路由行程的ulimit -n設定值。

tor_relay_load_tcp_exhaustion_total

這幾行訊息代表中繼節點已經耗盡TCP連接埠。

請嘗試依照上述方法調整sysctl設定值。

tor_relay_load_global_rate_limit_reached_total

若發現此計數器的數值在短時間內爆增的話,就表示該中繼節點發生擁塞了。 有可能是因為它被某個洋蔥服務站台用作護衛節點,或者是遭受到網路上的分散式阻斷服務攻擊。

若您的中繼節點一直處於負荷超載狀態,且又無法查明原因的話,請聯繫network-report@torproject.org。 您可以利用network-report的OpenPGP金鑰來將郵件加密。

升級 Tor 中繼或將其移至另一台電腦時,請務必保留相同的身份金鑰 (儲存在 keys/ed25519_master_id_secret_key and keys/secret_id_key 在你的資料目錄中).

If you are a bridge operator, also make sure to keep pt_state/. It contains data required for your bridge to keep working with the same bridge line.

For simplicity, just copying over the entire DataDirectory should work too.

You may wish to keep backups of these identity keys, plus pt_state for a bridge, so you can restore the relay if something goes wrong.

下方列出了預設會使用的幾個連接埠號,但是請注意,任何中繼節點架設者都可以藉由修改torrc設定檔或是程式碼來使用其他任何連接埠。 根據原始碼版本 src/or/policies.c (line 85line 1901) 從原始碼發布 release-0.4.6:

reject 0.0.0.0/8
reject 169.254.0.0/16
reject 127.0.0.0/8
reject 192.168.0.0/16
reject 10.0.0.0/8
reject 172.16.0.0/12

reject *:25
reject *:119
reject *:135-139
reject *:445
reject *:563
reject *:1214
reject *:4661-4666
reject *:6346-6429
reject *:6699
reject *:6881-6999
accept *:*

BridgeDB 使用六項機制來分發橋接:HTTPS、Moat、Email、 Telegram、Settings 和 Reserved。 橋接中繼站的架設者可以透過中繼節點搜尋引擎,查詢自己的橋接中繼站正在使用哪種方式。 在表單中輸入您的橋接中繼站的<HASHED FINGERPRINT>並點擊「搜尋」。

架設者也能夠自己選擇要使用哪種派送方式。 想要更改模式,請將 torrc 文件中的 BridgeDistribution 設置修改爲以下之一:https、moat、email、telegram、settings、none 或 any。

請參閱橋接中繼站安裝後指南以了解更多相關資訊。

  • 出口節點是最迫切需要的中繼節點,但是這種節點同時也是面臨法律爭議風險最高的中繼節點(請勿在自己家裡架設出口節點)。
  • 如果您希望以最輕鬆簡便的方式架設中繼節點,那高速的護衛節點是非常實用的選擇
  • 再來就是橋接中繼站。

我們一直努力讓洋蔥路由中繼節點的架設過程更容易且方便:

  • 如果中繼節點偶而需要離線的話也沒關係。 目錄主管機構主機會在短時間內發現,並且停止將該中繼節點廣播出去。 只不過這種情況仍請儘量不要太頻繁發生,因為每當中繼節點斷線時,所有通過它的連線也都會被中斷。
  • 每個 Tor 中繼節點都有一組出口節點政策,用以指定來自哪個中繼節點的什麼樣的連線要被允許或拒絕。 如果您不希望您的中繼節點被當成出口節點來使用的話,可以將它設定成只允許通往其他洋蔥路由中繼節點的連線。
  • 您的中繼節點會針對最近的時間裡可用的網路頻寬進行被動式估測以及廣播,故擁有高頻寬的中繼節點會比低頻寬的節點吸引到更多的使用者,因此,低頻寬的中繼節點也是有相當的實用價值。

為什麼中繼節點的負載量差異會很大

洋蔥路由會管理調節整個網路上的頻寬用量,它的現行策略對於大多數的中繼節點來說,都可以運作良好。 然而,Tor 的目標與其他像是位元洪流之類的通訊協定不同。 Tor 的主要目標是提供低延遲率的網頁載入服務,因此會需要預留頻寬以提昇連線速率。 而位元洪流的目標是提供整批下載服務,因此就會盡可能的耗盡所有可用頻寬。

我們目前正在開發一個新的頻寬掃描器,以使這個部份更容易理解與維護。 它會針對未被量測或是量測率偏低的中繼節點進行診斷。

為什麼洋蔥路由會需要頻寬掃描器?

大多數的網路服務供應商會告知您網路的最大速率。 但是洋蔥路由的使用者是來自世界各地,並且他們每次都會以隨機的方式選定一兩個護衛節點來連線。 因此,我們必須要知道每個中繼節點實際上與全世界的網路連通速度是如何。

因此,即使所有中繼運營者將其公佈的頻寬設置為其本地連接速度,我們仍然需要頻寬權限來平衡網際網路不同部分之間的負載。

正常的中繼節點負載量是多少?

正常的中繼節點負載量是可用容載量的30%-80%。 這樣對於使用者來說是最佳狀態,因為負荷超載的中繼節點其延遲率會偏高。 (我們的期望是能夠擁有足夠的中繼節點,以便讓每個節點的平均負載量都落在10%左右,這樣 Tor 網路速度就會幾乎跟普通網際網路一樣快)。

有些時候,中繼節點速度降慢的原因,是因為中央處理器效能不足或是網路連線受到限制。 也有些時候是因為網路速度太慢造成的,例如說該中繼節點與其他節點間的連線有瓶頸,或是位處於較遙遠的地段。

找出中繼節點速度緩慢的原因

造成中繼節點速度緩慢的可能原因有很多,底下逐一說明追查的方式。

系統限制

  • 請確認中繼節點主機的記憶體、中央處理器、網路接套以及檔案描述符的使用量

這些資訊有些在洋蔥路由啟動時會被記錄於歷程記錄中,另外有些資訊則可利用像是top之類的工具軟體查得。

網路服務供應商的限制

  • 確認您的中繼節點通往其他節點的網路連線(頻寬與延遲率)。 有時候中繼節點透過 Comcast公司的網路傳輸會較慢。 位處於北美洲或西歐地區以外的中繼節點也通常會比較慢。

洋蔥路由網路限制

中繼節點的頻寬會受到節點主機本身觀測到的頻寬,或是目錄主管機構的量測值所限制。 底下方式可以查出到底是哪個量測值限制造成的:

  • 查閱consensus-health(超大網頁)上各個節點針對您的中繼節點所作的投票結果,尤其是它們的平均值。 如果您的中繼節點被部份目錄主管機構標記為停機狀態的話:
    • 請確認IPv4或IPv6的位址是否設定錯誤?
    • 它的IPv4或IPv6位址是否無法由某些地區的網路存取到?
    • 是否有多臺中繼節點使用同一個IPv4位址?

或者是確認您的中繼節點所觀測到的頻寬與速率(限制)。 在Metrics上查詢中繼。 將滑鼠游標移至頻寬標頭,可以得知中繼節點觀測到的頻寬值與資料傳輸率。

這裡有幾個比較細節的範例可參考:共識權重下降以及出口節點速率提昇

要如何解決

此圖表中的最小數值會限制該中繼節點被配得的頻寬。

  • 如果是頻寬資料傳輸率造成的話,那可以增加您的torrc設定檔裡有關BandwidthRate、Burst或RelayBandwidthRate、Burst的相關設定值。
  • 如果是受觀測到的頻寬限制的話,那除非中繼節點軟體的觀測值提昇,否則它是不會調昇頻寬限制量的。 此時您就必須要更深入追查此值低落的原因。
  • 如果是量測頻寬的平均值偏低的話,那就表示您的中繼節點通往大部分的頻寬主管機構主機的連線較慢所導致。 此時您就必須要更深入追查量測值低落的原因。

對中繼節點做自我量測

如果您的中繼節點軟體判定自己的速度較慢,或是被頻寬主管機構主機認定較慢的話,您可以用這種方式自行量測自己的頻寬值:

  • 使用 Tor 運行測試,看看 Tor 連接到您的網路的速度有多快

    For this, you need to configure a tor client to use use your relay as entry. If your relay has only Guard flag, set EntryNodes with your relay fingerprint in torrc. If your relay doesn't have Guard flag or it has Guard and Exit flags, you can't set your relay as an entry node (see https://gitlab.torproject.org/tpo/core/tor/-/issues/22204), but you can set it as your bridge, even if it is not a bridge. To set your relay as a bridge, add to your torrc:

    Bridge <ip>:<port>
    UseBridge 1
    

    Then download a large file using your SocksPort as a socks proxy. For this, you can use curl, eg:

    curl https://target/path --proxy socks5h://<user>:<password>@127.0.0.1:<socks-port>
    

    Using different user/password guarantees different circuits. You can use $RANDOM.

    That will give you some idea of how much traffic your relay can sustain.

    Alternatively, you can run relay_bw to test your relay using 2 hops circuits, in a similar way as sbws does.

  • Run a test using tor and chutney to find out how fast tor can get on your CPU. Keep increasing the data volume until the bandwidth stops increasing.

會的,對於抵禦特定某些攻擊手法來說,您的匿名保護機制是會更完備。

最簡單的例子是,當攻擊者掌控了少數幾個 Tor 中繼節點時。 他們只能夠看見連線來自於您,但是無法分辨該連線是您自己所發起的,還是轉接其他使用者的連線。

但在某些情況下,這樣做的保護還是會失效:就是當攻擊者能夠監控您的所有對內與對外網路連線時,那他還是能夠輕易的分辨出,哪些連線是您所發起的,而哪些連線是轉接自其他使用者的。 (即使是在這樣的情況下,除非攻擊者剛好也同時監控到您的網路連線的目標網站,否則他仍然無法得知您目前正與誰連線交換資料,但若他真的恰好也有監控到目標網站的流量,那此時不論您是否使用洋蔥網路,安全防護效果就都沒什麼差別了。)

而架設洋蔥路由中繼節點也是會有一些缺點的。 首先,目前我們的中繼節點總數只有幾百個而已,因此若您自己架設中繼節點的話,攻擊者會馬上察覺您是個非常注重匿名性保護的人。 再來,有些非常刁鑽弔詭的攻擊手法,可以在只知道您是否有架設中繼節點的情況下就發動,這些手法目前還未被深入研究了解或測試,舉例來說,攻擊者可以發動連線並藉由您的中繼節點來轉接,再觀察資料流入與流出的時間差,如此即使攻擊者無法實際監控您的網路,仍然可以「觀測」出您目前是否有發動網路連線。

這個議題目前仍在廣泛的討論與研究中,故其風險的暴露與攻擊的效益權衡目前仍未有定論。 這其實主要還是取決於您最憂慮的攻擊手法為何。 我們認為對於大部分的使用者來說,這是個很好的方向。

請參閱portforward.com以了解如何在NAT或路由器中設定連接埠轉送。

如果您是在內網區段架設中繼節點的話,那您就會需要設定連接埠轉送機制。 有關於TCP連線轉送在不同的系統上會有不同的作法,您可以參考身處防火牆內問答集裡的幾個範例。

另外,這裡也有個在GNU/Linux系統中使用iptables的設定範例:

/sbin/iptables -A INPUT -i eth0 -p tcp --destination-port 9001 -j ACCEPT

如果您網路的介面不是「eth0」的話,這個值可能需要調整(連接外部網路的介面)。 大部分的情況下,您可能只有一個網路介面(除了loopback之外),因此這部份應該不至於太複雜。

在torrc設定檔裡有個項目,可以讓您指定在特定時間區段裡,中繼節點容許使用的總位元組數。

    AccountingStart day week month [day] HH:MM

這個項目讓您指定計數器歸零重置的時間點,例如要設定在一週內可容許使用的總位元組數量的話(在每個禮拜三的上午十點整),您可以這樣設定:

    AccountingStart week 3 10:00
    AccountingMax 500 GBytes

This specifies the maximum amount of data your relay will send during an accounting period, and the maximum amount of data your relay will receive during an accounting period. 當計數時間區段結束時(由AccountingStart指定),在AccountingMax裡的計數器值就會自動歸零。

範例:假設您希望每天的資料傳送量以及接收量分別以50 GB為上限,並且在每天的中午自動歸零重新起計:

    AccountingStart day 12:00
    AccountingMax 50 GBytes

但請注意,您的中繼節點並不一定每次都會在計數時間區段開始的時候就啟動。 它會記錄並觀測在過往幾的計數時間區段中,頻寬配額的耗用速度,再自行於下一個時間區段裡隨機選定某個時間點啟動。 這樣可以避免出現一種情況,就是幾百個中繼節點都在月初同時啟動運作,但是到了月底時卻沒有運作中的中繼節點了。

如果您希望貢獻的網路頻寬總額遠低於您的總網路速率的話,我們建議您以日為單位設定計數時間區段,如此可以避免您的主機在每月的第一天,就把整個月的頻寬配額耗用殆盡。 只要把您每月預定要用的頻寬配額除以30來設定,並且可能要考慮限定傳輸速率,以便讓主機每天的可用時間盡可能拉長:比如說您希望對於傳送或接收的頻寬配額分別設定為X GB的話,那就可以把RelayBandwidthRate的值設定為20*X KBytes。 例如說,您每天都有50 GB的頻寬配額可以貢獻,那就可以把RelayBandwidthRate設定為1000 KBytes,這樣一來可以保證您的中繼節點每天都至少會有半天以上的時間在運作。

    AccountingStart day 0:00
    AccountingMax 50 GBytes
    RelayBandwidthRate 1000 KBytes
    RelayBandwidthBurst 5000 KBytes # 允許更高的突發但保持平均

您的觀念並沒有錯,在大多數的情況下,當有一個位元組的資料流進您的洋蔥路由中繼節點,就代表也會有一個位元組的資料流出,反之也是亦然,但是仍會有少數幾個例外情況:

若您有開啟DirPort旗標的話,那洋蔥路由客戶端程式就會對您的主機索取目錄清單資料。 這種索取目錄的請求(HTTP GET)資料量都很少,但須回覆的資料量則相對龐大。 通常這就是讓您的主機對網路「寫入」與「讀取」資料量會有差異的主要原因。

另一個小例外則是當您架設的是出口節點時,您的主機會從連線出口端(例如即時通訊軟體或SSH連線)接收少量的位元組資料,再將之組裝成512位元組的資料包後,送入洋蔥路由網路中。

對於 AccountingMax以及BandwidthRate這兩個參數的設定值,會同時被套用到洋蔥路由程式的客戶端以及中繼節點中。 因此當您在歷程記錄中看見如下的訊息時,表示您的洋蔥路由已經進入休眠模式,同時您也將無法繼續上網瀏覽網頁:

Bandwidth soft limit reached; commencing hibernation.
No new connections will be accepted

這個問題的解決方式是執行兩個獨立的洋蔥路由行程:一個給中繼節點使用,另一個給客戶端程式使用,並且讓它們有各自獨立的設定。 其中一種可行的作法(若您從中繼節點設定開始做起的話)如下:

  • 在洋蔥路由中繼節點的torrc設定檔中,把SocksPort的值設定為0。
  • 從torrc.sample再建立一個新的客戶端torrc設定檔,並且確定它沒有跟中繼節點共用同一個歷程記錄檔。 依照慣例可以把名稱分別取為torrc.client以及torrc.relay。
  • 編輯洋蔥路由客戶端程式以及中繼節點程式裡的設定腳本,在裡面加入-f /path/to/correct/torrc設定。
  • 在 Linux/BSD/MacOS X系統裡,將設定腳本改為Tor.client以及Tor.relay可以較容易將兩者的設定值分離開。

簡而言之,它的原理就是:

  • 會有一個ed25519的主身份金鑰檔,名為「ed25519_master_id_secret_key」。 這把金鑰是最重要的,因此請確定它有安全的備份,且它也是機敏檔案,必須要被特別保護。 如果您是手動產製這把金鑰並且有設定密碼的話,那洋蔥路由就能夠幫您把它加密保護。
  • 還會有一把中程的簽署金鑰名為「ed25519_signing_secret_key」,是專門產製給洋蔥路由使用的。 並且,還會產製出一份以主身份金鑰簽署的憑證,檔名為「ed25519_signing_cert」,並確認該中程簽署金鑰在特定的時間裡是有效的。 預設的效期是30天,但這可由torrc設定檔裡的「SigningKeyLifetime N days|weeks|months」項目來變更。
  • 並且還會有一把主公開金鑰名為「ed25519_master_id_public_key」,它是中繼節點在網路上的身份識別。 這把金鑰就不具有機敏性了,它可以從「ed5519_master_id_secret_key」直接運算生成。

若金鑰仍有效的話,洋蔥路由只會需要存取中程簽署金鑰以及憑證檔而已,所以主身份金鑰不需要存放在主機的DataDirectory/keys目錄中,可將它置於另一臺電腦或儲存媒體裡保存。 在中程簽署金鑰以及憑證的效期結束前,您必須要去手動更新,否則的話該臺中繼節點上的洋蔥路由程式會自動關閉。

然而,這個功能是選擇性的,除非您想要,不然的話可以不使用。 如果您想要讓中繼節點可以長時間自主運行,不希望時常要手動去更新中程簽署金鑰的話,可以把主身份金鑰置於DataDirectory/keys裡,但請記得也要另外備份,以免需要重新安裝軟體時可用。 如果您想要啟用這項功能的話,請參閱我們關於此主題的詳細指南

對於客戶端程式而言,護衛節點的使用量原本就會比其他類型節點要低,大多數的客戶端程式可能還沒有切換原本使用的護衛節點。 若要了解更多細節,可以閱讀這篇部落格貼文,或者是這篇論文護衛節點更換策略:洋蔥路由之入口節點選用策略之研析與改進框架

當出口節點的設定錯誤,或者是屬於惡意人士架設的主機,它就會被標記上BadExit的旗標,因此可以防止洋蔥路由程式將該它作為迴路的出口節點來使用,實際上來說,中繼節點只要被標記上這個旗標,就等於是變成非出口節點。 如果我們發現您的出口節點有問題,或者是當網路流量通過您的節點時有可疑的現象,但是又無法跟您取得聯繫以釐清問題時,就會把您的節點標上此旗標。因此請您直接與不良節點管理團隊聯絡,以便解決此問題。

所有的對外連線都應該被設定為允許,這樣您的中繼節點才能夠與其他中繼節點通訊。

在許多司法管轄地區裡,中繼節點的架設者都會受到普通承載人相關法規的保護,就像是網路服務供應商,當有第三方利用其服務進行違反法律之行為時,承載人在法律上會受到免責保護。 但是當出口節點設定連線過濾條件時,此法律上的保護將會失效。

Tor 主張與提倡不受干預的自由網路存取。 出口中繼節點不可以針對通過它們主機的連線進行過濾。 若被發現出口中繼節點進行此類過濾的話,將會被列為不良出口節點

太棒了,我們很高興您願意架設多臺中繼節點來貢獻網路。 但是麻煩請不要在同一個網路區段中,同時架設超過數十臺,因為洋蔥路由網路的其中一個關鍵,就是要讓整個網路架構更分散且更多元。

如果您決定要架設超過一臺中繼節點的話,麻煩請在每臺節點的torrc設定檔裡調整「MyFamily」項目,把您所架設維護的中繼節點都列進去(每臺皆以英數逗號分隔):

MyFamily $fingerprint1,$fingerprint2,$fingerprint3

其中每個特徵碼都是一串由40個字元所組成的識別碼(不含空白字元)。

如此一來洋蔥路由客戶端程式在建立迴路時,就會避免在同一條迴路中,同時用到多個由您所架設維護的中繼節點。 您應該要把所有由您所掌控的中繼節點都列入MyFamily設定值裡,不論這些節點主機是否位於同一個地理位置。

在torrc設定檔中有兩個選項您可以使用:

BandwidthRate 是指可使用頻寬的最大上限值(單位為每秒位元組數)。 例如,您可以設定成「BandwidthRate 10 MBytes」來把頻寬限制在每秒10 Megabytes以內(較高速的連線),或者是設定成「BandwidthRate 500 KBytes」來把頻寬限制在每秒500 KBytes以內(相當於品質中庸的有限電纜連線速率)。 對於BandwidthRate的最小設定值是每秒75 kilobytes。

BandwidthBurst 則是位元組池,意指連線的資料傳輸率可在短時間內超過BandwidthRate的容許值,但以長時間的流量統計來說,其平均值仍會接近於BandwidthRate。 因此,將BandwidthRate設定較低但BandwidthBurst設定較高的話,可以讓尖峰時間的流量短時間內提高,但長時間的整體平均值仍可以壓在較低的數值。 舉例來說,若您將BandwidthBurst以及BandwidthRate都設定在每秒500 KBytes的話,那您的每秒傳輸速率永遠都不會有超過500 kilobytes的時候,但是若您將BandwidthBurst設定較高(例如5MBytes),那它在尖峰時間的傳輸速率仍可以大幅提昇,直到將該位元組池的額度耗盡為止。

如果您的網路服務連線是非對稱型的(上傳速率低於下載速率),那您應該將BandwidthRate的值設定低於較小的那個頻寬速率(通常是上傳頻寬)。 否則的話,當連線傳輸率較高時,您的封包遺失率也會大幅上升,這個部份會需要您親自實驗測試過後,才能找出最合適的理想值。 然後再把BandwidthBurst跟BandwidthRate設定成相同的值。

以Linux系統架設的洋蔥路由節點還會有另一個選項:可以將洋蔥路由的網路流量優先權值設定低於其他網路流量,如此可以避免該電腦上的其他個人網路活動頻寬受到洋蔥路由的衝擊。 在洋蔥路由資源的貢獻目錄裡,有一個腳本程式可以達成此目的。

此外,休眠選項可指定 Tor 在每個時間段只提供一定量的頻寬(比如每月 100 GB)。相關資訊,可參閱休眠條目

請注意,這裡的BandwidthRate以及BandwidthBurst數值的單位都是位元組,而不是位元。