frp 搭建与 nginx 反向代理
前段时间武汉长时间的干旱,电力不足,公司所在园区限电,不开空调(电脑可开),所以只能远程办公。远程桌面客户端有很多, 如 RemoteDesktop、向日葵、anyDesk 等。由于公司用的是内网,所以还需要一个内网穿透工具,之前在论坛看到过很多次所以我 选择了 frp,还有 zerotier 等其他工具,还没研究过。
frp 服务器端
标题部分 frp 服务器端首先需要一个有公网 ip 的服务器,最开始我是在 digitalocean 上的 vps 上搭建的,但是由于是国外的服务器,搭建好后发现速度 捉急。后来我换了个阿里云的 ECS,由于是临时使用,我就选了个最低配的 30 天试用版。 首先在 github release 页面找到 linux 平台的安装版本,登录到云服务器,下载并解压:
curl -sLo/tmp/frp.tar.gz https://github.com/fatedier/frp/releases/download/v0.44.0/frp_0.44.0_linux_amd64.tar.gz
# 解压到 /tmp 目录tar -xvf /tmp/frp.tar.gz -C /tmprm /tmp/frp.tar.gz
sudo mv /tmp/frp_0.44.0_linux_amd64 ~/frp
修改 frps.ini
frp 服务端配置文件,所有配置及其相应解释可以在 frps_full.ini
中找到。
# [common] is integral section[common]# A literal address or host name for IPv6 must be enclosed# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"bind_addr = 0.0.0.0bind_port = 5443# udp port used for kcp protocol, it can be same with 'bind_port'# if not set, kcp is disabled in frpskcp_bind_port = 5443# if you want to configure or reload frps by dashboard, dashboard_port must be setdashboard_port = 6443# dashboard assets directory(only for debug mode)dashboard_user = admindashboard_pwd = strong_password# assets_dir = ./staticvhost_http_port = 5000vhost_https_port = 5001# console or real logFile path like ./frps.loglog_file = ./frps.log# debug, info, warn, errorlog_level = infolog_max_days = 3# auth tokentoken = secret_token# only allow frpc to bind ports you list, if you set nothing, there won't be any limit#allow_ports = 1-65535# pool_count in each proxy will change to max_pool_count if they exceed the maximum valuemax_pool_count = 50# if tcp stream multiplexing is used, default is truetcp_mux = true
其中 vhost_http_port
和 vhost_https_port
默认为 80 和 443,如果你的服务器有博客之类的则可能已经被占用
,所以这里做了修改。配置好之后开启服务:./frps -c frps.ini
即可。
使用 systemd 设置服务端开机自启
标题部分 使用 systemd 设置服务端开机自启创建 fprs.servcie
文件在 frp 目录,这里我把 frp 解压后的文件放在 /root/frp
。
[Unit]Description=frps daemonAfter=syslog.target network.targetWants=network.target
[Service]Type=simpleRestart=alwaysRestartSec=1minUser=rootExecStart=/root/frp/frps -c /root/frp/frps.iniExecStop=/usr/bin/killall frpc
[Install]WantedBy=multi-user.target
然后在 /etc/systemd/system/
创建一个 symlink,启动 & enable 服务即可,注意日志的路径记得在 frps.ini
中
配置好,最好用绝对路径。
ln -s /root/frp/frps.service /etc/systemd/system/frps.service
systemctl start frps.service
systemctl enable frps.service
frp 客户端
标题部分 frp 客户端一个服务端可以链接许多个客户端,上面的配置中 max_pool_count 配置了 50。客户端支持各种类型(功能)的连接,ssh、tcp、 http 等,下面说一下我用到的 3 种。
wsl2 开启 ssh 连接
标题部分 wsl2 开启 ssh 连接; frpc.ini[common]server_addr = x.x.x.x # 服务端的 ip,如果有配置域名也可以使用域名server_port = 5443 # 服务端端口token = secret_token # 服务端配置的 token
[ssh-wsl-work]type = tcplocal_ip = 127.0.0.1local_port = 22remote_port = 6001 # 注意这里要保证 vps 防火墙规则允许此端口
./frpc -c frpc.ini
开启 frp 客户端连接。
首先被 ssh 的 wsl 需要开启 sshd 服务,由于 wsl2 被砍掉了 system init 服务,无法设置开机自启,所以需要手动启动服务
sudo service sshd start
。不过在启动之前,需要先编辑一下 /etc/ssh/sshd_config
配置文件,
在末尾加入(或者 uncomment)下面两个配置,注意 AllowUsers
后面是个 tab。
PasswordAuthentication yesAllowUsers username
在另一台电脑 ssh -oPort username@x.x.x.x
,即可连接上 wsl,
windows 远程桌面
标题部分 windows 远程桌面; frpc.ini[common]server_addr = x.x.x.x # 服务端的 ip,如果有配置域名也可以使用域名server_port = 5443 # 服务端端口token = secret_token # 服务端配置的 token
[remote_desktop_work]type = tcplocal_ip = 127.0.0.1# 远程桌面端口,这个不能改local_port = 3389remote_port = 7005
打开 cmd 切换到 frp 程序目录,输入 ./frpc -c frpc.ini
开启 frp 客户端连接。如果有需要,可以通过设置
windows 开机脚本来让 frpc 开机自启,可以参看 这里
在另一台电脑打开 RDP 连接 server_addr:7005
,输入远程电脑允许的用户凭据即可。
http 服务映射(反向代理)
标题部分 http 服务映射(反向代理); frpc.ini; common 省略
[web01]type = httplocal_ip = 172.22.54.78 # 本地iplocal_port = 3000 # 本地服务端口costom_domains = web01.custom.domain # 这个服务自定义的域名,在域名托管者处 添加 A record 指向云服务器地址即可
客户端服务开启后,访问 http://web01.custom.domain:5000
即可,这个是前面服务端配置中的 vhost_http_port
字段定义的。
结合 nginx 反向代理使用
标题部分 结合 nginx 反向代理使用有了 frp 做内网穿透,就可以结合 nginx 的反向代理来实现在家里开启本地前端服务,连接上公司内网中的后端接口服务了。
在公司内网的电脑 frpc 客户端加上需要被穿透的端口:
; frpc.ini
[wsl-frontend-project]type = httplocal_ip = 172.22.1.93 # 本地 iplocal_port = 8000 # 反向代理监听的 端口custom_domains = project-api.cusotm.doamin # 再加一个 A record
然后再公司服务器开启一个 nginx 服务,主要配置如下:
server { listen 8000; # 穿透的端口 location / { root /usr/share/nginx/html; index index.html index.htm index.php; client_max_body_size 10M; proxy_pass http://10.12.137.13:2014; proxy_redirect default; client_max_body_size 1000m; proxy_set_header Host $http_host; 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; }
# 更具体的配置,示例 location /auth { root html; index index.html index.htm index.php; proxy_pass http://10.12.137.13:2014/cloud/api/auth; # 后端服务的地址 proxy_redirect default; client_max_body_size 1000m; proxy_set_header Host $http_host; 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; } }
在家中的电脑开启前端服务,修改 api 服务为 http://project-api.custom.domain:5000
,这里的 5000 还是为上文
服务端配置的端口。
可能遇到的问题
标题部分 可能遇到的问题- 如果云服务器开启了防火墙,比如 ufw (Ubuntu),需要
sudo ufw enable port
来开启相应的端口 - 以上的 wsl 都是 Ubuntu
- Windows 上无法访问 nginx 反向代理暴露的端口的服务,可能是被 windows 防火墙规则阻止,打开 高级安全 Windows Defender 防火墙 允许 nginx.exe 的入站与出站流量
参考
标题部分 参考- 视频教程 https://www.youtube.com/watch?v=UeuPNkDK84o
- frp github 项目地址 https://github.com/fatedier/frp
- websocket 的 nginx 反向代理 https://www.xncoding.com/2018/03/12/fullstack/nginx-websocket.html