侧边栏壁纸
博主头像
qiql博主等级

水能载舟,亦可赛艇

  • 累计撰写 33 篇文章
  • 累计创建 28 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

Nginx + FRP反向代理实现二级域名访问内网服务并配置 https

qiql
2023-06-04 / 0 评论 / 3 点赞 / 387 阅读 / 2,176 字

零 概述

假如在内网中部署了一个服务,并想实现在公网访问,可以通过内网穿透,然后用IP+端口的形式来进行实现,但是暴露一个端口号既不安全也不美观,网上有一些教程是通过二级域名+端口或三级域名的方式实现的,但是也不美观,本文将介绍如何通过使用Nginx加FRP的方式,直接实现二级域名访问到内网服务。

实验前需要准备:

  • 一台公网云服务器,假设IP为:66.66.66.66,可以放开部分端口,如 80, 443, 7000,7001
  • 一个顶级域名:example.com
  • A解析:a.example.com,需解析指向到 66.66.66.66 这台公网服务器上
  • 一台能联网的内网服务器,应用将部署在这台内网服务器上

最终实现的目标是,直接以 a.example.com 访问到这台内网服务器的某个 web 服务,且可以配置 https 访问

一 安装 Nginx

部署 FRP 之前,首先需要有一台公网云服务器,在公网云服务器上部署安装 Nginx

# 获取nginx安装包
wget https://mirrors.qiql.net/pkgs/nginx-1.23.0.tar.gz

# 解压
tar -zxvf ../nginx-1.23.0.tar.gz 

cd nginx-1.23.0
# 安装必要的依赖
sudo yum -y install pcre-devel
sudo yum -y install openssl-devel

# 进行配置,--prefix是指定安装路径,--with-http_ssl_module 是使得Nginx支持https
./configure --prefix=/usr/local/nginx --with-http_ssl_module

# 编译Nginx -j 默认使用机器上所有的核心,-j 2 可以只指定两个核心
make -j

# 进行安装,将编译得到的二进制文件和配置文件等拷贝到之前由--prefix参数所指定的目录中去
make install

# 切换到Nginx的安装目录
cd /usr/local/nginx 

# 启动Nginx
sudo  ./sbin/nginx

二 安装 FRP

FRP 的安装分为服务端和客户端两部分,需要先在公网服务器上安装好服务端,然后在内网服务器上安装客户端

FRP官方文档:https://gofrp.org/docs/

FRP历史各版本文档:https://www.bookstack.cn/read/frp/spilt.2.spilt.3.README_zh.md

(官方文档很简洁明了,但是少了很多对FRP功能的叙述,可以先按照官方文档进行基本的安装。配置文件热更新等高级功能建议参考历史版本文档)

2.1 服务端

登陆到公网服务器上,安装FRP的服务端

# 获取FRP安装包
wget https://mirrors.qiql.net/pkgs/frp_0.48.0_linux_amd64.tar.gz

# 解压
tar -zxvf frp_0.48.0_linux_amd64.tar.gz
cd frp-0.48.0

FRP 并不需要编译,只需要修改配置文件即可。找到 frps.ini 文件,修改配置如下:

[common]
 # 默认为 7000 端口,且这个 7000 端口需要在公网服务器的安全组中打开
bind_port = 7000
# frpc Client客户端连接Frps服务端时的token 为了安全 建议添加
token = xxxxxx

# web端管理控制面板相关配置【可选】
dashboard_port = 7500
dashboard_user = username
dashboard_pwd = password

# 需要穿透http的统一访问端口(http类型的内网穿透,必须设置vhost_http_port,并且所有的http类型的客户端都将通过同一个vhost_http_port访问)
vhost_http_port = 7001
# https的访问端口(如果需要的话)
# vhost_https_port = 7443

启动FRP

./frps -c frps.ini

2.2 客户端

登陆到内网服务器上,安装 FRP 的客户端

# 获取FRP安装包
wget https://mirrors.qiql.net/pkgs/frp_0.48.0_linux_amd64.tar.gz

# 解压
tar -zxvf frp_0.48.0_linux_amd64.tar.gz
cd frp-0.48.0

修改frpc.ini文件

[common]
server_addr = 66.66.66.66 # 公网服务器的IP地址
server_port = 7000 # frps.ini文件中填写的端口
token = qiqlhkadmin # 填写与frps.ini文件中一样的token
admin_addr = 127.0.0.1 # 启用 admin 端口,用于提供 API 服务,可以用于客户端配置文件热加载
admin_port = 7400 # adnin 具体端口

# 如果想要直接 ssh 到内网服务器上,需进行以下配置
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6666
# 进行以上配置后,即可通过 ssh -p 6666 root@66.66.66.66 命令登陆到内网服务器

# 以下为 web 服务的配置方式
[web01]
type=http
local_ip = 127.0.0.1 # 无需修改
local_port = 1234     # 修改为 web 服务在本机启动的端口
custom_domains = a.xxx.com # 修改为二级域名,该域名需要解析到公网服务器的IP

启动FRP客户端

./frpc -c ./frpc.ini

如果后续有新的WEB网站代理需求,但重启FRP又很麻烦,可以执行以下命令来热更新frpc的配置文件

./frpc reload -c ./frpc.ini

2.3 配置守护进程

以下为frps(服务端)的守护进程配置方式,客户端的守护进程配置方式与之相似。

要使用 systemd 来控制 frps,需要先安装 systemd,然后在 /etc/systemd/system 目录下创建一个 frps.service 文件。

  1. 如Linux服务端上没有安装 systemd,可以使用 yumapt 等命令安装 systemd

    # yum
    yum install systemd
    # apt
    apt install systemd
    
  2. 使用文本编辑器,如 vim 创建并编辑 frps.service 文件。

    $ vim /etc/systemd/system/frps.service
    

    写入内容

    [Unit]
    # 服务名称,可自定义
    Description = frp server
    After = network.target syslog.target
    Wants = network.target
    
    [Service]
    Type = simple
    # 启动frps的命令,需修改为您的frps的安装路径
    ExecStart = /path/to/frps -c /path/to/frps.ini
    
    [Install]
    WantedBy = multi-user.target
    
  3. 使用 systemd 命令,管理 frps。

    # 启动frp
    systemctl start frps
    # 停止frp
    systemctl stop frps
    # 重启frp
    systemctl restart frps
    # 查看frp状态
    systemctl status frps
    
  4. 配置 frps 开机自启。

    systemctl enable frps
    

三 配置Nginx代理

假设一个web服务启动在内网服务器的1234端口上,想要以a.xx.com来访问该服务,可以参考以下配置来修改nginx的nginx.conf文件

3.1 http访问

    server {
        listen       80;
        server_name  a.example.com;
        location / {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://127.0.0.1:7001; # 这里的7001端口填写之前安装FRP时配置的 vhost_http_port 参数
        }
        error_page  500 502 503 504  /50x.html;

        location /50x.html {
            root   /usr/local/nginx/html;
        }
    }

修改完毕后,进入到nginx的sbin目录,执行./nginx -s reload 命令即可热更新nginx的配置文件

3.2 https访问

一般配置https,都需要配置全站https,否则浏览器仍认为该站点是不完全安全的,这时需要在nginx的配置文件中添加一个转发,可以将所有http的请求都转发为https的请求:

    server {
        listen       80;
        server_name  a.example.com; 
        rewrite ^(.*)$ https://$host$1 permanent;
    }

另外,如果需要配置https,还需要申请CA证书,前往阿里云控制台 > 搜索数字证书管理服务(SSL证书)> SSL证书> 免费证书> 创建证书即可完成免费CA证书的创建

image-20230604174754986

免费证书下发后,下载nginx版本的证书(应该是一个zip压缩包)

推荐在nginx的安装目录中新建一个cert目录,专门用于存放证书的pem和key文件

找到nginx的配置文件nginx.conf,添加以下内容:

    server {
        listen       443 ssl;
        server_name  a.example.com;

        charset utf-8;

        access_log  logs/host.https.a.example.com.access.log  main; # 添加该网站访问日志
        ssl_certificate     /usr/local/nginx/cert/a.example.com.pem;    # 修改为该网站 CA证书的 pem文件绝对路径
        ssl_certificate_key /usr/local/nginx/cert/a.example.com.key; # 修改为该网站 CA证书的 key文件绝对路径
        location / {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://127.0.0.1:7001;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
     }

注意,由于该配置文件中,还启用了日志文件的main格式,需要将以下配置的注释取消掉:

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

然后,重载nginx的配置文件即可: ./nginx -s reload

通过以上配置,便可以通过二级域名直接访问到内网服务器中的web服务,公网服务器只需要暴露四个端口(80,443,7000,7001)即可完成配置。

3

评论区