frp程式能夠讓內網主機輕鬆地提供對外服務,只要在公網(雲端)主機上架設frps,就可以讓內部主機提供外網功能。但內部主機直接放在公網上供人存取,可能會有安全上的疑慮,所以務必先做好資安相關部署再正式啟用。
行動網路已逐漸成為生活必需品,與固網線路相較,行動網路受限於IP數量限制、先天架構及價格考量,鮮少提供真實IP供用戶使用。因此使用行動網路要架設網站相對困難。本文將介紹如何在使用行動網路的狀況下,透過在雲端(公網)的Linux主機,從而連入行動網路後端的主機,進一步提供http及https的連線功能。
實作環境與測試架構
目前市面上可以做到內網穿透的工具很多,例如Ngrok、Localtunnel、花生殼等等。廣義來說,其實SSH Tunnel也算是一種內網穿透機制,這些工具各有其利弊。在本文中採用的frp是使用Go語言開發的,它的全名是Fast Reverse Proxy,顧名思義,它是一個快速的反向代理伺服器。其設定方式相當簡單,功能也很強大。除了內網穿透之外,也可以讓外部伺服器提供對外服務、Proxy、Socket5的部分功能,甚至也能加上簡單的帳號及密碼認證功能。
本次實作所使用的作業系統及軟體版本如下:
‧公網主機:Ubuntu 14.04.6、frp_0.33.0
‧內部主機:Ubuntu 20.04.1、frp_0.34.0、Apache 2.4.41、OpenSSH_8.2p1
這裡會在公網主機上使用frps,在內部主機使用frpc,分別擔任Server及Client的角色。
圖1為本測試使用的架構圖,從圖中可以看出,在公網主機或雲端主機(frps with public IP address,FQDN為stock.ddnsking.com)上架設frps(frp Server),在內部主機(10.100.32.34)則安裝frpc(frp Client)的軟體。在兩者建立連線之後,外部使用者可以連接frps的特定Port,此時frps會將其封包轉發至frpc的指定Port。
如此一來,即使是原先無法直接提供對外服務的主機,也能簡單地提供對外服務的功能。
frps相關設定說明
原則上,應該要手動下載frps的原始程式,並自行編輯其設定檔,再啟動frps以達到預期的功能。但網路上已有人提供簡易的安裝方式,其採取對話視窗的方式進行安裝及設定,因此在此階段先使用此方式進行安裝及設定。首先,將安裝檔下載回來:
wget https://raw.githubusercontent. com/MvsCode/frps-onekey/master/ install-frps.sh -O ./install-frps.sh
接著,賦予其可執行的屬性。然後,執行安裝程式:
chmod 700 ./install-frps.sh ./install-frps.sh install
接下來,安裝程式會逐步詢問相關資訊,基本上都是使用預設值即可(直接按下〔Enter〕鍵):
Please select frps download url: [1].aliyun [2].github (default) Enter your choice (1, 2 or exit. default [github]):
此處為用來建立連線的Port,請設定為能被外部網路連線的Port,在此使用預設值5443:
Please input frps bind_port [1-65535] (Default Server Port: 5443): frps bind_port: 5443
由於本次示範公網主機的80 Port有對外服務,因此使用8000 Port避免衝突:
Please input frps vhost_http_port [1-65535](Default : 80):8000 frps vhost_http_port: 8000
接著要設定https Port,這裡使用預設的443:
Please input frps vhost_https_port [1-65535](Default : 443):443 frps vhost_https_port: 443
frps其實有提供儀表板介面,可以簡單地從網頁看出目前的使用情形,在此使用預設的6443 Port。
Please input frps dashboard_port [1- 65535](Default : 6443): frps dashboard_port: 6443
必須設定儀表板介面的帳號,使用預設的admin即可:
Please input frps dashboard_user(Default : admin): frps dashboard_user: admin
接著要設定網頁介面的密碼,系統會自動產生,如果有其他需求亦可自行設定,在此設定為liveisnevereasy:
Please input frps dashboard_pwd (Default : tklzEU4G): liveisnevereasy frps dashboard_pwd: liveisnevereasy
然後是在建立建線時使用的Token,可以想像為建立連線時的密碼,可避免frps讓外人任意建立連線,在此使用系統自動產生的數值即可:
Please input frps token(Default : kdC5ePAaBDa656gD): frps token: kdC5ePAaBDa656gD
緊接著是最重要的部分,若有對外https連線的需求,建議輸入FQDN,若僅有http的需求,輸入IP即可:
Please input frps subdomain_host(Def ault : 59.105.191.159):stock.ddnsking.com frps subdomain_host: stock.ddnsking.com
隨後還有六個問題會詢問,包含每個連線可建立的連接數(Max Pool count)、Log等級及留存日、是否使用tcp_mux(tcp port service multiplexer)及kcp加速等。若無特殊需求,建議使用預設值即可。
設定完成後,它會將之前的所有設定列表,若沒有問題就輸入任意鍵繼續安裝流程:
========== Check your input ========= You Server IP : 59.105.191.159 Bind port : 5443 kcp support : true vhost http port : 8000 vhost https port : 443 Dashboard port : 6443 Dashboard user : admin Dashboard password : liveisnevereasy token : kdC5ePAaBDa656gD subdomain_host : stock.ddnsking.com tcp_mux : true Max Pool count : 50 Log level : info Log max days : 3 Log file : enable ===================================== Press any key to start...or Press Ctrl+ c to cancel
安裝完成後,主程式及設定檔均會存放在「/usr/local/frps」目錄中,若後續需要手動調整frps的設定檔,必須進入此目錄,手動編輯frps.ini,並重新啟動frps。
想要執行frps時,只須在任意目錄執行「frps start」指令,就可以啟動其程式。在程式啟動後,可以看一下目前的網路連線情形,如圖2所示,可使用「ss -antp」指令查看。
由圖2中可以看出,frps所Listen的Port包含443、8000、5443、6443以及6000。
然後使用瀏覽器開啟「http://stock.ddnsking.com:6443」,其輸出如圖3所示。可以發現,此儀表板有簡單的統計功能,並沒有管理功能。不過,此儀表板能夠檢視網路的使用量,若為雲端主機的租用者,將可藉此調整其流量租約。
frpc相關設定介紹
相較於frps有人寫好安裝Script,frpc則必須手動進行安裝及設定。
首先,切換至「/usr/local」目錄:
cd /usr/local/
接著,下載目前最新的0.34版:
wget https://github.com/fatedier/frp/ releases/download/v0.34.0/frp_0.34.0_ linux_amd64.tar.gz
frp最新的版本會放在「https://github.com/fatedier/frp/releases/」網址,可自行依需求下載。
接著,將之解壓縮,並重新命名為frpc,避免與frps主機混淆,然後切換至該目錄:
tar frp_0.34.0_linux_amd64.tar.gz mv frp_0.34.0_linux_amd64 frpc cd frpc
下載的原始檔中,同時會有frps和frpc,在此僅使用frpc。
先做最簡單的設定,編輯frpc.ini,並設定其內容如下例。server_addr部分,設定為frps主機的公網IP。而token的部分,請與frps.ini相符。在此設定將frps的6000 Port轉發至本機(127.0.0.1)的22 Port:
[common] server_addr = 59.105.191.159 server_port = 5443 token = kdC5ePAaBDa656gD log_file = ./frpc.log # debug, info, warn, error log_level = debug log_max_days = 3 [ssh] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 6000
frpc.ini設定好存檔後,接著執行frpc(請切換至該目錄):
./frpc -c frpc.ini &
確認成功執行之後,從外地主機(139.175.16.2)使用SSH Client連線至stock.ddnsking.com的6000 Port,就可建立連線至frpc的SSH Port。
然後,查看frpc目前建立的連線。在此使用「ss -anpt | grep frpc」指令,可以看出10.100.32.34(frpc)透過49620 Port連線至59.105.191.159的5443 Port,另外frpc從本機的43124 Port連線至本機的22 Port,如圖4所示。
接著,查看frps的連線情形,可以看出139.175.13.32(10.100.32.34的Public IP),使用TCP Port 49620連線至59.105.191.159的5443 Port,以建立frp連線。外部主機139.175.16.2連線至59.105.191.159的6000 Port,如圖5所示。從圖4和圖5可以發現,6000 Port的連線需求會被包在5443 Port的連線中,在frpc看不出建立6000 Port的連線。
HTTP封包的轉發
接著要進行設定,讓內部主機的網頁能夠被公網上的電腦存取。
回到frpc的主機,切換至「/usr/local/frpc」目錄,編輯frpc.ini,並新增以下內容:
[http] type = http local_port = 80 custom_domains = stock.ddnsking.com
在此補充說明一下,如果只有http的需求,在frps.ini的subdomain_host以及frpc.ini的custom_domains使用IP即可,無須使用FQDN。除此之外,[http]裡的http可以自行命名,這裡只是單純以功能來命名便於識別。
在frpc.ini設定完成後,將frpc重啟:
kill -9 `ps ax | grep frpc.ini | grep -v grep | awk '{print $1}'` ./frpc -c frpc.ini &
接著開啟「http://stock.ddnsking.com:8000」,可以看到在10.100.32.34上架設的網頁,如圖6所示。由於採取的是http連線,因此可以發現這是一個不安全的連線。
直接把內部網頁放在公網上有點危險,所以在frpc.ini加上一點保護機制。在的段落中,加上以下的設定值:
http_user = klting http_pwd = showmethemoney
接著,別忘了重啟frpc。再次開啟「http://stock.ddnsking.com:8000」,就能看到詢問帳號及密碼的視窗,如圖7所示。
HTTPS封包的轉發
可以使用frp讓內部的http網站提供https的服務。既然是https的服務,當然要申請合法的憑證,因此在進行frpc設定之前,要先備妥合法的憑證。由於提供對外連線的實際上是stock.ddnsking.com這一部主機,因此要申請憑證時也是以其名稱進行申請。
這裡以可以免費使用90天的zerossl作為示範,網址為「https://zerossl.com/」。
在簡單地註冊帳號之後,登入此網站,並點選「New Certificate」申請新的憑證,如圖8所示。
接著,在Enter Domains頁面中,輸入「stock.ddnsking.com」,如圖9所示,然後點選「Next Step →」。
接下來選擇有效期限,由於本次僅是測試性質,使用預設的90天效期即可。90天效期的憑證是免費的,頁面如圖10所示,點選「Next Step →」繼續。
再來要選擇方案,同樣選擇預設的「Free」,並點選「Next Step →」,如圖11所示。
之後是最重要的部分,要讓zerossl驗證目前網站的身分,在此使用的是「HTTP File Upload」的方式。簡單來說,要在「http://stock.ddnsking.com/.well-knows/pki-validation/」目錄中,將zerossl提供的檔案(點選Download Auth File連結就可以下載)放進去,並設定網頁伺服器和檔案的屬性,讓zerossl網站可以讀取這個檔案。在準備完成後,點選「Next Step →」讓zerossl檢查檔案,如圖12所示。
可以用瀏覽器開啟圖12中的連結,確認可以讀取該檔案的內容後,再點選「Verify Domain」,如圖13所示。
在所有的步驟都完成後,終於可以下載憑證的相關檔案。如圖14所示,點選「Next Step →」將之下載。
把憑證的壓縮檔下載後上傳至frpc主機,將之解壓縮後放置到自訂的目錄內。在此例中,放置在「/etc/apache2/sites-available/」目錄中。
最後編輯frpc.ini,並新增以下內容:
[https] type = https local_port = 80 custom_domains = stock.ddnsking.com plugin = https2http plugin_local_addr = 127.0.0.1:80 plugin_host_header_rewrite = 127.0.0.1 plugin_header_X-From-Where = frp plugin_crt_path = /etc/apache2/sites- available/certificate.crt plugin_key_path = /etc/apache2/sites- available/private.key
在此做一簡單說明,[https]同樣只是名稱,可以自行命名。本次使用frp的https2http模組(Plugin),將https的連線需求,轉換為http的連線需求,再轉發給frpc指定的http伺服器。因為IP實際上是不一樣的,因此header的部分也必須改寫為127.0.0.1。另外,也告知X-From-Where是由frp設定的。事實上,header的部分不設定也可以正常運作,但為了有利於之後的維運及追蹤,建議還是設定為佳。crt及key的部分,則是剛剛解壓縮的憑證壓縮檔,裡面包含了這兩個檔案。
接著開啟「https://stock.ddnsking.com」,就可以在瀏覽器看到鎖頭的圖示,如圖15所示,代表這是一個合法的憑證。
點選這個鎖頭的圖示,就能夠檢視憑證的詳細資訊,如圖16所示,可以看到簽發者是ZeroSSL,有效期確實是90天無誤。
結語
frp使用非常簡單的方式,讓內網主機可以輕鬆地提供對外服務。只要能夠在公網(雲端)主機上架設frps,就可以讓內部主機提供外網功能。但內部主機若要直接放在公網上供人存取時,記得要做好資安的相關部署。frps和frpc在連線時並沒有加密,可以在frps增加「use_encryption = true」設定,這個功能提供加密,會讓連線更安全。
此外,frp也提供stcp的連線方式,能夠讓對外服務更安全。如果真的需要使用frp讓內部主機提供對外服務時,千萬記得要做好資安防護的工作。
<本文作者:丁光立,在ISP工作多年。對於Cisco設備較熟悉,除此之外也研究Linux,這幾年慢慢把觸角伸到資安的領域,並會在自己的blog(http://tiserle.blogspot.com/)分享一些實務上的經驗和測試心得。>