FRP 内网穿透使用 TLS 双向加密

FRP 内网穿透使用 TLS 双向加密

frp 是一个开源强大的内网穿透工具,本文介绍如何在 frp 中开启 TLS 双向加密,使内网穿透更安全。

从 v0.52.0 版本开始,frp 开始支持 TOML、YAML 和 JSON 作为配置文件格式。

请注意,INI 已被弃用,并将在未来的发布中移除。新功能只能在 TOML、YAML 或 JSON 中使用。

建议使用 TOML 作为配置文件格式。

从 v0.50.0 开始,transport.tls.enable 的默认值将会为 true,默认开启 TLS 协议加密。

如果 frps 端没有配置证书,则会使用随机生成的证书来加密流量。

默认情况下,frpc 开启 TLS 加密功能,但是不校验 frps 的证书。

启用双向 TLS 加密需要先生成证书,首先建立一个文件夹,新建 my-openssl.cnf 文件并写入以下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[ ca ]
default_ca = CA_default
[ CA_default ]
x509_extensions = usr_cert
[ req ]
default_bits = 2048
default_md = sha256
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca
string_mask = utf8only
[ req_distinguished_name ]
[ req_attributes ]
[ usr_cert ]
basicConstraints = CA:FALSE
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = CA:true

生成默认 ca:

1
2
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=example.ca.com" -days 5000 -out ca.crt

生成服务端证书:

1
2
3
4
5
6
7
8
9
10
11
12
openssl genrsa -out server.key 2048

openssl req -new -sha256 -key server.key \
-subj "/C=XX/ST=DEFAULT/L=DEFAULT/O=DEFAULT/CN=server.com" \
-reqexts SAN \
-config <(cat my-openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:localhost,IP: 你的服务端公网 IP,DNS:example.server.com")) \
-out server.csr

openssl x509 -req -days 5000 -sha256 \
-in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-extfile <(printf "subjectAltName=DNS:localhost,IP: 你的服务端公网 IP,DNS:example.server.com") \
-out server.crt

subjectAltName 中的 IP 地址改为服务端的公网 IP,否则客户端连接时会报如下错误:

[W] [service.go:133] login to server failed: tls: failed to verify certificate: x509: certificate is valid for 127.0.0.1, not x.x.x.x

生成客户端证书:

1
2
3
4
5
6
7
8
9
10
11
12
openssl genrsa -out client.key 2048

openssl req -new -sha256 -key client.key \
-subj "/C=XX/ST=DEFAULT/L=DEFAULT/O=DEFAULT/CN=client.com" \
-reqexts SAN \
-config <(cat my-openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:client.com,DNS:example.client.com")) \
-out client.csr

openssl x509 -req -days 5000 -sha256 \
-in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-extfile <(printf "subjectAltName=DNS:client.com,DNS:example.client.com") \
-out client.crt

最终的文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
.
├── ca.crt
├── ca.key
├── ca.srl
├── client.crt
├── client.csr
├── client.key
├── my-openssl.cnf
├── server.crt
├── server.csr
└── server.key

1 directory, 8 file

将证书上传到服务端并修改配置文件,增加 tls 验证相关配置:

frpc.toml
1
2
3
transport.tls.certFile = "/to/cert/path/client.crt"
transport.tls.keyFile = "/to/key/path/client.key"
transport.tls.trustedCaFile = "/to/ca/path/ca.crt"
frps.toml
1
2
3
transport.tls.certFile = "/to/cert/path/server.crt"
transport.tls.keyFile = "/to/key/path/server.key"
transport.tls.trustedCaFile = "/to/ca/path/ca.crt"

随后重启服务端和客户端。至此,客户端和服务端的双向验证配置完毕。

参考资料:

  1. https://gofrp.org/docs/overview/

FRP 内网穿透使用 TLS 双向加密

https://cui.cc/frp-security-config/

作者

南山崔崔

发布于

2023-08-24

许可协议