mirror of https://github.com/fatedier/frp
				
				
				
			
						commit
						47c1a3e52c
					
				
							
								
								
									
										11
									
								
								README.md
								
								
								
								
							
							
						
						
									
										11
									
								
								README.md
								
								
								
								
							| 
						 | 
				
			
			@ -6,7 +6,7 @@
 | 
			
		|||
 | 
			
		||||
## What is frp?
 | 
			
		||||
 | 
			
		||||
frp is a fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.Now, it supports tcp, http and https protocol when requests can be forwarded by domains to backward web services.
 | 
			
		||||
frp is a fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet. Now, it supports tcp, http and https protocol when requests can be forwarded by domains to backward web services.
 | 
			
		||||
 | 
			
		||||
## Catalog
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -37,9 +37,9 @@ frp is a fast reverse proxy to help you expose a local server behind a NAT or fi
 | 
			
		|||
 | 
			
		||||
## Status
 | 
			
		||||
 | 
			
		||||
frp is under development and you can try it with latest release version.Master branch for releasing stable version when dev branch for developing.
 | 
			
		||||
frp is under development and you can try it with latest release version. Master branch for releasing stable version when dev branch for developing.
 | 
			
		||||
 | 
			
		||||
**We may change any protocol and can't promise backward compatible.Please check the release log when upgrading.**
 | 
			
		||||
**We may change any protocol and can't promise backward compatible. Please check the release log when upgrading.**
 | 
			
		||||
 | 
			
		||||
## Architecture
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -149,9 +149,12 @@ Configure a port for dashboard to enable this feature:
 | 
			
		|||
```ini
 | 
			
		||||
[common]
 | 
			
		||||
dashboard_port = 7500
 | 
			
		||||
# dashboard's username and password are both optional,if not set, default is admin.
 | 
			
		||||
dashboard_username = abc
 | 
			
		||||
dashboard_password = abc
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Then visit `http://[server_addr]:7500` to see dashboard.
 | 
			
		||||
Then visit `http://[server_addr]:7500` to see dashboard, default username and password are both `admin`.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -146,9 +146,12 @@ frp 目前正在前期开发阶段,master 分支用于发布稳定版本,dev
 | 
			
		|||
```ini
 | 
			
		||||
[common]
 | 
			
		||||
dashboard_port = 7500
 | 
			
		||||
# dashboard 用户名密码可选,默认都为 admin
 | 
			
		||||
dashboard_username = abc
 | 
			
		||||
dashboard_password = abc
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
打开浏览器通过 `http://[server_addr]:7500` 访问 dashboard 界面。
 | 
			
		||||
打开浏览器通过 `http://[server_addr]:7500` 访问 dashboard 界面,用户名密码默认为 `admin`。
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,9 @@ vhost_http_port = 80
 | 
			
		|||
vhost_https_port = 443
 | 
			
		||||
# if you want to configure or reload frps by dashboard, dashboard_port must be set
 | 
			
		||||
dashboard_port = 7500
 | 
			
		||||
# dashboard username and password for basic protect, if not set, both default value is admin
 | 
			
		||||
dashboard_username = abc
 | 
			
		||||
dashboard_password = abc
 | 
			
		||||
# dashboard assets directory(only for debug mode)
 | 
			
		||||
# assets_dir = ./static
 | 
			
		||||
# console or real logFile path like ./frps.log
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,19 +30,21 @@ import (
 | 
			
		|||
 | 
			
		||||
// common config
 | 
			
		||||
var (
 | 
			
		||||
	ConfigFile     string = "./frps.ini"
 | 
			
		||||
	BindAddr       string = "0.0.0.0"
 | 
			
		||||
	BindPort       int64  = 7000
 | 
			
		||||
	VhostHttpPort  int64  = 0 // if VhostHttpPort equals 0, don't listen a public port for http protocol
 | 
			
		||||
	VhostHttpsPort int64  = 0 // if VhostHttpsPort equals 0, don't listen a public port for https protocol
 | 
			
		||||
	DashboardPort  int64  = 0 // if DashboardPort equals 0, dashboard is not available
 | 
			
		||||
	AssetsDir      string = ""
 | 
			
		||||
	LogFile        string = "console"
 | 
			
		||||
	LogWay         string = "console" // console or file
 | 
			
		||||
	LogLevel       string = "info"
 | 
			
		||||
	LogMaxDays     int64  = 3
 | 
			
		||||
	PrivilegeMode  bool   = false
 | 
			
		||||
	PrivilegeToken string = ""
 | 
			
		||||
	ConfigFile        string = "./frps.ini"
 | 
			
		||||
	BindAddr          string = "0.0.0.0"
 | 
			
		||||
	BindPort          int64  = 7000
 | 
			
		||||
	VhostHttpPort     int64  = 0 // if VhostHttpPort equals 0, don't listen a public port for http protocol
 | 
			
		||||
	VhostHttpsPort    int64  = 0 // if VhostHttpsPort equals 0, don't listen a public port for https protocol
 | 
			
		||||
	DashboardPort     int64  = 0 // if DashboardPort equals 0, dashboard is not available
 | 
			
		||||
	DashboardUsername string = "admin"
 | 
			
		||||
	DashboardPassword string = "admin"
 | 
			
		||||
	AssetsDir         string = ""
 | 
			
		||||
	LogFile           string = "console"
 | 
			
		||||
	LogWay            string = "console" // console or file
 | 
			
		||||
	LogLevel          string = "info"
 | 
			
		||||
	LogMaxDays        int64  = 3
 | 
			
		||||
	PrivilegeMode     bool   = false
 | 
			
		||||
	PrivilegeToken    string = ""
 | 
			
		||||
 | 
			
		||||
	// if PrivilegeAllowPorts is not nil, tcp proxies which remote port exist in this map can be connected
 | 
			
		||||
	PrivilegeAllowPorts map[int64]struct{}
 | 
			
		||||
| 
						 | 
				
			
			@ -119,6 +121,16 @@ func loadCommonConf(confFile string) error {
 | 
			
		|||
		DashboardPort = 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tmpStr, ok = conf.Get("common", "dashboard_username")
 | 
			
		||||
	if ok {
 | 
			
		||||
		DashboardUsername = tmpStr
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tmpStr, ok = conf.Get("common", "dashboard_password")
 | 
			
		||||
	if ok {
 | 
			
		||||
		DashboardPassword = tmpStr
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tmpStr, ok = conf.Get("common", "assets_dir")
 | 
			
		||||
	if ok {
 | 
			
		||||
		AssetsDir = tmpStr
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,9 +15,11 @@
 | 
			
		|||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/fatedier/frp/src/assets"
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +40,7 @@ func RunDashboardServer(addr string, port int64) (err error) {
 | 
			
		|||
	// view, see dashboard_view.go
 | 
			
		||||
	mux.Handle("/favicon.ico", http.FileServer(assets.FileSystem))
 | 
			
		||||
	mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(assets.FileSystem)))
 | 
			
		||||
	mux.HandleFunc("/", viewDashboard)
 | 
			
		||||
	mux.HandleFunc("/", use(viewDashboard, basicAuth))
 | 
			
		||||
 | 
			
		||||
	address := fmt.Sprintf("%s:%d", addr, port)
 | 
			
		||||
	server := &http.Server{
 | 
			
		||||
| 
						 | 
				
			
			@ -58,3 +60,43 @@ func RunDashboardServer(addr string, port int64) (err error) {
 | 
			
		|||
	go server.Serve(ln)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func use(h http.HandlerFunc, middleware ...func(http.HandlerFunc) http.HandlerFunc) http.HandlerFunc {
 | 
			
		||||
	for _, m := range middleware {
 | 
			
		||||
		h = m(h)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return h
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func basicAuth(h http.HandlerFunc) http.HandlerFunc {
 | 
			
		||||
	return func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
 | 
			
		||||
		w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
 | 
			
		||||
 | 
			
		||||
		s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
 | 
			
		||||
		if len(s) != 2 {
 | 
			
		||||
			http.Error(w, "Not authorized", 401)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		b, err := base64.StdEncoding.DecodeString(s[1])
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			http.Error(w, err.Error(), 401)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pair := strings.SplitN(string(b), ":", 2)
 | 
			
		||||
		if len(pair) != 2 {
 | 
			
		||||
			http.Error(w, "Not authorized", 401)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if pair[0] != DashboardUsername || pair[1] != DashboardPassword {
 | 
			
		||||
			http.Error(w, "Not authorized", 401)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		h.ServeHTTP(w, r)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue