在公网服务器搭建frps(service),在内网本地机子搭建frpc(client),流量通过访问公网ip,经过frps服务端转发到fprc客户端,fprc再转发到本地web应用。
官方下载地址 https://github.com/fatedier/frp/releases
 官方文档地址https://gofrp.org/docs/
服务端:frp_0.44.0_linux_amd64.tar.gz
 客户端:frp_0.44.0_windows_amd64.zip
一、http
服务端frps(公网服务器)
这里我用虚拟机模拟了一台公网服务器:192.168.111.201
   
    - 
     
      
     
     
      
       # 解压
      
     
 
    - 
     
      
     
     
      
       tar -xzvf frp_0.44.0_linux_amd64.tar.gz
      
     
 
    - 
     
      
     
     
      
       cd frp_0.44.0_linux_amd64
      
     
 
    - 
     
      
     
     
      
       # 配置服务端
      
     
 
    - 
     
      
     
     
      
       vi frps.ini
      
     
 
   
 
配置 frps.ini
   
    - 
     
      
     
     
      
       [
       common]
      
     
 
    - 
     
      
     
     
      
       # frp服务端的端口,frp客户端需要连接这个端口握手
      
     
 
    - 
     
      
     
     
      
       bind_port = 
       7000
      
     
 
    - 
     
      
     
     
      
       # 公网服务端对外提供的http端口
      
     
 
    - 
     
      
     
     
      
       vhost_http_port=
       8080
      
     
 
   
 
启动服务端
./frps -c frps.ini 
后台启动运行服务端
nohup ./frps -c frps.ini >/dev/null 2>&1 &
 
客户端frpc(内网本地)
配置 frpc.ini
   
    - 
     
      
     
     
      
       [common]
      
     
 
    - 
     
      
     
     
      
       # frps服务端的ip和端口
      
     
 
    - 
     
      
     
     
      
       server_addr = 
       192.168.
       111.201
      
     
 
    - 
     
      
     
     
      
       server_port = 
       7000
      
     
 
    - 
     
      
     
     
       
      
     
 
    - 
     
      
     
     
      
       [web01]
      
     
 
    - 
     
      
     
     
      
       type = http
      
     
 
    - 
     
      
     
     
      
       # 本地web应用的ip和端口
      
     
 
    - 
     
      
     
     
      
       local_ip = 
       127.0.
       0.1
      
     
 
    - 
     
      
     
     
      
       local_port = 
       8080
      
     
 
    - 
     
      
     
     
      
       #公网服务器的ip或域名
      
     
 
    - 
     
      
     
     
      
       custom_domains = 
       192.168.
       111.201
      
     
 
   
 
到解压根目录启动客户端
frpc -c frpc.ini 
访问公网ip已经可以反向代理到本地web服务了。
以上就是一个简单的内网穿透 http 例子。
二、https
使用官方推荐的如下配置:
frps.ini
  
   - 
    
     
    
    
     
      [
      common]
     
    
 
   - 
    
     
    
    
     
      bind_port = 
      7000
     
    
 
   - 
    
     
    
    
     
      vhost_https_port = 
      443
     
    
 
  
 
frpc.ini
  
   - 
    
     
    
    
     
      [common]
     
    
 
   - 
    
     
    
    
     
      server_addr = 
      192.168.
      111.201
     
    
 
   - 
    
     
    
    
     
      server_port = 
      7000
     
    
 
   - 
    
     
    
    
      
     
    
 
   - 
    
     
    
    
     
      [plugin_https2https]
     
    
 
   - 
    
     
    
    
     
      type = https
     
    
 
   - 
    
     
    
    
     
      custom_domains = 
      192.168.
      111.201
     
    
 
   - 
    
     
    
    
     
      plugin = https2https
     
    
 
   - 
    
     
    
    
     
      plugin_local_addr = 
      127.0.
      0.1:
      8443
     
    
 
   - 
    
     
    
    
     
      #plugin_crt_path = ./server.crt
     
    
 
   - 
    
     
    
    
     
      #plugin_key_path = ./server.key
     
    
 
   - 
    
     
    
    
     
      plugin_host_header_rewrite = 
      127.0.
      0.1
     
    
 
   - 
    
     
    
    
     
      plugin_header_X-
      From-
      Where = frp
     
    
 
  
 
结果一直报如下错误,没找到解决办。

三、tcp实现https
研究了好久,才反应过来,http协议在应用层,tcp在传输层,且http是基于tcp的。
 既然https失败了,直接转发tcp就是,把ssl放在本地web应用中就可以了,frp只做tcp流量转发。
frps.ini
  
   - 
    
     
    
    
     
      [
      common]
     
    
 
   - 
    
     
    
    
     
      bind_port = 
      7000
     
    
 
  
 
frpc.ini
  
   - 
    
     
    
    
     
      [common]
     
    
 
   - 
    
     
    
    
     
      server_addr = 
      192.168.
      111.201
     
    
 
   - 
    
     
    
    
     
      server_port = 
      7000
     
    
 
   - 
    
     
    
    
      
     
    
 
   - 
    
     
    
    
     
      [tcp]
     
    
 
   - 
    
     
    
    
     
      type = tcp
     
    
 
   - 
    
     
    
    
     
      # 本地web应用的ip和端口
     
    
 
   - 
    
     
    
    
     
      local_ip = 
      127.0.
      0.1
     
    
 
   - 
    
     
    
    
     
      local_port = 
      8443
     
    
 
   - 
    
     
    
    
     
      # 公网服务器提供给外网访问的端口
     
    
 
   - 
    
     
    
    
     
      remote_port = 
      443
     
    
 
  
 

四、安全加固
 上面有2个不安全的地方:
 1、frpc 和 frps 之间的身份验证不安全,默认为 token,这种方式存在被中间人攻击的威胁。
 2、frpc 和 frps 之间的流量未加密,可以通过 TLS 协议加密,解决被中间人攻击的威胁。
frps.ini
  
   - 
    
     
    
    
     
      [
      common]
     
    
 
   - 
    
     
    
    
     
      #frps服务端监听的端口,frpc客户端要来连接。
     
    
 
   - 
    
     
    
    
     
      bind_port = 
      7000
     
    
 
   - 
    
     
    
    
     
      #密码设置复杂点,frps服务端密码和frpc客户端密码要一致。
     
    
 
   - 
    
     
    
    
     
      token = mm123456789
     
    
 
  
 
frpc.ini
  
   - 
    
     
    
    
     
      [common]
     
    
 
   - 
    
     
    
    
     
      # frps服务端的ip和端口
     
    
 
   - 
    
     
    
    
     
      server_addr = 
      192.168.
      111.201
     
    
 
   - 
    
     
    
    
     
      server_port = 
      7000
     
    
 
   - 
    
     
    
    
     
      #密码设置复杂点,frps服务端密码和frpc客户端密码要一致。
     
    
 
   - 
    
     
    
    
     
      token = mm123456789
     
    
 
   - 
    
     
    
    
      
     
    
 
   - 
    
     
    
    
     
      [tcp]
     
    
 
   - 
    
     
    
    
     
      type = tcp
     
    
 
   - 
    
     
    
    
     
      # 本地web应用的ip和端口
     
    
 
   - 
    
     
    
    
     
      local_ip = 
      127.0.
      0.1
     
    
 
   - 
    
     
    
    
     
      local_port = 
      8443
     
    
 
   - 
    
     
    
    
     
      # 公网服务器提供给外网访问的端口
     
    
 
   - 
    
     
    
    
     
      remote_port = 
      443
     
    
 
  
 
 
双向验证
双向验证即 frpc 和 frps 通过本地 ca 证书去验证对方的身份。理论上 frpc 和 frps 的 ca 证书可以不同,只要能验证对方身份即可。
frps.ini
  
   - 
    
     
    
    
     
      # frps.ini
     
    
 
   - 
    
     
    
    
     
      [common]
     
    
 
   - 
    
     
    
    
     
      #frps服务端监听的端口,frpc客户端要来连接。
     
    
 
   - 
    
     
    
    
     
      bind_port = 7000
     
    
 
   - 
    
     
    
    
     
      #密码设置复杂点,frps服务端密码和frpc客户端密码要一致。
     
    
 
   - 
    
     
    
    
     
      token = mm123456789
     
    
 
   - 
    
     
    
    
      
     
    
 
   - 
    
     
    
    
     
      tls_cert_file = ./server.crt
     
    
 
   - 
    
     
    
    
     
      tls_key_file = ./server.key
     
    
 
   - 
    
     
    
    
     
      tls_trusted_ca_file = ./ca.crt
     
    
 
  
 
frpc.ini
  
   - 
    
     
    
    
     
      # frpc.ini
     
    
 
   - 
    
     
    
    
     
      [common]
     
    
 
   - 
    
     
    
    
     
      # frps服务端的ip和端口
     
    
 
   - 
    
     
    
    
     
      server_addr = 192.168.111.201
     
    
 
   - 
    
     
    
    
     
      server_port = 7000
     
    
 
   - 
    
     
    
    
     
      #密码设置复杂点,frps服务端密码和frpc客户端密码要一致。
     
    
 
   - 
    
     
    
    
     
      token = mm123456789
     
    
 
   - 
    
     
    
    
      
     
    
 
   - 
    
     
    
    
     
      # frpc开启TLS加密功能
     
    
 
   - 
    
     
    
    
     
      tls_enable = 
      true
     
    
 
   - 
    
     
    
    
     
      tls_cert_file = ./client.crt
     
    
 
   - 
    
     
    
    
     
      tls_key_file = ./client.key
     
    
 
   - 
    
     
    
    
     
      tls_trusted_ca_file = ./ca.crt
     
    
 
   - 
    
     
    
    
      
     
    
 
   - 
    
     
    
    
     
      [tcp]
     
    
 
   - 
    
     
    
    
     
      type = tcp
     
    
 
   - 
    
     
    
    
     
      # 本地web应用的ip和端口
     
    
 
   - 
    
     
    
    
     
      local_ip = 127.0.0.1
     
    
 
   - 
    
     
    
    
     
      local_port = 8443
     
    
 
   - 
    
     
    
    
     
      # 公网服务器提供给外网访问的端口
     
    
 
   - 
    
     
    
    
     
      remote_port = 443
     
    
 
   - 
    
     
    
    
      
     
    
 
  
  
 生成SAN 证书
 
1、准备默认 my-openssl.cnf 配置文件于当前目录
  
   - 
    
     
    
    
     
      cat > my-openssl.cnf << EOF
     
    
 
   - 
    
     
    
    
     
      [ 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
     
    
 
  
  
2、生成默认CA
  
   - 
    
     
    
    
     
      openssl genrsa -out ca.
      key 
      2048
     
    
 
   - 
    
     
    
    
     
      openssl req -x509 -
      new -nodes -
      key ca.
      key -subj 
      "/CN=example.ca.com" -days 
      3650 -out ca.crt
     
    
 
  
 
3、生成服务端证书
将 192.168.111.201 改成自己的服务端的ip
  
   - 
    
     
    
    
     
      openssl genrsa -out 
      server.key 
      2048
     
    
 
   - 
    
     
    
    
      
     
    
 
   - 
    
     
    
    
     
      openssl req -
      new -sha256 -key 
      server.key \
     
    
 
   - 
    
     
    
    
     
          -subj 
      "/C=XX/ST=DEFAULT/L=DEFAULT/O=DEFAULT/CN=192.168.111.201" \
     
    
 
   - 
    
     
    
    
     
          -reqexts SAN \
     
    
 
   - 
    
     
    
    
     
          -config <(cat my-openssl.cnf <(printf 
      "\n[SAN]\nsubjectAltName=DNS:localhost,IP:127.0.0.1,DNS:server.com,IP:192.168.111.201")) \
     
    
 
   - 
    
     
    
    
     
          -out 
      server.csr
     
    
 
   - 
    
     
    
    
      
     
    
 
   - 
    
     
    
    
     
      openssl x509 -req -days 
      3650 -sha256 \
     
    
 
   - 
    
     
    
    
     
      	-
      in 
      server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
     
    
 
   - 
    
     
    
    
     
      	-extfile <(printf 
      "subjectAltName=DNS:localhost,IP:127.0.0.1,DNS:server.com,IP:192.168.111.201") \
     
    
 
   - 
    
     
    
    
     
      	-out 
      server.crt
     
    
 
  
 
4、生成客户端证书
使用 who 命令查询客户端的ip地址。我这里是192.168.111.1
将 192.168.111.1 改成自己的客户端的ip
  
   - 
    
     
    
    
     
      openssl genrsa -
      out client.key 
      2048
     
    
 
   - 
    
     
    
    
     
      openssl req -new -sha256 -key client.key \
     
    
 
   - 
    
     
    
    
     
          -subj 
      "/C=XX/ST=DEFAULT/L=DEFAULT/O=DEFAULT/CN=192.168.111.1" \
     
    
 
   - 
    
     
    
    
     
          -reqexts SAN \
     
    
 
   - 
    
     
    
    
     
          -config <(cat my-openssl.cnf <(printf 
      "\n[SAN]\nsubjectAltName=DNS:client.com,IP:192.168.111.1")) \
     
    
 
   - 
    
     
    
    
     
          -
      out client.csr
     
    
 
   - 
    
     
    
    
      
     
    
 
   - 
    
     
    
    
     
      openssl x509 -req -days 
      3650 -sha256 \
     
    
 
   - 
    
     
    
    
     
          -
      in client.csr -CA ca.crt -
      CAkey ca.key -
      CAcreateserial \
     
    
 
   - 
    
     
    
    
     
      	-extfile <(printf 
      "subjectAltName=DNS:client.com,IP:192.168.111.1") \
     
    
 
   - 
    
     
    
    
     
      	-
      out client.crt
     
    
 
  
 
 

最终生成了10个文件。
 server.crt、server.key、ca.crt 拷贝到 frp服务端解压目录下。
 client.crt、client.key、ca.crt 拷贝到 frp客户端解压目录下。
转载:https://blog.csdn.net/u014644574/article/details/128303747
					