mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-06-23 16:03:04 +02:00
Added uptime monitor and summary struct converter
This commit is contained in:
parent
b5f3234d45
commit
3902a0283b
118
src/README.md
118
src/README.md
@ -1,118 +1,31 @@
|
||||
# Zoraxy
|
||||
# ReverseProxy
|
||||
|
||||
General purpose request (reverse) proxy and forwarding tool for low power devices. Now written in Go!
|
||||
Reverse proxy subservice for ArozOS
|
||||
|
||||
### Features
|
||||
|
||||
- Simple to use interface with detail in-system instructions
|
||||
|
||||
- Reverse Proxy
|
||||
|
||||
- Subdomain Reverse Proxy
|
||||
|
||||
- Virtual Directory Reverse Proxy
|
||||
### Install
|
||||
|
||||
- Redirection Rules
|
||||
Git clone this inside the subservice folder of ArozOS, build it and start it up in ArozOS subservice menu.
|
||||
|
||||
- TLS / SSL setup and deploy
|
||||
You can also use it separately as a really basic reverse proxy server that server website based on domain / virtual directories. You can also add another load balancer in front of multiple reverse proxy server nodes if it is necessary in your case.
|
||||
|
||||
- Blacklist by country or IP address (single IP, CIDR or wildcard for beginners :D)
|
||||
|
||||
- (More features work in progress)
|
||||
|
||||
## Usage
|
||||
### Build
|
||||
|
||||
Zoraxy provide basic authentication system for standalone mode. To use it in standalone mode, follow the instruction below for your desired deployment platform.
|
||||
Requirement: Go 1.16 or above
|
||||
|
||||
### Standalone Mode
|
||||
|
||||
Standalone mode is the default mode for Zoraxy. This allow single account to manage your reverse proxy server just like a home router. This mode is suitable for new owners for homelab or makers start growing their web services into multiple servers.
|
||||
|
||||
#### Linux
|
||||
|
||||
```bash
|
||||
//Download the latest zoraxy binary and web.tar.gz from the Release page
|
||||
sudo chmod 775 ./zoraxy web.tar.gz
|
||||
sudo ./zoraxy -port=:8000
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
Download the binary executable and web.tar.gz, put them into the same folder and double click the binary file to start it.
|
||||
|
||||
#### Raspberry Pi
|
||||
|
||||
The installation method is same as Linux. If you are using Raspberry Pi 4 or newer models, pick the arm64 release. For older version of Pis, use the arm (armv6) version instead.
|
||||
|
||||
#### Other ARM SBCs or Android phone with Termux
|
||||
|
||||
The installation method is same as Linux. For other ARM SBCs, please refer to your SBC's CPU architecture and pick the one that is suitable for your device.
|
||||
|
||||
### External Permission Managment Mode
|
||||
|
||||
If you already have a up-stream reverse proxy server in place with permission management, you can use Zoraxy in noauth mode. To enable no-auth mode, start Zoraxy with the following flag
|
||||
|
||||
```bash
|
||||
./zoraxy -noauth=true
|
||||
```
|
||||
|
||||
*Note: For security reaons, you should only enable no-auth if you are running Zoraxy in a trusted environment or with another authentication management proxy in front.*
|
||||
|
||||
#### Use with ArozOS
|
||||
|
||||
[ArozOS ](https://arozos.com)subservice is a build in permission managed reverse proxy server. To use zoraxy with arozos, connect to your arozos host via ssh and use the following command to install zoraxy
|
||||
|
||||
```bash
|
||||
# cd into your arozos subservice folder. Sometime it is under ~/arozos/src/subservice
|
||||
cd ~/arozos/subservices
|
||||
mkdir zoraxy
|
||||
cd ./zoraxy
|
||||
|
||||
# Download the release binary from Github release
|
||||
wget {binary executable link from release page}
|
||||
wget {web.tar.gz link from release page}
|
||||
|
||||
# Set permission. Change this if required
|
||||
sudo chmod 775 -R ./
|
||||
|
||||
# Start zoraxy to see if the downloaded arch is correct. If yes, you should
|
||||
# see it start unzipping
|
||||
./zoraxy
|
||||
|
||||
# After the unzip done, press Ctrl + C to kill it
|
||||
# Rename it to valid arozos subservice binary format
|
||||
mv ./zoraxy zoraxy_linux_amd64
|
||||
|
||||
# If you are using SBCs with different CPU arch
|
||||
mv ./zoraxy zoraxy_linux_arm
|
||||
mv ./zoraxy zoraxy_linux_arm64
|
||||
|
||||
# Restart arozos
|
||||
sudo systemctl restart arozos
|
||||
|
||||
|
||||
git clone {this_repo}
|
||||
cd ReverseProxy
|
||||
./build.sh
|
||||
```
|
||||
|
||||
To start the module, go to System Settings > Modules > Subservice and enable it in the menu. You should be able to see a new module named "Zoraxy" pop up in the start menu.
|
||||
To start the module, make sure .disabled file does not exists and start arozos system. You should be able to see a new module named "ReverseProxy" pop up in the start menu.
|
||||
|
||||
|
||||
|
||||
## Build from Source
|
||||
|
||||
*Requirement: Go 1.17 or above*
|
||||
|
||||
```bash
|
||||
git clone https://github.com/tobychui/zoraxy
|
||||
cd ./zoraxy/src
|
||||
go mod tidy
|
||||
go build
|
||||
|
||||
./zoraxy
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Forward Modes
|
||||
### Usage
|
||||
|
||||
#### Proxy Modes
|
||||
|
||||
@ -121,8 +34,12 @@ There are two mode in the ReverseProxy Subservice
|
||||
1. vdir mode (Virtual Dirctories)
|
||||
2. subd mode (Subdomain Proxying Mode)
|
||||
|
||||
|
||||
|
||||
Vdir mode proxy web request based on the virtual directories given in the request URL. For example, when configured to redirect /example to example.com, any visits to {your_domain}/example will be proxied to example.com.
|
||||
|
||||
|
||||
|
||||
Subd mode proxy web request based on sub-domain exists in the request URL. For example, when configured to redirect example.localhost to example.com, any visits that includes example.localhost (e.g. example.localhost/page1) will be proxied to example.com (e.g. example.com/page1)
|
||||
|
||||
#### Root Proxy
|
||||
@ -131,6 +48,3 @@ Root proxy is the main proxy destination where if all proxy root name did not ma
|
||||
|
||||
|
||||
|
||||
## License
|
||||
|
||||
To be decided (Currently: All Right Reserved)
|
||||
|
@ -68,9 +68,10 @@ func initAPIs() {
|
||||
authRouter.HandleFunc("/api/blacklist/ip/remove", handleIpBlacklistRemove)
|
||||
authRouter.HandleFunc("/api/blacklist/enable", handleBlacklistEnable)
|
||||
|
||||
//Statistic API
|
||||
//Statistic & uptime monitoring API
|
||||
authRouter.HandleFunc("/api/stats/summary", statisticCollector.HandleTodayStatLoad)
|
||||
|
||||
authRouter.HandleFunc("/api/stats/countries", HandleCountryDistrSummary)
|
||||
authRouter.HandleFunc("/api/utm/list", HandleUptimeMonitorListing)
|
||||
//Upnp
|
||||
authRouter.HandleFunc("/api/upnp/discover", handleUpnpDiscover)
|
||||
//If you got APIs to add, append them here
|
||||
|
97
src/helpers.go
Normal file
97
src/helpers.go
Normal file
@ -0,0 +1,97 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"imuslab.com/zoraxy/mod/dynamicproxy"
|
||||
"imuslab.com/zoraxy/mod/uptime"
|
||||
"imuslab.com/zoraxy/mod/utils"
|
||||
)
|
||||
|
||||
/*
|
||||
Statistic Summary
|
||||
*/
|
||||
//Handle conversion of statistic daily summary to country summary
|
||||
func HandleCountryDistrSummary(w http.ResponseWriter, r *http.Request) {
|
||||
requestClientCountry := map[string]int{}
|
||||
statisticCollector.DailySummary.RequestClientIp.Range(func(key, value interface{}) bool {
|
||||
//Get this client country of original
|
||||
clientIp := key.(string)
|
||||
//requestCount := value.(int)
|
||||
|
||||
ci, err := geodbStore.ResolveCountryCodeFromIP(clientIp)
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
isoCode := ci.CountryIsoCode
|
||||
if isoCode == "" {
|
||||
//local or reserved addr
|
||||
isoCode = "local"
|
||||
}
|
||||
uc, ok := requestClientCountry[isoCode]
|
||||
if !ok {
|
||||
//Create the counter
|
||||
requestClientCountry[isoCode] = 1
|
||||
} else {
|
||||
requestClientCountry[isoCode] = uc + 1
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
js, _ := json.Marshal(requestClientCountry)
|
||||
utils.SendJSONResponse(w, string(js))
|
||||
}
|
||||
|
||||
/*
|
||||
Up Time Monitor
|
||||
*/
|
||||
//Generate uptime monitor targets from reverse proxy rules
|
||||
func GetUptimeTargetsFromReverseProxyRules(dp *dynamicproxy.Router) []*uptime.Target {
|
||||
subds := dp.GetSDProxyEndpointsAsMap()
|
||||
vdirs := dp.GetVDProxyEndpointsAsMap()
|
||||
|
||||
UptimeTargets := []*uptime.Target{}
|
||||
for subd, target := range subds {
|
||||
url := "http://" + target.Domain
|
||||
protocol := "http"
|
||||
if target.RequireTLS {
|
||||
url = "https://" + target.Domain
|
||||
protocol = "https"
|
||||
}
|
||||
UptimeTargets = append(UptimeTargets, &uptime.Target{
|
||||
ID: subd,
|
||||
Name: subd,
|
||||
URL: url,
|
||||
Protocol: protocol,
|
||||
})
|
||||
}
|
||||
|
||||
for vdir, target := range vdirs {
|
||||
url := "http://" + target.Domain
|
||||
protocol := "http"
|
||||
if target.RequireTLS {
|
||||
url = "https://" + target.Domain
|
||||
protocol = "https"
|
||||
}
|
||||
UptimeTargets = append(UptimeTargets, &uptime.Target{
|
||||
ID: vdir,
|
||||
Name: "*" + vdir,
|
||||
URL: url,
|
||||
Protocol: protocol,
|
||||
})
|
||||
}
|
||||
|
||||
return UptimeTargets
|
||||
}
|
||||
|
||||
//Handle rendering up time monitor data
|
||||
func HandleUptimeMonitorListing(w http.ResponseWriter, r *http.Request) {
|
||||
if uptimeMonitor != nil {
|
||||
uptimeMonitor.HandleUptimeLogRead(w, r)
|
||||
} else {
|
||||
http.Error(w, "500 - Internal Server Error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
67
src/main.go
67
src/main.go
@ -1,14 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@ -20,7 +18,7 @@ import (
|
||||
"imuslab.com/zoraxy/mod/statistic"
|
||||
"imuslab.com/zoraxy/mod/tlscert"
|
||||
"imuslab.com/zoraxy/mod/upnp"
|
||||
"imuslab.com/zoraxy/mod/utils"
|
||||
"imuslab.com/zoraxy/mod/uptime"
|
||||
)
|
||||
|
||||
//General flags
|
||||
@ -29,16 +27,17 @@ var showver = flag.Bool("version", false, "Show version of this server")
|
||||
|
||||
var (
|
||||
name = "Zoraxy"
|
||||
version = "2.1"
|
||||
version = "2.11"
|
||||
|
||||
handler *aroz.ArozHandler
|
||||
sysdb *database.Database
|
||||
authAgent *auth.AuthAgent
|
||||
tlsCertManager *tlscert.Manager
|
||||
redirectTable *redirection.RuleTable
|
||||
geodbStore *geodb.Store
|
||||
statisticCollector *statistic.Collector
|
||||
upnpClient *upnp.UPnPClient
|
||||
handler *aroz.ArozHandler //Handle arozos managed permission system
|
||||
sysdb *database.Database //System database
|
||||
authAgent *auth.AuthAgent //Authentication agent
|
||||
tlsCertManager *tlscert.Manager //TLS / SSL management
|
||||
redirectTable *redirection.RuleTable //Handle special redirection rule sets
|
||||
geodbStore *geodb.Store //GeoIP database
|
||||
statisticCollector *statistic.Collector //Collecting statistic from visitors
|
||||
upnpClient *upnp.UPnPClient //UPnP Client for poking holes
|
||||
uptimeMonitor *uptime.Monitor //Uptime monitor service worker
|
||||
)
|
||||
|
||||
// Kill signal handler. Do something before the system the core terminate.
|
||||
@ -63,11 +62,11 @@ func main() {
|
||||
Name: name,
|
||||
Desc: "Dynamic Reverse Proxy Server",
|
||||
Group: "Network",
|
||||
IconPath: "Zoraxy/img/small_icon.png",
|
||||
IconPath: "reverseproxy/img/small_icon.png",
|
||||
Version: version,
|
||||
StartDir: "Zoraxy/index.html",
|
||||
StartDir: "reverseproxy/index.html",
|
||||
SupportFW: true,
|
||||
LaunchFWDir: "Zoraxy/index.html",
|
||||
LaunchFWDir: "reverseproxy/index.html",
|
||||
SupportEmb: false,
|
||||
InitFWSize: []int{1080, 580},
|
||||
})
|
||||
@ -79,9 +78,6 @@ func main() {
|
||||
|
||||
SetupCloseHandler()
|
||||
|
||||
//Check if all required files are here
|
||||
ValidateSystemFiles()
|
||||
|
||||
//Create database
|
||||
db, err := database.NewDatabase("sys.db", false)
|
||||
if err != nil {
|
||||
@ -127,6 +123,10 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
//Create a upnp client
|
||||
err = initUpnp()
|
||||
if err != nil {
|
||||
@ -151,34 +151,3 @@ func main() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Unzip web.tar.gz if file exists
|
||||
func ValidateSystemFiles() error {
|
||||
if !utils.FileExists("./web") || !utils.FileExists("./system") {
|
||||
//Check if the web.tar.gz exists
|
||||
if utils.FileExists("./web.tar.gz") {
|
||||
//Unzip the file
|
||||
f, err := os.Open("./web.tar.gz")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = utils.ExtractTarGzipByStream(filepath.Clean("./"), f, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Delete the web.tar.gz
|
||||
os.Remove("./web.tar.gz")
|
||||
} else {
|
||||
return errors.New("system files not found")
|
||||
}
|
||||
}
|
||||
return errors.New("system files not found or corrupted")
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"imuslab.com/zoraxy/mod/dynamicproxy"
|
||||
"imuslab.com/zoraxy/mod/uptime"
|
||||
"imuslab.com/zoraxy/mod/utils"
|
||||
)
|
||||
|
||||
@ -95,6 +96,18 @@ func ReverseProxtInit() {
|
||||
dynamicProxyRouter.StartProxyService()
|
||||
log.Println("Dynamic Reverse Proxy service started")
|
||||
|
||||
//Add all proxy services to uptime monitor
|
||||
//Create a uptime monitor service
|
||||
go func() {
|
||||
//This must be done in go routine to prevent blocking on system startup
|
||||
uptimeMonitor, _ = uptime.NewUptimeMonitor(&uptime.Config{
|
||||
Targets: GetUptimeTargetsFromReverseProxyRules(dynamicProxyRouter),
|
||||
Interval: 300, //5 minutes
|
||||
MaxRecordsStore: 288, //1 day
|
||||
})
|
||||
log.Println("Uptime Monitor background service started")
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
func ReverseProxyHandleOnOff(w http.ResponseWriter, r *http.Request) {
|
||||
@ -178,6 +191,12 @@ func ReverseProxyHandleAddEndpoint(w http.ResponseWriter, r *http.Request) {
|
||||
//Save it
|
||||
SaveReverseProxyConfig(eptype, rootname, endpoint, useTLS)
|
||||
|
||||
//Update utm if exists
|
||||
if uptimeMonitor != nil {
|
||||
uptimeMonitor.Config.Targets = GetUptimeTargetsFromReverseProxyRules(dynamicProxyRouter)
|
||||
uptimeMonitor.CleanRecords()
|
||||
}
|
||||
|
||||
utils.SendOK(w)
|
||||
|
||||
}
|
||||
@ -199,6 +218,13 @@ func DeleteProxyEndpoint(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
RemoveReverseProxyConfig(ep)
|
||||
|
||||
//Update utm if exists
|
||||
if uptimeMonitor != nil {
|
||||
uptimeMonitor.Config.Targets = GetUptimeTargetsFromReverseProxyRules(dynamicProxyRouter)
|
||||
uptimeMonitor.CleanRecords()
|
||||
}
|
||||
|
||||
utils.SendOK(w)
|
||||
}
|
||||
|
||||
|
12
src/specialRouter.go
Normal file
12
src/specialRouter.go
Normal file
@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
specialRouter.go
|
||||
|
||||
This script holds special routers
|
||||
that handle special features in sub modules
|
||||
*/
|
||||
|
||||
func injectSpecialRoutingRules() {
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user