25

時間過得真快,距離這個系列的上一篇文章《商業級4G代理搭建指南【準備篇】》發布的時間已經過了兩個星期了,上個星期由于各種瑣事纏身,周二開始就沒空寫文章了,所以就咕咕咕了。

那麼在準備篇中,我們了解了一下搭建 4G 代理所需要的軟硬件,也知道了各種選擇的優劣勢。現在,我們就可以開始實際搭建了,相信大家也是期待已久了。


基本思路

從這篇文章的标題中我們可以看出,這一次的搭建方案主要用到的是 Docker,你可能會很好奇,Docker 跟搭建 4G 代理有什麼關系嗎?

嗯,關系很大,我們把整件事情梳理一下,先來看看搭建 4G 代理時的基本流程:

  1. 調用網卡撥号,撥号成功後會創建一個虛拟網卡。(正常情況下使用這個虛拟網卡就能上網了)

  2. 在多網卡的情況下,重複第一步,會得到多個虛拟網卡。

  3. 啟動代理服務器,使其使用虛拟網卡作為出網網卡,并使用接入内網的實體網卡作為入網網卡。

    使用起來差不多是這樣的

但是呢,有個問題,根據我之前的測試結果來看,目前在 Linux 環境下還沒有一個 HTTP 代理服務器是可以做到分别指定出網網卡和入網網卡的,嗯...這就很麻煩了,因為如果我們無法這麼做的話,就會出現類似于下面這樣的問題:

  1. 出網和入網都在虛拟網卡上,使用代理服務器必須要走公網訪問。
  2. 入網為實體網卡,但出網被代理服務器鎖定為了某一個,無法利用到多網卡。

嗯...那麼不用 HTTP 代理服務器,用那些經常被用來做一些騷操作的 Socks5 代理服務器呢?如果可以指定網卡的話,再用像 Privoxy 之類的工具把 Socks5 代理轉成 HTTP 代理就好了。(某知名扶牆軟件的 Windows 版本就是這麼轉的 HTTP 代理)

在經過一番嘗試後,我發現雖然有些 Socks5 代理服務器的文檔中是說可以指定網卡,但按照說明操作後,似乎并不能直接做到我想要的效果(要麼還是鎖定在某一個上面、要麼上不了網),所以還是存在一些問題的。可能是需要配合路由表設置來進行操作吧,不過我對網絡工程的了解不怎麼深,搞了幾天也沒搞出來,于是乎還得想想别的辦法。

這時候,我想到了一個東西——Docker,它可以用來解決這個問題!

因為 Docker 容器被創建後,不管外界的網卡有多少個,容器内部的網卡都隻會有一個Docker自己的虛拟網卡(容器間通信用的)和一個本地環回接口(不用管它),而且我們在容器内進行撥号操作時,産生的那個新的虛拟網卡也不會影響到外界或其他容器,這樣的話,代理服務器就不需要指定網卡了,直接啟動就能跑!

那麼現在整個流程就跑通了,進入實際操作環節看看吧!


系統方面

這個 Docker 版的搭建方式,系統方面的選擇很多,由于我使用的樣例設備是樹莓派,所以這裡就選擇使用了 Raspbian(樹莓派專屬版 Debian)。如果你使用的是其他設備的話,直接選擇一個自己常用的系統就好。

那麼準備好之後的第一步當然是先下載并安裝 Docker,這裡我直接使用 Docker 官方提供的一鍵安裝腳本來進行安裝:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# 出自官方文檔:https://docs.docker.com/install/linux/docker-ce/debian/#install-using-the-convenience-script

這個一鍵安裝腳本理論上來講所有 Linux 發行版都可以使用,畢竟已經出來很長時間了,如果不行的話請自行使用搜索引擎查找相關資料。

裝好 Docker 之後,你有兩個選擇:

  1. 進入體驗模式,了解一下具體操作細節是怎麼樣的。
  2. 不看這一段,翻到本文最下方直接使用我寫好的輪子。

啟動容器

體驗的話,我們就直接這麼啟動一個 Docker 容器吧,執行以下命令:

sudo docker run -it --rm --privileged -p 3128:3128 ubuntu:18.04 bash
上面這條命令的意思是,啟動一個内部系統為 Ubuntu18.04 的容器,并進入容器内部的 Shell 執行 bash 命令,如果退出 bash 就自動銷毀容器;然後映射容器内的端口3128到外界,映射出來的外界端口也是3128;最後 privileged 參數是開啟特權模式,用于将網卡設備映射進容器内。

如果下載鏡像很慢的話,可以搜一下“Docker 加速器”,也可以直接扶牆。

測試一下網卡是否正常

進入容器内部後,我們可以執行一下 ls /dev/ttyUSB* 看一下網卡有沒有正常被識别出來(在容器外也是一樣的,因為開了特權模式),如果是和我買的同一款 4G 網卡的話,在隻插入一張網卡的情況下你會看到4個 ttyUSB 設備。

插入了三張網卡的樣子,一共12個 ttyUSB 設備

不同 4G 網卡和硬件組合可能會有差異,請以實際情況為準。

如果你可以看到4✖4G網卡個數個 ttyUSB 設備的話,就說明沒有問題,可以開始下一步了。

撥号上網

接下來要做的就是撥号了,撥号方面可以選擇使用 Wvdial 這種工具,也可以選擇使用像 Fanconn 這樣的商家提供的撥号腳本(直接調用 PPPD),使用起來的效果會有一些區别。如果商家沒有提供撥号腳本的話,就用 Wvdial 吧,它能自動生成配置,上手即用。

我這邊的話,由于 Fanconn 的技術人員直接提供了個撥号腳本,那我就用這個腳本了,Wvdial 的文檔網上有很多很詳盡的,這裡就不再多提,需要的朋友自行搜索即可。

如果你用的是 Fanconn 的這個撥号腳本(怎麼弄進容器内就不用我說了吧?),那麼直接在 apt install ppp 安裝好撥号工具之後,用 chmod +x quectel-pppd.sh 給撥号腳本加個運行權限,然後 ./quectel-pppd.sh /dev/ttyUSB3 即可。

撥号時使用的 /dev/ttyUSB3 是指 4G 網卡的第四個通信端口,文檔中的解釋為:ttyUSB3→For PPP connections or AT command communication,翻譯一下就是用于 PPP 連接或 AT 命令通信。

撥号之後用 ifconfig 之類的工具即可看到類似下圖中的狀态:

可以看到,如前文所述,現在有三個網卡,一個是 Docker 自己的、一個是本地環回接口(這個不用管)、一個是撥号産生的虛拟網卡。

如果不是在 Docker 容器内使用的話,還會有個 wwan0(或其他名字),那個是 4G 網卡本體。

測試是否能正常上網

現在如果你用 curl 的 --interface 參數指定虛拟網卡進行請求的話(如:curl --interface ppp0 https://ip.cn),是已經可以請求成功的了,IP 也會是你所使用的 SIM 卡對應的運營商分配的。

由于 Docker 的鏡像通常都是極度精簡的,所以 Ubuntu 鏡像裡并沒有預裝像 net-tools、iputils-ping、vim、curl 之類的這些包,需要自行安裝。所以如果你發現 ifconfig、ping、curl、vim 用不了,不要驚慌,這是正常現象,執行 apt install 包名 命令安裝即可。

如果你無法直接請求成功的話,就可能是 DNS 解析出問題了,可以嘗試 ping 一個公網 IP(如:ping 1.1.1.1)和一個域名(如:ping ip.cn),如果 IP 能 ping 通但域名會報 DNS 解析失敗的話,就可以确認是 DNS 設置問題了。

4G 撥号時如果出現 DNS 設置問題,通常是因為撥号工具沒有正常地将運營商返回的 DNS 服務器設置寫入到配置中,我們可以手動配置一下(你要強制指定某一個 DNS 也可以):

# 以下為阿裡雲的公共DNS
echo 'nameserver 223.5.5.5' >> /etc/resolv.conf
echo 'nameserver 223.6.6.6' >> /etc/resolv.conf
在 Docker 容器中,這個 /etc/resolv.conf 文件可能還會有兩條内容,是容器本身所需要的,建議不要删除/覆蓋,否則會出現容器間無法使用容器名互相通信的情況。

啟動代理服務器

那麼在測試撥号後确實可以通過 4G 網卡上網了之後,我們就可以把代理服務器啟動了,這裡我使用的是 TinyProxy。

測試發現,Squid 對資源的占用更大一些,不利于多網卡情況下的使用,會影響到 4G 網卡的數量上限。

apt install tinyproxy 一波,然後 vim /etc/tinyproxy/tinyproxy.conf 修改一下配置。

要修改的配置主要有:

  • Port 配置項改為3128,因為我們前面映射出來的端口是3128。
  • Listen 配置項改為0.0.0.0,因為我們需要在其他設備上使用這個代理服務器。
  • Allow 配置項注釋掉或改為0.0.0.0/0,默認的127.0.0.1會導緻其他設備無法訪問。

改完之後保存一波,然後就可以直接執行 tinyproxy 啟動了...嗎?

等等,還有一個操作要做!那就是将默認路由指向到虛拟網卡上,很簡單,執行以下命令即可:

route del -net 0.0.0.0 eth0
route add -net 0.0.0.0 ppp0

這兩條命令的意思是:先将默認的、指向 eth0 這個網卡的上網路由删除,然後添加一個同樣的、指向 ppp0 這個網卡的路由。

改完默認路由後的效果就是,即使你不使用 curl 的 --interface 參數,也能直接使用 4G 網卡上網了。

如果沒有改默認路由的話,在不指定網卡的情況下,4G 網卡并不會被使用到,因為默認路由指向的是 Docker 自身的虛拟網卡,那個網卡通向你原本的内網環境。也就是說,IP 不會變!

那麼現在,你可以執行 tinyproxy 啟動代理服務器了。

測試代理服務器

好了,代理服務器應該已經正常啟動了,現在我們可以在另一個設備上嘗試連接那個容器中的代理服務器,看看是否能正常通過它使用 4G 網卡上網。

例如我這裡樹莓派分配到的IP是:192.168.137.66,那麼我就可以用這樣的 curl 命令或 Python 代碼進行測試:

curl:

curl "https://ip.cn"
curl -x "192.168.137.66:3128" "https://ip.cn"

Python:

import requests
resp = requests.get("https://ip.cn", proxies={"https": "http://192.168.137.66:3128"})
no_proxy_resp = requests.get("https://ip.cn")
print(resp.text)
print(no_proxy_resp.text)

測試出來的結果應該與前面在容器内部測試時的一緻,在使用代理後 IP 就變成了運營商分配的基站 IP。

更換 IP

那麼最核心的問題來了,怎麼更換 IP 呢?

其實和使用那些撥号 VPS 架設代理服務器一樣,我們隻需要重新撥個号就能換 IP 了,直接 kill 掉 pppd 進程就可以讓它斷開撥号,斷開後重新執行一遍撥号腳本就是重新撥号了。

斷開撥号方面 Fanconn 的技術人員也提供了一個腳本,同樣在 chmod +x quectel-ppp-kill 賦予運行權限之後,執行 ./quectel-ppp-kill 就可以了。

但需要注意的是,蜂窩網絡的撥号在斷開後,IP 仍然會保留一段時間(具體多久不清楚,可能跟連接的基站也有關系),所以我們需要強制性地讓網卡重新搜網。

冷門小知識:手機上開啟關閉飛行模式的效果就是重新搜網,通常隻是關閉“移動數據”的話,效果是與斷開撥号一緻的。

怎麼做呢?很簡單,就兩行命令:

AT+CFUN=0
AT+CFUN=1

但注意哦,這是 AT 命令,不是 Linux 下的 Shell 命令,AT 命令是一種調制解調器命令語言,我們如果需要将它執行起來,需要這麼做:

echo "AT+CFUN=0" > /dev/ttyUSB2
# 中間間隔1秒左右
echo "AT+CFUN=1" > /dev/ttyUSB2
這裡使用的 /dev/ttyUSB2 是指 4G 網卡的第三個通信端口,文檔中的解釋為:ttyUSB2→For AT command communication,與第四個通信端口類似,隻是它不能用于 PPP 連接、隻能用于 AT 命令通信而已。

不同樣使用第四個通信端口的原因是那個端口有被占用的可能性,直接區分開最穩妥,本來網卡也就是提供了兩個 AT 命令通信渠道的。

在使網卡重新搜網後的幾秒至十幾/幾十秒内的時間裡,你無法正常撥号,需要等待它初始化完成後才可以撥号成功,具體等待時間以信号強度為準,我測試的時候通常5秒以内就可以了。

所以如果你在斷開後一直撥号失敗,不妨過一會兒再試。


總結

那麼現在操作流程也跑通了,我們也了解到了整個的内部細節,最後要做的就是把每個網卡都分别分配一個容器,這樣我們就能實現文章開頭所提到的——“使用虛拟網卡作為出網網卡,并使用接入内網的實體網卡作為入網網卡”的效果了。

實際操作起來的話,就是把指定網卡的部分給配置化,然後在啟動容器的時候傳入就好了,使用 Docker 的容器環境變量相關設置可以很輕松地實現這個功能。

最後,我們可以以這個思路,構建一個 docker-compose 模闆,模闆的核心内容一是做個簡易的4G網卡容器集群,二是啟動個 Squid,用來聚合代理服務器,這樣我們使用的時候隻需要指定一個代理服務器就能随機更換了,操作起來更加方便。


好了,上面就是 Docker 版搭建方式的思路和整個的搭建流程,如果你懶得看的話,直接用我寫好的輪子也是可以的,隻需要發送消息【Docker版4G代理】到公衆号【NightTeam】即可。

評價

最後的最後,我給這個搭建方式打個評價吧。

這個搭建方式并不完美,因為變量太多,而且很多地方肯定不如系統級原生支持的那麼穩定,長期使用可能會出現各種奇奇怪怪的問題。

然後 Docker 的資源占用其實挺高的,會浪費相當多的内存在啟動容器上,如果隻是兩三個網卡還好,如果數量大一點的話,像樹莓派2B 這種小内存的設備根本就扛不住。

另外代理服務器本身對資源的消耗也是比較高的,高頻調用下對樹莓派2B 的小 CPU 壓力還是蠻大的,即使我對它的 CPU 進行了超頻,在并發測試時也還是會出現輕松打滿 CPU 的情況。

但是!截止目前,我還有兩種基于路由器系統的搭建方案沒寫出來!所以...敬請期待後續的其他搭建方案(斜眼笑)。


文章作者:「夜幕團隊 NightTeam」 - Loco

夜幕團隊成立于 2019 年,團隊包括崔慶才、周子淇、陳祥安、唐轶飛、馮威、蔡晉、戴煌金、張冶青和韋世東。

涉獵的編程語言包括但不限于 Python、Rust、C++、Go,領域涵蓋爬蟲、深度學習、服務研發、對象存儲等。團隊非正亦非邪,隻做認為對的事情,請大家小心。

你可能感興趣的

以後可以自己搭代理了,爬蟲團隊用起來可以滿足的

回複

載入中...