Updates 2.6.3

+ Added X-Forwarded-Proto for automatic proxy detector
+ Split blacklist and whitelist from geodb script file
+ Optimized compile binary size
+ Added access control to TCP proxy
+ Added "invalid config detect" in up time monitor for isse #7
+ Fixed minor bugs in advance stats panel
+ Reduced file size of embedded materials
This commit is contained in:
Toby Chui 2023-06-08 21:42:03 +08:00
parent 5db50c1ca2
commit 5e7599756f
27 changed files with 391 additions and 194 deletions

View File

@ -38,7 +38,7 @@ var ztAuthToken = flag.String("ztauth", "", "ZeroTier authtoken for the local no
var ztAPIPort = flag.Int("ztport", 9993, "ZeroTier controller API port") var ztAPIPort = flag.Int("ztport", 9993, "ZeroTier controller API port")
var ( var (
name = "Zoraxy" name = "Zoraxy"
version = "2.6.2" version = "2.6.3"
nodeUUID = "generic" nodeUUID = "generic"
development = false //Set this to false to use embedded web fs development = false //Set this to false to use embedded web fs
bootTime = time.Now().Unix() bootTime = time.Now().Unix()

View File

@ -278,6 +278,12 @@ func addXForwardedForHeader(req *http.Request) {
clientIP = strings.Join(prior, ", ") + ", " + clientIP clientIP = strings.Join(prior, ", ") + ", " + clientIP
} }
req.Header.Set("X-Forwarded-For", clientIP) req.Header.Set("X-Forwarded-For", clientIP)
if req.TLS != nil {
req.Header.Set("X-Forwarded-Proto", "https")
} else {
req.Header.Set("X-Forwarded-Proto", "http")
}
} }
} }

View File

@ -57,6 +57,7 @@ func (router *Router) rewriteURL(rooturl string, requestURL string) string {
// Handle subdomain request // Handle subdomain request
func (h *ProxyHandler) subdomainRequest(w http.ResponseWriter, r *http.Request, target *ProxyEndpoint) { func (h *ProxyHandler) subdomainRequest(w http.ResponseWriter, r *http.Request, target *ProxyEndpoint) {
r.Header.Set("X-Forwarded-Host", r.Host) r.Header.Set("X-Forwarded-Host", r.Host)
r.Header.Set("X-Forwarded-Server", "zoraxy-"+h.Parent.Option.HostUUID)
requestURL := r.URL.String() requestURL := r.URL.String()
if r.Header["Upgrade"] != nil && strings.ToLower(r.Header["Upgrade"][0]) == "websocket" { if r.Header["Upgrade"] != nil && strings.ToLower(r.Header["Upgrade"][0]) == "websocket" {
//Handle WebSocket request. Forward the custom Upgrade header and rewrite origin //Handle WebSocket request. Forward the custom Upgrade header and rewrite origin
@ -116,6 +117,7 @@ func (h *ProxyHandler) proxyRequest(w http.ResponseWriter, r *http.Request, targ
r.URL, _ = url.Parse(rewriteURL) r.URL, _ = url.Parse(rewriteURL)
r.Header.Set("X-Forwarded-Host", r.Host) r.Header.Set("X-Forwarded-Host", r.Host)
r.Header.Set("X-Forwarded-Server", "zoraxy-"+h.Parent.Option.HostUUID)
if r.Header["Upgrade"] != nil && strings.ToLower(r.Header["Upgrade"][0]) == "websocket" { if r.Header["Upgrade"] != nil && strings.ToLower(r.Header["Upgrade"][0]) == "websocket" {
//Handle WebSocket request. Forward the custom Upgrade header and rewrite origin //Handle WebSocket request. Forward the custom Upgrade header and rewrite origin
r.Header.Set("A-Upgrade", "websocket") r.Header.Set("A-Upgrade", "websocket")

View File

@ -22,6 +22,7 @@ type ProxyHandler struct {
} }
type RouterOption struct { type RouterOption struct {
HostUUID string
Port int Port int
UseTls bool UseTls bool
ForceHttpsRedirect bool ForceHttpsRedirect bool

View File

@ -0,0 +1,91 @@
package geodb
import "strings"
/*
Blacklist.go
This script store the blacklist related functions
*/
//Geo Blacklist
func (s *Store) AddCountryCodeToBlackList(countryCode string) {
countryCode = strings.ToLower(countryCode)
s.sysdb.Write("blacklist-cn", countryCode, true)
}
func (s *Store) RemoveCountryCodeFromBlackList(countryCode string) {
countryCode = strings.ToLower(countryCode)
s.sysdb.Delete("blacklist-cn", countryCode)
}
func (s *Store) IsCountryCodeBlacklisted(countryCode string) bool {
countryCode = strings.ToLower(countryCode)
var isBlacklisted bool = false
s.sysdb.Read("blacklist-cn", countryCode, &isBlacklisted)
return isBlacklisted
}
func (s *Store) GetAllBlacklistedCountryCode() []string {
bannedCountryCodes := []string{}
entries, err := s.sysdb.ListTable("blacklist-cn")
if err != nil {
return bannedCountryCodes
}
for _, keypairs := range entries {
ip := string(keypairs[0])
bannedCountryCodes = append(bannedCountryCodes, ip)
}
return bannedCountryCodes
}
//IP Blacklsits
func (s *Store) AddIPToBlackList(ipAddr string) {
s.sysdb.Write("blacklist-ip", ipAddr, true)
}
func (s *Store) RemoveIPFromBlackList(ipAddr string) {
s.sysdb.Delete("blacklist-ip", ipAddr)
}
func (s *Store) GetAllBlacklistedIp() []string {
bannedIps := []string{}
entries, err := s.sysdb.ListTable("blacklist-ip")
if err != nil {
return bannedIps
}
for _, keypairs := range entries {
ip := string(keypairs[0])
bannedIps = append(bannedIps, ip)
}
return bannedIps
}
func (s *Store) IsIPBlacklisted(ipAddr string) bool {
var isBlacklisted bool = false
s.sysdb.Read("blacklist-ip", ipAddr, &isBlacklisted)
if isBlacklisted {
return true
}
//Check for IP wildcard and CIRD rules
AllBlacklistedIps := s.GetAllBlacklistedIp()
for _, blacklistRule := range AllBlacklistedIps {
wildcardMatch := MatchIpWildcard(ipAddr, blacklistRule)
if wildcardMatch {
return true
}
cidrMatch := MatchIpCIDR(ipAddr, blacklistRule)
if cidrMatch {
return true
}
}
return false
}

View File

@ -3,8 +3,8 @@ package geodb
import ( import (
_ "embed" _ "embed"
"log" "log"
"net"
"net/http" "net/http"
"strings"
"imuslab.com/zoraxy/mod/database" "imuslab.com/zoraxy/mod/database"
) )
@ -112,170 +112,6 @@ func (s *Store) Close() {
} }
/*
Country code based black / white list
*/
func (s *Store) AddCountryCodeToBlackList(countryCode string) {
countryCode = strings.ToLower(countryCode)
s.sysdb.Write("blacklist-cn", countryCode, true)
}
func (s *Store) RemoveCountryCodeFromBlackList(countryCode string) {
countryCode = strings.ToLower(countryCode)
s.sysdb.Delete("blacklist-cn", countryCode)
}
func (s *Store) AddCountryCodeToWhitelist(countryCode string) {
countryCode = strings.ToLower(countryCode)
s.sysdb.Write("whitelist-cn", countryCode, true)
}
func (s *Store) RemoveCountryCodeFromWhitelist(countryCode string) {
countryCode = strings.ToLower(countryCode)
s.sysdb.Delete("whitelist-cn", countryCode)
}
func (s *Store) IsCountryCodeBlacklisted(countryCode string) bool {
countryCode = strings.ToLower(countryCode)
var isBlacklisted bool = false
s.sysdb.Read("blacklist-cn", countryCode, &isBlacklisted)
return isBlacklisted
}
func (s *Store) IsCountryCodeWhitelisted(countryCode string) bool {
countryCode = strings.ToLower(countryCode)
var isWhitelisted bool = false
s.sysdb.Read("whitelist-cn", countryCode, &isWhitelisted)
return isWhitelisted
}
func (s *Store) GetAllBlacklistedCountryCode() []string {
bannedCountryCodes := []string{}
entries, err := s.sysdb.ListTable("blacklist-cn")
if err != nil {
return bannedCountryCodes
}
for _, keypairs := range entries {
ip := string(keypairs[0])
bannedCountryCodes = append(bannedCountryCodes, ip)
}
return bannedCountryCodes
}
func (s *Store) GetAllWhitelistedCountryCode() []string {
whitelistedCountryCode := []string{}
entries, err := s.sysdb.ListTable("whitelist-cn")
if err != nil {
return whitelistedCountryCode
}
for _, keypairs := range entries {
ip := string(keypairs[0])
whitelistedCountryCode = append(whitelistedCountryCode, ip)
}
return whitelistedCountryCode
}
/*
IP based black / whitelist
*/
func (s *Store) AddIPToBlackList(ipAddr string) {
s.sysdb.Write("blacklist-ip", ipAddr, true)
}
func (s *Store) RemoveIPFromBlackList(ipAddr string) {
s.sysdb.Delete("blacklist-ip", ipAddr)
}
func (s *Store) AddIPToWhiteList(ipAddr string) {
s.sysdb.Write("whitelist-ip", ipAddr, true)
}
func (s *Store) RemoveIPFromWhiteList(ipAddr string) {
s.sysdb.Delete("whitelist-ip", ipAddr)
}
func (s *Store) IsIPBlacklisted(ipAddr string) bool {
var isBlacklisted bool = false
s.sysdb.Read("blacklist-ip", ipAddr, &isBlacklisted)
if isBlacklisted {
return true
}
//Check for IP wildcard and CIRD rules
AllBlacklistedIps := s.GetAllBlacklistedIp()
for _, blacklistRule := range AllBlacklistedIps {
wildcardMatch := MatchIpWildcard(ipAddr, blacklistRule)
if wildcardMatch {
return true
}
cidrMatch := MatchIpCIDR(ipAddr, blacklistRule)
if cidrMatch {
return true
}
}
return false
}
func (s *Store) IsIPWhitelisted(ipAddr string) bool {
var isBlacklisted bool = false
s.sysdb.Read("whitelist-ip", ipAddr, &isBlacklisted)
if isBlacklisted {
return true
}
//Check for IP wildcard and CIRD rules
AllBlacklistedIps := s.GetAllBlacklistedIp()
for _, blacklistRule := range AllBlacklistedIps {
wildcardMatch := MatchIpWildcard(ipAddr, blacklistRule)
if wildcardMatch {
return true
}
cidrMatch := MatchIpCIDR(ipAddr, blacklistRule)
if cidrMatch {
return true
}
}
return false
}
func (s *Store) GetAllBlacklistedIp() []string {
bannedIps := []string{}
entries, err := s.sysdb.ListTable("blacklist-ip")
if err != nil {
return bannedIps
}
for _, keypairs := range entries {
ip := string(keypairs[0])
bannedIps = append(bannedIps, ip)
}
return bannedIps
}
func (s *Store) GetAllWhitelistedIp() []string {
whitelistedIp := []string{}
entries, err := s.sysdb.ListTable("whitelist-ip")
if err != nil {
return whitelistedIp
}
for _, keypairs := range entries {
ip := string(keypairs[0])
whitelistedIp = append(whitelistedIp, ip)
}
return whitelistedIp
}
/* /*
Check if a IP address is blacklisted, in either country or IP blacklist Check if a IP address is blacklisted, in either country or IP blacklist
IsBlacklisted default return is false (allow access) IsBlacklisted default return is false (allow access)
@ -341,6 +177,23 @@ func (s *Store) IsWhitelisted(ipAddr string) bool {
return false return false
} }
// A helper function that check both blacklist and whitelist for access
// for both geoIP and ip / CIDR ranges
func (s *Store) AllowIpAccess(ipaddr string) bool {
if s.IsBlacklisted(ipaddr) {
return false
}
return s.IsWhitelisted(ipaddr)
}
func (s *Store) AllowConnectionAccess(conn net.Conn) bool {
if addr, ok := conn.RemoteAddr().(*net.TCPAddr); ok {
return s.AllowIpAccess(addr.IP.String())
}
return true
}
func (s *Store) GetRequesterCountryISOCode(r *http.Request) string { func (s *Store) GetRequesterCountryISOCode(r *http.Request) string {
ipAddr := GetRequesterIP(r) ipAddr := GetRequesterIP(r)
if ipAddr == "" { if ipAddr == "" {

View File

@ -0,0 +1,91 @@
package geodb
import "strings"
/*
Whitelist.go
This script handles whitelist related functions
*/
//Geo Whitelist
func (s *Store) AddCountryCodeToWhitelist(countryCode string) {
countryCode = strings.ToLower(countryCode)
s.sysdb.Write("whitelist-cn", countryCode, true)
}
func (s *Store) RemoveCountryCodeFromWhitelist(countryCode string) {
countryCode = strings.ToLower(countryCode)
s.sysdb.Delete("whitelist-cn", countryCode)
}
func (s *Store) IsCountryCodeWhitelisted(countryCode string) bool {
countryCode = strings.ToLower(countryCode)
var isWhitelisted bool = false
s.sysdb.Read("whitelist-cn", countryCode, &isWhitelisted)
return isWhitelisted
}
func (s *Store) GetAllWhitelistedCountryCode() []string {
whitelistedCountryCode := []string{}
entries, err := s.sysdb.ListTable("whitelist-cn")
if err != nil {
return whitelistedCountryCode
}
for _, keypairs := range entries {
ip := string(keypairs[0])
whitelistedCountryCode = append(whitelistedCountryCode, ip)
}
return whitelistedCountryCode
}
//IP Whitelist
func (s *Store) AddIPToWhiteList(ipAddr string) {
s.sysdb.Write("whitelist-ip", ipAddr, true)
}
func (s *Store) RemoveIPFromWhiteList(ipAddr string) {
s.sysdb.Delete("whitelist-ip", ipAddr)
}
func (s *Store) IsIPWhitelisted(ipAddr string) bool {
var isWhitelisted bool = false
s.sysdb.Read("whitelist-ip", ipAddr, &isWhitelisted)
if isWhitelisted {
return true
}
//Check for IP wildcard and CIRD rules
AllWhitelistedIps := s.GetAllWhitelistedIp()
for _, whitelistRules := range AllWhitelistedIps {
wildcardMatch := MatchIpWildcard(ipAddr, whitelistRules)
if wildcardMatch {
return true
}
cidrMatch := MatchIpCIDR(ipAddr, whitelistRules)
if cidrMatch {
return true
}
}
return false
}
func (s *Store) GetAllWhitelistedIp() []string {
whitelistedIp := []string{}
entries, err := s.sysdb.ListTable("whitelist-ip")
if err != nil {
return whitelistedIp
}
for _, keypairs := range entries {
ip := string(keypairs[0])
whitelistedIp = append(whitelistedIp, ip)
}
return whitelistedIp
}

16
src/mod/sshprox/embed.go Normal file
View File

@ -0,0 +1,16 @@
//go:build (windows && amd64) || (linux && mipsle) || (linux && riscv64)
// +build windows,amd64 linux,mipsle linux,riscv64
package sshprox
import "embed"
/*
Bianry embedding
Make sure when compile, gotty binary exists in static.gotty
*/
var (
//go:embed gotty/LICENSE
gotty embed.FS
)

View File

@ -0,0 +1,18 @@
//go:build linux && 386
// +build linux,386
package sshprox
import "embed"
/*
Bianry embedding for i386 builds
Make sure when compile, gotty binary exists in static.gotty
*/
var (
//go:embed gotty/gotty_linux_386
//go:embed gotty/.gotty
//go:embed gotty/LICENSE
gotty embed.FS
)

View File

@ -0,0 +1,18 @@
//go:build linux && amd64
// +build linux,amd64
package sshprox
import "embed"
/*
Bianry embedding for AMD64 builds
Make sure when compile, gotty binary exists in static.gotty
*/
var (
//go:embed gotty/gotty_linux_amd64
//go:embed gotty/.gotty
//go:embed gotty/LICENSE
gotty embed.FS
)

View File

@ -0,0 +1,18 @@
//go:build linux && arm
// +build linux,arm
package sshprox
import "embed"
/*
Bianry embedding for ARM(v6/7) builds
Make sure when compile, gotty binary exists in static.gotty
*/
var (
//go:embed gotty/gotty_linux_arm
//go:embed gotty/.gotty
//go:embed gotty/LICENSE
gotty embed.FS
)

View File

@ -0,0 +1,18 @@
//go:build linux && arm64
// +build linux,arm64
package sshprox
import "embed"
/*
Bianry embedding for ARM64 builds
Make sure when compile, gotty binary exists in static.gotty
*/
var (
//go:embed gotty/gotty_linux_arm64
//go:embed gotty/.gotty
//go:embed gotty/LICENSE
gotty embed.FS
)

View File

@ -1,7 +1,6 @@
package sshprox package sshprox
import ( import (
"embed"
"errors" "errors"
"fmt" "fmt"
"log" "log"
@ -28,16 +27,6 @@ import (
online ssh terminal online ssh terminal
*/ */
/*
Bianry embedding
Make sure when compile, gotty binary exists in static.gotty
*/
var (
//go:embed gotty/*
gotty embed.FS
)
type Manager struct { type Manager struct {
StartingPort int StartingPort int
Instances []*Instance Instances []*Instance

View File

@ -58,11 +58,23 @@ func forward(conn1 net.Conn, conn2 net.Conn, aTob *int64, bToa *int64) {
wg.Wait() wg.Wait()
} }
func accept(listener net.Listener) (net.Conn, error) { func (c *ProxyRelayConfig) accept(listener net.Listener) (net.Conn, error) {
conn, err := listener.Accept() conn, err := listener.Accept()
if err != nil { if err != nil {
return nil, err return nil, err
} }
//Check if connection in blacklist or whitelist
if addr, ok := conn.RemoteAddr().(*net.TCPAddr); ok {
if !c.parent.Options.AccessControlHandler(conn) {
time.Sleep(300 * time.Millisecond)
conn.Close()
log.Println("[x]", "Connection from "+addr.IP.String()+" rejected by access control policy")
return nil, errors.New("Connection from " + addr.IP.String() + " rejected by access control policy")
}
}
log.Println("[√]", "accept a new client. remote address:["+conn.RemoteAddr().String()+"], local address:["+conn.LocalAddr().String()+"]") log.Println("[√]", "accept a new client. remote address:["+conn.RemoteAddr().String()+"], local address:["+conn.LocalAddr().String()+"]")
return conn, err return conn, err
} }
@ -203,7 +215,7 @@ func (c *ProxyRelayConfig) Port2port(port1 string, port2 string, stopChan chan b
}() }()
for { for {
conn1, err := accept(listen1) conn1, err := c.accept(listen1)
if err != nil { if err != nil {
if !c.Running { if !c.Running {
return nil return nil
@ -211,7 +223,7 @@ func (c *ProxyRelayConfig) Port2port(port1 string, port2 string, stopChan chan b
continue continue
} }
conn2, err := accept(listen2) conn2, err := c.accept(listen2)
if err != nil { if err != nil {
if !c.Running { if !c.Running {
return nil return nil
@ -224,7 +236,7 @@ func (c *ProxyRelayConfig) Port2port(port1 string, port2 string, stopChan chan b
time.Sleep(time.Duration(c.Timeout) * time.Second) time.Sleep(time.Duration(c.Timeout) * time.Second)
continue continue
} }
forward(conn1, conn2, &c.aTobAccumulatedByteTransfer, &c.bToaAccumulatedByteTransfer) go forward(conn1, conn2, &c.aTobAccumulatedByteTransfer, &c.bToaAccumulatedByteTransfer)
} }
} }
@ -248,7 +260,7 @@ func (c *ProxyRelayConfig) Port2host(allowPort string, targetAddress string, sto
//Start blocking loop for accepting connections //Start blocking loop for accepting connections
for { for {
conn, err := accept(server) conn, err := c.accept(server)
if conn == nil || err != nil { if conn == nil || err != nil {
if !c.Running { if !c.Running {
//Terminate by stop chan. Exit listener loop //Terminate by stop chan. Exit listener loop
@ -322,7 +334,7 @@ func (c *ProxyRelayConfig) Host2host(address1, address2 string, stopChan chan bo
return nil return nil
} }
} }
forward(host1, host2, &c.aTobAccumulatedByteTransfer, &c.bToaAccumulatedByteTransfer) go forward(host1, host2, &c.aTobAccumulatedByteTransfer, &c.bToaAccumulatedByteTransfer)
} }
return nil return nil

View File

@ -2,6 +2,7 @@ package tcpprox
import ( import (
"errors" "errors"
"net"
uuid "github.com/satori/go.uuid" uuid "github.com/satori/go.uuid"
"imuslab.com/zoraxy/mod/database" "imuslab.com/zoraxy/mod/database"
@ -40,11 +41,14 @@ type ProxyRelayConfig struct {
stopChan chan bool //Stop channel to stop the listener stopChan chan bool //Stop channel to stop the listener
aTobAccumulatedByteTransfer int64 //Accumulated byte transfer from A to B aTobAccumulatedByteTransfer int64 //Accumulated byte transfer from A to B
bToaAccumulatedByteTransfer int64 //Accumulated byte transfer from B to A bToaAccumulatedByteTransfer int64 //Accumulated byte transfer from B to A
parent *Manager `json:"-"`
} }
type Options struct { type Options struct {
Database *database.Database Database *database.Database
DefaultTimeout int DefaultTimeout int
AccessControlHandler func(net.Conn) bool
} }
type Manager struct { type Manager struct {
@ -59,16 +63,34 @@ type Manager struct {
func NewTCProxy(options *Options) *Manager { func NewTCProxy(options *Options) *Manager {
options.Database.NewTable("tcprox") options.Database.NewTable("tcprox")
//Load relay configs from db
previousRules := []*ProxyRelayConfig{} previousRules := []*ProxyRelayConfig{}
if options.Database.KeyExists("tcprox", "rules") { if options.Database.KeyExists("tcprox", "rules") {
options.Database.Read("tcprox", "rules", &previousRules) options.Database.Read("tcprox", "rules", &previousRules)
} }
return &Manager{ //Check if the AccessControlHandler is empty. If yes, set it to always allow access
if options.AccessControlHandler == nil {
options.AccessControlHandler = func(conn net.Conn) bool {
//Always allow access
return true
}
}
//Create a new proxy manager for TCP
thisManager := Manager{
Options: options, Options: options,
Configs: previousRules,
Connections: 0, Connections: 0,
} }
//Inject manager into the rules
for _, rule := range previousRules {
rule.parent = &thisManager
}
thisManager.Configs = previousRules
return &thisManager
} }
func (m *Manager) NewConfig(config *ProxyRelayOptions) string { func (m *Manager) NewConfig(config *ProxyRelayOptions) string {
@ -85,6 +107,8 @@ func (m *Manager) NewConfig(config *ProxyRelayOptions) string {
stopChan: nil, stopChan: nil,
aTobAccumulatedByteTransfer: 0, aTobAccumulatedByteTransfer: 0,
bToaAccumulatedByteTransfer: 0, bToaAccumulatedByteTransfer: 0,
parent: m,
} }
m.Configs = append(m.Configs, &thisConfig) m.Configs = append(m.Configs, &thisConfig)
m.SaveConfigToDatabase() m.SaveConfigToDatabase()

View File

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"log" "log"
"net/http" "net/http"
"strings"
"time" "time"
"imuslab.com/zoraxy/mod/utils" "imuslab.com/zoraxy/mod/utils"
@ -220,7 +221,24 @@ func getWebsiteStatusWithLatency(url string) (bool, int64, int) {
func getWebsiteStatus(url string) (int, error) { func getWebsiteStatus(url string) (int, error) {
resp, err := http.Get(url) resp, err := http.Get(url)
if err != nil { if err != nil {
return 0, err //Try replace the http with https and vise versa
rewriteURL := ""
if strings.Contains(url, "https://") {
rewriteURL = strings.ReplaceAll(url, "https://", "http://")
} else if strings.Contains(url, "http://") {
rewriteURL = strings.ReplaceAll(url, "http://", "https://")
}
resp, err = http.Get(rewriteURL)
if err != nil {
if strings.Contains(err.Error(), "http: server gave HTTP response to HTTPS client") {
//Invalid downstream reverse proxy settings, but it is online
//return SSL handshake failed
return 525, nil
}
return 0, err
}
} }
status_code := resp.StatusCode status_code := resp.StatusCode
resp.Body.Close() resp.Body.Close()

View File

@ -47,6 +47,7 @@ func ReverseProxtInit() {
} }
dprouter, err := dynamicproxy.NewDynamicProxy(dynamicproxy.RouterOption{ dprouter, err := dynamicproxy.NewDynamicProxy(dynamicproxy.RouterOption{
HostUUID: nodeUUID,
Port: inboundPort, Port: inboundPort,
UseTls: useTls, UseTls: useTls,
ForceHttpsRedirect: forceHttpsRedirect, ForceHttpsRedirect: forceHttpsRedirect,

View File

@ -163,7 +163,8 @@ func startupSequence() {
//Create TCP Proxy Manager //Create TCP Proxy Manager
tcpProxyManager = tcpprox.NewTCProxy(&tcpprox.Options{ tcpProxyManager = tcpprox.NewTCProxy(&tcpprox.Options{
Database: sysdb, Database: sysdb,
AccessControlHandler: geodbStore.AllowConnectionAccess,
}) })
//Create WoL MAC storage table //Create WoL MAC storage table

View File

@ -109,7 +109,13 @@
} }
ontimeRate++; ontimeRate++;
}else{ }else{
dotType = "offline"; if (thisStatus.StatusCode >= 500 && thisStatus.StatusCode < 600){
//Special type of error, cause by downstream reverse proxy
dotType = "error";
}else{
dotType = "offline";
}
} }
let datetime = format_time(thisStatus.Timestamp); let datetime = format_time(thisStatus.Timestamp);
@ -126,12 +132,20 @@
//Check of online status now //Check of online status now
let currentOnlineStatus = "Unknown"; let currentOnlineStatus = "Unknown";
let onlineStatusCss = ``; let onlineStatusCss = ``;
let reminderEle = ``;
if (value[value.length - 1].Online){ if (value[value.length - 1].Online){
currentOnlineStatus = `<i class="circle icon"></i> Online`; currentOnlineStatus = `<i class="circle icon"></i> Online`;
onlineStatusCss = `color: #3bd671;`; onlineStatusCss = `color: #3bd671;`;
}else{ }else{
currentOnlineStatus = `<i class="circle icon"></i> Offline`; if (value[value.length - 1].StatusCode >= 500 && value[value.length - 1].StatusCode < 600){
onlineStatusCss = `color: #df484a;`; currentOnlineStatus = `<i class="exclamation circle icon"></i> Misconfigured`;
onlineStatusCss = `color: #f38020;`;
reminderEle = `<small style="${onlineStatusCss}">Downstream proxy server is online with misconfigured settings</small>`;
}else{
currentOnlineStatus = `<i class="circle icon"></i> Offline`;
onlineStatusCss = `color: #df484a;`;
}
} }
//Generate the html //Generate the html
@ -151,6 +165,7 @@
<div class="status" style="marign-top: 1em;"> <div class="status" style="marign-top: 1em;">
${statusDotList} ${statusDotList}
</div> </div>
${reminderEle}
<div class="ui divider"></div> <div class="ui divider"></div>
</div>`); </div>`);
} }

BIN
src/web/img/public/bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 MiB

BIN
src/web/img/public/bg2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 MiB

View File

@ -23,7 +23,7 @@
width: 100%; width: 100%;
opacity: 0.8; opacity: 0.8;
z-index: -99; z-index: -99;
background-image: url("img/public/bg.png"); background-image: url("img/public/bg.jpg");
background-size: auto 100%; background-size: auto 100%;
background-position: right top; background-position: right top;
background-repeat: no-repeat; background-repeat: no-repeat;

View File

@ -23,7 +23,7 @@
width: 100%; width: 100%;
opacity: 0.8; opacity: 0.8;
z-index: -99; z-index: -99;
background-image: url("img/public/bg2.png"); background-image: url("img/public/bg2.jpg");
background-size: auto 100%; background-size: auto 100%;
background-position: right top; background-position: right top;
background-repeat: no-repeat; background-repeat: no-repeat;

View File

@ -95,6 +95,10 @@
loadDateRange(); loadDateRange();
function isValidDateFormat(dateString) { function isValidDateFormat(dateString) {
if (dateString.indexOf("_") >= 0){
//Replace all the _ to -
dateString = dateString.split("_").join("-");
}
// Create a regular expression pattern for the yyyy-mm-dd format // Create a regular expression pattern for the yyyy-mm-dd format
const pattern = /^\d{4}-\d{2}-\d{2}$/; const pattern = /^\d{4}-\d{2}-\d{2}$/;

View File

@ -117,6 +117,7 @@ func GetUptimeTargetsFromReverseProxyRules(dp *dynamicproxy.Router) []*uptime.Ta
url = "https://" + target.Domain url = "https://" + target.Domain
protocol = "https" protocol = "https"
} }
UptimeTargets = append(UptimeTargets, &uptime.Target{ UptimeTargets = append(UptimeTargets, &uptime.Target{
ID: subd, ID: subd,
Name: subd, Name: subd,