目錄
一、為什么需要NAT?
二、NAT的核心:從“一對一”到“多對一”
(1)靜態NAT
(2)動態NAT
(3)NAPT
三、NAPT的雙刃劍:安全與局
四、內網穿透
(1)為什么需要內網穿透而不是簡單的配置端口映射?
(2)第三方公網服務器作為中轉站
五、常見的內網穿透成熟方案
(1)開放云服務器的安全組端口
(2)部署FRP服務端到云服務器上
1.下載并解壓FRP包
2.編輯服務端配置文件
3.啟動FRP服務端
(3)部署FRP客戶端到物理機上
1.下載 FRP 客戶端
2.解壓 FRP 安裝包
3.編輯 FRP 客戶端配置文件 frpc.ini
4.啟動FRP客戶端
????????在之前我們已經簡單了解過了NAT的原理,但是還有幾個問題沒有仔細考慮,本篇文章補充說明了這些,讓我們對NAT和內網穿透的理解更加深刻。
一、為什么需要NAT?
? ? ? ??在了解NAT之前,我們得先解決一個關鍵問題:IP地址不夠用了。
????????互聯網中的每一臺設備(電腦、手機、服務器)要互相通信,都需要一個唯一的“身份證”——公網IP地址(比如你在網上看到的“202.97.xx.xx”)。但公網IP的總量是有限的(IPv4協議下約43億個),隨著手機、智能家電等設備爆發式增長,43億個IP早就不夠分配了。
????????這時候,NAT(Network Address Translation,網絡地址轉換) 技術應運而生。它的核心思路是:讓一個“公網IP”代表多個“內網設備”。簡單說,你家路由器會有一個從運營商那里分到的公網IP(現代家庭路由器可能也是運營商下面的內網IP),而家里的電腦、手機、平板用的是“內網私有IP”(比如“192.168.1.100”“10.0.0.5”)——這些私有IP只在你家內網有效,無法直接被互聯網識別。當內網設備要訪問外網時,路由器會把“私有IP”轉換成“公網IP”,相當于用一個“公共身份證”幫所有內網設備“代辦”上網業務,從而節省了大量公網IP資源。
二、NAT的核心:從“一對一”到“多對一”
? ? ? ? 最古老最基礎的NAT是靜態NAT,但是現在我們日常使用得更多的是動態NAT,但真正解決多設備共享一個公網IP的關鍵是NAPT。
(1)靜態NAT
????????靜態NAT是最簡單的NAT形式,原理是“一個內網私有IP對應一個公網IP”,且這種對應關系是固定不變的。比如企業里有一臺需要外網訪問的服務器(內網IP:192.168.2.10),管理員會在路由器上配置“192.168.2.10 ? 203.0.113.5”的固定映射——外網設備訪問203.0.113.5時,路由器會自動轉發到192.168.2.10。
?
? ? ? ? 靜態NAT的問題也很明顯:它依然是“一對一”,一個內網只能有一個設備使用該公網IP對外通信,否則會公網沖突。
? ? ? ? 即全球在同一時刻仍然只能有43億個設備接入公網,無法解決公網IP不夠用的問題,更多用于需要“外網固定訪問內網設備”的場景(如服務器),不是家庭或普通企業的首選。
(2)動態NAT
????????動態NAT會建立一個“公網IP池”(比如運營商分配給企業的10個公網IP),當內網設備訪問外網時,路由器會從IP池里“臨時借”一個公網IP給它,用完后歸還,供其他設備使用。這種方式實現了“多內網設備共享多個公網IP”,比靜態NAT更節省資源,但依然需要多個公網IP,對于“家里只有一個公網IP”的場景來說,還是不夠用。
? ? ? ? 動態NAT本質和靜態NAT一樣,都是僅僅使用IP來區分主機。
家用路由器相當于公網IP池容量為1的場景:
還有可能出現下面這種情況,讓本就不充裕的公網IP占有時間進一步減少:
(3)NAPT
????????NAPT(Network Address and Port Translation,網絡地址與端口轉換)是NAT的“進階版”,也是家庭、辦公網絡的“標配”。它的核心突破是:不僅轉換“IP地址”,還會轉換“端口號”,從而實現“多個內網設備共享一個公網IP”。
?
????????你可能會問:“多個設備用同一個公網IP,外網回復的數據怎么知道該發給誰?”答案就在“端口號”里。
????????每個網絡連接都有一個“端口號”(范圍0-65535),比如你用瀏覽器訪問網頁用的是80端口(HTTP)或443端口(HTTPS),手機微信發消息也會用一個隨機端口。NAPT的工作流程可以拆解為3步,用“小明用電腦上百度”舉例:
?
(1)內網發起請求:小明的電腦(內網IP:192.168.1.100,端口:54321)要訪問百度服 ????????務器(公網IP:180.101.49.12,端口:80),請求數據包先發送到家里的路由器。
(2)路由器做“翻譯”并記錄:路由器收到數據包后,會做兩件事:
????????- 把“內網IP(192.168.1.100)”換成“自己的公網IP(比如220.181.xx.xx)”;
????????- 把“內網端口(54321)”換成一個隨機的“公網端口(比如67890)”;????????注意:在之前的NAT中,一般是不會記錄端口號的,因為他們是用IP進行區分
????????- 同時在路由器里記錄一條“NAT表項”:?內網(192.168.1.100:54321) ? 公網(220.181.xx.xx:67890)?,這條記錄會暫時保存(比如1-5分鐘,沒有數據傳輸就刪除)。
(3)外網回復并轉發:百度服務器收到請求后,會向“220.181.xx.xx:67890”回復數據。路由器收到回復后,會查剛才記錄的“NAT表項”,發現“67890端口”對應小明的電腦(192.168.1.100:54321),就把數據轉發給小明的電腦。
????????通過“IP+端口”的組合,NAPT實現了“多對一”的共享:即使家里10臺設備同時上網,路由器只要給每臺設備分配不同的“公網端口”,就能通過同一個公網IP區分所有設備的連接,互不干擾。
三、NAPT的雙刃劍:安全與局限
NAPT不僅解決了IP短缺問題,還自帶“安全buff”,但也有一些無法回避的局限。
(1)自帶“防火墻”效果:保護內網安全
????????由于NAPT只允許“內網主動發起連接”,不允許“外網主動發起連接”,相當于給內網加了一道天然的“門衛”。比如外網有一臺陌生設備想訪問你家的電腦(192.168.1.100),它只能訪問你家路由器的公網IP,但路由器的NAT表項里沒有“外網主動連接”的記錄,會直接丟棄請求——這就是為什么NAT模式下,外網默認找不到你家的設備,大大降低了被攻擊的風險。
? ? ? ? 當內網主動發起連接后,路由器才會記錄該NAPT表項,然后路由器會根據通信的類型(UDP/TCP)以及通信的間隔考慮,要不要移除這個NAPT表項。在沒有移除之前,外網可以通過查表訪問到該內網進程。一旦長期沒有通信,或者內網主動斷開,NAPT表項被移除,外網還想通過原來的表項查找就找不到了。
(2)局限:外網無法直接訪問內網設備
????????凡事有利有弊,NAPT的安全特性也帶來了局限:如果你想在內網搭建一個服務器(比如個人網站、游戲服務器),讓外網的朋友訪問,默認是做不到的——因為外網發起的連接會被路由器丟棄。
????????要解決這個問題,需要手動配置“端口映射”(也叫“端口轉發”):在路由器上手動添加一條規則,比如“把公網端口80映射到內網192.168.1.100的80端口”。這樣一來,外網設備訪問“你的公網IP:80”時,路由器就會按照規則轉發到你的服務器,相當于給特定設備“開了一個專屬通道”。
? ? ? ? 手動配置端口映射相當于,在路由器中記錄了一個持久的NAPT表項。從而突破了NAPT失活的限制。當外網訪問當前路由器的指定Port時,由于有持久的路由器IP+路由器Port<--->內網主機IP+主機Port的映射,所以外網能訪問到內網設備。
四、內網穿透
(1)為什么需要內網穿透而不是簡單的配置端口映射?
? ? ? ? 雖然上面我們說使用“手動配置端口映射”能解決外網無法主動訪問內網設備的問題。但在實際中往往具有局限性:它需要手動登錄路由器管理后臺并配置端口轉發;然后關閉路由器防火墻;而且路由器永遠不能重啟(因為路由器的公網IP是運營商通過DHCP動態分配的)。
? ? ? ? 且不說上述操作的復雜性,安全性就大大降低了,這樣一來所有的外網設備都可以通過比如8080這個特定端口訪問到內網設備,如果內網設備存在BUG,則及其容易被惡意攻擊。
????????然后對于一些運營商,還會采取特定手段隱藏家庭路由器的公網IP,或者讓給一個片區的家庭路由器級聯到運營商路由器,所以真正有公網IP的是運營商路由器。它的防護級別更高,你總不能說跑到運營商那里去要求他給你固定綁定一個端口吧!
? ? ? ? 于是內網穿透技術應運而生。
(2)第三方公網服務器作為中轉站
? ? ? ? 既然NAPT表項在TCP等長連接下固定不變,那么理論上只需要讓內網服務器對每一個外網客戶端都建立長連接不就好了嗎?但是我內網設備作為服務器,一般不可能主動發起連接請求,所以這個是不可行的。
? ? ? ? 由于NAPT是單向通信的,那么只需要讓服務端和一個擁有公網IP的機器建立長久的TCP長連接(服務器到中間服務器的映射路徑不會改變)。此時我們就能把這個中間服務器當做原本的內網服務器來看,讓其看起來擁有了“公網IP”。
????????你可以認為路由器做了類似手動配置端口映射的操作,因為在TCP長連接下,表項本身就是持久的。
此后在外網的視角下,它訪問的就是一個具有公網IP的服務器。
五、常見的內網穿透成熟方案
????????常見的內網穿透軟件有FRP、Ngrok、花生殼等。在這里我們選擇FRP,因為它是一款開源免費軟件,用戶可以自由使用,不過想要使用它必須得有一臺云服務器,剛好我們這里就有一臺。
(1)開放云服務器的安全組端口
? ? ? ? 因為云服務器對于外網訪問默認都會有限制,開放對應的端口就是讓這個云服務器的端口可以被外網訪問到。
登錄阿里云控制臺,進入 "云服務器 ECS"→"實例"→目標服務器→"安全組"→"配置規則"→"入方向",添加以下端口:
- 服務端監聽端口:
7000
(FRP 通信端口) - 穿透服務端口(示例):
3389
(遠程桌面)、22
(SSH)、80
(HTTP)、7500
(FRP 儀表盤,可選)
配置時 "授權對象" 填0.0.0.0/0
(允許所有 IP 訪問,或限制為指定 IP) - FRP服務器暴露給外網的端口號:8080
添加完成后應該是包含這幾個的:
(2)部署FRP服務端到云服務器上
1.下載并解壓FRP包
- 打開 FRP 官方 GitHub 發布頁面(https://github.com/fatedier/frp/releases),根據云服務器的操作系統(如 Linux 系統選擇?
frp_版本號_linux_amd64.tar.gz
),下載最新穩定版的 FRP 安裝包。- 通過工具(如 Xshell 的文件傳輸功能、WinSCP 等)將安裝包上傳到云服務器的合適目錄(如?
/usr/local/
)。- 進入該目錄,執行解壓命令(以?
frp_0.56.0_linux_amd64.tar.gz
?為例):- 解壓完成后,將文件夾重命名為?
frp
?以便后續操作:
2.編輯服務端配置文件
3.啟動FRP服務端
./frps -c ./frps.ini
(3)部署FRP客戶端到物理機上
? ? ? ? 因為我們這里物理機是Windows,而虛擬機是在物理機上運行的,通過端口映射讓物理機把數據轉發給虛擬機的,所以這個FRP服務要部署在Windows上,千萬不要錯誤的放到虛擬機上了,否則一輩子都使用不到FRP客戶端。
1.下載 FRP 客戶端
- 訪問官方下載地址:前往 FRP 的官方 GitHub 發布頁面,地址是https://github.com/fatedier/frp/releases?。在這個頁面,你可以看到針對不同操作系統和架構的 FRP 安裝包。
- 選擇合適的安裝包:由于我們的物理機是 Windows 系統,找到以
frp_版本號_windows_amd64.zip
?格式命名的文件(一般適用于 64 位 Windows 系統,如果是 32 位系統,選擇對應的 32 位版本 ,不過現在大部分 Windows 設備都是 64 位),版本號選擇最新穩定版本。比如當前最新穩定版本是frp_0.56.0_windows_amd64.zip
?,點擊文件名進行下載。
????????在這里我的物理機老是連接不上github,但是我發現可以先用云服務器下載,然后用sz命令傳到物理機上。
2.解壓 FRP 安裝包
????????下載完成后,得到一個壓縮文件(例如frp_0.56.0_windows_amd64.zip
?),將它解壓到 Windows 物理機上你方便操作的目錄,比如D:\frp
?。解壓方式很簡單,右鍵點擊壓縮包,選擇 “解壓到當前文件夾” 或者 “解壓到指定文件夾(如 D:\frp)”(如果安裝了 WinRAR、360 壓縮等解壓軟件,操作類似)。
3.編輯 FRP 客戶端配置文件 frpc.ini
????????解壓完成后,進入解壓后的目錄(如D:\frp
?),找到frpc.toml
文件,這是 FRP 客戶端的配置文件,我們需要對它進行編輯以滿足內網穿透需求。你可以使用 Windows 系統自帶的記事本程序打開它,也可以使用像 Notepad++ (下載地址:https://notepad-plus-plus.org/downloads/?,功能更強大,對代碼格式顯示更友好)這樣的文本編輯器。
????????以下是一份配置示例,假設云服務器公網 IP 為120.xxx.xxx.xxx
?,云服務器上 FRP 服務端的監聽端口為7000
?,我們要把物理機本地 8888 端口(已和虛擬機映射)映射到云服務器的 8080 端口供外網訪問:????????
[common]
server_addr = 120.xxx.xxx.xxx # 替換為你實際的云服務器公網IP
server_port = 7000 # 要和云服務器上FRP服務端配置的bind_port一致[physical_machine_8888]
type = tcp
local_ip = 127.0.0.1 # 物理機本地回環地址,用于訪問本地映射的8888端口
local_port = 8888 # 物理機上與虛擬機映射的端口
remote_port = 8080 # 云服務器上用于供外網訪問物理機8888端口的公網端口
配置項解釋
?
- [common]?:這是公共配置段,用于設置客戶端連接服務端的通用信息。
- server_addr?:指定云服務器的公網 IP 地址,確保填寫準確,否則客戶端無法連接到服務端。
- server_port?:要與云服務器上 FRP 服務端配置文件
frps.ini
?中的bind_port
?一致,這樣客戶端才能正確連接到服務端。- [physical_machine_8888]?:這是一個自定義的穿透規則段,名字可以自行定義,只要在配置文件中不重復即可。
- type?:指定穿透的協議類型,這里是
tcp
?,如果是其他協議(如 UDP ),需要相應修改。- local_ip?:因為要訪問物理機本地映射的端口,所以填寫
127.0.0.1
?,表示本地回環地址。- local_port?:填寫物理機上與虛擬機映射的端口,即 8888 端口。
- remote_port?:填寫云服務器上開放的供外網訪問的端口,這里是 8080 端口,要確保云服務器的安全組已經開放該端口。
編輯完成后,保存
frpc.toml
文件。
4.啟動FRP客戶端
- 以管理員身份打開命令提示符?:在 Windows 搜索欄中輸入 “cmd”,右鍵點擊 “命令提示符”,選擇 “以管理員身份運行”。
- 進入 FRP 目錄:在命令提示符中,使用
cd
?命令進入 FRP 解壓后的目錄,比如cd D:\frp
?。- 啟動 FRP 客戶端:在命令提示符中輸入
frpc.exe -c frpc.ini
?,然后按下回車鍵。如果配置正確,命令提示符會顯示一些連接相關的信息,同時不會出現報錯,這就表示 FRP 客戶端已經成功啟動并嘗試連接云服務器上的 FRP 服務端。
????????完成以上步驟后,就成功在 Windows 物理機上部署了 FRP 客戶端,外網設備就可以通過云服務器公網IP:8080
?訪問到物理機 8888 端口關聯的虛擬機服務了。