From a468cde26b009547dddbc7678b983ad214a2b40b Mon Sep 17 00:00:00 2001 From: okxlin <61420215+okxlin@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:50:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0filebrowser=E3=80=81frpc?= =?UTF-8?q?=E3=80=81frps=E3=80=81home-assistant=E3=80=81nextcloud=E3=80=81?= =?UTF-8?q?hexo=E3=80=81zfile=20(#299)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/filebrowser/2.24.1/data.yml | 17 + .../filebrowser/2.24.1/data/.filebrowser.json | 8 + apps/filebrowser/2.24.1/data/database.db | 0 apps/filebrowser/2.24.1/docker-compose.yml | 21 + apps/filebrowser/README.md | 44 + apps/filebrowser/data.yml | 20 + apps/filebrowser/logo.png | Bin 0 -> 7872 bytes apps/frpc/0.51.2/data.yml | 9 + apps/frpc/0.51.2/data/frpc.ini | 9 + apps/frpc/0.51.2/data/frpc_full.ini | 365 ++++++ apps/frpc/0.51.2/data/frps.ini | 2 + apps/frpc/0.51.2/data/frps_full.ini | 168 +++ apps/frpc/0.51.2/docker-compose.yml | 11 + apps/frpc/README.md | 1151 +++++++++++++++++ apps/frpc/data.yml | 20 + apps/frpc/logo.png | Bin 0 -> 26073 bytes apps/frps/0.51.2/data.yml | 9 + apps/frps/0.51.2/data/frpc.ini | 9 + apps/frps/0.51.2/data/frpc_full.ini | 365 ++++++ apps/frps/0.51.2/data/frps.ini | 2 + apps/frps/0.51.2/data/frps_full.ini | 168 +++ apps/frps/0.51.2/docker-compose.yml | 11 + apps/frps/README.md | 1151 +++++++++++++++++ apps/frps/data.yml | 20 + apps/frps/logo.png | Bin 0 -> 26073 bytes apps/hexo/README.md | 102 ++ apps/hexo/data.yml | 20 + apps/hexo/logo.png | Bin 0 -> 5336 bytes apps/hexo/stable-23-07-01/data.yml | 24 + apps/hexo/stable-23-07-01/docker-compose.yml | 24 + .../2023.8.0.dev20230723/data.yml | 10 + .../2023.8.0.dev20230723/docker-compose.yml | 13 + apps/home-assistant/README.md | 33 + apps/home-assistant/data.yml | 20 + apps/home-assistant/logo.png | Bin 0 -> 7060 bytes apps/nextcloud/27.0.1/data.yml | 12 + apps/nextcloud/27.0.1/docker-compose.yml | 23 + apps/nextcloud/README.md | 163 +++ apps/nextcloud/data.yml | 20 + apps/nextcloud/logo.png | Bin 0 -> 8999 bytes apps/zfile/4.1.5/data.yml | 17 + apps/zfile/4.1.5/docker-compose.yml | 20 + apps/zfile/README.md | 71 + apps/zfile/data.yml | 20 + apps/zfile/logo.png | Bin 0 -> 5737 bytes 45 files changed, 4172 insertions(+) create mode 100644 apps/filebrowser/2.24.1/data.yml create mode 100644 apps/filebrowser/2.24.1/data/.filebrowser.json create mode 100644 apps/filebrowser/2.24.1/data/database.db create mode 100644 apps/filebrowser/2.24.1/docker-compose.yml create mode 100644 apps/filebrowser/README.md create mode 100644 apps/filebrowser/data.yml create mode 100644 apps/filebrowser/logo.png create mode 100644 apps/frpc/0.51.2/data.yml create mode 100644 apps/frpc/0.51.2/data/frpc.ini create mode 100644 apps/frpc/0.51.2/data/frpc_full.ini create mode 100644 apps/frpc/0.51.2/data/frps.ini create mode 100644 apps/frpc/0.51.2/data/frps_full.ini create mode 100644 apps/frpc/0.51.2/docker-compose.yml create mode 100644 apps/frpc/README.md create mode 100644 apps/frpc/data.yml create mode 100644 apps/frpc/logo.png create mode 100644 apps/frps/0.51.2/data.yml create mode 100644 apps/frps/0.51.2/data/frpc.ini create mode 100644 apps/frps/0.51.2/data/frpc_full.ini create mode 100644 apps/frps/0.51.2/data/frps.ini create mode 100644 apps/frps/0.51.2/data/frps_full.ini create mode 100644 apps/frps/0.51.2/docker-compose.yml create mode 100644 apps/frps/README.md create mode 100644 apps/frps/data.yml create mode 100644 apps/frps/logo.png create mode 100644 apps/hexo/README.md create mode 100644 apps/hexo/data.yml create mode 100644 apps/hexo/logo.png create mode 100644 apps/hexo/stable-23-07-01/data.yml create mode 100644 apps/hexo/stable-23-07-01/docker-compose.yml create mode 100644 apps/home-assistant/2023.8.0.dev20230723/data.yml create mode 100644 apps/home-assistant/2023.8.0.dev20230723/docker-compose.yml create mode 100644 apps/home-assistant/README.md create mode 100644 apps/home-assistant/data.yml create mode 100644 apps/home-assistant/logo.png create mode 100644 apps/nextcloud/27.0.1/data.yml create mode 100644 apps/nextcloud/27.0.1/docker-compose.yml create mode 100644 apps/nextcloud/README.md create mode 100644 apps/nextcloud/data.yml create mode 100644 apps/nextcloud/logo.png create mode 100644 apps/zfile/4.1.5/data.yml create mode 100644 apps/zfile/4.1.5/docker-compose.yml create mode 100644 apps/zfile/README.md create mode 100644 apps/zfile/data.yml create mode 100644 apps/zfile/logo.png diff --git a/apps/filebrowser/2.24.1/data.yml b/apps/filebrowser/2.24.1/data.yml new file mode 100644 index 000000000..cd96ae14e --- /dev/null +++ b/apps/filebrowser/2.24.1/data.yml @@ -0,0 +1,17 @@ +additionalProperties: + formFields: + - default: 40071 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: HTTP Port + labelZh: HTTP端口 + required: true + rule: paramPort + type: number + - default: ./data/mnt + edit: true + envKey: MOUNT_PATH + labelEn: Mount folder path + labelZh: 挂载文件夹路径 + required: true + type: text diff --git a/apps/filebrowser/2.24.1/data/.filebrowser.json b/apps/filebrowser/2.24.1/data/.filebrowser.json new file mode 100644 index 000000000..fbcf6a1a7 --- /dev/null +++ b/apps/filebrowser/2.24.1/data/.filebrowser.json @@ -0,0 +1,8 @@ +{ + "port": 80, + "baseURL": "", + "address": "", + "log": "stdout", + "database": "/database/filebrowser.db", + "root": "/srv" + } \ No newline at end of file diff --git a/apps/filebrowser/2.24.1/data/database.db b/apps/filebrowser/2.24.1/data/database.db new file mode 100644 index 000000000..e69de29bb diff --git a/apps/filebrowser/2.24.1/docker-compose.yml b/apps/filebrowser/2.24.1/docker-compose.yml new file mode 100644 index 000000000..fe4f611a3 --- /dev/null +++ b/apps/filebrowser/2.24.1/docker-compose.yml @@ -0,0 +1,21 @@ +version: '3' +services: + filebrowser: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:80" + volumes: + - "${MOUNT_PATH}:/srv" + - "./data/database.db:/database.db" + - "./data/.filebrowser.json:/.filebrowser.json" + user: "${UID}:${GID}" + image: filebrowser/filebrowser:v2.24.1 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/apps/filebrowser/README.md b/apps/filebrowser/README.md new file mode 100644 index 000000000..31d513480 --- /dev/null +++ b/apps/filebrowser/README.md @@ -0,0 +1,44 @@ +# 使用说明 + +- 默认账户密码 + +``` +username:admin +password:admin +``` + +# 原始相关 + +

+ +

+ +![Preview](https://user-images.githubusercontent.com/5447088/50716739-ebd26700-107a-11e9-9817-14230c53efd2.gif) + +[![Build](https://github.com/filebrowser/filebrowser/actions/workflows/main.yaml/badge.svg)](https://github.com/filebrowser/filebrowser/actions/workflows/main.yaml) +[![Go Report Card](https://goreportcard.com/badge/github.com/filebrowser/filebrowser?style=flat-square)](https://goreportcard.com/report/github.com/filebrowser/filebrowser) +[![Documentation](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/filebrowser/filebrowser) +[![Version](https://img.shields.io/github/release/filebrowser/filebrowser.svg?style=flat-square)](https://github.com/filebrowser/filebrowser/releases/latest) +[![Chat IRC](https://img.shields.io/badge/freenode-%23filebrowser-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23filebrowser) + +filebrowser provides a file managing interface within a specified directory and it can be used to upload, delete, preview, rename and edit your files. It allows the creation of multiple users and each user can have its own directory. It can be used as a standalone app. + +## Features + +Please refer to our docs at [https://filebrowser.org/features](https://filebrowser.org/features) + +## Install + +For installation instructions please refer to our docs at [https://filebrowser.org/installation](https://filebrowser.org/installation). + +## Configuration + +[Authentication Method](https://filebrowser.org/configuration/authentication-method) - You can change the way the user authenticates with the filebrowser server + +[Command Runner](https://filebrowser.org/configuration/command-runner) - The command runner is a feature that enables you to execute any shell command you want before or after a certain event. + +[Custom Branding](https://filebrowser.org/configuration/custom-branding) - You can customize your File Browser installation by change its name to any other you want, by adding a global custom style sheet and by using your own logotype if you want. + +## Contributing + +If you're interested in contributing to this project, our docs are best places to start [https://filebrowser.org/contributing](https://filebrowser.org/contributing). diff --git a/apps/filebrowser/data.yml b/apps/filebrowser/data.yml new file mode 100644 index 000000000..c4a5bbfff --- /dev/null +++ b/apps/filebrowser/data.yml @@ -0,0 +1,20 @@ +name: File Browser +tags: + - 工具 +title: 网页文件浏览器 +type: 工具 +description: 网页文件浏览器 +additionalProperties: + key: filebrowser + name: File Browser + tags: + - Tool + shortDescZh: 网页文件浏览器 + shortDescEn: Web File Browser + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://filebrowser.org/ + github: https://github.com/filebrowser/filebrowser + document: https://filebrowser.org/ \ No newline at end of file diff --git a/apps/filebrowser/logo.png b/apps/filebrowser/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1d76ec2f8c0f0dc81a6cac0c210b4f732c947d50 GIT binary patch literal 7872 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 eUeKOg@qYnD1-H(P$||G)0000" "var1=" to the additional parameters. +# oidc_additional_audience = https://dev.auth.com/api/v2/ +# oidc_additional_var1 = foobar + +# set admin address for control frpc's action by http api such as reload +admin_addr = 127.0.0.1 +admin_port = 7400 +admin_user = admin +admin_pwd = admin +# Admin assets directory. By default, these assets are bundled with frpc. +# assets_dir = ./static + +# connections will be established in advance, default value is zero +pool_count = 5 + +# if tcp stream multiplexing is used, default is true, it must be same with frps +# tcp_mux = true + +# specify keep alive interval for tcp mux. +# only valid if tcp_mux is true. +# tcp_mux_keepalive_interval = 60 + +# your proxy name will be changed to {user}.{proxy} +user = your_name + +# decide if exit program when first login failed, otherwise continuous relogin to frps +# default is true +login_fail_exit = true + +# communication protocol used to connect to server +# supports tcp, kcp, quic and websocket now, default is tcp +protocol = tcp + +# set client binding ip when connect server, default is empty. +# only when protocol = tcp or websocket, the value will be used. +connect_server_local_ip = 0.0.0.0 + +# quic protocol options +# quic_keepalive_period = 10 +# quic_max_idle_timeout = 30 +# quic_max_incoming_streams = 100000 + +# if tls_enable is true, frpc will connect frps by tls +tls_enable = true + +# tls_cert_file = client.crt +# tls_key_file = client.key +# tls_trusted_ca_file = ca.crt +# tls_server_name = example.com + +# specify a dns server, so frpc will use this instead of default one +# dns_server = 8.8.8.8 + +# proxy names you want to start separated by ',' +# default is empty, means all proxies +# start = ssh,dns + +# heartbeat configure, it's not recommended to modify the default value +# The default value of heartbeat_interval is 10 and heartbeat_timeout is 90. Set negative value +# to disable it. +# heartbeat_interval = 30 +# heartbeat_timeout = 90 + +# additional meta info for client +meta_var1 = 123 +meta_var2 = 234 + +# specify udp packet size, unit is byte. If not set, the default value is 1500. +# This parameter should be same between client and server. +# It affects the udp and sudp proxy. +udp_packet_size = 1500 + +# include other config files for proxies. +# includes = ./confd/*.ini + +# By default, frpc will connect frps with first custom byte if tls is enabled. +# If DisableCustomTLSFirstByte is true, frpc will not send that custom byte. +disable_custom_tls_first_byte = false + +# Enable golang pprof handlers in admin listener. +# Admin port must be set first. +pprof_enable = false + +# 'ssh' is the unique proxy name +# if user in [common] section is not empty, it will be changed to {user}.{proxy} such as 'your_name.ssh' +[ssh] +# tcp | udp | http | https | stcp | xtcp, default is tcp +type = tcp +local_ip = 127.0.0.1 +local_port = 22 +# limit bandwidth for this proxy, unit is KB and MB +bandwidth_limit = 1MB +# where to limit bandwidth, can be 'client' or 'server', default is 'client' +bandwidth_limit_mode = client +# true or false, if true, messages between frps and frpc will be encrypted, default is false +use_encryption = false +# if true, message will be compressed +use_compression = false +# remote port listen by frps +remote_port = 6001 +# frps will load balancing connections for proxies in same group +group = test_group +# group should have same group key +group_key = 123456 +# enable health check for the backend service, it support 'tcp' and 'http' now +# frpc will connect local service's port to detect it's healthy status +health_check_type = tcp +# health check connection timeout +health_check_timeout_s = 3 +# if continuous failed in 3 times, the proxy will be removed from frps +health_check_max_failed = 3 +# every 10 seconds will do a health check +health_check_interval_s = 10 +# additional meta info for each proxy +meta_var1 = 123 +meta_var2 = 234 + +[ssh_random] +type = tcp +local_ip = 127.0.0.1 +local_port = 22 +# if remote_port is 0, frps will assign a random port for you +remote_port = 0 + +# if you want to expose multiple ports, add 'range:' prefix to the section name +# frpc will generate multiple proxies such as 'tcp_port_6010', 'tcp_port_6011' and so on. +[range:tcp_port] +type = tcp +local_ip = 127.0.0.1 +local_port = 6010-6020,6022,6024-6028 +remote_port = 6010-6020,6022,6024-6028 +use_encryption = false +use_compression = false + +[dns] +type = udp +local_ip = 114.114.114.114 +local_port = 53 +remote_port = 6002 +use_encryption = false +use_compression = false + +[range:udp_port] +type = udp +local_ip = 127.0.0.1 +local_port = 6010-6020 +remote_port = 6010-6020 +use_encryption = false +use_compression = false + +# Resolve your domain names to [server_addr] so you can use http://web01.yourdomain.com to browse web01 and http://web02.yourdomain.com to browse web02 +[web01] +type = http +local_ip = 127.0.0.1 +local_port = 80 +use_encryption = false +use_compression = true +# http username and password are safety certification for http protocol +# if not set, you can access this custom_domains without certification +http_user = admin +http_pwd = admin +# if domain for frps is frps.com, then you can access [web01] proxy by URL http://web01.frps.com +subdomain = web01 +custom_domains = web01.yourdomain.com +# locations is only available for http type +locations = /,/pic +# route requests to this service if http basic auto user is abc +# route_by_http_user = abc +host_header_rewrite = example.com +# params with prefix "header_" will be used to update http request headers +header_X-From-Where = frp +health_check_type = http +# frpc will send a GET http request '/status' to local http service +# http service is alive when it return 2xx http response code +health_check_url = /status +health_check_interval_s = 10 +health_check_max_failed = 3 +health_check_timeout_s = 3 + +[web02] +type = https +local_ip = 127.0.0.1 +local_port = 8000 +use_encryption = false +use_compression = false +subdomain = web01 +custom_domains = web02.yourdomain.com +# if not empty, frpc will use proxy protocol to transfer connection info to your local service +# v1 or v2 or empty +proxy_protocol_version = v2 + +[plugin_unix_domain_socket] +type = tcp +remote_port = 6003 +# if plugin is defined, local_ip and local_port is useless +# plugin will handle connections got from frps +plugin = unix_domain_socket +# params with prefix "plugin_" that plugin needed +plugin_unix_path = /var/run/docker.sock + +[plugin_http_proxy] +type = tcp +remote_port = 6004 +plugin = http_proxy +plugin_http_user = abc +plugin_http_passwd = abc + +[plugin_socks5] +type = tcp +remote_port = 6005 +plugin = socks5 +plugin_user = abc +plugin_passwd = abc + +[plugin_static_file] +type = tcp +remote_port = 6006 +plugin = static_file +plugin_local_path = /var/www/blog +plugin_strip_prefix = static +plugin_http_user = abc +plugin_http_passwd = abc + +[plugin_https2http] +type = https +custom_domains = test.yourdomain.com +plugin = https2http +plugin_local_addr = 127.0.0.1:80 +plugin_crt_path = ./server.crt +plugin_key_path = ./server.key +plugin_host_header_rewrite = 127.0.0.1 +plugin_header_X-From-Where = frp + +[plugin_https2https] +type = https +custom_domains = test.yourdomain.com +plugin = https2https +plugin_local_addr = 127.0.0.1:443 +plugin_crt_path = ./server.crt +plugin_key_path = ./server.key +plugin_host_header_rewrite = 127.0.0.1 +plugin_header_X-From-Where = frp + +[plugin_http2https] +type = http +custom_domains = test.yourdomain.com +plugin = http2https +plugin_local_addr = 127.0.0.1:443 +plugin_host_header_rewrite = 127.0.0.1 +plugin_header_X-From-Where = frp + +[secret_tcp] +# If the type is secret tcp, remote_port is useless +# Who want to connect local port should deploy another frpc with stcp proxy and role is visitor +type = stcp +# sk used for authentication for visitors +sk = abcdefg +local_ip = 127.0.0.1 +local_port = 22 +use_encryption = false +use_compression = false + +# user of frpc should be same in both stcp server and stcp visitor +[secret_tcp_visitor] +# frpc role visitor -> frps -> frpc role server +role = visitor +type = stcp +# the server name you want to visitor +server_name = secret_tcp +sk = abcdefg +# connect this address to visitor stcp server +bind_addr = 127.0.0.1 +bind_port = 9000 +use_encryption = false +use_compression = false + +[p2p_tcp] +type = xtcp +sk = abcdefg +local_ip = 127.0.0.1 +local_port = 22 +use_encryption = false +use_compression = false + +[p2p_tcp_visitor] +role = visitor +type = xtcp +server_name = p2p_tcp +sk = abcdefg +bind_addr = 127.0.0.1 +bind_port = 9001 +use_encryption = false +use_compression = false + +[tcpmuxhttpconnect] +type = tcpmux +multiplexer = httpconnect +local_ip = 127.0.0.1 +local_port = 10701 +custom_domains = tunnel1 +# route_by_http_user = user1 diff --git a/apps/frpc/0.51.2/data/frps.ini b/apps/frpc/0.51.2/data/frps.ini new file mode 100644 index 000000000..229567a9d --- /dev/null +++ b/apps/frpc/0.51.2/data/frps.ini @@ -0,0 +1,2 @@ +[common] +bind_port = 7000 diff --git a/apps/frpc/0.51.2/data/frps_full.ini b/apps/frpc/0.51.2/data/frps_full.ini new file mode 100644 index 000000000..2d5e08e17 --- /dev/null +++ b/apps/frpc/0.51.2/data/frps_full.ini @@ -0,0 +1,168 @@ +# [common] is integral section +[common] +# A literal address or host name for IPv6 must be enclosed +# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80" +# For single "bind_addr" field, no need square brackets, like "bind_addr = ::". +bind_addr = 0.0.0.0 +bind_port = 7000 + +# udp port to help make udp hole to penetrate nat +bind_udp_port = 7001 + +# udp port used for kcp protocol, it can be same with 'bind_port'. +# if not set, kcp is disabled in frps. +kcp_bind_port = 7000 + +# udp port used for quic protocol. +# if not set, quic is disabled in frps. +# quic_bind_port = 7002 +# quic protocol options +# quic_keepalive_period = 10 +# quic_max_idle_timeout = 30 +# quic_max_incoming_streams = 100000 + +# specify which address proxy will listen for, default value is same with bind_addr +# proxy_bind_addr = 127.0.0.1 + +# if you want to support virtual host, you must set the http port for listening (optional) +# Note: http port and https port can be same with bind_port +vhost_http_port = 80 +vhost_https_port = 443 + +# response header timeout(seconds) for vhost http server, default is 60s +# vhost_http_timeout = 60 + +# tcpmux_httpconnect_port specifies the port that the server listens for TCP +# HTTP CONNECT requests. If the value is 0, the server will not multiplex TCP +# requests on one single port. If it's not - it will listen on this value for +# HTTP CONNECT requests. By default, this value is 0. +# tcpmux_httpconnect_port = 1337 + +# If tcpmux_passthrough is true, frps won't do any update on traffic. +# tcpmux_passthrough = false + +# set dashboard_addr and dashboard_port to view dashboard of frps +# dashboard_addr's default value is same with bind_addr +# dashboard is available only if dashboard_port is set +dashboard_addr = 0.0.0.0 +dashboard_port = 7500 + +# dashboard user and passwd for basic auth protect +dashboard_user = admin +dashboard_pwd = admin + +# dashboard TLS mode +dashboard_tls_mode = false +# dashboard_tls_cert_file = server.crt +# dashboard_tls_key_file = server.key + +# enable_prometheus will export prometheus metrics on {dashboard_addr}:{dashboard_port} in /metrics api. +enable_prometheus = true + +# dashboard assets directory(only for debug mode) +# assets_dir = ./static + +# console or real logFile path like ./frps.log +log_file = ./frps.log + +# trace, debug, info, warn, error +log_level = info + +log_max_days = 3 + +# disable log colors when log_file is console, default is false +disable_log_color = false + +# DetailedErrorsToClient defines whether to send the specific error (with debug info) to frpc. By default, this value is true. +detailed_errors_to_client = true + +# authentication_method specifies what authentication method to use authenticate frpc with frps. +# If "token" is specified - token will be read into login message. +# If "oidc" is specified - OIDC (Open ID Connect) token will be issued using OIDC settings. By default, this value is "token". +authentication_method = token + +# authenticate_heartbeats specifies whether to include authentication token in heartbeats sent to frps. By default, this value is false. +authenticate_heartbeats = false + +# AuthenticateNewWorkConns specifies whether to include authentication token in new work connections sent to frps. By default, this value is false. +authenticate_new_work_conns = false + +# auth token +token = 12345678 + +# oidc_issuer specifies the issuer to verify OIDC tokens with. +# By default, this value is "". +oidc_issuer = + +# oidc_audience specifies the audience OIDC tokens should contain when validated. +# By default, this value is "". +oidc_audience = + +# oidc_skip_expiry_check specifies whether to skip checking if the OIDC token is expired. +# By default, this value is false. +oidc_skip_expiry_check = false + +# oidc_skip_issuer_check specifies whether to skip checking if the OIDC token's issuer claim matches the issuer specified in OidcIssuer. +# By default, this value is false. +oidc_skip_issuer_check = false + +# heartbeat configure, it's not recommended to modify the default value +# the default value of heartbeat_timeout is 90. Set negative value to disable it. +# heartbeat_timeout = 90 + +# user_conn_timeout configure, it's not recommended to modify the default value +# the default value of user_conn_timeout is 10 +# user_conn_timeout = 10 + +# only allow frpc to bind ports you list, if you set nothing, there won't be any limit +allow_ports = 2000-3000,3001,3003,4000-50000 + +# pool_count in each proxy will change to max_pool_count if they exceed the maximum value +max_pool_count = 5 + +# max ports can be used for each client, default value is 0 means no limit +max_ports_per_client = 0 + +# tls_only specifies whether to only accept TLS-encrypted connections. By default, the value is false. +tls_only = false + +# tls_cert_file = server.crt +# tls_key_file = server.key +# tls_trusted_ca_file = ca.crt + +# if subdomain_host is not empty, you can set subdomain when type is http or https in frpc's configure file +# when subdomain is test, the host used by routing is test.frps.com +subdomain_host = frps.com + +# if tcp stream multiplexing is used, default is true +# tcp_mux = true + +# specify keep alive interval for tcp mux. +# only valid if tcp_mux is true. +# tcp_mux_keepalive_interval = 60 + +# tcp_keepalive specifies the interval between keep-alive probes for an active network connection between frpc and frps. +# If negative, keep-alive probes are disabled. +# tcp_keepalive = 7200 + +# custom 404 page for HTTP requests +# custom_404_page = /path/to/404.html + +# specify udp packet size, unit is byte. If not set, the default value is 1500. +# This parameter should be same between client and server. +# It affects the udp and sudp proxy. +udp_packet_size = 1500 + +# Enable golang pprof handlers in dashboard listener. +# Dashboard port must be set first +pprof_enable = false + +[plugin.user-manager] +addr = 127.0.0.1:9000 +path = /handler +ops = Login + +[plugin.port-manager] +addr = 127.0.0.1:9001 +path = /handler +ops = NewProxy diff --git a/apps/frpc/0.51.2/docker-compose.yml b/apps/frpc/0.51.2/docker-compose.yml new file mode 100644 index 000000000..2537e0248 --- /dev/null +++ b/apps/frpc/0.51.2/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3" +services: + frpc: + container_name: ${CONTAINER_NAME} + restart: always + network_mode: "host" + volumes: + - "${CONFIG_FILE_PATH}:/etc/frp/frpc.ini" + image: "snowdreamtech/frpc:0.51.2" + labels: + createdBy: "Apps" diff --git a/apps/frpc/README.md b/apps/frpc/README.md new file mode 100644 index 000000000..4aeec4f20 --- /dev/null +++ b/apps/frpc/README.md @@ -0,0 +1,1151 @@ +# frp + +[![Build Status](https://circleci.com/gh/fatedier/frp.svg?style=shield)](https://circleci.com/gh/fatedier/frp) +[![GitHub release](https://img.shields.io/github/tag/fatedier/frp.svg?label=release)](https://github.com/fatedier/frp/releases) + +[README](README.md) | [中文文档](README_zh.md) + +

Gold Sponsors

+ +

+ + + +   + + + +

+ + + +## What is frp? + +frp is a fast reverse proxy that allows you to expose a local server located behind a NAT or firewall to the Internet. It currently supports **TCP** and **UDP**, as well as **HTTP** and **HTTPS** protocols, enabling requests to be forwarded to internal services via domain name. + +frp also offers a P2P connect mode. + +## Table of Contents + + + +- [frp](#frp) + - [What is frp?](#what-is-frp) + - [Table of Contents](#table-of-contents) + - [Development Status](#development-status) + - [Architecture](#architecture) + - [Example Usage](#example-usage) + - [Access your computer in a LAN network via SSH](#access-your-computer-in-a-lan-network-via-ssh) + - [Accessing Internal Web Services with Custom Domains in LAN](#accessing-internal-web-services-with-custom-domains-in-lan) + - [Forward DNS query requests](#forward-dns-query-requests) + - [Forward Unix Domain Socket](#forward-unix-domain-socket) + - [Expose a simple HTTP file server](#expose-a-simple-http-file-server) + - [Enable HTTPS for a local HTTP(S) service](#enable-https-for-a-local-https-service) + - [Expose your service privately](#expose-your-service-privately) + - [P2P Mode](#p2p-mode) + - [Features](#features) + - [Configuration Files](#configuration-files) + - [Using Environment Variables](#using-environment-variables) + - [Split Configures Into Different Files](#split-configures-into-different-files) + - [Dashboard](#dashboard) + - [Admin UI](#admin-ui) + - [Monitor](#monitor) + - [Prometheus](#prometheus) + - [Authenticating the Client](#authenticating-the-client) + - [Token Authentication](#token-authentication) + - [OIDC Authentication](#oidc-authentication) + - [Encryption and Compression](#encryption-and-compression) + - [TLS](#tls) + - [Hot-Reloading frpc configuration](#hot-reloading-frpc-configuration) + - [Get proxy status from client](#get-proxy-status-from-client) + - [Only allowing certain ports on the server](#only-allowing-certain-ports-on-the-server) + - [Port Reuse](#port-reuse) + - [Bandwidth Limit](#bandwidth-limit) + - [For Each Proxy](#for-each-proxy) + - [TCP Stream Multiplexing](#tcp-stream-multiplexing) + - [Support KCP Protocol](#support-kcp-protocol) + - [Support QUIC Protocol](#support-quic-protocol) + - [Connection Pooling](#connection-pooling) + - [Load balancing](#load-balancing) + - [Service Health Check](#service-health-check) + - [Rewriting the HTTP Host Header](#rewriting-the-http-host-header) + - [Setting other HTTP Headers](#setting-other-http-headers) + - [Get Real IP](#get-real-ip) + - [HTTP X-Forwarded-For](#http-x-forwarded-for) + - [Proxy Protocol](#proxy-protocol) + - [Require HTTP Basic Auth (Password) for Web Services](#require-http-basic-auth-password-for-web-services) + - [Custom Subdomain Names](#custom-subdomain-names) + - [URL Routing](#url-routing) + - [TCP Port Multiplexing](#tcp-port-multiplexing) + - [Connecting to frps via HTTP PROXY](#connecting-to-frps-via-http-proxy) + - [Range ports mapping](#range-ports-mapping) + - [Client Plugins](#client-plugins) + - [Server Manage Plugins](#server-manage-plugins) + - [Development Plan](#development-plan) + - [Contributing](#contributing) + - [Donation](#donation) + - [GitHub Sponsors](#github-sponsors) + - [PayPal](#paypal) + + + +## Development Status + +frp is currently under development. You can try the latest release version in the `master` branch, or use the `dev` branch to access the version currently in development. + +We are currently working on version 2 and attempting to perform some code refactoring and improvements. However, please note that it will not be compatible with version 1. + +We will transition from version 0 to version 1 at the appropriate time and will only accept bug fixes and improvements, rather than big feature requests. + +## Architecture + +![architecture](https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/architecture.png) + +## Example Usage + +To begin, download the latest program for your operating system and architecture from the [Release](https://github.com/fatedier/frp/releases) page. + +Next, place the `frps` binary and `frps.ini` configuration file on Server A, which has a public IP address. + +Finally, place the `frpc` binary and `frpc.ini` configuration file on Server B, which is located on a LAN that cannot be directly accessed from the public internet. + +### Access your computer in a LAN network via SSH + +1. Modify `frps.ini` on server A by setting the `bind_port` for frp clients to connect to: + + ```ini + # frps.ini + [common] + bind_port = 7000 + ``` + +2. Start `frps` on server A: + + `./frps -c ./frps.ini` + +3. Modify `frpc.ini` on server B and set the `server_addr` field to the public IP address of your frps server: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [ssh] + type = tcp + local_ip = 127.0.0.1 + local_port = 22 + remote_port = 6000 + ``` + +Note that the `local_port` (listened on the client) and `remote_port` (exposed on the server) are used for traffic going in and out of the frp system, while the `server_port` is used for communication between frps and frpc. + +4. Start `frpc` on server B: + + `./frpc -c ./frpc.ini` + +5. To access server B from another machine through server A via SSH (assuming the username is `test`), use the following command: + + `ssh -oPort=6000 test@x.x.x.x` + +### Accessing Internal Web Services with Custom Domains in LAN + +Sometimes we need to expose a local web service behind a NAT network to others for testing purposes with our own domain name. + +Unfortunately, we cannot resolve a domain name to a local IP. However, we can use frp to expose an HTTP(S) service. + +1. Modify `frps.ini` and set the HTTP port for vhost to 8080: + + ```ini + # frps.ini + [common] + bind_port = 7000 + vhost_http_port = 8080 + ``` + +2. Start `frps`: + + `./frps -c ./frps.ini` + +3. Modify `frpc.ini` and set `server_addr` to the IP address of the remote frps server. Specify the `local_port` of your web service: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [web] + type = http + local_port = 80 + custom_domains = www.example.com + ``` + +4. Start `frpc`: + + `./frpc -c ./frpc.ini` + +5. Map the A record of `www.example.com` to either the public IP of the remote frps server or a CNAME record pointing to your original domain. + +6. Visit your local web service using url `http://www.example.com:8080`. + +### Forward DNS query requests + +1. Modify `frps.ini`: + + ```ini + # frps.ini + [common] + bind_port = 7000 + ``` + +2. Start `frps`: + + `./frps -c ./frps.ini` + +3. Modify `frpc.ini` and set `server_addr` to the IP address of the remote frps server. Forward DNS query requests to the Google Public DNS server `8.8.8.8:53`: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [dns] + type = udp + local_ip = 8.8.8.8 + local_port = 53 + remote_port = 6000 + ``` + +4. Start frpc: + + `./frpc -c ./frpc.ini` + +5. Test DNS resolution using the `dig` command: + + `dig @x.x.x.x -p 6000 www.google.com` + +### Forward Unix Domain Socket + +Expose a Unix domain socket (e.g. the Docker daemon socket) as TCP. + +Configure `frps` as above. + +1. Start `frpc` with the following configuration: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [unix_domain_socket] + type = tcp + remote_port = 6000 + plugin = unix_domain_socket + plugin_unix_path = /var/run/docker.sock + ``` + +2. Test the configuration by getting the docker version using `curl`: + + `curl http://x.x.x.x:6000/version` + +### Expose a simple HTTP file server + +Expose a simple HTTP file server to access files stored in the LAN from the public Internet. + +Configure `frps` as described above, then: + +1. Start `frpc` with the following configuration: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [test_static_file] + type = tcp + remote_port = 6000 + plugin = static_file + plugin_local_path = /tmp/files + plugin_strip_prefix = static + plugin_http_user = abc + plugin_http_passwd = abc + ``` + +2. Visit `http://x.x.x.x:6000/static/` from your browser and specify correct username and password to view files in `/tmp/files` on the `frpc` machine. + +### Enable HTTPS for a local HTTP(S) service + +You may substitute `https2https` for the plugin, and point the `plugin_local_addr` to a HTTPS endpoint. + +1. Start `frpc` with the following configuration: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [test_https2http] + type = https + custom_domains = test.example.com + + plugin = https2http + plugin_local_addr = 127.0.0.1:80 + plugin_crt_path = ./server.crt + plugin_key_path = ./server.key + plugin_host_header_rewrite = 127.0.0.1 + plugin_header_X-From-Where = frp + ``` + +2. Visit `https://test.example.com`. + +### Expose your service privately + +To mitigate risks associated with exposing certain services directly to the public network, STCP (Secret TCP) mode requires a preshared key to be used for access to the service from other clients. + +Configure `frps` same as above. + +1. Start `frpc` on machine B with the following config. This example is for exposing the SSH service (port 22), and note the `sk` field for the preshared key, and that the `remote_port` field is removed here: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [secret_ssh] + type = stcp + sk = abcdefg + local_ip = 127.0.0.1 + local_port = 22 + ``` + +2. Start another `frpc` (typically on another machine C) with the following config to access the SSH service with a security key (`sk` field): + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [secret_ssh_visitor] + type = stcp + role = visitor + server_name = secret_ssh + sk = abcdefg + bind_addr = 127.0.0.1 + bind_port = 6000 + ``` + +3. On machine C, connect to SSH on machine B, using this command: + + `ssh -oPort=6000 127.0.0.1` + +### P2P Mode + +**xtcp** is designed to transmit large amounts of data directly between clients. A frps server is still needed, as P2P here only refers to the actual data transmission. + +Note that it may not work with all types of NAT devices. You might want to fallback to stcp if xtcp doesn't work. + +1. In `frps.ini` configure a UDP port for xtcp: + + ```ini + # frps.ini + bind_udp_port = 7001 + ``` + +2. Start `frpc` on machine B, and expose the SSH port. Note that the `remote_port` field is removed: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [p2p_ssh] + type = xtcp + sk = abcdefg + local_ip = 127.0.0.1 + local_port = 22 + ``` + +3. Start another `frpc` (typically on another machine C) with the configuration to connect to SSH using P2P mode: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [p2p_ssh_visitor] + type = xtcp + role = visitor + server_name = p2p_ssh + sk = abcdefg + bind_addr = 127.0.0.1 + bind_port = 6000 + ``` + +4. On machine C, connect to SSH on machine B, using this command: + + `ssh -oPort=6000 127.0.0.1` + +## Features + +### Configuration Files + +Read the full example configuration files to find out even more features not described here. + +[Full configuration file for frps (Server)](./conf/frps_full.ini) + +[Full configuration file for frpc (Client)](./conf/frpc_full.ini) + +### Using Environment Variables + +Environment variables can be referenced in the configuration file, using Go's standard format: + +```ini +# frpc.ini +[common] +server_addr = {{ .Envs.FRP_SERVER_ADDR }} +server_port = 7000 + +[ssh] +type = tcp +local_ip = 127.0.0.1 +local_port = 22 +remote_port = {{ .Envs.FRP_SSH_REMOTE_PORT }} +``` + +With the config above, variables can be passed into `frpc` program like this: + +``` +export FRP_SERVER_ADDR="x.x.x.x" +export FRP_SSH_REMOTE_PORT="6000" +./frpc -c ./frpc.ini +``` + +`frpc` will render configuration file template using OS environment variables. Remember to prefix your reference with `.Envs`. + +### Split Configures Into Different Files + +You can split multiple proxy configs into different files and include them in the main file. + +```ini +# frpc.ini +[common] +server_addr = x.x.x.x +server_port = 7000 +includes=./confd/*.ini +``` + +```ini +# ./confd/test.ini +[ssh] +type = tcp +local_ip = 127.0.0.1 +local_port = 22 +remote_port = 6000 +``` + +### Dashboard + +Check frp's status and proxies' statistics information by Dashboard. + +Configure a port for dashboard to enable this feature: + +```ini +[common] +dashboard_port = 7500 +# dashboard's username and password are both optional +dashboard_user = admin +dashboard_pwd = admin +``` + +Then visit `http://[server_addr]:7500` to see the dashboard, with username and password both being `admin`. + +Additionally, you can use HTTPS port by using your domains wildcard or normal SSL certificate: + +```ini +[common] +dashboard_port = 7500 +# dashboard's username and password are both optional +dashboard_user = admin +dashboard_pwd = admin +dashboard_tls_mode = true +dashboard_tls_cert_file = server.crt +dashboard_tls_key_file = server.key +``` + +Then visit `https://[server_addr]:7500` to see the dashboard in secure HTTPS connection, with username and password both being `admin`. + +![dashboard](https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/dashboard.png) + +### Admin UI + +The Admin UI helps you check and manage frpc's configuration. + +Configure an address for admin UI to enable this feature: + +```ini +[common] +admin_addr = 127.0.0.1 +admin_port = 7400 +admin_user = admin +admin_pwd = admin +``` + +Then visit `http://127.0.0.1:7400` to see admin UI, with username and password both being `admin`. + +### Monitor + +When dashboard is enabled, frps will save monitor data in cache. It will be cleared after process restart. + +Prometheus is also supported. + +#### Prometheus + +Enable dashboard first, then configure `enable_prometheus = true` in `frps.ini`. + +`http://{dashboard_addr}/metrics` will provide prometheus monitor data. + +### Authenticating the Client + +There are 2 authentication methods to authenticate frpc with frps. + +You can decide which one to use by configuring `authentication_method` under `[common]` in `frpc.ini` and `frps.ini`. + +Configuring `authenticate_heartbeats = true` under `[common]` will use the configured authentication method to add and validate authentication on every heartbeat between frpc and frps. + +Configuring `authenticate_new_work_conns = true` under `[common]` will do the same for every new work connection between frpc and frps. + +#### Token Authentication + +When specifying `authentication_method = token` under `[common]` in `frpc.ini` and `frps.ini` - token based authentication will be used. + +Make sure to specify the same `token` in the `[common]` section in `frps.ini` and `frpc.ini` for frpc to pass frps validation + +#### OIDC Authentication + +When specifying `authentication_method = oidc` under `[common]` in `frpc.ini` and `frps.ini` - OIDC based authentication will be used. + +OIDC stands for OpenID Connect, and the flow used is called [Client Credentials Grant](https://tools.ietf.org/html/rfc6749#section-4.4). + +To use this authentication type - configure `frpc.ini` and `frps.ini` as follows: + +```ini +# frps.ini +[common] +authentication_method = oidc +oidc_issuer = https://example-oidc-issuer.com/ +oidc_audience = https://oidc-audience.com/.default +``` + +```ini +# frpc.ini +[common] +authentication_method = oidc +oidc_client_id = 98692467-37de-409a-9fac-bb2585826f18 # Replace with OIDC client ID +oidc_client_secret = oidc_secret +oidc_audience = https://oidc-audience.com/.default +oidc_token_endpoint_url = https://example-oidc-endpoint.com/oauth2/v2.0/token +``` + +### Encryption and Compression + +The features are off by default. You can turn on encryption and/or compression: + +```ini +# frpc.ini +[ssh] +type = tcp +local_port = 22 +remote_port = 6000 +use_encryption = true +use_compression = true +``` + +#### TLS + +frp supports the TLS protocol between `frpc` and `frps` since v0.25.0. + +For port multiplexing, frp sends a first byte `0x17` to dial a TLS connection. + +Configure `tls_enable = true` in the `[common]` section to `frpc.ini` to enable this feature. + +To **enforce** `frps` to only accept TLS connections - configure `tls_only = true` in the `[common]` section in `frps.ini`. **This is optional.** + +**`frpc` TLS settings (under the `[common]` section):** +```ini +tls_enable = true +tls_cert_file = certificate.crt +tls_key_file = certificate.key +tls_trusted_ca_file = ca.crt +``` + +**`frps` TLS settings (under the `[common]` section):** +```ini +tls_only = true +tls_enable = true +tls_cert_file = certificate.crt +tls_key_file = certificate.key +tls_trusted_ca_file = ca.crt +``` + +You will need **a root CA cert** and **at least one SSL/TLS certificate**. It **can** be self-signed or regular (such as Let's Encrypt or another SSL/TLS certificate provider). + +If you using `frp` via IP address and not hostname, make sure to set the appropriate IP address in the Subject Alternative Name (SAN) area when generating SSL/TLS Certificates. + +Given an example: + +* Prepare openssl config file. It exists at `/etc/pki/tls/openssl.cnf` in Linux System and `/System/Library/OpenSSL/openssl.cnf` in MacOS, and you can copy it to current path, like `cp /etc/pki/tls/openssl.cnf ./my-openssl.cnf`. If not, you can build it by yourself, like: +``` +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 +``` + +* build ca certificates: +``` +openssl genrsa -out ca.key 2048 +openssl req -x509 -new -nodes -key ca.key -subj "/CN=example.ca.com" -days 5000 -out ca.crt +``` + +* build frps certificates: +``` +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:127.0.0.1,DNS:example.server.com")) \ + -out server.csr + +openssl x509 -req -days 365 -sha256 \ + -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ + -extfile <(printf "subjectAltName=DNS:localhost,IP:127.0.0.1,DNS:example.server.com") \ + -out server.crt +``` + +* build frpc certificates: +``` +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 365 -sha256 \ + -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ + -extfile <(printf "subjectAltName=DNS:client.com,DNS:example.client.com") \ + -out client.crt +``` + +### Hot-Reloading frpc configuration + +The `admin_addr` and `admin_port` fields are required for enabling HTTP API: + +```ini +# frpc.ini +[common] +admin_addr = 127.0.0.1 +admin_port = 7400 +``` + +Then run command `frpc reload -c ./frpc.ini` and wait for about 10 seconds to let `frpc` create or update or remove proxies. + +**Note that parameters in [common] section won't be modified except 'start'.** + +You can run command `frpc verify -c ./frpc.ini` before reloading to check if there are config errors. + +### Get proxy status from client + +Use `frpc status -c ./frpc.ini` to get status of all proxies. The `admin_addr` and `admin_port` fields are required for enabling HTTP API. + +### Only allowing certain ports on the server + +`allow_ports` in `frps.ini` is used to avoid abuse of ports: + +```ini +# frps.ini +[common] +allow_ports = 2000-3000,3001,3003,4000-50000 +``` + +`allow_ports` consists of specific ports or port ranges (lowest port number, dash `-`, highest port number), separated by comma `,`. + +### Port Reuse + +`vhost_http_port` and `vhost_https_port` in frps can use same port with `bind_port`. frps will detect the connection's protocol and handle it correspondingly. + +We would like to try to allow multiple proxies bind a same remote port with different protocols in the future. + +### Bandwidth Limit + +#### For Each Proxy + +```ini +# frpc.ini +[ssh] +type = tcp +local_port = 22 +remote_port = 6000 +bandwidth_limit = 1MB +``` + +Set `bandwidth_limit` in each proxy's configure to enable this feature. Supported units are `MB` and `KB`. + +Set `bandwidth_limit_mode` to `client` or `server` to limit bandwidth on the client or server side. Default is `client`. + +### TCP Stream Multiplexing + +frp supports tcp stream multiplexing since v0.10.0 like HTTP2 Multiplexing, in which case all logic connections to the same frpc are multiplexed into the same TCP connection. + +You can disable this feature by modify `frps.ini` and `frpc.ini`: + +```ini +# frps.ini and frpc.ini, must be same +[common] +tcp_mux = false +``` + +### Support KCP Protocol + +KCP is a fast and reliable protocol that can achieve the transmission effect of a reduction of the average latency by 30% to 40% and reduction of the maximum delay by a factor of three, at the cost of 10% to 20% more bandwidth wasted than TCP. + +KCP mode uses UDP as the underlying transport. Using KCP in frp: + +1. Enable KCP in frps: + + ```ini + # frps.ini + [common] + bind_port = 7000 + # Specify a UDP port for KCP. + kcp_bind_port = 7000 + ``` + + The `kcp_bind_port` number can be the same number as `bind_port`, since `bind_port` field specifies a TCP port. + +2. Configure `frpc.ini` to use KCP to connect to frps: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + # Same as the 'kcp_bind_port' in frps.ini + server_port = 7000 + protocol = kcp + ``` + +### Support QUIC Protocol + +QUIC is a new multiplexed transport built on top of UDP. + +Using QUIC in frp: + +1. Enable QUIC in frps: + + ```ini + # frps.ini + [common] + bind_port = 7000 + # Specify a UDP port for QUIC. + quic_bind_port = 7000 + ``` + + The `quic_bind_port` number can be the same number as `bind_port`, since `bind_port` field specifies a TCP port. + +2. Configure `frpc.ini` to use QUIC to connect to frps: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + # Same as the 'quic_bind_port' in frps.ini + server_port = 7000 + protocol = quic + ``` + +### Connection Pooling + +By default, frps creates a new frpc connection to the backend service upon a user request. With connection pooling, frps keeps a certain number of pre-established connections, reducing the time needed to establish a connection. + +This feature is suitable for a large number of short connections. + +1. Configure the limit of pool count each proxy can use in `frps.ini`: + + ```ini + # frps.ini + [common] + max_pool_count = 5 + ``` + +2. Enable and specify the number of connection pool: + + ```ini + # frpc.ini + [common] + pool_count = 1 + ``` + +### Load balancing + +Load balancing is supported by `group`. + +This feature is only available for types `tcp`, `http`, `tcpmux` now. + +```ini +# frpc.ini +[test1] +type = tcp +local_port = 8080 +remote_port = 80 +group = web +group_key = 123 + +[test2] +type = tcp +local_port = 8081 +remote_port = 80 +group = web +group_key = 123 +``` + +`group_key` is used for authentication. + +Connections to port 80 will be dispatched to proxies in the same group randomly. + +For type `tcp`, `remote_port` in the same group should be the same. + +For type `http`, `custom_domains`, `subdomain`, `locations` should be the same. + +### Service Health Check + +Health check feature can help you achieve high availability with load balancing. + +Add `health_check_type = tcp` or `health_check_type = http` to enable health check. + +With health check type **tcp**, the service port will be pinged (TCPing): + +```ini +# frpc.ini +[test1] +type = tcp +local_port = 22 +remote_port = 6000 +# Enable TCP health check +health_check_type = tcp +# TCPing timeout seconds +health_check_timeout_s = 3 +# If health check failed 3 times in a row, the proxy will be removed from frps +health_check_max_failed = 3 +# A health check every 10 seconds +health_check_interval_s = 10 +``` + +With health check type **http**, an HTTP request will be sent to the service and an HTTP 2xx OK response is expected: + +```ini +# frpc.ini +[web] +type = http +local_ip = 127.0.0.1 +local_port = 80 +custom_domains = test.example.com +# Enable HTTP health check +health_check_type = http +# frpc will send a GET request to '/status' +# and expect an HTTP 2xx OK response +health_check_url = /status +health_check_timeout_s = 3 +health_check_max_failed = 3 +health_check_interval_s = 10 +``` + +### Rewriting the HTTP Host Header + +By default frp does not modify the tunneled HTTP requests at all as it's a byte-for-byte copy. + +However, speaking of web servers and HTTP requests, your web server might rely on the `Host` HTTP header to determine the website to be accessed. frp can rewrite the `Host` header when forwarding the HTTP requests, with the `host_header_rewrite` field: + +```ini +# frpc.ini +[web] +type = http +local_port = 80 +custom_domains = test.example.com +host_header_rewrite = dev.example.com +``` + +The HTTP request will have the `Host` header rewritten to `Host: dev.example.com` when it reaches the actual web server, although the request from the browser probably has `Host: test.example.com`. + +### Setting other HTTP Headers + +Similar to `Host`, You can override other HTTP request headers with proxy type `http`. + +```ini +# frpc.ini +[web] +type = http +local_port = 80 +custom_domains = test.example.com +host_header_rewrite = dev.example.com +header_X-From-Where = frp +``` + +Note that parameter(s) prefixed with `header_` will be added to HTTP request headers. + +In this example, it will set header `X-From-Where: frp` in the HTTP request. + +### Get Real IP + +#### HTTP X-Forwarded-For + +This feature is for http proxy only. + +You can get user's real IP from HTTP request headers `X-Forwarded-For`. + +#### Proxy Protocol + +frp supports Proxy Protocol to send user's real IP to local services. It support all types except UDP. + +Here is an example for https service: + +```ini +# frpc.ini +[web] +type = https +local_port = 443 +custom_domains = test.example.com + +# now v1 and v2 are supported +proxy_protocol_version = v2 +``` + +You can enable Proxy Protocol support in nginx to expose user's real IP in HTTP header `X-Real-IP`, and then read `X-Real-IP` header in your web service for the real IP. + +### Require HTTP Basic Auth (Password) for Web Services + +Anyone who can guess your tunnel URL can access your local web server unless you protect it with a password. + +This enforces HTTP Basic Auth on all requests with the username and password specified in frpc's configure file. + +It can only be enabled when proxy type is http. + +```ini +# frpc.ini +[web] +type = http +local_port = 80 +custom_domains = test.example.com +http_user = abc +http_pwd = abc +``` + +Visit `http://test.example.com` in the browser and now you are prompted to enter the username and password. + +### Custom Subdomain Names + +It is convenient to use `subdomain` configure for http and https types when many people share one frps server. + +```ini +# frps.ini +subdomain_host = frps.com +``` + +Resolve `*.frps.com` to the frps server's IP. This is usually called a Wildcard DNS record. + +```ini +# frpc.ini +[web] +type = http +local_port = 80 +subdomain = test +``` + +Now you can visit your web service on `test.frps.com`. + +Note that if `subdomain_host` is not empty, `custom_domains` should not be the subdomain of `subdomain_host`. + +### URL Routing + +frp supports forwarding HTTP requests to different backend web services by url routing. + +`locations` specifies the prefix of URL used for routing. frps first searches for the most specific prefix location given by literal strings regardless of the listed order. + +```ini +# frpc.ini +[web01] +type = http +local_port = 80 +custom_domains = web.example.com +locations = / + +[web02] +type = http +local_port = 81 +custom_domains = web.example.com +locations = /news,/about +``` + +HTTP requests with URL prefix `/news` or `/about` will be forwarded to **web02** and other requests to **web01**. + +### TCP Port Multiplexing + +frp supports receiving TCP sockets directed to different proxies on a single port on frps, similar to `vhost_http_port` and `vhost_https_port`. + +The only supported TCP port multiplexing method available at the moment is `httpconnect` - HTTP CONNECT tunnel. + +When setting `tcpmux_httpconnect_port` to anything other than 0 in frps under `[common]`, frps will listen on this port for HTTP CONNECT requests. + +The host of the HTTP CONNECT request will be used to match the proxy in frps. Proxy hosts can be configured in frpc by configuring `custom_domain` and / or `subdomain` under `type = tcpmux` proxies, when `multiplexer = httpconnect`. + +For example: + +```ini +# frps.ini +[common] +bind_port = 7000 +tcpmux_httpconnect_port = 1337 +``` + +```ini +# frpc.ini +[common] +server_addr = x.x.x.x +server_port = 7000 + +[proxy1] +type = tcpmux +multiplexer = httpconnect +custom_domains = test1 +local_port = 80 + +[proxy2] +type = tcpmux +multiplexer = httpconnect +custom_domains = test2 +local_port = 8080 +``` + +In the above configuration - frps can be contacted on port 1337 with a HTTP CONNECT header such as: + +``` +CONNECT test1 HTTP/1.1\r\n\r\n +``` +and the connection will be routed to `proxy1`. + +### Connecting to frps via HTTP PROXY + +frpc can connect to frps using HTTP proxy if you set OS environment variable `HTTP_PROXY`, or if `http_proxy` is set in frpc.ini file. + +It only works when protocol is tcp. + +```ini +# frpc.ini +[common] +server_addr = x.x.x.x +server_port = 7000 +http_proxy = http://user:pwd@192.168.1.128:8080 +``` + +### Range ports mapping + +Proxy with names that start with `range:` will support mapping range ports. + +```ini +# frpc.ini +[range:test_tcp] +type = tcp +local_ip = 127.0.0.1 +local_port = 6000-6006,6007 +remote_port = 6000-6006,6007 +``` + +frpc will generate 8 proxies like `test_tcp_0`, `test_tcp_1`, ..., `test_tcp_7`. + +### Client Plugins + +frpc only forwards requests to local TCP or UDP ports by default. + +Plugins are used for providing rich features. There are built-in plugins such as `unix_domain_socket`, `http_proxy`, `socks5`, `static_file`, `http2https`, `https2http`, `https2https` and you can see [example usage](#example-usage). + +Specify which plugin to use with the `plugin` parameter. Configuration parameters of plugin should be started with `plugin_`. `local_ip` and `local_port` are not used for plugin. + +Using plugin **http_proxy**: + +```ini +# frpc.ini +[http_proxy] +type = tcp +remote_port = 6000 +plugin = http_proxy +plugin_http_user = abc +plugin_http_passwd = abc +``` + +`plugin_http_user` and `plugin_http_passwd` are configuration parameters used in `http_proxy` plugin. + +### Server Manage Plugins + +Read the [document](/doc/server_plugin.md). + +Find more plugins in [gofrp/plugin](https://github.com/gofrp/plugin). + +## Development Plan + +* Log HTTP request information in frps. + +## Contributing + +Interested in getting involved? We would like to help you! + +* Take a look at our [issues list](https://github.com/fatedier/frp/issues) and consider sending a Pull Request to **dev branch**. +* If you want to add a new feature, please create an issue first to describe the new feature, as well as the implementation approach. Once a proposal is accepted, create an implementation of the new features and submit it as a pull request. +* Sorry for my poor English. Improvements for this document are welcome, even some typo fixes. +* If you have great ideas, send an email to fatedier@gmail.com. + +**Note: We prefer you to give your advise in [issues](https://github.com/fatedier/frp/issues), so others with a same question can search it quickly and we don't need to answer them repeatedly.** + +## Donation + +If frp helps you a lot, you can support us by: + +### GitHub Sponsors + +Support us by [Github Sponsors](https://github.com/sponsors/fatedier). + +You can have your company's logo placed on README file of this project. + +### PayPal + +Donate money by [PayPal](https://www.paypal.me/fatedier) to my account **fatedier@gmail.com**. + diff --git a/apps/frpc/data.yml b/apps/frpc/data.yml new file mode 100644 index 000000000..ce62167b4 --- /dev/null +++ b/apps/frpc/data.yml @@ -0,0 +1,20 @@ +name: frpc-frp客户端 +tags: + - 工具 +title: frp是一种反向代理工具,常用于内网穿透(客户端) +type: 工具 +description: frp是一种反向代理工具,常用于内网穿透(客户端) +additionalProperties: + key: frpc + name: frpc-frp客户端 + tags: + - Tool + shortDescZh: frp是一种反向代理工具,常用于内网穿透(客户端) + shortDescEn: frp is a reverse proxy tool that is commonly used for intranet penetration(Client) + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/fatedier/frp + github: https://github.com/fatedier/frp + document: https://github.com/fatedier/frp/blob/dev/README_zh.md diff --git a/apps/frpc/logo.png b/apps/frpc/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..023fe72df4c2c99878a8f9c803ecbe3f1e4204cf GIT binary patch literal 26073 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 literal 0 KcmV+b0RR6000031 diff --git a/apps/frps/0.51.2/data.yml b/apps/frps/0.51.2/data.yml new file mode 100644 index 000000000..770f903e1 --- /dev/null +++ b/apps/frps/0.51.2/data.yml @@ -0,0 +1,9 @@ +additionalProperties: + formFields: + - default: ./data/frps.ini + edit: false + envKey: CONFIG_FILE_PATH + labelEn: Configuration file path + labelZh: 配置文件路径 + required: true + type: text diff --git a/apps/frps/0.51.2/data/frpc.ini b/apps/frps/0.51.2/data/frpc.ini new file mode 100644 index 000000000..13a8e5f6f --- /dev/null +++ b/apps/frps/0.51.2/data/frpc.ini @@ -0,0 +1,9 @@ +[common] +server_addr = 127.0.0.1 +server_port = 7000 + +[ssh] +type = tcp +local_ip = 127.0.0.1 +local_port = 22 +remote_port = 6000 diff --git a/apps/frps/0.51.2/data/frpc_full.ini b/apps/frps/0.51.2/data/frpc_full.ini new file mode 100644 index 000000000..29f6bcab5 --- /dev/null +++ b/apps/frps/0.51.2/data/frpc_full.ini @@ -0,0 +1,365 @@ +# [common] is integral section +[common] +# A literal address or host name for IPv6 must be enclosed +# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80" +# For single "server_addr" field, no need square brackets, like "server_addr = ::". +server_addr = 0.0.0.0 +server_port = 7000 + +# The maximum amount of time a dial to server will wait for a connect to complete. Default value is 10 seconds. +# dial_server_timeout = 10 + +# dial_server_keepalive specifies the interval between keep-alive probes for an active network connection between frpc and frps. +# If negative, keep-alive probes are disabled. +# dial_server_keepalive = 7200 + +# if you want to connect frps by http proxy or socks5 proxy or ntlm proxy, you can set http_proxy here or in global environment variables +# it only works when protocol is tcp +# http_proxy = http://user:passwd@192.168.1.128:8080 +# http_proxy = socks5://user:passwd@192.168.1.128:1080 +# http_proxy = ntlm://user:passwd@192.168.1.128:2080 + +# console or real logFile path like ./frpc.log +log_file = ./frpc.log + +# trace, debug, info, warn, error +log_level = info + +log_max_days = 3 + +# disable log colors when log_file is console, default is false +disable_log_color = false + +# for authentication, should be same as your frps.ini +# authenticate_heartbeats specifies whether to include authentication token in heartbeats sent to frps. By default, this value is false. +authenticate_heartbeats = false + +# authenticate_new_work_conns specifies whether to include authentication token in new work connections sent to frps. By default, this value is false. +authenticate_new_work_conns = false + +# auth token +token = 12345678 + +authentication_method = + +# oidc_client_id specifies the client ID to use to get a token in OIDC authentication if AuthenticationMethod == "oidc". +# By default, this value is "". +oidc_client_id = + +# oidc_client_secret specifies the client secret to use to get a token in OIDC authentication if AuthenticationMethod == "oidc". +# By default, this value is "". +oidc_client_secret = + +# oidc_audience specifies the audience of the token in OIDC authentication if AuthenticationMethod == "oidc". By default, this value is "". +oidc_audience = + +# oidc_scope specifies the permisssions of the token in OIDC authentication if AuthenticationMethod == "oidc". By default, this value is "". +oidc_scope = + +# oidc_token_endpoint_url specifies the URL which implements OIDC Token Endpoint. +# It will be used to get an OIDC token if AuthenticationMethod == "oidc". By default, this value is "". +oidc_token_endpoint_url = + +# oidc_additional_xxx specifies additional parameters to be sent to the OIDC Token Endpoint. +# For example, if you want to specify the "audience" parameter, you can set as follow. +# frp will add "audience=" "var1=" to the additional parameters. +# oidc_additional_audience = https://dev.auth.com/api/v2/ +# oidc_additional_var1 = foobar + +# set admin address for control frpc's action by http api such as reload +admin_addr = 127.0.0.1 +admin_port = 7400 +admin_user = admin +admin_pwd = admin +# Admin assets directory. By default, these assets are bundled with frpc. +# assets_dir = ./static + +# connections will be established in advance, default value is zero +pool_count = 5 + +# if tcp stream multiplexing is used, default is true, it must be same with frps +# tcp_mux = true + +# specify keep alive interval for tcp mux. +# only valid if tcp_mux is true. +# tcp_mux_keepalive_interval = 60 + +# your proxy name will be changed to {user}.{proxy} +user = your_name + +# decide if exit program when first login failed, otherwise continuous relogin to frps +# default is true +login_fail_exit = true + +# communication protocol used to connect to server +# supports tcp, kcp, quic and websocket now, default is tcp +protocol = tcp + +# set client binding ip when connect server, default is empty. +# only when protocol = tcp or websocket, the value will be used. +connect_server_local_ip = 0.0.0.0 + +# quic protocol options +# quic_keepalive_period = 10 +# quic_max_idle_timeout = 30 +# quic_max_incoming_streams = 100000 + +# if tls_enable is true, frpc will connect frps by tls +tls_enable = true + +# tls_cert_file = client.crt +# tls_key_file = client.key +# tls_trusted_ca_file = ca.crt +# tls_server_name = example.com + +# specify a dns server, so frpc will use this instead of default one +# dns_server = 8.8.8.8 + +# proxy names you want to start separated by ',' +# default is empty, means all proxies +# start = ssh,dns + +# heartbeat configure, it's not recommended to modify the default value +# The default value of heartbeat_interval is 10 and heartbeat_timeout is 90. Set negative value +# to disable it. +# heartbeat_interval = 30 +# heartbeat_timeout = 90 + +# additional meta info for client +meta_var1 = 123 +meta_var2 = 234 + +# specify udp packet size, unit is byte. If not set, the default value is 1500. +# This parameter should be same between client and server. +# It affects the udp and sudp proxy. +udp_packet_size = 1500 + +# include other config files for proxies. +# includes = ./confd/*.ini + +# By default, frpc will connect frps with first custom byte if tls is enabled. +# If DisableCustomTLSFirstByte is true, frpc will not send that custom byte. +disable_custom_tls_first_byte = false + +# Enable golang pprof handlers in admin listener. +# Admin port must be set first. +pprof_enable = false + +# 'ssh' is the unique proxy name +# if user in [common] section is not empty, it will be changed to {user}.{proxy} such as 'your_name.ssh' +[ssh] +# tcp | udp | http | https | stcp | xtcp, default is tcp +type = tcp +local_ip = 127.0.0.1 +local_port = 22 +# limit bandwidth for this proxy, unit is KB and MB +bandwidth_limit = 1MB +# where to limit bandwidth, can be 'client' or 'server', default is 'client' +bandwidth_limit_mode = client +# true or false, if true, messages between frps and frpc will be encrypted, default is false +use_encryption = false +# if true, message will be compressed +use_compression = false +# remote port listen by frps +remote_port = 6001 +# frps will load balancing connections for proxies in same group +group = test_group +# group should have same group key +group_key = 123456 +# enable health check for the backend service, it support 'tcp' and 'http' now +# frpc will connect local service's port to detect it's healthy status +health_check_type = tcp +# health check connection timeout +health_check_timeout_s = 3 +# if continuous failed in 3 times, the proxy will be removed from frps +health_check_max_failed = 3 +# every 10 seconds will do a health check +health_check_interval_s = 10 +# additional meta info for each proxy +meta_var1 = 123 +meta_var2 = 234 + +[ssh_random] +type = tcp +local_ip = 127.0.0.1 +local_port = 22 +# if remote_port is 0, frps will assign a random port for you +remote_port = 0 + +# if you want to expose multiple ports, add 'range:' prefix to the section name +# frpc will generate multiple proxies such as 'tcp_port_6010', 'tcp_port_6011' and so on. +[range:tcp_port] +type = tcp +local_ip = 127.0.0.1 +local_port = 6010-6020,6022,6024-6028 +remote_port = 6010-6020,6022,6024-6028 +use_encryption = false +use_compression = false + +[dns] +type = udp +local_ip = 114.114.114.114 +local_port = 53 +remote_port = 6002 +use_encryption = false +use_compression = false + +[range:udp_port] +type = udp +local_ip = 127.0.0.1 +local_port = 6010-6020 +remote_port = 6010-6020 +use_encryption = false +use_compression = false + +# Resolve your domain names to [server_addr] so you can use http://web01.yourdomain.com to browse web01 and http://web02.yourdomain.com to browse web02 +[web01] +type = http +local_ip = 127.0.0.1 +local_port = 80 +use_encryption = false +use_compression = true +# http username and password are safety certification for http protocol +# if not set, you can access this custom_domains without certification +http_user = admin +http_pwd = admin +# if domain for frps is frps.com, then you can access [web01] proxy by URL http://web01.frps.com +subdomain = web01 +custom_domains = web01.yourdomain.com +# locations is only available for http type +locations = /,/pic +# route requests to this service if http basic auto user is abc +# route_by_http_user = abc +host_header_rewrite = example.com +# params with prefix "header_" will be used to update http request headers +header_X-From-Where = frp +health_check_type = http +# frpc will send a GET http request '/status' to local http service +# http service is alive when it return 2xx http response code +health_check_url = /status +health_check_interval_s = 10 +health_check_max_failed = 3 +health_check_timeout_s = 3 + +[web02] +type = https +local_ip = 127.0.0.1 +local_port = 8000 +use_encryption = false +use_compression = false +subdomain = web01 +custom_domains = web02.yourdomain.com +# if not empty, frpc will use proxy protocol to transfer connection info to your local service +# v1 or v2 or empty +proxy_protocol_version = v2 + +[plugin_unix_domain_socket] +type = tcp +remote_port = 6003 +# if plugin is defined, local_ip and local_port is useless +# plugin will handle connections got from frps +plugin = unix_domain_socket +# params with prefix "plugin_" that plugin needed +plugin_unix_path = /var/run/docker.sock + +[plugin_http_proxy] +type = tcp +remote_port = 6004 +plugin = http_proxy +plugin_http_user = abc +plugin_http_passwd = abc + +[plugin_socks5] +type = tcp +remote_port = 6005 +plugin = socks5 +plugin_user = abc +plugin_passwd = abc + +[plugin_static_file] +type = tcp +remote_port = 6006 +plugin = static_file +plugin_local_path = /var/www/blog +plugin_strip_prefix = static +plugin_http_user = abc +plugin_http_passwd = abc + +[plugin_https2http] +type = https +custom_domains = test.yourdomain.com +plugin = https2http +plugin_local_addr = 127.0.0.1:80 +plugin_crt_path = ./server.crt +plugin_key_path = ./server.key +plugin_host_header_rewrite = 127.0.0.1 +plugin_header_X-From-Where = frp + +[plugin_https2https] +type = https +custom_domains = test.yourdomain.com +plugin = https2https +plugin_local_addr = 127.0.0.1:443 +plugin_crt_path = ./server.crt +plugin_key_path = ./server.key +plugin_host_header_rewrite = 127.0.0.1 +plugin_header_X-From-Where = frp + +[plugin_http2https] +type = http +custom_domains = test.yourdomain.com +plugin = http2https +plugin_local_addr = 127.0.0.1:443 +plugin_host_header_rewrite = 127.0.0.1 +plugin_header_X-From-Where = frp + +[secret_tcp] +# If the type is secret tcp, remote_port is useless +# Who want to connect local port should deploy another frpc with stcp proxy and role is visitor +type = stcp +# sk used for authentication for visitors +sk = abcdefg +local_ip = 127.0.0.1 +local_port = 22 +use_encryption = false +use_compression = false + +# user of frpc should be same in both stcp server and stcp visitor +[secret_tcp_visitor] +# frpc role visitor -> frps -> frpc role server +role = visitor +type = stcp +# the server name you want to visitor +server_name = secret_tcp +sk = abcdefg +# connect this address to visitor stcp server +bind_addr = 127.0.0.1 +bind_port = 9000 +use_encryption = false +use_compression = false + +[p2p_tcp] +type = xtcp +sk = abcdefg +local_ip = 127.0.0.1 +local_port = 22 +use_encryption = false +use_compression = false + +[p2p_tcp_visitor] +role = visitor +type = xtcp +server_name = p2p_tcp +sk = abcdefg +bind_addr = 127.0.0.1 +bind_port = 9001 +use_encryption = false +use_compression = false + +[tcpmuxhttpconnect] +type = tcpmux +multiplexer = httpconnect +local_ip = 127.0.0.1 +local_port = 10701 +custom_domains = tunnel1 +# route_by_http_user = user1 diff --git a/apps/frps/0.51.2/data/frps.ini b/apps/frps/0.51.2/data/frps.ini new file mode 100644 index 000000000..229567a9d --- /dev/null +++ b/apps/frps/0.51.2/data/frps.ini @@ -0,0 +1,2 @@ +[common] +bind_port = 7000 diff --git a/apps/frps/0.51.2/data/frps_full.ini b/apps/frps/0.51.2/data/frps_full.ini new file mode 100644 index 000000000..2d5e08e17 --- /dev/null +++ b/apps/frps/0.51.2/data/frps_full.ini @@ -0,0 +1,168 @@ +# [common] is integral section +[common] +# A literal address or host name for IPv6 must be enclosed +# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80" +# For single "bind_addr" field, no need square brackets, like "bind_addr = ::". +bind_addr = 0.0.0.0 +bind_port = 7000 + +# udp port to help make udp hole to penetrate nat +bind_udp_port = 7001 + +# udp port used for kcp protocol, it can be same with 'bind_port'. +# if not set, kcp is disabled in frps. +kcp_bind_port = 7000 + +# udp port used for quic protocol. +# if not set, quic is disabled in frps. +# quic_bind_port = 7002 +# quic protocol options +# quic_keepalive_period = 10 +# quic_max_idle_timeout = 30 +# quic_max_incoming_streams = 100000 + +# specify which address proxy will listen for, default value is same with bind_addr +# proxy_bind_addr = 127.0.0.1 + +# if you want to support virtual host, you must set the http port for listening (optional) +# Note: http port and https port can be same with bind_port +vhost_http_port = 80 +vhost_https_port = 443 + +# response header timeout(seconds) for vhost http server, default is 60s +# vhost_http_timeout = 60 + +# tcpmux_httpconnect_port specifies the port that the server listens for TCP +# HTTP CONNECT requests. If the value is 0, the server will not multiplex TCP +# requests on one single port. If it's not - it will listen on this value for +# HTTP CONNECT requests. By default, this value is 0. +# tcpmux_httpconnect_port = 1337 + +# If tcpmux_passthrough is true, frps won't do any update on traffic. +# tcpmux_passthrough = false + +# set dashboard_addr and dashboard_port to view dashboard of frps +# dashboard_addr's default value is same with bind_addr +# dashboard is available only if dashboard_port is set +dashboard_addr = 0.0.0.0 +dashboard_port = 7500 + +# dashboard user and passwd for basic auth protect +dashboard_user = admin +dashboard_pwd = admin + +# dashboard TLS mode +dashboard_tls_mode = false +# dashboard_tls_cert_file = server.crt +# dashboard_tls_key_file = server.key + +# enable_prometheus will export prometheus metrics on {dashboard_addr}:{dashboard_port} in /metrics api. +enable_prometheus = true + +# dashboard assets directory(only for debug mode) +# assets_dir = ./static + +# console or real logFile path like ./frps.log +log_file = ./frps.log + +# trace, debug, info, warn, error +log_level = info + +log_max_days = 3 + +# disable log colors when log_file is console, default is false +disable_log_color = false + +# DetailedErrorsToClient defines whether to send the specific error (with debug info) to frpc. By default, this value is true. +detailed_errors_to_client = true + +# authentication_method specifies what authentication method to use authenticate frpc with frps. +# If "token" is specified - token will be read into login message. +# If "oidc" is specified - OIDC (Open ID Connect) token will be issued using OIDC settings. By default, this value is "token". +authentication_method = token + +# authenticate_heartbeats specifies whether to include authentication token in heartbeats sent to frps. By default, this value is false. +authenticate_heartbeats = false + +# AuthenticateNewWorkConns specifies whether to include authentication token in new work connections sent to frps. By default, this value is false. +authenticate_new_work_conns = false + +# auth token +token = 12345678 + +# oidc_issuer specifies the issuer to verify OIDC tokens with. +# By default, this value is "". +oidc_issuer = + +# oidc_audience specifies the audience OIDC tokens should contain when validated. +# By default, this value is "". +oidc_audience = + +# oidc_skip_expiry_check specifies whether to skip checking if the OIDC token is expired. +# By default, this value is false. +oidc_skip_expiry_check = false + +# oidc_skip_issuer_check specifies whether to skip checking if the OIDC token's issuer claim matches the issuer specified in OidcIssuer. +# By default, this value is false. +oidc_skip_issuer_check = false + +# heartbeat configure, it's not recommended to modify the default value +# the default value of heartbeat_timeout is 90. Set negative value to disable it. +# heartbeat_timeout = 90 + +# user_conn_timeout configure, it's not recommended to modify the default value +# the default value of user_conn_timeout is 10 +# user_conn_timeout = 10 + +# only allow frpc to bind ports you list, if you set nothing, there won't be any limit +allow_ports = 2000-3000,3001,3003,4000-50000 + +# pool_count in each proxy will change to max_pool_count if they exceed the maximum value +max_pool_count = 5 + +# max ports can be used for each client, default value is 0 means no limit +max_ports_per_client = 0 + +# tls_only specifies whether to only accept TLS-encrypted connections. By default, the value is false. +tls_only = false + +# tls_cert_file = server.crt +# tls_key_file = server.key +# tls_trusted_ca_file = ca.crt + +# if subdomain_host is not empty, you can set subdomain when type is http or https in frpc's configure file +# when subdomain is test, the host used by routing is test.frps.com +subdomain_host = frps.com + +# if tcp stream multiplexing is used, default is true +# tcp_mux = true + +# specify keep alive interval for tcp mux. +# only valid if tcp_mux is true. +# tcp_mux_keepalive_interval = 60 + +# tcp_keepalive specifies the interval between keep-alive probes for an active network connection between frpc and frps. +# If negative, keep-alive probes are disabled. +# tcp_keepalive = 7200 + +# custom 404 page for HTTP requests +# custom_404_page = /path/to/404.html + +# specify udp packet size, unit is byte. If not set, the default value is 1500. +# This parameter should be same between client and server. +# It affects the udp and sudp proxy. +udp_packet_size = 1500 + +# Enable golang pprof handlers in dashboard listener. +# Dashboard port must be set first +pprof_enable = false + +[plugin.user-manager] +addr = 127.0.0.1:9000 +path = /handler +ops = Login + +[plugin.port-manager] +addr = 127.0.0.1:9001 +path = /handler +ops = NewProxy diff --git a/apps/frps/0.51.2/docker-compose.yml b/apps/frps/0.51.2/docker-compose.yml new file mode 100644 index 000000000..9c06326d4 --- /dev/null +++ b/apps/frps/0.51.2/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3" +services: + frps: + container_name: ${CONTAINER_NAME} + restart: always + network_mode: "host" + volumes: + - "${CONFIG_FILE_PATH}:/etc/frp/frps.ini" + image: "snowdreamtech/frps:0.51.2" + labels: + createdBy: "Apps" diff --git a/apps/frps/README.md b/apps/frps/README.md new file mode 100644 index 000000000..4aeec4f20 --- /dev/null +++ b/apps/frps/README.md @@ -0,0 +1,1151 @@ +# frp + +[![Build Status](https://circleci.com/gh/fatedier/frp.svg?style=shield)](https://circleci.com/gh/fatedier/frp) +[![GitHub release](https://img.shields.io/github/tag/fatedier/frp.svg?label=release)](https://github.com/fatedier/frp/releases) + +[README](README.md) | [中文文档](README_zh.md) + +

Gold Sponsors

+ +

+ + + +   + + + +

+ + + +## What is frp? + +frp is a fast reverse proxy that allows you to expose a local server located behind a NAT or firewall to the Internet. It currently supports **TCP** and **UDP**, as well as **HTTP** and **HTTPS** protocols, enabling requests to be forwarded to internal services via domain name. + +frp also offers a P2P connect mode. + +## Table of Contents + + + +- [frp](#frp) + - [What is frp?](#what-is-frp) + - [Table of Contents](#table-of-contents) + - [Development Status](#development-status) + - [Architecture](#architecture) + - [Example Usage](#example-usage) + - [Access your computer in a LAN network via SSH](#access-your-computer-in-a-lan-network-via-ssh) + - [Accessing Internal Web Services with Custom Domains in LAN](#accessing-internal-web-services-with-custom-domains-in-lan) + - [Forward DNS query requests](#forward-dns-query-requests) + - [Forward Unix Domain Socket](#forward-unix-domain-socket) + - [Expose a simple HTTP file server](#expose-a-simple-http-file-server) + - [Enable HTTPS for a local HTTP(S) service](#enable-https-for-a-local-https-service) + - [Expose your service privately](#expose-your-service-privately) + - [P2P Mode](#p2p-mode) + - [Features](#features) + - [Configuration Files](#configuration-files) + - [Using Environment Variables](#using-environment-variables) + - [Split Configures Into Different Files](#split-configures-into-different-files) + - [Dashboard](#dashboard) + - [Admin UI](#admin-ui) + - [Monitor](#monitor) + - [Prometheus](#prometheus) + - [Authenticating the Client](#authenticating-the-client) + - [Token Authentication](#token-authentication) + - [OIDC Authentication](#oidc-authentication) + - [Encryption and Compression](#encryption-and-compression) + - [TLS](#tls) + - [Hot-Reloading frpc configuration](#hot-reloading-frpc-configuration) + - [Get proxy status from client](#get-proxy-status-from-client) + - [Only allowing certain ports on the server](#only-allowing-certain-ports-on-the-server) + - [Port Reuse](#port-reuse) + - [Bandwidth Limit](#bandwidth-limit) + - [For Each Proxy](#for-each-proxy) + - [TCP Stream Multiplexing](#tcp-stream-multiplexing) + - [Support KCP Protocol](#support-kcp-protocol) + - [Support QUIC Protocol](#support-quic-protocol) + - [Connection Pooling](#connection-pooling) + - [Load balancing](#load-balancing) + - [Service Health Check](#service-health-check) + - [Rewriting the HTTP Host Header](#rewriting-the-http-host-header) + - [Setting other HTTP Headers](#setting-other-http-headers) + - [Get Real IP](#get-real-ip) + - [HTTP X-Forwarded-For](#http-x-forwarded-for) + - [Proxy Protocol](#proxy-protocol) + - [Require HTTP Basic Auth (Password) for Web Services](#require-http-basic-auth-password-for-web-services) + - [Custom Subdomain Names](#custom-subdomain-names) + - [URL Routing](#url-routing) + - [TCP Port Multiplexing](#tcp-port-multiplexing) + - [Connecting to frps via HTTP PROXY](#connecting-to-frps-via-http-proxy) + - [Range ports mapping](#range-ports-mapping) + - [Client Plugins](#client-plugins) + - [Server Manage Plugins](#server-manage-plugins) + - [Development Plan](#development-plan) + - [Contributing](#contributing) + - [Donation](#donation) + - [GitHub Sponsors](#github-sponsors) + - [PayPal](#paypal) + + + +## Development Status + +frp is currently under development. You can try the latest release version in the `master` branch, or use the `dev` branch to access the version currently in development. + +We are currently working on version 2 and attempting to perform some code refactoring and improvements. However, please note that it will not be compatible with version 1. + +We will transition from version 0 to version 1 at the appropriate time and will only accept bug fixes and improvements, rather than big feature requests. + +## Architecture + +![architecture](https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/architecture.png) + +## Example Usage + +To begin, download the latest program for your operating system and architecture from the [Release](https://github.com/fatedier/frp/releases) page. + +Next, place the `frps` binary and `frps.ini` configuration file on Server A, which has a public IP address. + +Finally, place the `frpc` binary and `frpc.ini` configuration file on Server B, which is located on a LAN that cannot be directly accessed from the public internet. + +### Access your computer in a LAN network via SSH + +1. Modify `frps.ini` on server A by setting the `bind_port` for frp clients to connect to: + + ```ini + # frps.ini + [common] + bind_port = 7000 + ``` + +2. Start `frps` on server A: + + `./frps -c ./frps.ini` + +3. Modify `frpc.ini` on server B and set the `server_addr` field to the public IP address of your frps server: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [ssh] + type = tcp + local_ip = 127.0.0.1 + local_port = 22 + remote_port = 6000 + ``` + +Note that the `local_port` (listened on the client) and `remote_port` (exposed on the server) are used for traffic going in and out of the frp system, while the `server_port` is used for communication between frps and frpc. + +4. Start `frpc` on server B: + + `./frpc -c ./frpc.ini` + +5. To access server B from another machine through server A via SSH (assuming the username is `test`), use the following command: + + `ssh -oPort=6000 test@x.x.x.x` + +### Accessing Internal Web Services with Custom Domains in LAN + +Sometimes we need to expose a local web service behind a NAT network to others for testing purposes with our own domain name. + +Unfortunately, we cannot resolve a domain name to a local IP. However, we can use frp to expose an HTTP(S) service. + +1. Modify `frps.ini` and set the HTTP port for vhost to 8080: + + ```ini + # frps.ini + [common] + bind_port = 7000 + vhost_http_port = 8080 + ``` + +2. Start `frps`: + + `./frps -c ./frps.ini` + +3. Modify `frpc.ini` and set `server_addr` to the IP address of the remote frps server. Specify the `local_port` of your web service: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [web] + type = http + local_port = 80 + custom_domains = www.example.com + ``` + +4. Start `frpc`: + + `./frpc -c ./frpc.ini` + +5. Map the A record of `www.example.com` to either the public IP of the remote frps server or a CNAME record pointing to your original domain. + +6. Visit your local web service using url `http://www.example.com:8080`. + +### Forward DNS query requests + +1. Modify `frps.ini`: + + ```ini + # frps.ini + [common] + bind_port = 7000 + ``` + +2. Start `frps`: + + `./frps -c ./frps.ini` + +3. Modify `frpc.ini` and set `server_addr` to the IP address of the remote frps server. Forward DNS query requests to the Google Public DNS server `8.8.8.8:53`: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [dns] + type = udp + local_ip = 8.8.8.8 + local_port = 53 + remote_port = 6000 + ``` + +4. Start frpc: + + `./frpc -c ./frpc.ini` + +5. Test DNS resolution using the `dig` command: + + `dig @x.x.x.x -p 6000 www.google.com` + +### Forward Unix Domain Socket + +Expose a Unix domain socket (e.g. the Docker daemon socket) as TCP. + +Configure `frps` as above. + +1. Start `frpc` with the following configuration: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [unix_domain_socket] + type = tcp + remote_port = 6000 + plugin = unix_domain_socket + plugin_unix_path = /var/run/docker.sock + ``` + +2. Test the configuration by getting the docker version using `curl`: + + `curl http://x.x.x.x:6000/version` + +### Expose a simple HTTP file server + +Expose a simple HTTP file server to access files stored in the LAN from the public Internet. + +Configure `frps` as described above, then: + +1. Start `frpc` with the following configuration: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [test_static_file] + type = tcp + remote_port = 6000 + plugin = static_file + plugin_local_path = /tmp/files + plugin_strip_prefix = static + plugin_http_user = abc + plugin_http_passwd = abc + ``` + +2. Visit `http://x.x.x.x:6000/static/` from your browser and specify correct username and password to view files in `/tmp/files` on the `frpc` machine. + +### Enable HTTPS for a local HTTP(S) service + +You may substitute `https2https` for the plugin, and point the `plugin_local_addr` to a HTTPS endpoint. + +1. Start `frpc` with the following configuration: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [test_https2http] + type = https + custom_domains = test.example.com + + plugin = https2http + plugin_local_addr = 127.0.0.1:80 + plugin_crt_path = ./server.crt + plugin_key_path = ./server.key + plugin_host_header_rewrite = 127.0.0.1 + plugin_header_X-From-Where = frp + ``` + +2. Visit `https://test.example.com`. + +### Expose your service privately + +To mitigate risks associated with exposing certain services directly to the public network, STCP (Secret TCP) mode requires a preshared key to be used for access to the service from other clients. + +Configure `frps` same as above. + +1. Start `frpc` on machine B with the following config. This example is for exposing the SSH service (port 22), and note the `sk` field for the preshared key, and that the `remote_port` field is removed here: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [secret_ssh] + type = stcp + sk = abcdefg + local_ip = 127.0.0.1 + local_port = 22 + ``` + +2. Start another `frpc` (typically on another machine C) with the following config to access the SSH service with a security key (`sk` field): + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [secret_ssh_visitor] + type = stcp + role = visitor + server_name = secret_ssh + sk = abcdefg + bind_addr = 127.0.0.1 + bind_port = 6000 + ``` + +3. On machine C, connect to SSH on machine B, using this command: + + `ssh -oPort=6000 127.0.0.1` + +### P2P Mode + +**xtcp** is designed to transmit large amounts of data directly between clients. A frps server is still needed, as P2P here only refers to the actual data transmission. + +Note that it may not work with all types of NAT devices. You might want to fallback to stcp if xtcp doesn't work. + +1. In `frps.ini` configure a UDP port for xtcp: + + ```ini + # frps.ini + bind_udp_port = 7001 + ``` + +2. Start `frpc` on machine B, and expose the SSH port. Note that the `remote_port` field is removed: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [p2p_ssh] + type = xtcp + sk = abcdefg + local_ip = 127.0.0.1 + local_port = 22 + ``` + +3. Start another `frpc` (typically on another machine C) with the configuration to connect to SSH using P2P mode: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + server_port = 7000 + + [p2p_ssh_visitor] + type = xtcp + role = visitor + server_name = p2p_ssh + sk = abcdefg + bind_addr = 127.0.0.1 + bind_port = 6000 + ``` + +4. On machine C, connect to SSH on machine B, using this command: + + `ssh -oPort=6000 127.0.0.1` + +## Features + +### Configuration Files + +Read the full example configuration files to find out even more features not described here. + +[Full configuration file for frps (Server)](./conf/frps_full.ini) + +[Full configuration file for frpc (Client)](./conf/frpc_full.ini) + +### Using Environment Variables + +Environment variables can be referenced in the configuration file, using Go's standard format: + +```ini +# frpc.ini +[common] +server_addr = {{ .Envs.FRP_SERVER_ADDR }} +server_port = 7000 + +[ssh] +type = tcp +local_ip = 127.0.0.1 +local_port = 22 +remote_port = {{ .Envs.FRP_SSH_REMOTE_PORT }} +``` + +With the config above, variables can be passed into `frpc` program like this: + +``` +export FRP_SERVER_ADDR="x.x.x.x" +export FRP_SSH_REMOTE_PORT="6000" +./frpc -c ./frpc.ini +``` + +`frpc` will render configuration file template using OS environment variables. Remember to prefix your reference with `.Envs`. + +### Split Configures Into Different Files + +You can split multiple proxy configs into different files and include them in the main file. + +```ini +# frpc.ini +[common] +server_addr = x.x.x.x +server_port = 7000 +includes=./confd/*.ini +``` + +```ini +# ./confd/test.ini +[ssh] +type = tcp +local_ip = 127.0.0.1 +local_port = 22 +remote_port = 6000 +``` + +### Dashboard + +Check frp's status and proxies' statistics information by Dashboard. + +Configure a port for dashboard to enable this feature: + +```ini +[common] +dashboard_port = 7500 +# dashboard's username and password are both optional +dashboard_user = admin +dashboard_pwd = admin +``` + +Then visit `http://[server_addr]:7500` to see the dashboard, with username and password both being `admin`. + +Additionally, you can use HTTPS port by using your domains wildcard or normal SSL certificate: + +```ini +[common] +dashboard_port = 7500 +# dashboard's username and password are both optional +dashboard_user = admin +dashboard_pwd = admin +dashboard_tls_mode = true +dashboard_tls_cert_file = server.crt +dashboard_tls_key_file = server.key +``` + +Then visit `https://[server_addr]:7500` to see the dashboard in secure HTTPS connection, with username and password both being `admin`. + +![dashboard](https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/dashboard.png) + +### Admin UI + +The Admin UI helps you check and manage frpc's configuration. + +Configure an address for admin UI to enable this feature: + +```ini +[common] +admin_addr = 127.0.0.1 +admin_port = 7400 +admin_user = admin +admin_pwd = admin +``` + +Then visit `http://127.0.0.1:7400` to see admin UI, with username and password both being `admin`. + +### Monitor + +When dashboard is enabled, frps will save monitor data in cache. It will be cleared after process restart. + +Prometheus is also supported. + +#### Prometheus + +Enable dashboard first, then configure `enable_prometheus = true` in `frps.ini`. + +`http://{dashboard_addr}/metrics` will provide prometheus monitor data. + +### Authenticating the Client + +There are 2 authentication methods to authenticate frpc with frps. + +You can decide which one to use by configuring `authentication_method` under `[common]` in `frpc.ini` and `frps.ini`. + +Configuring `authenticate_heartbeats = true` under `[common]` will use the configured authentication method to add and validate authentication on every heartbeat between frpc and frps. + +Configuring `authenticate_new_work_conns = true` under `[common]` will do the same for every new work connection between frpc and frps. + +#### Token Authentication + +When specifying `authentication_method = token` under `[common]` in `frpc.ini` and `frps.ini` - token based authentication will be used. + +Make sure to specify the same `token` in the `[common]` section in `frps.ini` and `frpc.ini` for frpc to pass frps validation + +#### OIDC Authentication + +When specifying `authentication_method = oidc` under `[common]` in `frpc.ini` and `frps.ini` - OIDC based authentication will be used. + +OIDC stands for OpenID Connect, and the flow used is called [Client Credentials Grant](https://tools.ietf.org/html/rfc6749#section-4.4). + +To use this authentication type - configure `frpc.ini` and `frps.ini` as follows: + +```ini +# frps.ini +[common] +authentication_method = oidc +oidc_issuer = https://example-oidc-issuer.com/ +oidc_audience = https://oidc-audience.com/.default +``` + +```ini +# frpc.ini +[common] +authentication_method = oidc +oidc_client_id = 98692467-37de-409a-9fac-bb2585826f18 # Replace with OIDC client ID +oidc_client_secret = oidc_secret +oidc_audience = https://oidc-audience.com/.default +oidc_token_endpoint_url = https://example-oidc-endpoint.com/oauth2/v2.0/token +``` + +### Encryption and Compression + +The features are off by default. You can turn on encryption and/or compression: + +```ini +# frpc.ini +[ssh] +type = tcp +local_port = 22 +remote_port = 6000 +use_encryption = true +use_compression = true +``` + +#### TLS + +frp supports the TLS protocol between `frpc` and `frps` since v0.25.0. + +For port multiplexing, frp sends a first byte `0x17` to dial a TLS connection. + +Configure `tls_enable = true` in the `[common]` section to `frpc.ini` to enable this feature. + +To **enforce** `frps` to only accept TLS connections - configure `tls_only = true` in the `[common]` section in `frps.ini`. **This is optional.** + +**`frpc` TLS settings (under the `[common]` section):** +```ini +tls_enable = true +tls_cert_file = certificate.crt +tls_key_file = certificate.key +tls_trusted_ca_file = ca.crt +``` + +**`frps` TLS settings (under the `[common]` section):** +```ini +tls_only = true +tls_enable = true +tls_cert_file = certificate.crt +tls_key_file = certificate.key +tls_trusted_ca_file = ca.crt +``` + +You will need **a root CA cert** and **at least one SSL/TLS certificate**. It **can** be self-signed or regular (such as Let's Encrypt or another SSL/TLS certificate provider). + +If you using `frp` via IP address and not hostname, make sure to set the appropriate IP address in the Subject Alternative Name (SAN) area when generating SSL/TLS Certificates. + +Given an example: + +* Prepare openssl config file. It exists at `/etc/pki/tls/openssl.cnf` in Linux System and `/System/Library/OpenSSL/openssl.cnf` in MacOS, and you can copy it to current path, like `cp /etc/pki/tls/openssl.cnf ./my-openssl.cnf`. If not, you can build it by yourself, like: +``` +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 +``` + +* build ca certificates: +``` +openssl genrsa -out ca.key 2048 +openssl req -x509 -new -nodes -key ca.key -subj "/CN=example.ca.com" -days 5000 -out ca.crt +``` + +* build frps certificates: +``` +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:127.0.0.1,DNS:example.server.com")) \ + -out server.csr + +openssl x509 -req -days 365 -sha256 \ + -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ + -extfile <(printf "subjectAltName=DNS:localhost,IP:127.0.0.1,DNS:example.server.com") \ + -out server.crt +``` + +* build frpc certificates: +``` +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 365 -sha256 \ + -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ + -extfile <(printf "subjectAltName=DNS:client.com,DNS:example.client.com") \ + -out client.crt +``` + +### Hot-Reloading frpc configuration + +The `admin_addr` and `admin_port` fields are required for enabling HTTP API: + +```ini +# frpc.ini +[common] +admin_addr = 127.0.0.1 +admin_port = 7400 +``` + +Then run command `frpc reload -c ./frpc.ini` and wait for about 10 seconds to let `frpc` create or update or remove proxies. + +**Note that parameters in [common] section won't be modified except 'start'.** + +You can run command `frpc verify -c ./frpc.ini` before reloading to check if there are config errors. + +### Get proxy status from client + +Use `frpc status -c ./frpc.ini` to get status of all proxies. The `admin_addr` and `admin_port` fields are required for enabling HTTP API. + +### Only allowing certain ports on the server + +`allow_ports` in `frps.ini` is used to avoid abuse of ports: + +```ini +# frps.ini +[common] +allow_ports = 2000-3000,3001,3003,4000-50000 +``` + +`allow_ports` consists of specific ports or port ranges (lowest port number, dash `-`, highest port number), separated by comma `,`. + +### Port Reuse + +`vhost_http_port` and `vhost_https_port` in frps can use same port with `bind_port`. frps will detect the connection's protocol and handle it correspondingly. + +We would like to try to allow multiple proxies bind a same remote port with different protocols in the future. + +### Bandwidth Limit + +#### For Each Proxy + +```ini +# frpc.ini +[ssh] +type = tcp +local_port = 22 +remote_port = 6000 +bandwidth_limit = 1MB +``` + +Set `bandwidth_limit` in each proxy's configure to enable this feature. Supported units are `MB` and `KB`. + +Set `bandwidth_limit_mode` to `client` or `server` to limit bandwidth on the client or server side. Default is `client`. + +### TCP Stream Multiplexing + +frp supports tcp stream multiplexing since v0.10.0 like HTTP2 Multiplexing, in which case all logic connections to the same frpc are multiplexed into the same TCP connection. + +You can disable this feature by modify `frps.ini` and `frpc.ini`: + +```ini +# frps.ini and frpc.ini, must be same +[common] +tcp_mux = false +``` + +### Support KCP Protocol + +KCP is a fast and reliable protocol that can achieve the transmission effect of a reduction of the average latency by 30% to 40% and reduction of the maximum delay by a factor of three, at the cost of 10% to 20% more bandwidth wasted than TCP. + +KCP mode uses UDP as the underlying transport. Using KCP in frp: + +1. Enable KCP in frps: + + ```ini + # frps.ini + [common] + bind_port = 7000 + # Specify a UDP port for KCP. + kcp_bind_port = 7000 + ``` + + The `kcp_bind_port` number can be the same number as `bind_port`, since `bind_port` field specifies a TCP port. + +2. Configure `frpc.ini` to use KCP to connect to frps: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + # Same as the 'kcp_bind_port' in frps.ini + server_port = 7000 + protocol = kcp + ``` + +### Support QUIC Protocol + +QUIC is a new multiplexed transport built on top of UDP. + +Using QUIC in frp: + +1. Enable QUIC in frps: + + ```ini + # frps.ini + [common] + bind_port = 7000 + # Specify a UDP port for QUIC. + quic_bind_port = 7000 + ``` + + The `quic_bind_port` number can be the same number as `bind_port`, since `bind_port` field specifies a TCP port. + +2. Configure `frpc.ini` to use QUIC to connect to frps: + + ```ini + # frpc.ini + [common] + server_addr = x.x.x.x + # Same as the 'quic_bind_port' in frps.ini + server_port = 7000 + protocol = quic + ``` + +### Connection Pooling + +By default, frps creates a new frpc connection to the backend service upon a user request. With connection pooling, frps keeps a certain number of pre-established connections, reducing the time needed to establish a connection. + +This feature is suitable for a large number of short connections. + +1. Configure the limit of pool count each proxy can use in `frps.ini`: + + ```ini + # frps.ini + [common] + max_pool_count = 5 + ``` + +2. Enable and specify the number of connection pool: + + ```ini + # frpc.ini + [common] + pool_count = 1 + ``` + +### Load balancing + +Load balancing is supported by `group`. + +This feature is only available for types `tcp`, `http`, `tcpmux` now. + +```ini +# frpc.ini +[test1] +type = tcp +local_port = 8080 +remote_port = 80 +group = web +group_key = 123 + +[test2] +type = tcp +local_port = 8081 +remote_port = 80 +group = web +group_key = 123 +``` + +`group_key` is used for authentication. + +Connections to port 80 will be dispatched to proxies in the same group randomly. + +For type `tcp`, `remote_port` in the same group should be the same. + +For type `http`, `custom_domains`, `subdomain`, `locations` should be the same. + +### Service Health Check + +Health check feature can help you achieve high availability with load balancing. + +Add `health_check_type = tcp` or `health_check_type = http` to enable health check. + +With health check type **tcp**, the service port will be pinged (TCPing): + +```ini +# frpc.ini +[test1] +type = tcp +local_port = 22 +remote_port = 6000 +# Enable TCP health check +health_check_type = tcp +# TCPing timeout seconds +health_check_timeout_s = 3 +# If health check failed 3 times in a row, the proxy will be removed from frps +health_check_max_failed = 3 +# A health check every 10 seconds +health_check_interval_s = 10 +``` + +With health check type **http**, an HTTP request will be sent to the service and an HTTP 2xx OK response is expected: + +```ini +# frpc.ini +[web] +type = http +local_ip = 127.0.0.1 +local_port = 80 +custom_domains = test.example.com +# Enable HTTP health check +health_check_type = http +# frpc will send a GET request to '/status' +# and expect an HTTP 2xx OK response +health_check_url = /status +health_check_timeout_s = 3 +health_check_max_failed = 3 +health_check_interval_s = 10 +``` + +### Rewriting the HTTP Host Header + +By default frp does not modify the tunneled HTTP requests at all as it's a byte-for-byte copy. + +However, speaking of web servers and HTTP requests, your web server might rely on the `Host` HTTP header to determine the website to be accessed. frp can rewrite the `Host` header when forwarding the HTTP requests, with the `host_header_rewrite` field: + +```ini +# frpc.ini +[web] +type = http +local_port = 80 +custom_domains = test.example.com +host_header_rewrite = dev.example.com +``` + +The HTTP request will have the `Host` header rewritten to `Host: dev.example.com` when it reaches the actual web server, although the request from the browser probably has `Host: test.example.com`. + +### Setting other HTTP Headers + +Similar to `Host`, You can override other HTTP request headers with proxy type `http`. + +```ini +# frpc.ini +[web] +type = http +local_port = 80 +custom_domains = test.example.com +host_header_rewrite = dev.example.com +header_X-From-Where = frp +``` + +Note that parameter(s) prefixed with `header_` will be added to HTTP request headers. + +In this example, it will set header `X-From-Where: frp` in the HTTP request. + +### Get Real IP + +#### HTTP X-Forwarded-For + +This feature is for http proxy only. + +You can get user's real IP from HTTP request headers `X-Forwarded-For`. + +#### Proxy Protocol + +frp supports Proxy Protocol to send user's real IP to local services. It support all types except UDP. + +Here is an example for https service: + +```ini +# frpc.ini +[web] +type = https +local_port = 443 +custom_domains = test.example.com + +# now v1 and v2 are supported +proxy_protocol_version = v2 +``` + +You can enable Proxy Protocol support in nginx to expose user's real IP in HTTP header `X-Real-IP`, and then read `X-Real-IP` header in your web service for the real IP. + +### Require HTTP Basic Auth (Password) for Web Services + +Anyone who can guess your tunnel URL can access your local web server unless you protect it with a password. + +This enforces HTTP Basic Auth on all requests with the username and password specified in frpc's configure file. + +It can only be enabled when proxy type is http. + +```ini +# frpc.ini +[web] +type = http +local_port = 80 +custom_domains = test.example.com +http_user = abc +http_pwd = abc +``` + +Visit `http://test.example.com` in the browser and now you are prompted to enter the username and password. + +### Custom Subdomain Names + +It is convenient to use `subdomain` configure for http and https types when many people share one frps server. + +```ini +# frps.ini +subdomain_host = frps.com +``` + +Resolve `*.frps.com` to the frps server's IP. This is usually called a Wildcard DNS record. + +```ini +# frpc.ini +[web] +type = http +local_port = 80 +subdomain = test +``` + +Now you can visit your web service on `test.frps.com`. + +Note that if `subdomain_host` is not empty, `custom_domains` should not be the subdomain of `subdomain_host`. + +### URL Routing + +frp supports forwarding HTTP requests to different backend web services by url routing. + +`locations` specifies the prefix of URL used for routing. frps first searches for the most specific prefix location given by literal strings regardless of the listed order. + +```ini +# frpc.ini +[web01] +type = http +local_port = 80 +custom_domains = web.example.com +locations = / + +[web02] +type = http +local_port = 81 +custom_domains = web.example.com +locations = /news,/about +``` + +HTTP requests with URL prefix `/news` or `/about` will be forwarded to **web02** and other requests to **web01**. + +### TCP Port Multiplexing + +frp supports receiving TCP sockets directed to different proxies on a single port on frps, similar to `vhost_http_port` and `vhost_https_port`. + +The only supported TCP port multiplexing method available at the moment is `httpconnect` - HTTP CONNECT tunnel. + +When setting `tcpmux_httpconnect_port` to anything other than 0 in frps under `[common]`, frps will listen on this port for HTTP CONNECT requests. + +The host of the HTTP CONNECT request will be used to match the proxy in frps. Proxy hosts can be configured in frpc by configuring `custom_domain` and / or `subdomain` under `type = tcpmux` proxies, when `multiplexer = httpconnect`. + +For example: + +```ini +# frps.ini +[common] +bind_port = 7000 +tcpmux_httpconnect_port = 1337 +``` + +```ini +# frpc.ini +[common] +server_addr = x.x.x.x +server_port = 7000 + +[proxy1] +type = tcpmux +multiplexer = httpconnect +custom_domains = test1 +local_port = 80 + +[proxy2] +type = tcpmux +multiplexer = httpconnect +custom_domains = test2 +local_port = 8080 +``` + +In the above configuration - frps can be contacted on port 1337 with a HTTP CONNECT header such as: + +``` +CONNECT test1 HTTP/1.1\r\n\r\n +``` +and the connection will be routed to `proxy1`. + +### Connecting to frps via HTTP PROXY + +frpc can connect to frps using HTTP proxy if you set OS environment variable `HTTP_PROXY`, or if `http_proxy` is set in frpc.ini file. + +It only works when protocol is tcp. + +```ini +# frpc.ini +[common] +server_addr = x.x.x.x +server_port = 7000 +http_proxy = http://user:pwd@192.168.1.128:8080 +``` + +### Range ports mapping + +Proxy with names that start with `range:` will support mapping range ports. + +```ini +# frpc.ini +[range:test_tcp] +type = tcp +local_ip = 127.0.0.1 +local_port = 6000-6006,6007 +remote_port = 6000-6006,6007 +``` + +frpc will generate 8 proxies like `test_tcp_0`, `test_tcp_1`, ..., `test_tcp_7`. + +### Client Plugins + +frpc only forwards requests to local TCP or UDP ports by default. + +Plugins are used for providing rich features. There are built-in plugins such as `unix_domain_socket`, `http_proxy`, `socks5`, `static_file`, `http2https`, `https2http`, `https2https` and you can see [example usage](#example-usage). + +Specify which plugin to use with the `plugin` parameter. Configuration parameters of plugin should be started with `plugin_`. `local_ip` and `local_port` are not used for plugin. + +Using plugin **http_proxy**: + +```ini +# frpc.ini +[http_proxy] +type = tcp +remote_port = 6000 +plugin = http_proxy +plugin_http_user = abc +plugin_http_passwd = abc +``` + +`plugin_http_user` and `plugin_http_passwd` are configuration parameters used in `http_proxy` plugin. + +### Server Manage Plugins + +Read the [document](/doc/server_plugin.md). + +Find more plugins in [gofrp/plugin](https://github.com/gofrp/plugin). + +## Development Plan + +* Log HTTP request information in frps. + +## Contributing + +Interested in getting involved? We would like to help you! + +* Take a look at our [issues list](https://github.com/fatedier/frp/issues) and consider sending a Pull Request to **dev branch**. +* If you want to add a new feature, please create an issue first to describe the new feature, as well as the implementation approach. Once a proposal is accepted, create an implementation of the new features and submit it as a pull request. +* Sorry for my poor English. Improvements for this document are welcome, even some typo fixes. +* If you have great ideas, send an email to fatedier@gmail.com. + +**Note: We prefer you to give your advise in [issues](https://github.com/fatedier/frp/issues), so others with a same question can search it quickly and we don't need to answer them repeatedly.** + +## Donation + +If frp helps you a lot, you can support us by: + +### GitHub Sponsors + +Support us by [Github Sponsors](https://github.com/sponsors/fatedier). + +You can have your company's logo placed on README file of this project. + +### PayPal + +Donate money by [PayPal](https://www.paypal.me/fatedier) to my account **fatedier@gmail.com**. + diff --git a/apps/frps/data.yml b/apps/frps/data.yml new file mode 100644 index 000000000..74c6e0729 --- /dev/null +++ b/apps/frps/data.yml @@ -0,0 +1,20 @@ +name: frps-frp服务端 +tags: + - 工具 +title: frp是一种反向代理工具,常用于内网穿透(服务端) +type: 工具 +description: frp是一种反向代理工具,常用于内网穿透(服务端) +additionalProperties: + key: frps + name: frps-frp服务端 + tags: + - Tool + shortDescZh: frp是一种反向代理工具,常用于内网穿透(服务端) + shortDescEn: frp is a reverse proxy tool that is commonly used for intranet penetration(Server) + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/fatedier/frp + github: https://github.com/fatedier/frp + document: https://github.com/fatedier/frp/blob/dev/README_zh.md diff --git a/apps/frps/logo.png b/apps/frps/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..023fe72df4c2c99878a8f9c803ecbe3f1e4204cf GIT binary patch literal 26073 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 literal 0 KcmV+b0RR6000031 diff --git a/apps/hexo/README.md b/apps/hexo/README.md new file mode 100644 index 000000000..6ed5f7bce --- /dev/null +++ b/apps/hexo/README.md @@ -0,0 +1,102 @@ +Hexo logo + +# Hexo + +> A fast, simple & powerful blog framework, powered by [Node.js](https://nodejs.org). + +[Website](https://hexo.io) | +[Documentation](https://hexo.io/docs/) | +[Installation Guide](https://hexo.io/docs/#Installation) | +[Contribution Guide](https://hexo.io/docs/contributing) | +[Code of Conduct](CODE_OF_CONDUCT.md) | +[API](https://hexo.io/api/) | +[Twitter](https://twitter.com/hexojs) + +[![NPM version](https://badge.fury.io/js/hexo.svg)](https://www.npmjs.com/package/hexo) +![Required Node version](https://img.shields.io/node/v/hexo) +[![Build Status](https://github.com/hexojs/hexo/workflows/Tester/badge.svg)](https://github.com/hexojs/hexo/actions?query=workflow%3ATester) +[![dependencies Status](https://img.shields.io/librariesio/release/npm/hexo)](https://libraries.io/npm/hexo) +[![Coverage Status](https://coveralls.io/repos/hexojs/hexo/badge.svg?branch=master)](https://coveralls.io/r/hexojs/hexo?branch=master) +[![Gitter](https://badges.gitter.im/hexojs/hexo.svg)](https://gitter.im/hexojs/hexo) +[![Discord Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/teM2Anj) +[![Telegram Chat](https://img.shields.io/badge/chat-on%20telegram-32afed.svg)](https://t.me/hexojs) +[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fhexojs%2Fhexo.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fhexojs%2Fhexo?ref=badge_shield) +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md) + +## Features + +- Blazing fast generating +- Support for GitHub Flavored Markdown and most Octopress plugins +- One-command deploy to GitHub Pages, Heroku, etc. +- Powerful API for limitless extensibility +- Hundreds of [themes](https://hexo.io/themes/) & [plugins](https://hexo.io/plugins/) + +## Quick Start + +**Install Hexo** + +``` bash +$ npm install hexo-cli -g +``` + +Install with [brew](https://brew.sh/) on macOS and Linux: + +```bash +$ brew install hexo +``` + +**Setup your blog** + +``` bash +$ hexo init blog +$ cd blog +``` + +**Start the server** + +``` bash +$ hexo server +``` + +**Create a new post** + +``` bash +$ hexo new "Hello Hexo" +``` + +**Generate static files** + +``` bash +$ hexo generate +``` + +## More Information + +- Read the [documentation](https://hexo.io/) +- Visit the [Awesome Hexo](https://github.com/hexojs/awesome-hexo) list +- Find solutions in [troubleshooting](https://hexo.io/docs/troubleshooting.html) +- Join discussion on [Google Group](https://groups.google.com/group/hexo), [Discord](https://discord.gg/teM2Anj), [Gitter](https://gitter.im/hexojs/hexo) or [Telegram](https://t.me/hexojs) +- See the [plugin list](https://hexo.io/plugins/) and the [theme list](https://hexo.io/themes/) on wiki +- Follow [@hexojs](https://twitter.com/hexojs) for latest news + +## Contributing + +We welcome you to join the development of Hexo. Please see [contributing document](https://hexo.io/docs/contributing). 🤗 + +Also, we welcome PR or issue to [official-plugins](https://github.com/hexojs). + +## Contributors + +[![](https://opencollective.com/Hexo/contributors.svg?width=890)](https://github.com/hexojs/hexo/graphs/contributors) + +## Backers + +[![Backers](https://opencollective.com/hexo/tiers/backers.svg?avatarHeight=36&width=600)](https://opencollective.com/hexo) + +## Sponsors + +RSS3 + +## License + +[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fhexojs%2Fhexo.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fhexojs%2Fhexo?ref=badge_large) diff --git a/apps/hexo/data.yml b/apps/hexo/data.yml new file mode 100644 index 000000000..3f5453e93 --- /dev/null +++ b/apps/hexo/data.yml @@ -0,0 +1,20 @@ +name: Hexo +tags: + - 建站 +title: 快速、简洁且高效的博客框架 +type: 建站 +description: 快速、简洁且高效的博客框架 +additionalProperties: + key: hexo + name: Hexo + tags: + - WebSite + shortDescZh: 快速、简洁且高效的博客框架 + shortDescEn: A fast, simple & powerful blog framework + type: website + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://hexo.io/ + github: https://github.com/hexojs/hexo + document: https://hexo.io/docs/ diff --git a/apps/hexo/logo.png b/apps/hexo/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..cc61dcece468136523efd9e52113ea26b9a04b1c GIT binary patch literal 5336 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, () +``` + +Please read the [Code of Conduct](https://nextcloud.com/community/code-of-conduct/). This document offers some guidance to ensure Nextcloud participants can cooperate effectively in a positive and inspiring atmosphere, and to explain how together we can strengthen and support each other. + +Please review the [guidelines for contributing](.github/CONTRIBUTING.md) to this repository. + +More information how to contribute: [https://nextcloud.com/contribute/](https://nextcloud.com/contribute/) diff --git a/apps/nextcloud/data.yml b/apps/nextcloud/data.yml new file mode 100644 index 000000000..3a2b9067c --- /dev/null +++ b/apps/nextcloud/data.yml @@ -0,0 +1,20 @@ +name: Nextcloud +tags: + - 建站 +title: Nextcloud服务器,所有数据的安全家园 +type: 建站 +description: Nextcloud服务器,所有数据的安全家园 +additionalProperties: + key: nextcloud + name: Nextcloud + tags: + - WebSite + shortDescZh: Nextcloud服务器,所有数据的安全家园 + shortDescEn: Nextcloud server, a safe home for all your data + type: website + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://nextcloud.com/ + github: https://github.com/nextcloud/server + document: https://docs.nextcloud.com/ diff --git a/apps/nextcloud/logo.png b/apps/nextcloud/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8d8168842f4b502026b7039058688079358c0fb0 GIT binary patch literal 8999 zcmV+?BiP)DP)2A|zG&{dP(uS6%ZPM>IY5V2# zd^~(S1d{LflYC$KjQ6DQ!7&#I1dc!t_5cV3HX(v0a0()50;eE?CU6QOXac7of+lbZ zB4`4qAc7`v3L&0gOpE0A*4Z56!caH%nlb?tqxQfttiu5QL49~ z)#@1Rp>qZzXa*$7g_x^RAXhEJWVH<0VG_`k|JSK7SaG=Ch@%Zg?5Nh`M576$X!pRN zNWpXe7#%Lb&1vCSoDhmp;gW#dLu;~OLq#jTDQUs>>NYsZ6Y?1%XdjU9X)H?%$K6>f z&sy?436ijU4U;=^-|s5RMwdhg)~5p*Af2xvSoQjN#QL_sAU+})Yk;lxMhn(*4s zwWu&y2X!n%86s#e@M#M7W=G=raWRM(WFcRS&FR9szt-c$<2B?k=>;O_i?}>G1n*8y zz?cB-kJ+NW-HtyVuEJ-9P2>RC1tRDUL_7+w=4$Zh=%~RSieGG~XvOl~WvFkr5B5-o z1VqpPMuti7WqvY75Aj*KHyX@#+_tk6n=0D|dnkj>CGRO*oEVBj*JKS_F#|xPn2!zf z)A2-3^k5HV(7B`q{X|YQ*3C;ph+z1C4KxL;oTS00c}Wls#Jj^0hX0csAS-e;SUE{E zAkW@V=C>IU_;zmUB`fMnQqU`MHF$C?cbDhIiJ|y*ZYo5)OHb67oSDuZ@EK20G;DnN`>04bja1-F;eU~{6{XhX9lu;xWp-C*${LM%)O zMSiRt)1yNWEfw_p9+TaP6OAV9(CYDHMJo>18w27fm>ny}2bU)X;L5$zZg--=Y=^<- zgx%#rsE`MRfQK*YV_Et)ni|+0Tu^)Pn_`#&8I2cm=cENSt`tmm4oRDSEje(fg2x$t-vs8F`Y&7Bn@XUAD=<&kw z8tl^Q2YihI33_^T2>v-eAt=s>Hmd`FKBmQczc#?(^8dH@z(_UTnHJCbxV|gX;gz3i zakPQ?tkRVjsQ{0SiNgKak&y7&754jQ8gTEviUGZMZkz(|OpQmTQq1a@yzzax4iD|G zMEL-s3jGqafOf|_JU%A)@eX@y4Y+kjsb3#bBNO244I?2Ju(xL|(3$bT{z`1C4y>Cw zF+_-WrX^r;Vkm3ZbOD(DT>%c%8GL?^j8Ef@DRKDyh)CAP;S23{CmuUgh4=m3`}-{D z7^whj=A~kCkOSPi(rmHg`mH6{;p39DdTuI~CM#LH|9ihS;PFG1tR7nT5 z$XJ@K&$O74v-%9|KA4tL6e6sfmpZ6n0bdulVEOJcnC!l7=Y0B>(i9@>zdCbJ#S8%9 zB0e@>nT}i1!ux&glqeZ%Vs5uPapSfUJg~nasA2|y|DJEggf(YT)MjDjdf8!O+@2B9 z@9QS1WjH(pVq9)a4a1H_89pai^egC$P%#c(lZ9lti1FaqfKOBS@9bnO&s6pKx>s{G ztlY2F>cG5>=kdRi7FMn|5YFk$n7Zy9jyJMnrFd>!OrQJnY0)9r?uUp1%_Ox9yBB97 z(ueW%DQJyMfGrEths+1-%7-%&d!2#vHFC_1ku$!B!RExA4TacO>-(NFP&AnB$X{Q` zis>yrM2NexyiW+@R8nl5pT^o2hb^+h#Q5>b^nTAny^dPMqww7oX#p|Gu>nm1pUp}} zPDIZo@evk+^leTTmToP^u?BW#MK)-)Ixv4@5lZ#Uw;vCWQulC+$4CYE{)#jxgu!$C z_``UW6kp{h_v!2CRnTutj>mYFGyub54=JC<>ba@i!aq|KA}mZ`ZW;K~k!ozM8hQcq zb?r7R-BQAMFMsj(#G@#DnV$@eEO5>zHn=h&w9i-^uY$fJPJ#PJ2G>k8P*N2l{C&y= zJM%pwA{l!tH&nFZ%~N#@uM#*;Hkt6~LFVxp_hw&s#!rroVr82a3|^iXiwTk5C)*x^ z7V~JlH$5TXgJP4rvQ(HB9Rdo#O{rmwu4S+}@%z2yLq75J{WA^N&v0))FV5|9&j=Oc zxpA>9jV$o+C<^~KJ<)3W8;5>D7Z-s0 z_EikXd)f()qOdeM3~x+{8+NhN6C$Pfofk`2H^)kdfJWKPqXSlp!enr%oXU?~cnX)TR6f2kir`$I7uREgX|ra?mA)2yshVIQ~=E z!BWK6T@$U2lj9?+q>0q4^Q@=as`Lky&xJ)HwMa&y2S}}I@ zS)arV098gSmhC9T^4(>y4Pu$i_2sR@Qp^DG+4<%{ySK&R!cE&taL2APpTrCRJG6R? zUvm~;7c=+1PKlBsJ@mqv&m-uiNlL~SUtiIRt2Y-9DCYK)f+j56Q95YWg|CYTPZUg9 zQ`#~pC3o#k7p~b-G$3KN+nrdpqlA@^f~Cn9EL$Ey&tkY_m9$x~Yl%wRfcmqGox|L)m%v4paHkXjp;`H z!2^|yvLQNo;dl)ygIq55Op6%}=HXo%F4#ZFb2>9#XTkZ@Zg=AT0VW-EGBrx(F)Yx4 zJED$BUfA(Q6E^y|XYP-7yOWhK${$WO51n|8fpWT;*(~QTD^Aw>6jSXBJG6QntQ+_W zBjMAYeKZXKnM!7kl&)qIHu$QzIjDQ-!d7--jR%v0*5C=+=5(9q*yQsfW*W*2bz4km z0Em|{vqf%aIUT9K-HuIe?|OYR`oyLXc}-raBnc(G9}5o%+PWM;esvz z=L0aqond%T@CP>b{)3Gnh@YW^rRU>X}Rq#6yK(eqVu#$6-TDG{EfFE#}by zsrr);#7r3`E7VXSgvC+~{lWCiN(vsu?ux)vL!BMLXaFcoFbx1_8Cn!>N)2Z9oTJiw8%kS-X}> z%x4^J*=dLGn4ztVtO`;-jaMeJQwJk2R*tI@m8@LLS0<`u!~S46Jvt<)_gj<@%Gxab z^2At1NdWD3r^j?m1AxQj!mb)-hV8pYsIY|LvJolfV^v-fqiYNV8J`~Xs!&XzDPYDR zB)EQ>m&ADQeoc~+aoxNFbw-cr*z>d4Ud=qX<@4Fe11?(|DduDA!i<2X1NFs~ER;SN zET%+-1ht5ICvh?%HeZ?UQ$-_h%#Bmvi`mJH$Fa4Gr`jXvZ%UZQ)Jpg?HqKAO6FJd- zE#Wg_LU3&92(LwBg2gRq;ls8c$!+QV*QyH?VB!mbtJ2o&y z(E~|{fW{3BOE)kjNiM|Rt1|IbehQ{{l#}pAh=9gz84);jT{c!u(y(%FIap`x7JAVw zr|_yoCBC~NmGMowVsW@|w84n8Ix|dmCwP=QkYuu2HsosN?a=CxzrJv=hv65Gjfuh= zlj8<^7~QCAx8X>=3FQV094_}6B}*yB#7G(Ip5@zjmGzz^O941>?FfvG7}_Pkyx{`y zNkL=3RZ06}nx6&12NNluM)6Ifd}_|r8&yUt;sW6L3kKfG750W!3I7|vRMm!NiygnVv}5HUB_|IA zhs%X~_mz9K%6S!ZahnDA>@5%UxLD!)a$UE^GM^SSF^&xu^JsjPpE6{l@ZO#l&x(oj zozwN6|9|m#4Qm|&0?o5WwY}Eu?$rqR-}BA**V&#^`cR@kXU1=LmUa6(z0JW&j$?M1 z80+Sx1~tyu7ydjhrq}BG{&1$n+^zn#&FR8*TZ@N$_WQ<)R;)bP`)bmsRr|hu6+Tx$ z3O2PS8y0OUg3e0}%3HtGv9c%3iYYkYswHVeRc1S$aV#b1v=lf05>UZif*_~Lh z@jSjA#4b=>DK}U#W!*Xa(oa_SODAezcCa(kbh_pT!#*D-;$h9aR6IK_hP7)xb5z^s z3bv`T4f8ji4{Ba#UmUJCV&)G8K5d71SbX;j{k_QH0@jr3;DS4$uSh}^?labONe)sy$*U0f{UQ$rKOLnIV&mY%f<;gm~YUhb~ z6i!~7&3XX;uPyC({9skU91>{?5nj#J;JOrcV>B!d7sjqW<5w-YP$3WROpC{@K@NZl zcx&XY$OSw+H$DcBj#jgtTXr!!w0bGDtCofNo#WR<&w+FqLW{VyFD{jH2sy6J>>U~}wg*1g+wG8<<4&_(3w%#YDSC20fWs6yUPU` zpN3M%Ly}yCOr;3fVUnP9Y;7>xF>du)R2kVR7bc)7T$>z*JF`@n6)R^H`=YZt@O5!B zJ}zj&k$UDOfmsoBSK>p2$d8p{dUOb~!z9R3ioIr2SR5{t8!Y&xxgEzFOxUi~<9LIK zQGMyYh?NR(WXXsj-&m4u>`oUJ{8)r-EY~0GL@nWCUYr86V&#|+DMPlh?@G2!W;@R4 z%-B<-$4;#t`)Uo0n}~LWbwPVWNK=ptd5{ZeI9%>BU%oEOY?2cp!JfsLL$>vAAXvV; z44)LRTOGD9_%wwWsQ@ujfhW1c;&8%XbE4X4L$f8Yp2(mGdMGh3PJ#9F(^%j04@F)$ zu4N^pb~rIKe7ZqoOH~`L8N%*ews`qO%_S#h;1U!x;0|zEw5f=*qJHW~HU4}|JJ`b* z6fQ|Y18)2Fj2{YoZbdd6usL1$-R^R%=p!19>s+#e2HaT>6V{v^HgUjxQQvOIto4QX zn5Ces;mRc~XaLZfY?%IC0p9whzW)~wQMOm>F>cKn?5`aj$-RN(k{2`pm>o_$dax4n zHl9bd4}niZ1&hOlM-NtF?uNo)HSR!i$(il?qccwB;Zf=#ZQA>xycLfetPDuMli>^z zbT4En#aNN6VO+PEZB90s@YIoNR$^SZ2oZEYj1HIJnag5ueM;D%*6TQ2Z^SD<)nI*j z>!9^R9}W;f`$&9<5O-um;CET7pw;2i+Z_0^s0AOMYv?u0na~{~Xg{GTclp}I387e= zs6=)cyCI)-?KW(vXvGiZt=Ll41`|h}KY@Y>njx`L0Vb(s$W_ZQUL{3}LWG16p-%_O zYNHKhdJ9f9x8q2?5r^xIC}=eYCB2KQ5J3k3ngXIF0;t4%i21Z9>dfYJ!Dw@$&E`P0 z(aLJrB*D$ls%Og)oG!P+M#~|$`f!0bRtTJe2%5kth@c6af(V+xDTts6oPr3Nz$u8J z37momn!qWDpb4CU2%5ktSQYeJQ{(Z)>|}(CeD|p5s%1F7bOhdW7w(R-3hC)9CtAGc`(vaVlxR%kmB< z1T=-e=4xPfx*+)XiNPLDK)6gL#UFE`uskyYs#QO;cHMw%Id0F0z#I+tW|!MDBJiiN z(U1hVVrXX!G#ky`hbqpFqMU4h#(+JUf6YkngiUgVPx6xRYOV&E0j%RpU`9X`XLq`g zEEloXf{Z}$m4FEPZ>Q?ubODcyR%1eB@H~fZ!yx41dklU{wD><`}Le;wA=!={Cj0_X^5cI9-5%|}P1kVFK*<`{`jqR{HoyZIoV@8Y|6C$NpH7f~^ zj#gvbnzMd=Cjy$nJJaIv`w@`<+~<~EH3k&w%#iSDj8jQ5I$VN>MyYXoMg(r(Rfe@? zx*pdN^C(aNBE`P7>ga4Q(wn7cSz0(g$xDKereL%?@m-k?)g~J>QUT`1Dez@}GA2e! zQOQ!jmx~E#PT}UNHhgxz3Ad(4;KLb-nDs-U-$hdH9~p^PCTaix&mYrb#mU-kE!18- zuEig7qOo$41`m!>V^@tHYf5#Ve=pTruxv*uzP}<3IS~^4Z%zspZ7S-~%Oyh0$NKqc zP;@MhPaUc5bxaF472!{`*4-;9 zq$#YPn}QUD2sWn+OScrGwhxhMjW(3&t)Bn74k=D1#0N7H0RXE@TQFzC`5s~h+)1<# z?5{w|m#1<4wh~{y4i9%^syt$T^k60K+Ed;`%z(Su`-~q7@MC2wXbSiwFA?zpDw0D1 z_-JM#Xv+P$Z`o1Wqn}EP#ewU$mSC4wk4Y?c$L&hM1>I=2!Q+Cxb5A*=+2hHv zQIPRzR2r=K?as1(_r?_lt6#-rL_7*FPjs6@R~0t(TL#$TaN(xyrKmO8AQ$lP)YxdB z@8u8k;uOeIieYv*ao@g*URPpA$C)Eg1jY05MNu<;tZYT7kcaoCC;0rnB^`wlKP_zR zR~YAXX3x@nd5rgdg!k^Pz@8fSUiZx@@mQD;iU&ujaaYI6@zRMJtnzZO^c4!gwaM;w z#&7;o4`TqT9_4Ekh>;55bh(?*`$C)5fwxY(g?~dzSU|!I=5@rKd{@?r`u4s%U7c=j z4_J};pw;ELXKw}0+%OVLl9X7Ir1W|~=}KaV(6c;Fi3-76Q~M8I>a14OTkSck(}g8l zigDVgcaPaCZ&xw6stpUq-l`*dB87;Z6ohlnZpK4#|{E?sa zv-f$K{(^-mT+IGsR|wq`gRckNKo#K$YUQMNf33&OY2lcxmf^L@akzU=d9SY(^Dc<; zww+}@n|WL=;AlhNd*EiX9W55SN6_Dtw6M~AUf3~ar|UxS4cl~DXLx=F^>p23n1?_C z$UsF`2362b7jV~}a-3K?0(WJp@cH@P4eZ)34v-p?jZs7Mu84Uw)?JZ`6om*bxc9xU zPmaSc&F$F9@E)CGrYZNfr%ccOEM3)c4}SxsQWYZ4|1+5#dlO=_#l70b`q+9}EeVYD zf*uZcy15;%c331noRQeglhl>-Z5Gd#WFAX_?i7Ge^O7(%Dg;g!uyji?ekgB+fTpl| zZYnaBzKJBXm)6Q%$GjlkzipDQbpGfjsbz@u!(wz*q7s1HTi4ZY-nlSE`6#f?*InG> zvC}R;*++9+?r=5RdE>7?)!?kojPy_u9`0g3>x$j!!iEk{-SW(cUPa{BeRDOqG1YB_ zc~&Jh6wv#2kPK&vuyW?#xnQd1l|vDj`kbi~M9niuq_T+wu2b>bm`VyWQzIbG(|{(<#-JKjcI~ zE^v!=cTM;0*^ia2s4>|f<?lQ>7t7My9X9HP38DBj zFR8~2%cm*)F((SojdQOEKQ)?qnCEOx7oP427x-P43V)vx*JFhW6Y=o*>|`uV2*o*_ ze^we_VYT4-$!oKb6CuHpEyY;ZkDVC+6haREejzpYHh;oA!xogk%YWTk~ zH4I7G>b_jv2MdY{#)i6IPzA?Qx*&I%XH#A+Z}ed+g^$vE4>F>Q2@ToPw{NW+N=(2t!_h=(S|S~5BVAeG#!V%Hmd`d ze_zn69s56dNw_T|0)Trvv$?VjO%^+nLWG#DkwY%vp{UJ*zy4H%k7p*K)#`xq)01AW zH4u1MeD@1%UF_D3aKwiQ@zJ>^l<519tg|>=IMZUr=x`~HG#K$ix%V%8TeTkhYmLZM zijgE2Av;WhIT{5PCWK-}j2!VHLe#a}@bXW!xMyz#>|IP|VjhhEI#CIwhzGfVhtthw?CmluI$Z8vh5Kp^ zNKuH8tPmkHRP1Su5hE2qZ*$XPL@&(5s$|DidI~+xfpT*54WU; z!(?~jwV&&Hy`I0YIzuajJSc^{9?@rPlBpCUFGh}p5Fum&8d{?bhw2U3Uu*0ULDz{| z!iQQS@ERm^F+7UG9E}`1wfa77(`pGH)1yNWEfHXMjRC*5^nUHGW0vqK)R=5I*5F>Y z`wEg5^JvW0$Pp(K;JdO`uK`G%#7G605Gh5hR0yNpfeM2ahw6-e+t;Oh8hNpDj8jPw zF5 + + +## ZFile 是什么? + +ZFile 是一个适用于个人的在线网盘(列目录)程序,可以将你各个存储类型的存储源,统一到一个网页中查看、预览、维护,再也不用去登录各种各样的网页登录后管理文件,现在你只需要在 ZFile 中使用。你只需要填写存储源相关信息,其他的令牌刷新,授权都是尽量自动化的,且有完善的文档帮助你使用。 + +- 支持对接 S3、OneDrive、SharePoint、Google Drive、多吉云、又拍云、本地存储、FTP、SFTP 等存储源 +- 支持在线浏览图片、播放音视频,文本文件、Office、obj(3d)等文件类型。 + +## 快速开始 + +请参考部署文档: [https://docs.zfile.vip](https://docs.zfile.vip) + +## 在线体验 + +[https://demo.zfile.vip](https://demo.zfile.vip) + +## 功能预览 + +### 文件列表 +![文件列表](https://cdn.jun6.net/uPic/2022/08/13/0urMn8.png) +### 画廊模式 +![图片预览](https://cdn.jun6.net/uPic/2022/08/13/d2J9aE.png) +### 视频预览 +![视频预览](https://cdn.jun6.net/uPic/2022/08/13/tBX00R.png) +### 文本预览 +![文本预览](https://cdn.jun6.net/uPic/2022/08/13/7dDy4G.png) +### 音频预览 +![音频预览](https://cdn.jun6.net/uPic/2022/08/13/N5bU1R.png) +### PDF 预览 +![PDF 预览](https://cdn.jun6.net/uPic/2022/08/13/H327bV.png) +### Office 预览 +![Office 预览](https://cdn.jun6.net/uPic/2022/08/27/RxeiqI.png) +### 3d 文件预览 +![3d 文件预览](https://cdn.jun6.net/uPic/2022/08/29/8iszyh.png) +### 生成直链 +![生成直链](https://cdn.jun6.net/uPic/2022/08/13/zCX3xT.jpg) +### 页面设置 +![页面设置](https://cdn.jun6.net/uPic/2022/08/13/54nYv2.png) +### 后台设置-登录 +![后台设置-登录](https://cdn.jun6.net/uPic/2022/08/13/J8P2Zf.png) +### 后台设置-存储源列表 +![后台设置-存储源列表](https://cdn.jun6.net/uPic/2022/08/13/jymieO.png) +### 后台设置-存储源权限控制 +![后台设置-存储源权限控制](https://cdn.jun6.net/uPic/2022/08/13/JgiwkH.jpg) +### 后台设置-添加存储源(本地存储) +![后台设置-添加存储源(本地存储)](https://cdn.jun6.net/uPic/2022/08/13/add-storage.png) +### 后台设置-添加存储源(世纪互联) +![后台设置-添加存储源(世纪互联)](https://cdn.jun6.net/uPic/2022/08/13/add-storage2.png) +### 后台设置-显示设置 +![后台设置-显示设置](https://cdn.jun6.net/uPic/2022/08/13/view-setting.png) + + +## 支持作者 + +如果本项目对你有帮助,请作者喝杯咖啡吧。 + +赞助我 + +## Status + +![Alt](https://repobeats.axiom.co/api/embed/580333f83b91087e713f15497e6433c50e1da090.svg "Repobeats analytics image") + +## Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=zfile-dev/zfile&type=Date)](https://star-history.com/#zfile-dev/zfile&Date) diff --git a/apps/zfile/data.yml b/apps/zfile/data.yml new file mode 100644 index 000000000..abade3ff0 --- /dev/null +++ b/apps/zfile/data.yml @@ -0,0 +1,20 @@ +name: ZFile +tags: + - 工具 +title: 基于 Java 的在线网盘程序 +type: 工具 +description: 基于 Java 的在线网盘程序 +additionalProperties: + key: zfile + name: ZFile + tags: + - Tool + shortDescZh: 基于 Java 的在线网盘程序 + shortDescEn: Java-based online disk program + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://www.zfile.vip/ + github: https://github.com/zfile-dev/zfile + document: https://docs.zfile.vip/ diff --git a/apps/zfile/logo.png b/apps/zfile/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..bc7480956fe843a9b6ce47b3309e6b44cdf84bd9 GIT binary patch literal 5737 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 b6pH@`SoQbe9m*9%00000NkvXXu0mjf)6NNx literal 0 KcmV+b0RR6000031