背景
用公司内网的服务器,或者公司的电脑搭建了一个web站点,却无法在外网访问web站点,或者在家想用ssh连接公司的内网服务器。frp就是如何利用内网穿透的方式实现以上功能。
准备
- • 有公网ip的公网服务器一台,需要在后台打开服务器安全组端口 6000、7000、8000,IP假定为8.134.122.126
- • 准备一台内网电脑/服务器。
- • 备案好的域名一个,假定为:xiaojin.visionmedicals.cn
配置公网服务器
步骤1:源码准备
代码语言:javascript复制wget https://github.com/fatedier/frp/releases/download/v0.45.0/frp_0.45.0_linux_amd64.tar.gz
tar -zxvf frp_0.45.0_linux_amd64.tar.gz -C /etc/
cd /etc/frp_0.45.0_linux_amd64/
步骤2:修改frps.ini
vim frps.ini
代码语言:javascript复制[common]
# listen 端口
bind_port = 7000
# 这两个端口可以和bind_port相同
vhost_http_port = 7000
vhost_https_port = 7000
# 配置服务器dashboard,监控服务器连接流量等,通过8.134.122.126:8000访问
dashboard_addr = 0.0.0.0
dashboard_port = 8000
dashboard_user = admin
dashboard_pwd = adminpasswd
# 设置token校验,客户端的token和它一致
authentication_method = token
token = admintoken
步骤3:解析域名和申请ssl证书
- 1. 解析域名 xiaojin.visionmedicals.cn到 8.134.122.126
- 2. 给域名申请ssl证书 xiaojin.visionmedicals.cn.pem 和 xiaojin.visionmedicals.cn.key
步骤4:开放端口
代码语言:javascript复制apt install firewalld # 安装防火墙
firewall-cmd --permanent --zone=public --add-port=7000/tcp
firewall-cmd --permanent --zone=public --add-port=10000/tcp
systemctl reload firewalld
阿里云控制台开放端口:实例详情》配置安全组规则》配置规则 (协议TCP)
步骤5:运行frp服务
代码语言:javascript复制/etc/frp_0.45.0_linux_amd64/frps -c /etc/frp_0.45.0_linux_amd64/frps.ini
# 成功运行如下
2022/12/10 11:59:30 [I] [root.go:206] frps uses config file: frps.ini
2022/12/10 11:59:31 [I] [service.go:196] frps tcp listen on 0.0.0.0:7000
2022/12/10 11:59:31 [I] [root.go:215] frps started successfully
本地服务器配置
步骤1:安装frp服务
代码语言:javascript复制wget https://github.com/fatedier/frp/releases/download/v0.45.0/frp_0.45.0_linux_amd64.tar.gz
tar -zxvf frp_0.45.0_linux_amd64.tar.gz -C /etc/
cd /etc/frp_0.45.0_linux_amd64/
步骤2:配置服务
vim frpc.ini
[common]
server_addr = 8.134.122.126
server_port = 7000
token = admintoken
# 客户端监控
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = admin
配置ssh、websocket服务
代码语言:javascript复制[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
MacOS默认不能远程访问,需要System Preferences->Sharing->Remote Login勾选才能访问 websocket配置和上面一样(底层为tcp协议),只需要换为对应的端口即可
步骤:3内网服务器运行服务
代码语言:javascript复制/etc/frp_0.45.0_linux_amd64/frpc -c /etc/frp_0.45.0_linux_amd64/frpc.ini
# 成功运行如下
2022/12/10 12:09:51 [I] [service.go:357] [bdd6a6b31aa4727a] login to server success, get run id [bdd6a6b31aa4727a], server udp port [0]
2022/12/10 12:09:51 [I] [proxy_manager.go:142] [bdd6a6b31aa4727a] proxy added: [ssh]
2022/12/10 12:09:51 [I] [control.go:177] [bdd6a6b31aa4727a] [ssh] start proxy success
测试ssh
测试ssh是否成功
代码语言:javascript复制ssh -p 6000 xj@8.134.122.126 #账号和密码是内网服务器的
http服务
代码语言:javascript复制[web01]
type = http
local_ip = 127.0.0.1
local_port = 80
custom_domains = web01.xiaojin.visionmedicals.cn
[web02]
type = http
local_ip = 127.0.0.1
local_port = 8081
custom_domains = web02.xiaojin.visionmedicals.cn
服务端frps.ini需要配置vhost_http_port参数,此处配置为7000 则http://web01.xiaojin.visionmedicals.cn:7000指向访问本地127.0.0.1:80的服务;http://web02.xiaojin.visionmedicals.cn:7000指向访问本地127.0.0.1:8081的服务;(8081可以指定本地服务器有多个站点的情况)
https服务
vim frpc.ini
[web01_https]
type = https
custom_domains = web01.xiaojin.visionmedicals.cn
plugin = https2http
plugin_local_addr = 127.0.0.1:80
# HTTPS 证书相关的配置
plugin_crt_path = /home/xj/temp/cert/9505151_web01.xiaojin.visionmedicals.cn.pem
plugin_key_path = /home/xj/temp/cert/9505151_web01.xiaojin.visionmedicals.cn.key
plugin_host_header_rewrite = 127.0.0.1
plugin_header_X-From-Where = frp
- • 这两个证书文件是外边的路径,不是容器里的。
- • 服务端frps.ini需要配置vhost_https_port参数,此处配置为7000
- • 直接访问https://web01.xiaojin.visionmedicals.cn:7000/ 可以访问 本地http://127.0.0.1:80服务
优化
1、去除域名的端口
本地端口用什么都可以,因为是转发到内网端口,别人看不到,但域名加端口就会别人看到了。想要达到以下的效果:
web01.xiaojin.visionmedicals.cn -> 8.134.122.126:80 -> frp服务端Http转发7000端口 -> 内网机器的Frp客户端 -> 内网8081端口web01站点
。
如果公网IP的服务器本来已经有web端点的话(80端口已占用的情况),可以做个端口转发的功能。
以下是公网服务器上的nginx配置,nginx转发到frp服务
代码语言:javascript复制server {
listen 80;
server_name web01.xiaojin.visionmedicals.cn;
location / {
proxy_pass http://8.134.122.126:7000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
}
}
2、将服务器端、客户端程序放到后台运行
代码语言:javascript复制服务器端
nohup ./frps -c frps.ini >/dev/null 2>/dev/null &
客户端
nohup ./frpc -c frpc.ini >/dev/null 2>/dev/null &
复制代码
3、将frp放至开机自启动(Ubuntu20.04方案)
step1.创建rc-local.service文件
代码语言:javascript复制sudo cp /lib/systemd/system/rc-local.service /etc/systemd/system
复制代码
然后修改/etc/systemd/system/rc-local.service,在文件最下方添加如下两行
代码语言:javascript复制[Install]
WantedBy=multi-user.target
Alias=rc-local.service
复制代码
step2:创建rc.local文件
创建**sudo vi /etc/rc.local **,里边写自己想要运行的命令。例:
代码语言:javascript复制#!/bin/sh
echo "This is test(xj)" > /tmp/my.log
#自行修改为绝对路径
nohup /root/frp/frpc -c /root/frp/frpc.ini &
复制代码
给**/etc/rc.local**加上可执行权限
代码语言:javascript复制sudo chmod x /etc/rc.local
复制代码
step3.测试
启动后可以发现:/tmp下已经有了my.log文件,里边内容为:"This is test"。
systemctl命令
启动服务
代码语言:javascript复制sudo systemctl start rc-local.service
复制代码
查看服务状态
代码语言:javascript复制sudo systemctl status rc-local.service