Skip to content

Commit

Permalink
Merge pull request #275 from tobychui/v3.1.0
Browse files Browse the repository at this point in the history
v3.1.0 Update
  • Loading branch information
tobychui authored Jul 31, 2024
2 parents 02ff288 + f4fa926 commit 0a734e0
Show file tree
Hide file tree
Showing 71 changed files with 6,668 additions and 4,215 deletions.
3 changes: 2 additions & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ VOLUME [ "/opt/zoraxy/config/" ]
WORKDIR /opt/zoraxy/config/

ENV AUTORENEW="86400"
ENV EARLYRENEW="30"
ENV FASTGEOIP="false"
ENV MDNS="true"
ENV MDNSNAME="''"
Expand All @@ -42,6 +43,6 @@ ENV WEBROOT="./www"
ENV ZTAUTH="''"
ENV ZTPORT="9993"

ENTRYPOINT "zoraxy" "-docker=true" "-autorenew=${AUTORENEW}" "-fastgeoip=${FASTGEOIP}" "-mdns=${MDNS}" "-mdnsname=${MDNSNAME}" "-noauth=${NOAUTH}" "-port=:${PORT}" "-sshlb=${SSHLB}" "-version=${VERSION}" "-webfm=${WEBFM}" "-webroot=${WEBROOT}" "-ztauth=${ZTAUTH}" "-ztport=${ZTPORT}"
ENTRYPOINT "zoraxy" "-docker=true" "-autorenew=${AUTORENEW}" "-earlyrenew=${EARLYRENEW}" "-fastgeoip=${FASTGEOIP}" "-mdns=${MDNS}" "-mdnsname=${MDNSNAME}" "-noauth=${NOAUTH}" "-port=:${PORT}" "-sshlb=${SSHLB}" "-version=${VERSION}" "-webfm=${WEBFM}" "-webroot=${WEBROOT}" "-ztauth=${ZTAUTH}" "-ztport=${ZTPORT}"

HEALTHCHECK --interval=15s --timeout=5s --start-period=10s --retries=3 CMD nc -vz 127.0.0.1 $PORT || exit 1
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ clean:

$(PLATFORMS):
@echo "Building $(os)/$(arch)"
GOROOT_FINAL=Git/ GOOS=$(os) GOARCH=$(arch) $(if $(filter linux/arm,$(os)/$(arch)),GOARM=6,) go build -o './dist/zoraxy_$(os)_$(arch)' -ldflags "-s -w" -trimpath
GOROOT_FINAL=Git/ GOOS=$(os) GOARCH=$(arch) $(if $(filter linux/arm,$(os)/$(arch)),GOARM=6,) CGO_ENABLED="0" go build -o './dist/zoraxy_$(os)_$(arch)' -ldflags "-s -w" -trimpath
# GOROOT_FINAL=Git/ GOOS=$(os) GOARCH=$(arch) GOARM=6 go build -o './dist/zoraxy_$(os)_$(arch)' -ldflags "-s -w" -trimpath


Expand Down
34 changes: 18 additions & 16 deletions src/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ import (

var requireAuth = true

func initAPIs() {

func initAPIs(targetMux *http.ServeMux) {
authRouter := auth.NewManagedHTTPRouter(auth.RouterOption{
AuthAgent: authAgent,
RequireAuth: requireAuth,
TargetMux: targetMux,
DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "401 - Unauthorized", http.StatusUnauthorized)
},
Expand All @@ -37,12 +37,12 @@ func initAPIs() {
if development {
fs = http.FileServer(http.Dir("web/"))
}
//Add a layer of middleware for advance control
//Add a layer of middleware for advance control
advHandler := FSHandler(fs)
http.Handle("/", advHandler)
targetMux.Handle("/", advHandler)

//Authentication APIs
registerAuthAPIs(requireAuth)
registerAuthAPIs(requireAuth, targetMux)

//Reverse proxy
authRouter.HandleFunc("/api/proxy/enable", ReverseProxyHandleOnOff)
Expand Down Expand Up @@ -77,6 +77,8 @@ func initAPIs() {
authRouter.HandleFunc("/api/proxy/header/add", HandleCustomHeaderAdd)
authRouter.HandleFunc("/api/proxy/header/remove", HandleCustomHeaderRemove)
authRouter.HandleFunc("/api/proxy/header/handleHSTS", HandleHSTSState)
authRouter.HandleFunc("/api/proxy/header/handleHopByHop", HandleHopByHop)
authRouter.HandleFunc("/api/proxy/header/handleHostOverwrite", HandleHostOverwrite)
authRouter.HandleFunc("/api/proxy/header/handlePermissionPolicy", HandlePermissionPolicy)
//Reverse proxy auth related APIs
authRouter.HandleFunc("/api/proxy/auth/exceptions/list", ListProxyBasicAuthExceptionPaths)
Expand Down Expand Up @@ -185,8 +187,8 @@ func initAPIs() {
authRouter.HandleFunc("/api/tools/fwdproxy/port", forwardProxy.HandlePort)

//Account Reset
http.HandleFunc("/api/account/reset", HandleAdminAccountResetEmail)
http.HandleFunc("/api/account/new", HandleNewPasswordSetup)
targetMux.HandleFunc("/api/account/reset", HandleAdminAccountResetEmail)
targetMux.HandleFunc("/api/account/new", HandleNewPasswordSetup)

//ACME & Auto Renewer
authRouter.HandleFunc("/api/acme/listExpiredDomains", acmeHandler.HandleGetExpiredDomains)
Expand Down Expand Up @@ -226,7 +228,7 @@ func initAPIs() {
authRouter.HandleFunc("/api/docker/containers", DockerUXOptimizer.HandleDockerContainersList)

//Others
http.HandleFunc("/api/info/x", HandleZoraxyInfo)
targetMux.HandleFunc("/api/info/x", HandleZoraxyInfo)
authRouter.HandleFunc("/api/info/geoip", HandleGeoIpLookup)
authRouter.HandleFunc("/api/conf/export", ExportConfigAsZip)
authRouter.HandleFunc("/api/conf/import", ImportConfigFromZip)
Expand All @@ -241,18 +243,18 @@ func initAPIs() {
}

// Function to renders Auth related APIs
func registerAuthAPIs(requireAuth bool) {
func registerAuthAPIs(requireAuth bool, targetMux *http.ServeMux) {
//Auth APIs
http.HandleFunc("/api/auth/login", authAgent.HandleLogin)
http.HandleFunc("/api/auth/logout", authAgent.HandleLogout)
http.HandleFunc("/api/auth/checkLogin", func(w http.ResponseWriter, r *http.Request) {
targetMux.HandleFunc("/api/auth/login", authAgent.HandleLogin)
targetMux.HandleFunc("/api/auth/logout", authAgent.HandleLogout)
targetMux.HandleFunc("/api/auth/checkLogin", func(w http.ResponseWriter, r *http.Request) {
if requireAuth {
authAgent.CheckLogin(w, r)
} else {
utils.SendJSONResponse(w, "true")
}
})
http.HandleFunc("/api/auth/username", func(w http.ResponseWriter, r *http.Request) {
targetMux.HandleFunc("/api/auth/username", func(w http.ResponseWriter, r *http.Request) {
username, err := authAgent.GetUserName(w, r)
if err != nil {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
Expand All @@ -262,12 +264,12 @@ func registerAuthAPIs(requireAuth bool) {
js, _ := json.Marshal(username)
utils.SendJSONResponse(w, string(js))
})
http.HandleFunc("/api/auth/userCount", func(w http.ResponseWriter, r *http.Request) {
targetMux.HandleFunc("/api/auth/userCount", func(w http.ResponseWriter, r *http.Request) {
uc := authAgent.GetUserCounts()
js, _ := json.Marshal(uc)
utils.SendJSONResponse(w, string(js))
})
http.HandleFunc("/api/auth/register", func(w http.ResponseWriter, r *http.Request) {
targetMux.HandleFunc("/api/auth/register", func(w http.ResponseWriter, r *http.Request) {
if authAgent.GetUserCounts() == 0 {
//Allow register root admin
authAgent.HandleRegisterWithoutEmail(w, r, func(username, reserved string) {
Expand All @@ -278,7 +280,7 @@ func registerAuthAPIs(requireAuth bool) {
utils.SendErrorResponse(w, "Root management account already exists")
}
})
http.HandleFunc("/api/auth/changePassword", func(w http.ResponseWriter, r *http.Request) {
targetMux.HandleFunc("/api/auth/changePassword", func(w http.ResponseWriter, r *http.Request) {
username, err := authAgent.GetUserName(w, r)
if err != nil {
http.Error(w, "401 - Unauthorized", http.StatusUnauthorized)
Expand Down
23 changes: 12 additions & 11 deletions src/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,27 +182,28 @@ func handleToggleTLSProxy(w http.ResponseWriter, r *http.Request) {
sysdb.Read("settings", "usetls", &currentTlsSetting)
}

newState, err := utils.PostPara(r, "set")
if err != nil {
//No setting. Get the current status
if r.Method == http.MethodGet {
//Get the current status
js, _ := json.Marshal(currentTlsSetting)
utils.SendJSONResponse(w, string(js))
} else {
if newState == "true" {
} else if r.Method == http.MethodPost {
newState, err := utils.PostBool(r, "set")
if err != nil {
utils.SendErrorResponse(w, "new state not set or invalid")
return
}
if newState {
sysdb.Write("settings", "usetls", true)
SystemWideLogger.Println("Enabling TLS mode on reverse proxy")
dynamicProxyRouter.UpdateTLSSetting(true)
} else if newState == "false" {
} else {
sysdb.Write("settings", "usetls", false)
SystemWideLogger.Println("Disabling TLS mode on reverse proxy")
dynamicProxyRouter.UpdateTLSSetting(false)
} else {
utils.SendErrorResponse(w, "invalid state given. Only support true or false")
return
}

utils.SendOK(w)

} else {
http.Error(w, "405 - Method not allowed", http.StatusMethodNotAllowed)
}
}

Expand Down
1 change: 1 addition & 0 deletions src/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ require (
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.2 // indirect
github.com/gophercloud/gophercloud v1.0.0 // indirect
github.com/gorilla/csrf v1.7.2 // indirect
github.com/gorilla/css v1.0.1 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions src/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7
github.com/gophercloud/gophercloud v1.0.0 h1:9nTGx0jizmHxDobe4mck89FyQHVyA3CaXLIUSGJjP9k=
github.com/gophercloud/gophercloud v1.0.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/csrf v1.7.2 h1:oTUjx0vyf2T+wkrx09Trsev1TE+/EbDAeHtSTbtC2eI=
github.com/gorilla/csrf v1.7.2/go.mod h1:F1Fj3KG23WYHE6gozCmBAezKookxbIvUJT+121wTuLk=
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
Expand Down
28 changes: 21 additions & 7 deletions src/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"github.com/google/uuid"
"github.com/gorilla/csrf"
"imuslab.com/zoraxy/mod/access"
"imuslab.com/zoraxy/mod/acme"
"imuslab.com/zoraxy/mod/auth"
Expand Down Expand Up @@ -50,14 +51,15 @@ var ztAuthToken = flag.String("ztauth", "", "ZeroTier authtoken for the local no
var ztAPIPort = flag.Int("ztport", 9993, "ZeroTier controller API port")
var runningInDocker = flag.Bool("docker", false, "Run Zoraxy in docker compatibility mode")
var acmeAutoRenewInterval = flag.Int("autorenew", 86400, "ACME auto TLS/SSL certificate renew check interval (seconds)")
var acmeCertAutoRenewDays = flag.Int("earlyrenew", 30, "Number of days to early renew a soon expiring certificate (days)")
var enableHighSpeedGeoIPLookup = flag.Bool("fastgeoip", false, "Enable high speed geoip lookup, require 1GB extra memory (Not recommend for low end devices)")
var staticWebServerRoot = flag.String("webroot", "./www", "Static web server root folder. Only allow chnage in start paramters")
var allowWebFileManager = flag.Bool("webfm", true, "Enable web file manager for static web server root folder")
var enableAutoUpdate = flag.Bool("cfgupgrade", true, "Enable auto config upgrade if breaking change is detected")

var (
name = "Zoraxy"
version = "3.0.9"
version = "3.1.0"
nodeUUID = "generic" //System uuid, in uuidv4 format
development = false //Set this to false to use embedded web fs
bootTime = time.Now().Unix()
Expand All @@ -71,10 +73,12 @@ var (
/*
Handler Modules
*/
sysdb *database.Database //System database
authAgent *auth.AuthAgent //Authentication agent
tlsCertManager *tlscert.Manager //TLS / SSL management
redirectTable *redirection.RuleTable //Handle special redirection rule sets
sysdb *database.Database //System database
authAgent *auth.AuthAgent //Authentication agent
tlsCertManager *tlscert.Manager //TLS / SSL management
redirectTable *redirection.RuleTable //Handle special redirection rule sets
webminPanelMux *http.ServeMux //Server mux for handling webmin panel APIs
csrfMiddleware func(http.Handler) http.Handler //CSRF protection middleware

pathRuleHandler *pathrule.Handler //Handle specific path blocking or custom headers
geodbStore *geodb.Store //GeoIP database, for resolving IP into country code
Expand Down Expand Up @@ -175,12 +179,22 @@ func main() {
}
nodeUUID = string(uuidBytes)

//Create a new webmin mux and csrf middleware layer
webminPanelMux = http.NewServeMux()
csrfMiddleware = csrf.Protect(
[]byte(nodeUUID),
csrf.CookieName("zoraxy-csrf"),
csrf.Secure(false),
csrf.Path("/"),
csrf.SameSite(csrf.SameSiteLaxMode),
)

//Startup all modules
startupSequence()

//Initiate management interface APIs
requireAuth = !(*noauth)
initAPIs()
initAPIs(webminPanelMux)

//Start the reverse proxy server in go routine
go func() {
Expand All @@ -193,7 +207,7 @@ func main() {
finalSequence()

SystemWideLogger.Println("Zoraxy started. Visit control panel at http://localhost" + *webUIPort)
err = http.ListenAndServe(*webUIPort, nil)
err = http.ListenAndServe(*webUIPort, csrfMiddleware(webminPanelMux))

if err != nil {
log.Fatal(err)
Expand Down
Loading

0 comments on commit 0a734e0

Please sign in to comment.