2023年底,電信界最大的新聞應該是台灣之星和亞太電信走入歷史,台灣的電信商再度回到三雄鼎立的局面。從產業經濟的角度觀察,雖然短期有兩家新的一類電信業者出現,但長期而言仍然是回歸三家廠商的寡占狀態。對於消費者而言,少了兩家小型電信商,最大的衝擊應該是廉價吃到飽資費方案走入歷史。
幸運的是,我在台灣之星初入市場時便申辦「終身188不限速吃到飽」方案(台灣之星與台灣大哥大合併後,依公平會的附款,台灣大哥大必須依原資費方案承作至4G執照到期,即2033年底)。
我本身擁有一台舊桌機搭建而成的個人伺服器(server),也有用NAS搭配Docker所運行的私人服務,因此對網路的速度與流量都有一定的需求。然而現行租屋處沒有申請固網,使我的伺服器和Docker運作停擺。為了解決此一問題,我萌生將台灣之星吃到飽門號作為租屋處網路的想法。雖然4G LTE的速度絕對比不上固網,但經實測也還有約 30~60 Mbps 的速度,勉強可以接受。
起初構想很簡單,將SIM卡插入閒置的Android手機,再用一條USB線連接至支援 3G/4G modem 的路由器(我目前是用 ASUS RT-AC51U)即可,但實際運作後才發現事情沒那麼單純。
在解釋我遇到什麼困難之前,必須先理解什麼是通訊埠轉發(port forwarding)。
任何server或網路服務運作時,必定需要接收來自外部網路的請求封包,例如我在咖啡廳用手機app登入server,就是手機app向server發出請求封包,並獲得server的回覆。因此,當此類app發送的請求封包抵達server所在的ip時,路由器必須適當的將請求封包轉送到後方正確的server通訊埠(port),這個轉送封包的工作,便是通訊埠轉發(port forwarding)。不正確的通訊埠轉發(port forwarding)會導致app無法和server建立連線。
此外,為了增加駭客的入侵成本,一般會將外部port與內部port分離,此時也需要路由器正確的將外部port來的請求封包轉送至內部port。舉例來說,我架在server上的私人網路服務是透過443 port運行,但我並不想要將server的443 port暴露在外網上,因此我將私人網路服務的外部port改為8080 port,因此我在咖啡廳時,只需在瀏覽器上打上「https://server的ip位置:8080/」,路由器就會將這個由外部8080 port來的請求封包轉送至內部server的443 port。
總而言之,通訊埠轉發(port forwarding)是自架server必須要有的功能,我的路由器當然也有。
使用電信商的4G LTE行動網路上網時,網路的封包都會經過電信商的NAT。CGNAT主要是為了緩解IPv4位址枯竭問題,電信商向客戶分配私網的IPv4位址而非公網的IPv4位址,這一點可由路由器取得的外網ip上得到印證,外部網路ip顯示的是192.168.X.X的私網ip (虛擬ip)。
如果只是一般上網、看影片、開視訊會議等等,基本上感受不到CGNAT。
但如果涉及通訊埠轉發(port forwarding),就會有問題。因為使用CGNAT,就好像自己的路由器是放在電信商的大路由器後面一樣,因此想要成功讓外部的請求封包正確送到自己的路由器,必須在電信商的大路由器上,也設定通訊埠轉發(port forwarding),才能順利運作。
簡單的講,「由內而外」的封包都沒有問題,所以上網、看影片都與一般固網無異;「由外而內」的請求封包,基本上都會被CGNAT所阻擋,更不要提在電信商的大路由器上設定通訊埠轉發(port forwarding)。
想要使用4G LTE行動網路、又要取得非虛擬的實體IPv4 ip,最簡單的方法就是花錢請電信商幫忙,但大多都限企業客戶才能申請,如中華電信的行動固定ip上網服務或遠傳的行動數據網路。
而以我的狀況來說,我不打算為了server成立一家公司,且目前也沒有看到台灣大哥大有類似的服務;縱使有這樣的服務,原來的台灣之星門號可不可以申請也是個疑問。
前面提到,CGNAT主要是因應IPv4位址枯竭問題,因此若改用IPv6,理論上就可以獲得實體的ip(請參閱後記)。但要改用IPv6的前提還不少。
首先是手機要支援IPv6。我的閒置手機是HTC One E8,由於機型較舊,並不支援IPv6;另一隻閒置手機是HTC U11,支援IPv6,但我的ASUS RT-AC51U路由器不支援U11作為3G/4G modem。
縱使手機支援IPv6、路由器也讀得到手機的3G/4G modem,由於獲取到的IPv6 ip仍然是浮動ip,因此必須使用DDNS,而DDNS也必須要支援IPv6。DDNS支援IPv6有兩個要素,一是路由器支援自動更新IPv6的ip給DDNS廠商、二是DDNS廠商也有IPv6的DDNS服務。
以我目前正在使用的ASUS路由器為例,依據華碩的官方說明,必須是韌體版本3.0.0.4.386.46061以後的版本才支援IPv6的DDNS。另外以我常用的DDNS廠商NO-IP而言,目前已經支援IPv6的DDNS(NO-IP目前僅能使用Linux DUC進行AAAA的更新)。
後記:後來我購買了TP-Link的4G LTE Router,雖然可以成功獲取IPv6的ip,但仍然非實體ip,故IPv6的解決方案目前仍不可行。
如果以上方法都不可行,那剩下的唯一解就是使用VPN。
VPN可以繞過CGNAT的限制,當然前提是必須有一個VPN Server在CGNAT外面,才能利用「由內而外」的方式繞過限制。但我如果有CGNAT外的地方可以架VPN Server,我就直接把server放在那邊就好了。
既然自行架設VPN Server不可行,那就只能購買市面上的VPN服務。但也不是所有的VPN服務都可以買。必須要VPN廠商有特別標示支援 port forwarding 才行。因為使用VPN時,VPN廠商就是另一個大路由器,那些外部請求封包一樣會被VPN廠商擋住。
雖然不是每個VPN廠商都提供 port forwarding 功能,但還是可以透過架設反向代理伺服器的方式,迴避無法支援 port forwarding 的問題。
我在架設Bitwarden的文章中有提到反向代理伺服器的概念。一般的代理伺服器,是代為處理「由內而外」的封包,使得欲造訪的網站或服務看不到真正的ip或port。而反向代理伺服器,就是代為處理「由外而內」的封包,即使不知道真正的ip或port,也能將封包正確送達。例如我幫我的Bitwarden服務申請了一個 bitwarden.examlpe 網址,Bitwarden app將封包送到這個網址所解析出來的ip位置,且Bitwarden app預設是走443 port。由於443 port是所有TLS協定所使用的port,送來的封包不一定都是Bitwarden app所發出的封包,因此需要一個反向代理伺服器將 bitwarden.examlpe 網址來的封包過濾出來,轉送到Bitwarden服務實際所在的Docker ip以及所使用的port。
借用反向代理伺服器處理「由外而內」封包的原理,理論上可以幫位在CGNAT後面的私人服務申請一個 service.example 網址,並將該網址的域名解析(DNS)託管到第三方的廠商,再建立一條從server到第三方廠商的通道,將所有來自 server.example 網址的流量都透過通道直送server,並藉由server上的反向代理伺服器,將來自 service.example 網址的封包轉送到私人服務實際所在的內部ip及port。也就是說,所有封包在外網都是走443 port,直到通過通道後,才由server上的反向代理伺服器進行封包轉送,從而無需在第三方廠商進行 port forwarding 設定。網路上也真的有神人利用CloudFlare實作出來。
但說到底,使用反向代理伺服器迴避 port forwarding 的前提,還是必須先與第三方廠商建立一條私人通道,再一股腦兒地將所有封包都送到server來過濾,只能算是VPN的變型。雖然可能不用支付VPN服務的錢,但仍然需要租用網址的錢,而且有幾個服務就要有幾個不一樣的網址(也可用子域名解決),仍然不算是完全免費,且技術門檻更高。
綜合上述,我應該會先嘗試改用IPv6的方案,若仍無法順利運作,才考慮付費使用有 port forwarding 功能的VPN服務,這應該是現階段用手機吃到飽網路架設個人伺服器比較好的實作方式。至於實際運作狀況,待我運行一段時間後再向大家更新。
有使用Synology NAS的人應該都知道 quickconnect (簡稱QC) 功能,其實 QC 的運作原理就跟VPN很像,NAS與 QC 的伺服器建立通道,當需要從外部網路連線時,會先連線到 QC 的伺服器,再由已經建立好的通道傳送請求封包,因此無論NAS是否位於路由器後面、路由器有無設定port forwarding,QC都能讓使用者在外網存取NAS。
但 QC 的伺服器一樣沒有開放 port forwarding 的功能,根據Synology的官網說明,透過 SMB、AFP、FTP、NFS、WebDAV 存取的服務,都不在 QC 的支援範圍內,因此想透過 QC 來繞過 CGNAT 仍然有所限制(僅限於 QC 支援的app,如DSM、Synology Drive、DS file等)。