Skip to content

Nginx+FRP实现域名访问内网应用

frp 是一个高性能的反向代理应用,可以帮助您轻松地进行内网穿透,对外网提供服务,支持 tcp, http, https 等协议类型,并且 web 服务支持根据域名进行路由转发。官方文档:https://gofrp.org/docs/

nginx下载地址

text
http://tengine.taobao.org/download/tengine-2.3.3.tar.gz

frp下载地址

text
https://mirror.ghproxy.com/https://github.com/fatedier/frp/releases/tag/v0.52.3

nginx编译安装

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 100.png

frp有两个端,一个服务端,一个客户端

服务端负责数据转发,所以它是放在云服务器上的,那客户端自然是放在内网的某一台机器上

整体架构

名称地址应用配置文件
云服务器139.224.x.xfrpsfrps.ini
内网主机192.168.100.188frpcfrpc.ini
内网主机192.168.100.188nginxnginx.conf, www.odboy.cn.conf

配置与解析

frps.ini

text
[common]
#这个端口必须在云服务器的安全组对外开放,用于客户端连接与端口注册
bind_port = 8000
#这个就类似你登录时候要的验证码一样,用于身份识别,其他人就不能随便连接了
token = 123456

frpc.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 = 7001

nginx.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 配置,结构如图所示

101.png

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