Nginx+FRP实现域名访问内网应用
frp 是一个高性能的反向代理应用,可以帮助您轻松地进行内网穿透,对外网提供服务,支持 tcp, http, https 等协议类型,并且 web 服务支持根据域名进行路由转发。官方文档:https://gofrp.org/docs/
nginx下载地址
text
http://tengine.taobao.org/download/tengine-2.3.3.tar.gzfrp下载地址
text
https://mirror.ghproxy.com/https://github.com/fatedier/frp/releases/tag/v0.52.3nginx编译安装
shell
# 首先,我们需要解压tengine-2.3.3.tar.gz,进入tengine-2.3.3目录,然后执行命令
yum install jemalloc-devel -y
# 这里的user和group最好不要用root(这里仅用于示范,请勿用于生产)
./configure --prefix=/usr/local/nginx --user=root --group=root --with-pcre --with-jemalloc --with-http_ssl_module --with-http_realip_module --with-http_gzip_static_module --with-http_stub_status_module以阿里云为例子
域名www.odboy.cn和odboy.cn指向了云服务器节点 139.224.x.x,这个需要在阿里云的DNS解析中进行配置,如下图所示 配置@和www指向云服务器节点 139.224.x.x 
frp有两个端,一个服务端,一个客户端
服务端负责数据转发,所以它是放在云服务器上的,那客户端自然是放在内网的某一台机器上
整体架构
| 名称 | 地址 | 应用 | 配置文件 |
|---|---|---|---|
| 云服务器 | 139.224.x.x | frps | frps.ini |
| 内网主机 | 192.168.100.188 | frpc | frpc.ini |
| 内网主机 | 192.168.100.188 | nginx | nginx.conf, www.odboy.cn.conf |
配置与解析
frps.ini
text
[common]
#这个端口必须在云服务器的安全组对外开放,用于客户端连接与端口注册
bind_port = 8000
#这个就类似你登录时候要的验证码一样,用于身份识别,其他人就不能随便连接了
token = 123456frpc.ini
text
[common]
#这个是云服务器的地址,这里也可以是指向公网地址的域名
server_addr = 139.224.x.x
#开启 TLS 协议加密
tls_enable = true
#这个端口就是在安全组中开放的端口,也是frp的服务端口
server_port = 8000
#和服务端的那个token一毛一样就行
token = 123456
#frpc.ini配置中可以有多个子配置,比如这里是blog,你还可以定义web或者ssh之类的
[blog]
#协议类型,更多可以在官方文档中找到,https://gofrp.org/docs/concepts/
type = tcp
#本地地址,如果是本机就填127.0.0.1,如果不是本机而是其他的内网机器,就填机器ip
local_ip = 127.0.0.1
#本地端口,当访问远程端口时,访问的本地端口,也是本地应用服务的端口
local_port = 8090
#远程端口,当访问服务端的8090时,转发到本地端口8090
remote_port = 8090
#[myapp]
#type = tcp
#local_ip = 127.0.0.1
#local_port = 8080
#remote_port = 7001nginx.conf配置
text
user root;
worker_processes auto;
events {
worker_connections 10240;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '"$http_x_forwarded_for" $remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$upstream_addr"';
#access_log logs/access.log main;
sendfile on;
keepalive_timeout 65;
# 调优: 32的倍数
proxy_headers_hash_max_size 51200;
proxy_headers_hash_bucket_size 6400;
client_max_body_size 50m;
# 这个是为了后面模块化方便,定义的存放方式
include /usr/local/nginx/conf/conf.d/*.conf;
}www.odboy.cn.conf 配置,结构如图所示

text
server {
# 监听80
listen 80;
server_name www.odboy.cn odboy.cn;
# 强制将http的URL重写成https
rewrite ^(.*) https://$server_name$1 permanent;
}
server
{
# 监听443
listen 443 ssl;
# 带www或者不带www都可以
server_name www.odboy.cn odboy.cn;
access_log /var/log/www.odboy.cn_access.log main;
charset utf-8;
client_max_body_size 1024m;
# SSL[配置]
ssl_certificate /usr/local/nginx/conf/ssl/www.odboy.cn.pem;
ssl_certificate_key /usr/local/nginx/conf/ssl/www.odboy.cn.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_prefer_server_ciphers on;
# 静态资源压缩[配置]
gzip on;
gzip_vary on;
# 不压缩临界值,大于1k的才压缩,一般不用改
gzip_min_length 1k;
gzip_buffers 4 16k;
# 压缩级别,数字越大压缩的越好
gzip_comp_level 6;
# 压缩文件类型, 缺啥补啥
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png image/x-icon;
#当访问www.odboy.cn或者odboy.cn时(也就是server_name配置的),将请求代理到本地的8090端口
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8090;
}
}启动命令参考
frps
shell
./frps -c ./frps.ini > frps.log &frpc
shell
./frpc -c ./frpc.ini > frpc.log &nginx
shell
./sbin/nginx -c ./conf/nginx.conf &整体流程解析
text
1、访问www.odboy.cn或odboy.cn,由DNS解析到云服务器默认的80端口
2、由于80端口被nginx监听,接着走www.odboy.cn.conf的代理
3、由于www.odboy.cn.conf的代理配置指向了本地8090端口,正巧frpc注册的远程端口也是8090
4、由于frpc.ini中的local_port=8090,remote_port=8090,所以当nginx代理将请求转发到8090的时候,frp又把请求转给了客户端的8090
