侧边栏壁纸
  • 累计撰写 269 篇文章
  • 累计创建 141 个标签
  • 累计收到 16 条评论

目 录CONTENT

文章目录

使用frp实现内网穿透

Sherlock
2017-11-23 / 0 评论 / 0 点赞 / 2636 阅读 / 0 字
温馨提示:
本文最后更新于2024-11-05,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

为了解决小区内宽带没有公网ip这个问题,需要使用内网穿透。内网穿透的方法有很多种,例如花生壳(需要硬件)、ngrok(尝试过,个人感觉不好用)等,本文主要介绍的使用frp实现内网穿透。

WHAT IS frp

-# 利用处于内网或防火墙后的机器,对外网环境提供 http 或 https 服务。

  • 对于 http, https 服务支持基于域名的虚拟主机,支持自定义域名绑定,使多个域名可以共用一个80端口。
  • 利用处于内网或防火墙后的机器,对外网环境提供 tcp 和 udp 服务,例如在家里通过 ssh 访问处于公司内网环境内的主机。

frp 的作者将其开源在了 https://github.com/fatedier/frp,并且提供了中文文档,可以直接查看文档获取需要的信息。
==frp 仍然处于前期开发阶段,目前的交互协议可能随时改变,不保证向后兼容,升级新版本时需要注意公告说明同时升级服务端和客户端。==

Before

使用frp,需要一台有公网IP的服务器(可以是VPS、阿里云ECS等),一台需要实现内网穿透的机器,SSH 工具,以及一个域名(如果只是建立SSH反向代理则不需要域名)。

Start

根据对应的操作系统及架构,从 Release 页面下载最新版本的程序。

官方文档地址:https://gofrp.org/zh-cn/docs/overview/

通过自定义域名访问部署于内网的 web 服务

编写 frp service 文件,以 CENTOS7 为例

vim /etc/systemd/system/frps.service

内容如下

[Unit]
Description = frp server
After = network.target syslog.target
Wants = network.target

[Service]
Type = simple
ExecStart = /opt/frp/frps -c /opt/frp/frps.toml

[Install]
WantedBy = multi-user.target

启动 frp 并设置开机启动

systemctl daemon-reload
systemctl enable frps
systemctl start frps
systemctl status frps

Server 端

首先在 云服务器 上操作:

cd /opt/
wget https://mirror.ghproxy.com/https://github.com/fatedier/frp/releases/download/v0.58.1/frp_0.58.1_linux_amd64.tar.gz
tar -xf frp_0.58.1_linux_amd64.tar.gz
ln -s frp_0.58.1_linux_amd64 frp
cd /opt/frp

外网主机作为服务端,可以去掉不必要的客户端文件

mv frpc frpc.bak
mv frpc.toml frpc.toml.bak

修改服务端配置文件frps.toml

vi frps.toml

配置如下:

完整示例可参考:https://github.com/fatedier/frp/blob/dev/conf/frps_full_example.toml

bindPort = 1103
vhostHTTPPort = 11039
#vhostHTTPSPort = 11034

# console or real logFile path like ./frps.log
log.to = "./frps.log"
# trace, debug, info, warn, error
log.level = "info"
log.maxDays = 3
# disable log colors when log.to is console, default is false
log.disablePrintColor = false

# Server Dashboard,可以查看frp服务状态以及统计信息
webServer.addr = "0.0.0.0"
webServer.port = 11030
webServer.user = "admin"
webServer.password = "admin"

启动

systemctl start frps

另外,我们刚才配置了dashboard ,所以可以通过http://[server_addr]:11030器查看 frp 的状态以及代理统计信息展示。

XTCP 点对点穿透

https://gofrp.org/zh-cn/docs/features/xtcp/
https://gofrp.org/zh-cn/docs/examples/xtcp/

需要被访问的客户端机器和访问者的客户端机器都配置frpc,暂时不想折腾了。

Client 端

修改 frpc.ini 文件,假设 frps 所在的服务器的 IP 为 x.x.x.xlocal_port 为本地机器上 web 服务对应的端口, 绑定自定义域名 www.yourdomain.com:

# frpc.ini
[common]
server_addr=x.x.x.x
server_port=11031

[web]
type=http
local_port=80
custom_domains=www.yourdomain.com

启动 frpc:

./frpc -c ./frpc.ini

www.yourdomain.com 的域名 A 记录解析到 IP x.x.x.x,如果服务器已经有对应的域名,也可以将 CNAME 记录解析到服务器原先的域名。通过浏览器访问 http://www.yourdomain.com:1103 即可访问到处于内网机器上的 web 服务。
如果是在 windows 机器上可以将启动命令写成批处理(需要根据实际位置修改路径):

# start_frpc.bat
@echo off
d:
cd D:\Program Files\frp_0.13.0\
start "frpc" "frpc.exe" -c frpc.ini

linux 机器上启动命令可以参考上文 start_frps.sh

通过密码保护你的 web 服务

由于所有客户端共用一个 frps 的 http 服务端口,任何知道你的域名和 url 的人都能访问到你部署在内网的 web 服务,但是在某些场景下需要确保只有限定的用户才能访问。
frp 支持通过 HTTP Basic Auth 来保护你的 web 服务,使用户需要通过用户名和密码才能访问到你的服务。
该功能目前仅限于 http 类型的代理,需要在 frpc 的代理配置中添加用户名和密码的设置。

# frpc.ini
[web]
type = http
local_port = 80
custom_domains = www.yourdomain.com
http_user = abc
http_pwd = abc

通过浏览器访问 http://www.yourdomain.com:1103,需要输入配置的用户名和密码才能访问。

URL 路由

frp 支持根据请求的 URL 路径路由转发到不同的后端服务。
通过配置文件中的 locations 字段指定一个或多个 proxy 能够匹配的 URL 前缀(目前==仅支持最大前缀匹配==,之后会考虑正则匹配)。例如指定 locations = /news,则所有 URL 以 /news 开头的请求都会被转发到这个服务。

# frpc.ini
[web01]
type = http
local_port = 80
custom_domains = web.yourdomain.com
locations = /

[web02]
type = http
local_port = 81
custom_domains = web.yourdomain.com
locations = /news,/about

按照上述的示例配置后,web.yourdomain.com 这个域名下所有以 /news 以及 /about 作为前缀的 URL 请求都会被转发到 web02,其余的请求会被转发到 web01
底层通信可选 kcp 协议

从 v0.12.0 版本开始,底层通信协议支持选择 kcp 协议,在弱网环境下传输效率提升明显,但是会有一些额外的流量消耗。

开启 kcp 协议支持:

frps.ini 中启用 kcp 协议支持,指定一个 udp 端口用于接收客户端请求:

# frps.ini
[common]
## server port(客户端连接时会使用)
bind_port=11031
# kcp 绑定的是 udp 端口,可以和 bind_port 一样
kcp_bind_port=11031
## 具体访问时使用的端口
vhost_http_port=1103

dashboard_port=11030
# dashboard 用户名密码,默认都为 admin
dashboard_user=admin
dashboard_pwd=admin

frpc.ini 指定需要使用的协议类型,目前只支持 tcp 和 kcp。其他代理配置不需要变更:

# frpc.ini
[common]
# vhost port 1103, dashboard port 11030
server_addr = x.x.x.x
# server_port 指定为 frps 的 kcp_bind_port
server_port = 11031
protocol = kcp

像之前一样使用 frp,需要注意开放相关机器上的 udp 的端口的访问权限。

身份验证

服务端和客户端的 common 配置中的 privilege_token 参数一致则身份验证通过。

需要注意的是 frpc 所在机器和 frps 所在机器的时间相差不能超过 15 分钟,因为时间戳会被用于加密验证中,防止报文被劫持后被其他人利用。
这个超时时间可以在配置文件中通过 authentication_timeout 这个参数来修改,单位为秒,默认值为 900,即 15 分钟。如果修改为 0,则 frps 将不对身份验证报文的时间戳进行超时校验。

Nginx 配置

    ## frp vhosts
    server {
        listen       80;
        server_name  "*.frp.xxx.cc";
        rewrite ^(.*)$ https://$host$1 permanent;
    }        
    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name  "*.frp.xxx.cc";
        
        ssl_certificate  /etc/letsencrypt/live/xxx/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/xxx/privkey.pem;
        
        location / {
            #对应frps.ini vhost_http_port=11039        
            proxy_pass http://127.0.0.1:11039;
            proxy_redirect off;
            #proxy_set_header Host $host:443;
            proxy_set_header Host $host;
            #router need     
            proxy_set_header Referer $http_referer;
            proxy_set_header Cookie $http_cookie;  
    
            proxy_ssl_server_name on;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;    
        }        
    } 
0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区