准备

一台有公网ip的vps

一台运行多个服务的内网主机

frp服务端

下载服务端

frp_0.61.0_linux_amd64.tar.gz

wget https://github.com/fatedier/frp/releases/download/v0.61.0/frp_0.61.0_linux_amd64.tar.gz
tar -zxvf frp_0.61.0_linux_amd64.tar.gz 
mv frp_0.61.0_linux_amd64 frp
mkdir /frp/logs

修改frps.toml

vim frps.toml
bindPort = 9881
#web dashboard配置
webServer.addr = "0.0.0.0"
webServer.port = 9882
webServer.user = "xxx"
webServer.password = "xxx"
#启用prometheus监控指标
enablePrometheus = true
#token权限验证,需与客户端配置一致
auth.method = "token"
auth.token = "xxx"
#日志配置
log.to = "/frp/logs/frps.log"
log.level = "info"
log.maxDays = 3

配置 systemd 守护进程

vim /etc/systemd/system/frps.service
[Unit]
Description=frps service
After=network.target syslog.target
Wants=network.target
[Service]
Type=simple
#Restart=always
Restart=on-failure
RestartSec=5s
#启动服务的命令
ExecStart=/frp/frps -c /frp/frps.toml
[Install]
WantedBy=multi-user.target

启动frp

systemctl start frps
systemctl status frps

访问 http://ip:9882

frp客户端

群晖套件版

修改frpc.toml

serverAddr = "xxxx" //vps的公网ip
serverPort = 9881

#web dashboard配置
webServer.addr = "0.0.0.0"
webServer.port = 9885
webServer.user = "xxx"
webServer.password = "xxx"

#token权限验证
auth.method = "token"
auth.token = "xxx"

log.to = "/frp/log/frpc.log"
log.level = "debug"
log.maxDays = 3

[[proxies]]
name = "xxx"
type = "tcp"
localIP = "127.0.0.1"
localPort = 9816
remotePort = 19816
transport.useCompression = true

TLS 加密

frpc 和 frps 之间的流量通过 TLS 加密,frps之间frpc双向验证

服务端

OpenSSL 生成证书

mkdir /frp/cert && cd /frp/cert
cat << 'EOF' >  my-openssl.cnf
[ 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
EOF

生成默认 ca

openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/C=CN/ST=ZJ/L=HZ/O=yeak/CN=yeak" -days 36500 -out ca.crt

生成 frps 证书

openssl genrsa -out server.key 2048
openssl req -new -sha256 -key server.key \
    -subj "/C=CN/ST=ZJ/L=HZ/O=yeak/CN=server.yeak.com" \
    -reqexts SAN \
    -config <(cat my-openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:XXXXXX")) \
    -out server.csr
openssl x509 -req -days 36500 -sha256 \
	-in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
	-extfile <(printf "subjectAltName=IP:XXXXXX") \
	-out server.crt

注:替换 IP:XXXXXX 为vps ip

生成frpc客户端证书

openssl genrsa -out client.key 2048
openssl req -new -sha256 -key client.key \
    -subj "/C=CN/ST=ZJ/L=HZ/O=yeak/CN=client.yeak.com" \
    -reqexts SAN \
    -config <(cat my-openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:192.168.xx.xx")) \
    -out client.csr
openssl x509 -req -days 36500 -sha256 \
    -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
	-extfile <(printf "subjectAltName=IP:192.168.xx.xx") \
	-out client.crt

注:替换 IP:192.168.xx.xx 为内网主机 ip

追加frps.toml

transport.tls.force = true
transport.tls.certFile = "/frp/cert/server.crt"
transport.tls.keyFile = "/frp/cert/server.key"
transport.tls.trustedCaFile ="/frp/cert/ca.crt"

客户端

将服务端目录/frp/cert下 client.key、client.crt、ca.crt 复制到内网主机/frp/cert目录下

追加frpc.toml

transport.tls.certFile = "/frp/cert/client.crt"
transport.tls.keyFile = "/frp/cert/client.key"
transport.tls.trustedCaFile ="/frp/cert/ca.crt"

测试

在vps上执行

sudo tcpdump -i any port 19816 -A

参考🔗