內容轉載自我的博客
1. 目的和機器信息
雲主機A(服務端),購買於雲服務器提供商,以下IP、端口、用戶名、密碼均為示例:
IP: 67.89.12.34
默認開啟ssh的22端口,用戶名為ubuntu,密碼為Test&123456+pwd
手動配置安全組,放通7000、8000-8100、8888端口的TCP連接(端口可任意設置,不與其他服務沖突即可)
7000端口用於服務端(frps.ini中的bind_port)與客戶端(frpc.ini中的server_port)建立基本通信、鑒權等
一個服務端可以用同一個端口連接不同的客戶端
8000-8100端口用來進行轉發,只在客戶端的配置文件frpc.ini中設置remote_port,每個端口轉發不同的服務
可以是一台內網服務器有多個服務;也可以是多台內網服務器,每台有不同數量的服務
8888端口用來配置frps的管理面板(80、443端口默認開啟)
內網服務器B(客戶端),自己購買的配置較高的服務器,但是沒有公網地址,所以只能局域網訪問,安裝ssh以便於其他用戶可以ssh連接到本機:
IP: 192.160.0.135
內網服務器B安裝ssh,選擇22端口,用戶名為myserver,密碼為Myser123456ver
將內網服務器B的22端口,轉發到雲主機A的8000端口
則用戶C可以使用如下代碼來遠程ssh連接內網服務器B
ssh -p 8000 myserver@67.89.12.34
使用如下代碼來將內網服務器B的/home/myserver/test.txt文件下載到用戶C的機器上
scp -P 8000 myserver@67.89.12.34:/home/myserver/test.txt ./Desktop/
用戶C(用戶端),只需要具備ssh連接的軟件
frp的系統架構和最終實現的效果如下圖
2. 雲主機A下載和配置frp-server
在github倉庫frp下載linux-amd64
版本,解壓為文件夾frp_linux_amd64
並放在/home/ubuntu/
目錄下,在frp_linux_amd64
文件夾創建log
目錄用於保存日志。修改frps.ini
文件為如下
[common]
# 綁定的IP地址,支持IPv6,不指定默認0.0.0.0
bind_addr = 0.0.0.0
# 服務端口
bind_port = 7000
# 設置服務器與客戶端的鑒權方式
authentication_method = token
# 客戶端與服務端通信的身份驗證令牌
token = ToKen&pwd+123for56
# 開啟frps儀表盤可以檢查frp的狀態和代理的統計信息
# frps儀表盤綁定的地址
dashboard_addr = 0.0.0.0
# frps儀表盤綁定的端口
dashboard_port = 8888
# 訪問frps儀表盤的用戶
dashboard_user = example_admin
# 用戶密碼
dashboard_pwd = AdMinVgfsHT67TFg
# 儀表盤頁面文件目錄,只適用於調試
# assets_dir = ./static
# 日志配置文件
# 日志文件,不指定日志信息默認輸出到控制台
log_file = /home/ubuntu/frp_linux_amd64/log/frps.log
# 日志等級,可用等級“trace, debug, info, warn, error”
log_level = info
# 日志保存最大保存時間
log_max_days = 7
# 每個客戶端連接服務端的最大連接數
max_pool_count = 5
# 每個客戶端最大可以使用的端口,0表示無限制
max_ports_per_client = 0
# 自定義子域名,需要在dns中將域名解析為泛域名
# subdomain_host = example.cn
# 是否使用tcp復用,默認為true
tcp_mux = true
3. 雲主機A安裝使用nginx(dashboard自定義域名,可選)
更新軟件源:sudo apt-get update
安裝nginx:sudo apt-get install nginx
訪問雲主機的ip確認nginx安裝成功
修改nginx配置文件:sudo vi /etc/nginx/nginx.conf
在http{}
合適位置添加以下代碼,這里的8888
端口與frps.ini
的dashboard_port
一致
一定要將http{}
里面的最后兩個include行注釋掉,修改才會生效
server{
listen 80;
# 如果需要ssl,參考https://blog.whuzfb.cn/blog/2020/07/07/web_https/
# listen 443 ssl;
# include ssl/example.cn.ssl.conf;
# 此時支持http與https
server_name frp.example.cn;
access_log /home/ubuntu/frp_linux_amd64/log/access.log;
error_log /home/ubuntu/frp_linux_amd64/log/error.log;
location /{
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://127.0.0.1:8888;
}
}
不重啟重新載入最新配置文件內容:sudo service nginx reload
停止nginx服務:sudo service nginx stop
重啟nginx服務:sudo service nginx restart
為域名example.cn添加一條名為frp的A記錄解析到67.89.12.34
4. 雲主機A設置frps開機自啟動(systemd)
打開frp_linux_amd64
文件夾下的systemd
目錄,編輯frps.service
文件(frps@.service
文件只是多了個自定義ini文件的功能),將其中的user=nobody
改為user=ubuntu
(即本機的用戶名),如果不改,啟動時候會報錯無法寫入日志文件,權限禁止
然后修改ExecStart、ExecReload
中的路徑為自己的文件路徑
將修改后的frps.service
文件復制到/etc/systemd/system/
:sudo cp ./frps.service /etc/systemd/system/
激活frps開機啟動:systemctl enable frps
手動運行frps服務:systemctl start frps
或service frps start
手動停止frps服務:systemctl stop frps
或service frps stop
手動重啟frps服務:systemctl restart frps
或service frps restart
查看frps運行狀態:systemctl status frps
或service frps status
關閉frps開機啟動:systemctl disable frps
5. 雲主機A設置frps開機自啟動(init.d)
創建start_frp.sh
文件:vi start_frp.sh
,內容如下(注釋不可刪除):
#!/bin/sh
### BEGIN INIT INFO
# Provides: svnd.sh
# Required-start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the svnd.sh daemon
# Description: starts svnd.sh using start-stop-daemon
### END INIT INFO
/home/ubuntu/frp_linux_amd64/frps -c /home/ubuntu/frp_linux_amd64/frps.ini
給予執行權限: chmod 775 start_frp.sh
復制到指定位置: sudo cp ./start_frp.sh /etc/init.d/
刷新即可: sudo update-rc.d start_frp.sh defaults 90
重啟即可發現自啟動進程: ps -ef | grep frp
取消frps自啟動(/etc/init.d/)
sudo rm /etc/init.d/start_frp.sh
sudo update-rc.d -f start_frp remove
6. 內網服務器B安裝配置frp-client
在github倉庫frp下載linux-amd64
版本,解壓為文件夾frp_linux_amd64
並放在/home/myserver/
目錄下,在frp_linux_amd64
文件夾創建log
目錄用於保存日志。修改frpc.ini
文件為如下
[common]
# 雲主機的公網ip
server_addr = 67.89.12.34
# 雲主機端frps.ini文件中的bind_port
server_port = 7000
# 客戶端與服務端通信的身份驗證令牌
token = ToKen&pwd+123for56
# 設置管理地址,用於通過http api控制frpc的動作,如重新加載
# admin_addr = 127.0.0.1
# admin_port = 7400
# admin_user = admin
# admin_passwd = admin
# 初始連接池的數量,默認為0
pool_count = 5
# 客戶端日志存儲位置
log_file = /home/myserver/frp_linux_amd64/log/frpc.log
# 保存日志的等級trace, debug, info, warn, error
log_level = info
# 最大保存天數
log_max_days = 7
# 是否啟用tcp復用,默認為true
tcp_mux = true
# 代理配置段名稱,如果上面配置user=your_name,則顯示為your_name.ssh
[ssh_B1_00]
# 協議默認tcp,可選tcp,udp,http,https,stcp,xtcp
type = tcp
# 本地地址
local_ip = 127.0.0.1
# 本地端口
local_port = 22
# 在服務器端開啟的遠程端口,即用戶使用自己電腦ssh連接時的端口
remote_port = 8000
# 雲服務器管理面板創建安全組
# 0.0.0.0/0 TCP:7000,8000-8100,8888 允許
# 從第三台機器上直接用ssh即可連接本機,即:
# 雲主機A安裝frps,內網自己配的服務器B安裝frpc
# 用戶不需要安裝frp,用戶直接使用ssh連接即可
# ssh -p 8000 myserver@67.89.12.34
# 此命令實現用戶C在他的電腦上遠程登錄到內網服務器B,
# myserver是內網服務器B的用戶名,67.89.12.34是雲主機A的ip
# scp -P 8000 ./1.deb myserver@67.89.12.34:/home/myserver/Desktop/
# 此命令實現用戶本機文件上傳到內網服務器B
# 若內網還有服務器B2,則雲主機A的frps不需要動
# 在內網服務器B2上面安裝frpc即可,注意其配置為:
# [common]
# server_addr = 67.89.12.34
# server_port = 7000
# 不要與內網服務器B重名
# [ssh_B2_00]
# type = tcp
# local_ip = 127.0.0.1
# local_port = 22
# 新的用於ssh訪問內網服務器B2的端口
# remote_port = 8001
7. 內網服務器B設置frpc開機自啟動(systemd)
打開frp_linux_amd64
文件夾下的systemd
目錄,編輯frpc.service
文件(frpc@.service
文件只是多了個自定義ini文件的功能),將其中的user=nobody
改為user=myserver
(即本機的用戶名),如果不改,啟動時候會報錯無法寫入日志文件,權限禁止
然后修改ExecStart、ExecReload
中的路徑為自己的文件路徑
將修改后的frpc.service
文件復制到/etc/systemd/system/
:sudo cp ./frpc.service /etc/systemd/system/
激活frpc開機啟動:systemctl enable frpc
手動運行frpc服務:systemctl start frpc
或service frpc start
手動停止frpc服務:systemctl stop frpc
或service frpc stop
手動重啟frpc服務:systemctl restart frpc
或service frpc restart
查看frpc運行狀態:systemctl status frpc
或service frpc status
關閉frpc開機啟動:systemctl disable frpc
8. 內網服務器B設置frpc開機自啟動(init.d)
創建start_frp.sh文件:vi start_frp.sh
,內容如下(注釋不可刪除):
#!/bin/sh
### BEGIN INIT INFO
# Provides: svnd.sh
# Required-start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the svnd.sh daemon
# Description: starts svnd.sh using start-stop-daemon
### END INIT INFO
/home/myserver/frp_linux_amd64/frpc -c /home/myserver/frp_linux_amd64/frpc.ini
給予執行權限: chmod 775 start_frp.sh
復制到指定位置: sudo cp ./start_frp.sh /etc/init.d/
刷新即可: sudo update-rc.d start_frp.sh defaults 90
重啟即可發現自啟動進程: ps -ef | grep frp
取消frpc自啟動(/etc/init.d/)
sudo rm /etc/init.d/start_frp.sh
sudo update-rc.d -f start_frp remove
9. SSH保活的幾種方法
10. 測試內網穿透
保證frps.service
與frpc.service
處於運行狀態,用戶C(可以是linux系統、Windows系統等)在本機使用ssh命令即可連接到內網服務器B:
- 使用如下代碼來遠程ssh連接內網服務器B
ssh -p 8000 myserver@67.89.12.34
- 使用如下代碼來將內網服務器B的
/home/myserver/test.txt
文件下載到用戶C的機器上
scp -P 8000 myserver@67.89.12.34:/home/myserver/test.txt ./Desktop/
11. frp暴露多個內網web服務
本部分是針對jupyterlab搭建瀏覽器開發環境的過程
雲主機配置
修改frps.ini
文件,添加以下內容:
# 不需要和frpc.ini一致,與frpc的端口無關
vhost_http_port = 6888
subdomain_host = example.cn
[myjupyter]
type = http
subdomain = myjupyter
[web02]
type = http
subdomain = web02
然后修改nginx的配置文件sudo vim /etc/nginx/nginx.conf
server{
listen 80;
server_name myjupyter.example.cn;
# 如果需要ssl,參考https://blog.whuzfb.cn/blog/2020/07/07/web_https/
# listen 443 ssl;
# include ssl/example.cn.ssl.conf;
# 此時支持http與https
access_log /home/ubuntu/frp_linux_amd64/log/access_jupyter.log;
error_log /home/ubuntu/frp_linux_amd64/log/error_jupyter.log;
location /{
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://127.0.0.1:8888;
}
location /api/kernels/ {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
# websocket support
proxy_http_version 1.1;
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "Upgrade";
proxy_read_timeout 86400;
}
location /terminals/ {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
# websocket support
proxy_http_version 1.1;
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "Upgrade";
proxy_read_timeout 86400;
}
}
server{
listen 80;
server_name web02.example.cn;
# include ssl/example.cn.ssl.conf;
access_log /home/ubuntu/frp_linux_amd64/log/access_web.log;
error_log /home/ubuntu/frp_linux_amd64/log/error_web.log;
location /{
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://127.0.0.1:8888;
}
location /api/kernels/ {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
# websocket support
proxy_http_version 1.1;
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "Upgrade";
proxy_read_timeout 86400;
}
location /terminals/ {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
# websocket support
proxy_http_version 1.1;
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "Upgrade";
proxy_read_timeout 86400;
}
}
內網服務器配置
修改frpc.ini文件,添加以下內容:
[myjupyter]
type = http
# 此端口運行web服務
local_port = 7777
subdomain = myjupyter
[web02]
type = http
# 此端口運行web服務
local_port = 7778
subdomain = web02
分別重啟nginx、frps與frpc即可配置成功