frp+nginx为内网http服务配置ssl

通过https访问内网的http服务

frp介绍


frp是一款非常经典并且功能非常强大的"打洞"(内网穿透)工具,简单来说,就是通过在内网机器和公网服务器之间搭建"隧道"(将内网服务的端口映射到公网服务器),从而使外部用户能够通过公网服务器访问到内网机器的服务

项目地址:https://github.com/fatedier/frp

中文文档:https://gofrp.org/zh-cn/

frp支持的协议和可实现的功能非常多,具体可以参考文档,本文只介绍如何暴露内网服务并通过nginx配置https

原理和过程介绍


其实非常简单,就一句话简单带过了

首先,frp将内网http服务映射到公网服务器的某个端口,然后在服务器通过nginx配置反向代理将请求发送到这个端口,由nginx服务器负责与客户端通信时的SSL/TLS加密,frp负责和内网服务通信

配置


首先,在内网机器和公网服务器都下载frp可执行程序,可以直接到frp的github项目中的release里下载最新版本。下载并解压后,可以得到服务端程序(frps)、客户端程序(frpc)和各自的配置文件(frps.tomlfrpc.toml

frps


公网服务器中只需要用到frpsfrps.toml

使用systemd管理frps服务


在多数场景下,我们通常使用的是Linux系统,因此建议使用systemd来管理frps

首先,在/etc/systemd/system目录下创建frps.service文件,写入以下内容,注意,仅需要将ExecStart后面中的/root/frp/frps/root/frp/frps.toml改为自己的对应文件的绝对路径

[Unit]
Description=Frp Server Service
After = network.target syslog.target
Wants = network.target

[Service]
Type=simple
Restart=on-failure
RestartSec=5s
ExecStart=/root/frp/frps -c /root/frp/frps.toml
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

保存并退出后,就可以使用systemd来管理frps服务啦

# 启动frp
systemctl start frps
# 停止frp
systemctl stop frps
# 重启frp
systemctl restart frps
# 查看frp状态
systemctl status frps
# 设置frps开机自启
systemctl enable frps

配置文件


接下来编辑frps.toml文件,写入以下内容:

bindPort = 17000
auth.method = "token"
auth.token = "YourStrongToken"
vhostHTTPPort = 18000

参数解释:

  • bindPort:设置frps服务的监听端口,用于和frpc建立连接

  • auth.method:设置认证方法,用于和frpc建立连接时进行身份认证,一般用token就可以

  • auth.token:设置一个用于用户认证的密码

  • vhostHTTPPort:设置内网http服务在公网服务器上的映射端口

设置好后,可以通过systemctl restart frps重启服务,服务端frps就配置完成,等待内网客户端frpc发起连接啦

frpc


内网服务器中只需要用到frpcfrpc.toml

打开frpc.toml文件进行编辑,写入以下内容:

serverAddr = "server_ip"
serverPort = 17000
auth.token = "YourStrongToken"

[[proxies]]
name = "web"
type = "http"
localPort = 80
customDomains = ["www.domain1.com"]

[[proxies]]
name = "web2"
type = "http"
localPort = 8080
customDomains = ["www.domain2.com"]

参数解释:

  • serverAddr:替换为公网服务器的ip地址

  • serverPortfrps服务监听端口

  • auth.tokenfrps设置的认证密码

[[proxies]]参数解释:

  • name:给内网http服务起个名字

  • type:协议类型设置为http

  • localPorthttp服务在内网的监听端口

  • customDomains:设置用于访问该http服务的域名

其中,customDomains非常重要,它用于确定访问的具体是哪一个内网服务,因为可以通过设置许多[[proxies]]来设置多个内网http服务,但是在公网服务器映射的端口只有一个,因此需要通过访问的域名来对应不同的内网http服务

配置完成后,如果是Linux系统,到对应路径执行./frpc -c frpc.toml就可以启动,同样也可以跟frps一样推荐用systemd管理;如果是Windows系统,可以设置任务计划来运行

nginx


完成frpsfrpc配置后,只需要到公网服务器配置一下nginx反向代理

首先为内网http服务设置一个域名,例如www.domain1.com,然后将域名解析到公网服务的ip,并用certbot申请SSL证书

/etc/nginx/conf.d/目录下为frps代理的内网http服务创建一个统一的nginx配置文件frps-http.conf,然后写入以下内容,需要将域名和证书替换为自己的

server {
    listen 80;
    server_name www.domain1.com;

    return 301 https://$server_name$request_uri;
}
server {
    listen 443 ssl;
    http2 on;
    server_name www.domain1.com;
    ssl_certificate /etc/letsencrypt/live/www.domain1.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.domain1.com/privkey.pem;

    location / {
      proxy_pass http://127.0.0.1:18000/;
      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;
    }
}

然后systemctl restart nginx后,就可以通过https://www.domain1.com访问对应的内网服务啦

关于加密的说明


你可能会发现,在整个过程中,客户端和nginx之间的通信采用了HTTPS进行了加密传输,nginx将流量反向代理到frps使用的是本地局域网环回地址所以也没有安全问题,但frpsfrpc之间通信的流量却是在公网传输的,所以是存在安全隐患的

不过,根据官方文档,最新版本的frpsfrpc之间的数据传输已经默认开启了TLS加密,不需要单独配置,当然,如果你想的话也可以按照如下示例指定开启或关闭:

[[proxies]]
name = "ssh"
type = "tcp"
localPort = 22
remotePort = 6000
transport.useEncryption = true   # 开启TLS加密
transport.useCompression = true  # 传输内容启动压缩,可以加快流量转发速度,但是会额外消耗一些 CPU 资源
转载请注明出处喔!( •̀ ω •́ )✧
发表了43篇文章 · 总计78.96k字
·
Built with Hugo
主题 StackJimmy 设计