使用frp+nginx内网穿透访问内网http服务

TrumanWong
3/24/2023
TrumanWong

内网穿透

内网穿透,即NAT穿透,进行 NAT 穿透是为了使具有某一个特定源 IP 地址和源端口号的数据包不被 NAT 设备屏蔽而正确路由到内网主机。对于没有公网IP的用户来说,用现成的内网穿透工具即可,如花生壳、NATAPPcpolar等。本文主要介绍用frp+nginx实现内网穿透。

frp

frp是什么

frp 是一个专注于内网穿透的高性能的开源反向代理应用,支持 TCPUDPHTTPHTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

安装frp

首先,在frp官网下载安装包,本文使用frp版本为0.48.0

客户端(内网中搭载http服务的主机)和服务端(拥有公网IP的服务器主机)执行如下命令:

$ wget https://github.com/fatedier/frp/releases/download/v0.48.0/frp_0.48.0_linux_amd64.tar.gz
$ tar -xzvf frp_0.48.0_linux_amd64.tar.gz
$ sudo mv frp_0.48.0_linux_amd64 /usr/local/frp
$ cd /usr/local/frp

修改客户端和服务端hosts文件,加入如下配置:

your_server_ip frp.example.com

服务端配置

修改frp目录下的frps.ini,加入如下配置:

[common]
bind_port = 7000 # 服务端监听端口,接收 frpc 的连接
token = your_token # 鉴权使用的 token 值,客户端需要设置一样的值才能鉴权通过
dashboard_port = 7500 # 启用 Dashboard 监听的本地端口
dashboard_user = your_dashboard_user # Dashboard HTTP BasicAuth 用户名	
dashboard_pwd = your_dashboard_pwd # Dashboard HTTP BasicAuth 密码
vhost_http_port = 7001 # 为 HTTP 类型代理监听的端口,启用后才支持 HTTP 类型的代理,默认不启用
别忘了将以上端口加入防火墙白名单,或者关闭防火墙。

客户端配置

修改frp目录下的frpc.ini,加入如下配置:

[common]
server_addr = your_server_addr # 连接服务端的地址,默认0.0.0.0
server_port = 7000 # 连接服务端的端口,默认7000
token = your_token # 鉴权使用的 token 值,与服务端一致

[web]
type = http # 代理类型,可选值:tcp, udp, http, https, stcp, sudp, xtcp, tcpmux
local_port = 7860 # 本地服务端口
custom_domains = frp.example.com # 服务器绑定自定义域名,用户通过 vhost_http_port 访问的 HTTP 请求如果 Host 在 custom_domains 配置的域名中,则会被路由到此代理配置的本地服务

配置supervisor使frp自启动

服务端和客户端执行如下命令:

# 安装supervisor
$ sudo apt-get install supervisor
$ sudo systemctl start supervisor
# 配置supervisor开机自启
$ sudo systemctl enable supervisor

服务端配置步骤如下:

$ sudo vim /etc/supervisor/frps.conf
# 加入如下配置
[program:frps]
process_name=%(program_name)s_%(process_num)02d
command=/usr/local/frp/frps -c /usr/local/frp/frps.ini
autostart=true
autorestart=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/usr/local/frp/supervisord.log
stderr_logfile=/usr/local/frp/supervisord_err.log
stopwaitsecs=3600
$ sudo supervisorctl update

客户端配置步骤如下:

$ sudo vim /etc/supervisor/frpc.conf
# 加入如下配置
[program:frpc]
process_name=%(program_name)s_%(process_num)02d
command=/usr/local/frp/frpc -c /usr/local/frp/frpc.ini
autostart=true
autorestart=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/usr/local/frp/supervisord.log
stderr_logfile=/usr/local/frp/supervisord_err.log
stopwaitsecs=3600
$ sudo supervisorctl update

nginx配置

服务端执行如下命令:

$ sudo apt-get install nginx
$ sudo vim /etc/nginx/conf.d/proxy.example.com.conf
# 加入如下配置
server
{
	listen 80;
	listen 443 ssl http2;
	# proxy.example.com为外网访问的域名
	server_name proxy.example.com;

	location / {
		proxy_pass http://frp.example.com:7001;
		proxy_set_header   X-Real-IP        $remote_addr;
		proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
	}
	index index.html index.htm default.php default.htm default.html;

	ssl_certificate    /etc/nginx/conf.d/cert/proxy.example.com.crt;
    ssl_certificate_key    /etc/nginx/conf.d/cert/proxy.example.com.key;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
 	
	access_log  /var/log/nginx/proxy.example.com.log;
    error_log  /var/log/nginx/proxy.example.com.error.log;
}
$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ nginx -s reload

测试内网穿透效果

服务开启后,在任意浏览器访问https://proxy.example.com,即可访问客户端Web服务。