FRP 端口映射配置注释
Table of Contents
1. 踩坑
1.1. 非默认端口访问需要全限定域名
给 web 服务做转发,比如从内网 443 端口转发到外网 10443 端口,在外网访问时要加上协议。
直接访问 <ip>:10443
浏览器会把请求解析为 http://<ip>:10443
使用 https 协议需要写 https://<ip>:10443
显式指定。
2. 服务端
放在公网机器上,比如阿里云服务器这种有固定 IP 的。
2.1. frp 服务端配置
下面是一个服务端配置文件的例子:
# 下面这句开头必须要有,表示配置的开始 [common] # frp 服务端端口(必须) bind_port = <port> # frp 服务端密码(必须) token = <passwd-token> # 认证超时时间,由于时间戳会被用于加密认证,防止报文劫持后被他人利用 # 因此服务端与客户端所在机器的时间差不能超过这个时间(秒) # 默认为900秒,即15分钟,如果设置成0就不会对报文时间戳进行超时验证 authentication_timeout = 900 # 仪表盘端口,只有设置了才能使用仪表盘(即后台) dashboard_port = 7500 # 仪表盘访问的用户名密码,如果不设置,则默认都是 admin # 注意和 token 区分开。token 用于客户端与服务端通信 # dashboard_pwd 用于登录 web 后台 dashboard_user = <uname> dashboard_pwd = <passwd-uname> # 如果想要用 frp 穿透访问内网中的网站(例如路由器设置页面) # 则必须要设置以下两个监听端口,不设置则不会开启这项功能 vhost_http_port = 10080 vhost_https_port = 10443 # 此设置需要配合客户端设置,仅在穿透到内网中的 http 或 https 时有用(可选) # 假设此项设置为 example.com,客户端配置 http 时将 subdomain 字段设置为 test # 在将 test.example.com 通过 DNS 解析到服务端 IP 后 # 可以使用此域名来访问客户端指定的 http subdomain_host = lishouzhong.top
2.2. nginx 转发 frp 流量以避免手动输入端口号
给一个自用的例子以供参考:
user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; # multi_accept on; } http { include /etc/nginx/mime.types; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" $upstream_cache_status'; access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 4096; resolver 8.8.8.8 8.8.4.4 valid=30s; # gzip gzip on; gzip_buffers 16 8K; gzip_comp_level 6; gzip_min_length 1k; gzip_types *; gzip_disable "MSIE [1-6]\."; # ie6 and previous version do not suport gzip gzip_vary on; proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=my_cache:30m max_size=2g inactive=3d use_temp_path=off loader_threshold=300 loader_files=200; # ssl config ssl_certificate </path/to/fullchain.pem>; ssl_certificate_key </path/to/privkey.pem>; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; # about 40000 sessions ssl_session_tickets off; ssl_stapling on; # open OCSP ssl_stapling_verify on; # open OCSP verify # TLS version ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; # ssl_prefer_server_ciphers OFF; # default OFF ssl_trusted_certificate </path/to/fullchain.pem>; # WebSocket upgrade map $http_upgrade $connection_upgrade { default upgrade; '' close; } # http to https server { listen 80; listen [::]:80; server_name .lishouzhong.top; location / { return 301 https://$host$request_uri; } } # frp admin server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name frpdashboard.lishouzhong.top; location / { proxy_pass http://127.0.0.1:7500; } } # frp http proxy psss server{ listen 443 ssl http2; server_name ~.*frp\.lishouzhong\.top$; location / { proxy_pass http://127.0.0.1:10080; proxy_ssl_server_name on; proxy_set_header Host $host; # webwocket proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 300s; proxy_send_timeout 300s; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } # frp https proxy pass server{ listen 443 ssl http2 ; server_name ~.*frps\.lishouzhong\.top$; location / { proxy_pass https://$host:10443; proxy_ssl_server_name on; proxy_set_header Host $host; # webwocket proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 300s; proxy_send_timeout 300s; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } }
3. 客户端配置
放在内网机器上,下面是一个客户端配置文件的例子:
# 表示配置开始 [common] # frp 服务端地址,ip 或域名二选一 server_addr = <example.com> | <ip> # frp 服务端端口,即填写服务端配置中的 bind_port server_port = 7000 # 填写 frp 服务端密码 token = <passwd-token> # 自定义一个配置名称放在开头,格式为 [<name>] [rpi_ssh] # 连接类型,填 tcp 或 udp type = tcp # 本地ip,填内网机器的ip # 如果是转发到frp客户端所在本机 ( 比如路由器 ) 则填 127.0.0.1 local_ip = 192.168.1.30 # 内网机器的端口,比如 ssh 端口是 22 local_port = 22 # 是否加密客户端与服务端之间的通信,默认是 false use_encryption = false # 是否压缩客户端与服务端之间的通信,默认是 false # 压缩可以节省流量,但需要消耗 CPU 资源 # 加密也会消耗 CPU 资源,但是不大 use_compression = true # frp 服务端的远程监听端口 # 即访问服务端 server_ip:remote_port 相当于访问客户端 local_ip:local_port # 填 0 会随机分配一个端口 remote_port = 6001 # 转发 windows rdp 端口的配置样例 # [28100_rdp] # type = tcp # local_ip = 192.168.2.19 # local_port = 3389 # remote_port = 7190 # use_encryption = false # use_compression = true [router_web] # 连接类型,填 http 或 https type = http local_ip = 192.168.1.2 local_port = 80 # http 可以考虑加密和压缩一下 use_encryption = true use_compression = true # 自定义访问网站的用户名和密码,如果不定义的话谁都可以访问,会不安全 # 有些路由器如果从内部访问web是不需要用户名密码的,因此需要在这里加一层密码保护 # 如果你发现不加这个密码保护,路由器配置页面原本的用户认证能正常生效的话,可以不加 # only for http, not https. #http_user = admin #http_pwd = admin # 在服务端配置了 subdomain_host = example.com # 假设这里我们填 web01,那么 DNS 将 解析到服务端ip后 # 就可以使用 web01.example.com:vhost_http_port 来访问内网的 http # 这个域名的作用是用来区分不同的 http,可以配置多个这样的内网 http subdomain = ros # 自定义域名,这个不同于 subdomain,你可以设置与 subdomain_host 无关的其他域名 # subdomain 与 custom_domains 中至少有一个必须要设置 #custom_domains = web02.yourdomain.com # 匹配路径,可以设置多个,用逗号分隔,比如 locations 配置如下, # 那么所有 http://xxx/abc 和 http://xxx/def 都会被转发到 http://xxx/ # 如果不需要这个功能可以不写这项,就直接该怎么访问就怎么访问 #locations = /abc,/def # 重写 host header,相当于反向代理中的“发送域名” # 如果设置了,转发 http 时,请求中的 host 会被替换成这个 # 一般情况下不需要用到这个,可以不写这项 #host_header_rewrite = dev.yourdomain.com