mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-06-03 06:07:20 +02:00
Updated GAN features
+ Added add controller as memeber feature + Deprecated aroz subservice support
This commit is contained in:
parent
059b0a2e1c
commit
216b53f224
35
README.md
35
README.md
@ -83,8 +83,6 @@ Usage of zoraxy:
|
|||||||
Disable authentication for management interface
|
Disable authentication for management interface
|
||||||
-port string
|
-port string
|
||||||
Management web interface listening port (default ":8000")
|
Management web interface listening port (default ":8000")
|
||||||
-rpt string
|
|
||||||
Reserved
|
|
||||||
-sshlb
|
-sshlb
|
||||||
Allow loopback web ssh connection (DANGER)
|
Allow loopback web ssh connection (DANGER)
|
||||||
-version
|
-version
|
||||||
@ -109,39 +107,6 @@ If you already have an upstream reverse proxy server in place with permission ma
|
|||||||
|
|
||||||
*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.*
|
*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
|
|
||||||
|
|
||||||
The [ArozOS](https://arozos.com) subservice is a built-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. Sometimes 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}
|
|
||||||
|
|
||||||
# Set permission. Change this if required.
|
|
||||||
sudo chmod 775 -R ./
|
|
||||||
|
|
||||||
# Start zoraxy to see if the downloaded arch is correct.
|
|
||||||
./zoraxy
|
|
||||||
|
|
||||||
# After unzipping, press Ctrl + C to kill it.
|
|
||||||
# Rename it to validate the ArozOS subservice binary format.
|
|
||||||
mv ./zoraxy zoraxy_linux_amd64
|
|
||||||
|
|
||||||
# If you are using SBCs with a different CPU arch, use the following names:
|
|
||||||
# mv ./zoraxy zoraxy_linux_arm
|
|
||||||
# mv ./zoraxy zoraxy_linux_arm64
|
|
||||||
|
|
||||||
# Restart ArozOS
|
|
||||||
sudo systemctl restart arozos
|
|
||||||
```
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||

|

|
||||||
|
@ -119,6 +119,8 @@ func initAPIs() {
|
|||||||
authRouter.HandleFunc("/api/gan/network/name", ganManager.HandleNetworkNaming)
|
authRouter.HandleFunc("/api/gan/network/name", ganManager.HandleNetworkNaming)
|
||||||
//authRouter.HandleFunc("/api/gan/network/detail", ganManager.HandleNetworkDetails)
|
//authRouter.HandleFunc("/api/gan/network/detail", ganManager.HandleNetworkDetails)
|
||||||
authRouter.HandleFunc("/api/gan/network/setRange", ganManager.HandleSetRanges)
|
authRouter.HandleFunc("/api/gan/network/setRange", ganManager.HandleSetRanges)
|
||||||
|
authRouter.HandleFunc("/api/gan/network/join", ganManager.HandleServerJoinNetwork)
|
||||||
|
authRouter.HandleFunc("/api/gan/network/leave", ganManager.HandleServerLeaveNetwork)
|
||||||
authRouter.HandleFunc("/api/gan/members/list", ganManager.HandleMemberList)
|
authRouter.HandleFunc("/api/gan/members/list", ganManager.HandleMemberList)
|
||||||
authRouter.HandleFunc("/api/gan/members/ip", ganManager.HandleMemberIP)
|
authRouter.HandleFunc("/api/gan/members/ip", ganManager.HandleMemberIP)
|
||||||
authRouter.HandleFunc("/api/gan/members/name", ganManager.HandleMemberNaming)
|
authRouter.HandleFunc("/api/gan/members/name", ganManager.HandleMemberNaming)
|
||||||
|
25
src/main.go
25
src/main.go
@ -13,7 +13,6 @@ import (
|
|||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"imuslab.com/zoraxy/mod/acme"
|
"imuslab.com/zoraxy/mod/acme"
|
||||||
"imuslab.com/zoraxy/mod/aroz"
|
|
||||||
"imuslab.com/zoraxy/mod/auth"
|
"imuslab.com/zoraxy/mod/auth"
|
||||||
"imuslab.com/zoraxy/mod/database"
|
"imuslab.com/zoraxy/mod/database"
|
||||||
"imuslab.com/zoraxy/mod/dynamicproxy/redirection"
|
"imuslab.com/zoraxy/mod/dynamicproxy/redirection"
|
||||||
@ -35,6 +34,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// General flags
|
// General flags
|
||||||
|
var webUIPort = flag.String("port", ":8000", "Management web interface listening port")
|
||||||
var noauth = flag.Bool("noauth", false, "Disable authentication for management interface")
|
var noauth = flag.Bool("noauth", false, "Disable authentication for management interface")
|
||||||
var showver = flag.Bool("version", false, "Show version of this server")
|
var showver = flag.Bool("version", false, "Show version of this server")
|
||||||
var allowSshLoopback = flag.Bool("sshlb", false, "Allow loopback web ssh connection (DANGER)")
|
var allowSshLoopback = flag.Bool("sshlb", false, "Allow loopback web ssh connection (DANGER)")
|
||||||
@ -63,7 +63,6 @@ var (
|
|||||||
/*
|
/*
|
||||||
Handler Modules
|
Handler Modules
|
||||||
*/
|
*/
|
||||||
handler *aroz.ArozHandler //Handle arozos managed permission system
|
|
||||||
sysdb *database.Database //System database
|
sysdb *database.Database //System database
|
||||||
authAgent *auth.AuthAgent //Authentication agent
|
authAgent *auth.AuthAgent //Authentication agent
|
||||||
tlsCertManager *tlscert.Manager //TLS / SSL management
|
tlsCertManager *tlscert.Manager //TLS / SSL management
|
||||||
@ -128,20 +127,8 @@ func ShutdownSeq() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
//Start the aoModule pipeline (which will parse the flags as well). Pass in the module launch information
|
//Parse startup flags
|
||||||
handler = aroz.HandleFlagParse(aroz.ServiceInfo{
|
flag.Parse()
|
||||||
Name: name,
|
|
||||||
Desc: "Dynamic Reverse Proxy Server",
|
|
||||||
Group: "Network",
|
|
||||||
IconPath: "zoraxy/img/small_icon.png",
|
|
||||||
Version: version,
|
|
||||||
StartDir: "zoraxy/index.html",
|
|
||||||
SupportFW: true,
|
|
||||||
LaunchFWDir: "zoraxy/index.html",
|
|
||||||
SupportEmb: false,
|
|
||||||
InitFWSize: []int{1080, 580},
|
|
||||||
})
|
|
||||||
|
|
||||||
if *showver {
|
if *showver {
|
||||||
fmt.Println(name + " - Version " + version)
|
fmt.Println(name + " - Version " + version)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
@ -166,7 +153,7 @@ func main() {
|
|||||||
startupSequence()
|
startupSequence()
|
||||||
|
|
||||||
//Initiate management interface APIs
|
//Initiate management interface APIs
|
||||||
requireAuth = !(*noauth || handler.IsUsingExternalPermissionManager())
|
requireAuth = !(*noauth)
|
||||||
initAPIs()
|
initAPIs()
|
||||||
|
|
||||||
//Start the reverse proxy server in go routine
|
//Start the reverse proxy server in go routine
|
||||||
@ -179,8 +166,8 @@ func main() {
|
|||||||
//Start the finalize sequences
|
//Start the finalize sequences
|
||||||
finalSequence()
|
finalSequence()
|
||||||
|
|
||||||
SystemWideLogger.Println("Zoraxy started. Visit control panel at http://localhost" + handler.Port)
|
SystemWideLogger.Println("Zoraxy started. Visit control panel at http://localhost" + *webUIPort)
|
||||||
err = http.ListenAndServe(handler.Port, nil)
|
err = http.ListenAndServe(*webUIPort, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -207,7 +207,7 @@ func (m *NetworkManager) HandleSetRanges(w http.ResponseWriter, r *http.Request)
|
|||||||
utils.SendOK(w)
|
utils.SendOK(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Handle listing of network members. Set details=true for listing all details
|
// Handle listing of network members. Set details=true for listing all details
|
||||||
func (m *NetworkManager) HandleMemberList(w http.ResponseWriter, r *http.Request) {
|
func (m *NetworkManager) HandleMemberList(w http.ResponseWriter, r *http.Request) {
|
||||||
netid, err := utils.GetPara(r, "netid")
|
netid, err := utils.GetPara(r, "netid")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -241,7 +241,7 @@ func (m *NetworkManager) HandleMemberList(w http.ResponseWriter, r *http.Request
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Handle Authorization of members
|
// Handle Authorization of members
|
||||||
func (m *NetworkManager) HandleMemberAuthorization(w http.ResponseWriter, r *http.Request) {
|
func (m *NetworkManager) HandleMemberAuthorization(w http.ResponseWriter, r *http.Request) {
|
||||||
netid, err := utils.PostPara(r, "netid")
|
netid, err := utils.PostPara(r, "netid")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -281,7 +281,7 @@ func (m *NetworkManager) HandleMemberAuthorization(w http.ResponseWriter, r *htt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Handle Delete or Add IP for a member in a network
|
// Handle Delete or Add IP for a member in a network
|
||||||
func (m *NetworkManager) HandleMemberIP(w http.ResponseWriter, r *http.Request) {
|
func (m *NetworkManager) HandleMemberIP(w http.ResponseWriter, r *http.Request) {
|
||||||
netid, err := utils.PostPara(r, "netid")
|
netid, err := utils.PostPara(r, "netid")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -356,7 +356,7 @@ func (m *NetworkManager) HandleMemberIP(w http.ResponseWriter, r *http.Request)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Handle naming for members
|
// Handle naming for members
|
||||||
func (m *NetworkManager) HandleMemberNaming(w http.ResponseWriter, r *http.Request) {
|
func (m *NetworkManager) HandleMemberNaming(w http.ResponseWriter, r *http.Request) {
|
||||||
netid, err := utils.PostPara(r, "netid")
|
netid, err := utils.PostPara(r, "netid")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -391,7 +391,7 @@ func (m *NetworkManager) HandleMemberNaming(w http.ResponseWriter, r *http.Reque
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Handle delete of a given memver
|
// Handle delete of a given memver
|
||||||
func (m *NetworkManager) HandleMemberDelete(w http.ResponseWriter, r *http.Request) {
|
func (m *NetworkManager) HandleMemberDelete(w http.ResponseWriter, r *http.Request) {
|
||||||
netid, err := utils.PostPara(r, "netid")
|
netid, err := utils.PostPara(r, "netid")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -426,3 +426,79 @@ func (m *NetworkManager) HandleMemberDelete(w http.ResponseWriter, r *http.Reque
|
|||||||
|
|
||||||
utils.SendOK(w)
|
utils.SendOK(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if a given network id is a network hosted on this zoraxy node
|
||||||
|
func (m *NetworkManager) IsLocalGAN(networkId string) bool {
|
||||||
|
networks, err := m.listNetworkIds()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, network := range networks {
|
||||||
|
if network == networkId {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle server instant joining a given network
|
||||||
|
func (m *NetworkManager) HandleServerJoinNetwork(w http.ResponseWriter, r *http.Request) {
|
||||||
|
netid, err := utils.PostPara(r, "netid")
|
||||||
|
if err != nil {
|
||||||
|
utils.SendErrorResponse(w, "net id not set")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if the target network is a network hosted on this server
|
||||||
|
if !m.IsLocalGAN(netid) {
|
||||||
|
utils.SendErrorResponse(w, "given network is not a GAN hosted on this node")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.memberExistsInNetwork(netid, m.ControllerID) {
|
||||||
|
utils.SendErrorResponse(w, "controller already inside network")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Join the network
|
||||||
|
err = m.joinNetwork(netid)
|
||||||
|
if err != nil {
|
||||||
|
utils.SendErrorResponse(w, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.SendOK(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle server instant leaving a given network
|
||||||
|
func (m *NetworkManager) HandleServerLeaveNetwork(w http.ResponseWriter, r *http.Request) {
|
||||||
|
netid, err := utils.PostPara(r, "netid")
|
||||||
|
if err != nil {
|
||||||
|
utils.SendErrorResponse(w, "net id not set")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if the target network is a network hosted on this server
|
||||||
|
if !m.IsLocalGAN(netid) {
|
||||||
|
utils.SendErrorResponse(w, "given network is not a GAN hosted on this node")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Leave the network
|
||||||
|
err = m.leaveNetwork(netid)
|
||||||
|
if err != nil {
|
||||||
|
utils.SendErrorResponse(w, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove it from target network if it is authorized
|
||||||
|
err = m.deleteMember(netid, m.ControllerID)
|
||||||
|
if err != nil {
|
||||||
|
utils.SendErrorResponse(w, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.SendOK(w)
|
||||||
|
}
|
||||||
|
@ -117,7 +117,7 @@ type MemberInfo struct {
|
|||||||
VRev int `json:"vRev"`
|
VRev int `json:"vRev"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get the zerotier node info from local service
|
// Get the zerotier node info from local service
|
||||||
func getControllerInfo(token string, apiPort int) (*NodeInfo, error) {
|
func getControllerInfo(token string, apiPort int) (*NodeInfo, error) {
|
||||||
url := "http://localhost:" + strconv.Itoa(apiPort) + "/status"
|
url := "http://localhost:" + strconv.Itoa(apiPort) + "/status"
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ func (m *NetworkManager) createNetwork() (*NetworkInfo, error) {
|
|||||||
return &networkInfo, nil
|
return &networkInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//List network details
|
// List network details
|
||||||
func (m *NetworkManager) getNetworkInfoById(networkId string) (*NetworkInfo, error) {
|
func (m *NetworkManager) getNetworkInfoById(networkId string) (*NetworkInfo, error) {
|
||||||
req, err := http.NewRequest("GET", os.ExpandEnv("http://localhost:"+strconv.Itoa(m.apiPort)+"/controller/network/"+networkId+"/"), nil)
|
req, err := http.NewRequest("GET", os.ExpandEnv("http://localhost:"+strconv.Itoa(m.apiPort)+"/controller/network/"+networkId+"/"), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -249,7 +249,7 @@ func (m *NetworkManager) setNetworkInfoByID(networkId string, newNetworkInfo *Ne
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//List network IDs
|
// List network IDs
|
||||||
func (m *NetworkManager) listNetworkIds() ([]string, error) {
|
func (m *NetworkManager) listNetworkIds() ([]string, error) {
|
||||||
req, err := http.NewRequest("GET", "http://localhost:"+strconv.Itoa(m.apiPort)+"/controller/network/", nil)
|
req, err := http.NewRequest("GET", "http://localhost:"+strconv.Itoa(m.apiPort)+"/controller/network/", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -281,7 +281,7 @@ func (m *NetworkManager) listNetworkIds() ([]string, error) {
|
|||||||
return networkIds, nil
|
return networkIds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//wrapper for checking if a network id exists
|
// wrapper for checking if a network id exists
|
||||||
func (m *NetworkManager) networkExists(networkId string) bool {
|
func (m *NetworkManager) networkExists(networkId string) bool {
|
||||||
networkIds, err := m.listNetworkIds()
|
networkIds, err := m.listNetworkIds()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -297,7 +297,7 @@ func (m *NetworkManager) networkExists(networkId string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
//delete a network
|
// delete a network
|
||||||
func (m *NetworkManager) deleteNetwork(networkID string) error {
|
func (m *NetworkManager) deleteNetwork(networkID string) error {
|
||||||
url := "http://localhost:" + strconv.Itoa(m.apiPort) + "/controller/network/" + networkID + "/"
|
url := "http://localhost:" + strconv.Itoa(m.apiPort) + "/controller/network/" + networkID + "/"
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
@ -330,8 +330,8 @@ func (m *NetworkManager) deleteNetwork(networkID string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Configure network
|
// Configure network
|
||||||
//Example: configureNetwork(netid, "192.168.192.1", "192.168.192.254", "192.168.192.0/24")
|
// Example: configureNetwork(netid, "192.168.192.1", "192.168.192.254", "192.168.192.0/24")
|
||||||
func (m *NetworkManager) configureNetwork(networkID string, ipRangeStart string, ipRangeEnd string, routeTarget string) error {
|
func (m *NetworkManager) configureNetwork(networkID string, ipRangeStart string, ipRangeEnd string, routeTarget string) error {
|
||||||
url := "http://localhost:" + strconv.Itoa(m.apiPort) + "/controller/network/" + networkID + "/"
|
url := "http://localhost:" + strconv.Itoa(m.apiPort) + "/controller/network/" + networkID + "/"
|
||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
@ -545,7 +545,7 @@ func (m *NetworkManager) memberExistsInNetwork(netid string, memid string) bool
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get a network memeber info by netid and memberid
|
// Get a network memeber info by netid and memberid
|
||||||
func (m *NetworkManager) getNetworkMemberInfo(netid string, memberid string) (*MemberInfo, error) {
|
func (m *NetworkManager) getNetworkMemberInfo(netid string, memberid string) (*MemberInfo, error) {
|
||||||
req, err := http.NewRequest("GET", "http://localhost:"+strconv.Itoa(m.apiPort)+"/controller/network/"+netid+"/member/"+memberid, nil)
|
req, err := http.NewRequest("GET", "http://localhost:"+strconv.Itoa(m.apiPort)+"/controller/network/"+netid+"/member/"+memberid, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -573,7 +573,7 @@ func (m *NetworkManager) getNetworkMemberInfo(netid string, memberid string) (*M
|
|||||||
return thisMemeberInfo, nil
|
return thisMemeberInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set the authorization state of a member
|
// Set the authorization state of a member
|
||||||
func (m *NetworkManager) AuthorizeMember(netid string, memberid string, setAuthorized bool) error {
|
func (m *NetworkManager) AuthorizeMember(netid string, memberid string, setAuthorized bool) error {
|
||||||
url := "http://localhost:" + strconv.Itoa(m.apiPort) + "/controller/network/" + netid + "/member/" + memberid
|
url := "http://localhost:" + strconv.Itoa(m.apiPort) + "/controller/network/" + netid + "/member/" + memberid
|
||||||
payload := []byte(`{"authorized": true}`)
|
payload := []byte(`{"authorized": true}`)
|
||||||
@ -600,7 +600,7 @@ func (m *NetworkManager) AuthorizeMember(netid string, memberid string, setAutho
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Delete a member from the network
|
// Delete a member from the network
|
||||||
func (m *NetworkManager) deleteMember(netid string, memid string) error {
|
func (m *NetworkManager) deleteMember(netid string, memid string) error {
|
||||||
req, err := http.NewRequest("DELETE", "http://localhost:"+strconv.Itoa(m.apiPort)+"/controller/network/"+netid+"/member/"+memid, nil)
|
req, err := http.NewRequest("DELETE", "http://localhost:"+strconv.Itoa(m.apiPort)+"/controller/network/"+netid+"/member/"+memid, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -620,3 +620,45 @@ func (m *NetworkManager) deleteMember(netid string, memid string) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make the host to join a given network
|
||||||
|
func (m *NetworkManager) joinNetwork(netid string) error {
|
||||||
|
req, err := http.NewRequest("POST", "http://localhost:"+strconv.Itoa(m.apiPort)+"/network/"+netid, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.Header.Set("X-Zt1-Auth", os.ExpandEnv(m.authToken))
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return errors.New("network error. Status code: " + strconv.Itoa(resp.StatusCode))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the host to leave a given network
|
||||||
|
func (m *NetworkManager) leaveNetwork(netid string) error {
|
||||||
|
req, err := http.NewRequest("DELETE", "http://localhost:"+strconv.Itoa(m.apiPort)+"/network/"+netid, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.Header.Set("X-Zt1-Auth", os.ExpandEnv(m.authToken))
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return errors.New("network error. Status code: " + strconv.Itoa(resp.StatusCode))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -140,7 +140,7 @@ func startupSequence() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if *allowMdnsScanning {
|
if *allowMdnsScanning {
|
||||||
portInt, err := strconv.Atoi(strings.Split(handler.Port, ":")[1])
|
portInt, err := strconv.Atoi(strings.Split(*webUIPort, ":")[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
portInt = 8000
|
portInt = 8000
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="header" style="font-size: 1.2em;" id="ganodeCount">0</div>
|
<div class="header" style="font-size: 1.2em;" id="ganodeCount">0</div>
|
||||||
<div class="description" id="connectedNodes" count="0">Connected Nodes</div>
|
<div class="description" id="connectedNodes" count="0">Connected Nodes</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -219,8 +218,8 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Bind event to tab switch
|
//Bind event to tab switch
|
||||||
tabSwitchEventBind["gan"] = function(){
|
tabSwitchEventBind["gan"] = function(){
|
||||||
//On switch over to this page, load info
|
//On switch over to this page, load info
|
||||||
listGANet();
|
listGANet();
|
||||||
initGANetID();
|
initGANetID();
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
<h2>Members</h2>
|
<h2>Members</h2>
|
||||||
<p>To join this network using command line, type <code>sudo zerotier-cli join <span class="ganetID"></span></code> on your device terminal</p>
|
<p>To join this network using command line, type <code>sudo zerotier-cli join <span class="ganetID"></span></code> on your device terminal</p>
|
||||||
<div class="ui checkbox" style="margin-bottom: 1em;">
|
<div class="ui checkbox" style="margin-bottom: 1em;">
|
||||||
<input id="showUnauthorizedMembers" type="checkbox" onchange="changeUnauthorizedVisibility(this.checked);">
|
<input id="showUnauthorizedMembers" type="checkbox" onchange="changeUnauthorizedVisibility(this.checked);" checked>
|
||||||
<label>Show Unauthorized Members</label>
|
<label>Show Unauthorized Members</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="" style="overflow-x: auto;">
|
<div class="" style="overflow-x: auto;">
|
||||||
@ -84,6 +84,11 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="ui divider"></div>
|
||||||
|
<h4>Add Controller as Member</h4>
|
||||||
|
<p>Optionally you can add the network controller (ZeroTier running on the Zoraxy node) as member for cross GAN reverse proxy to bypass NAT limitations.</p>
|
||||||
|
<button class="ui basic small button addControllerToNetworkBtn" onclick="ganAddControllerToNetwork(this);"><i class="green add icon"></i> Add Controller as Member</button>
|
||||||
|
<button class="ui basic small button removeControllerFromNetworkBtn" onclick="ganRemoveControllerFromNetwork(this);"><i class="red sign-out icon"></i> Remove Controller from Member</button>
|
||||||
<br><br>
|
<br><br>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
@ -355,7 +360,10 @@
|
|||||||
url: '/api/gan/members/list?netid=' + currentGANetID + '&detail=true',
|
url: '/api/gan/members/list?netid=' + currentGANetID + '&detail=true',
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
const tableBody = $('#networkMemeberTable');
|
let tableBody = $('#networkMemeberTable');
|
||||||
|
if (tableBody.length == 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
data.sort((a, b) => a.address.localeCompare(b.address));
|
data.sort((a, b) => a.address.localeCompare(b.address));
|
||||||
//Check if the new object equal to the old one
|
//Check if the new object equal to the old one
|
||||||
if (objectEqual(currentGANMemberList, data) && !forceUpdate){
|
if (objectEqual(currentGANMemberList, data) && !forceUpdate){
|
||||||
@ -592,6 +600,55 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Add and remove this controller node to network as member
|
||||||
|
function ganAddControllerToNetwork(){
|
||||||
|
$(".addControllerToNetworkBtn").addClass("disabled");
|
||||||
|
$(".addControllerToNetworkBtn").addClass("loading");
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "/api/gan/network/join",
|
||||||
|
method: "POST",
|
||||||
|
data: {
|
||||||
|
netid:currentGANetID,
|
||||||
|
},
|
||||||
|
success: function(data){
|
||||||
|
$(".addControllerToNetworkBtn").removeClass("disabled");
|
||||||
|
$(".addControllerToNetworkBtn").removeClass("loading");
|
||||||
|
if (data.error != undefined){
|
||||||
|
msgbox(data.error, false, 6000);
|
||||||
|
}else{
|
||||||
|
msgbox("Controller joint " + currentGANetID);
|
||||||
|
}
|
||||||
|
setTimeout(function(){
|
||||||
|
renderMemeberTable(true);
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function ganRemoveControllerFromNetwork(){
|
||||||
|
$(".removeControllerFromNetworkBtn").addClass("disabled");
|
||||||
|
$(".removeControllerFromNetworkBtn").addClass("loading");
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "/api/gan/network/leave",
|
||||||
|
method: "POST",
|
||||||
|
data: {
|
||||||
|
netid:currentGANetID,
|
||||||
|
},
|
||||||
|
success: function(data){
|
||||||
|
if (data.error != undefined){
|
||||||
|
msgbox(data.error, false, 6000);
|
||||||
|
}else{
|
||||||
|
msgbox("Controller left " + currentGANetID);
|
||||||
|
}
|
||||||
|
renderMemeberTable(true);
|
||||||
|
$(".removeControllerFromNetworkBtn").removeClass("disabled");
|
||||||
|
$(".removeControllerFromNetworkBtn").removeClass("loading");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//Entry points
|
//Entry points
|
||||||
function initGanetDetails(ganetId){
|
function initGanetDetails(ganetId){
|
||||||
currentGANetID = ganetId;
|
currentGANetID = ganetId;
|
||||||
@ -612,6 +669,11 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Switch from other tabs back to this, exit to GAN list
|
||||||
|
tabSwitchEventBind["gan"] = function(){
|
||||||
|
exitToGanList();
|
||||||
|
}
|
||||||
|
|
||||||
//Exit point
|
//Exit point
|
||||||
function exitToGanList(){
|
function exitToGanList(){
|
||||||
$("#gan").load("./components/gan.html", function(){
|
$("#gan").load("./components/gan.html", function(){
|
||||||
|
@ -284,10 +284,11 @@
|
|||||||
$("#mainmenu").find(".item").removeClass("active");
|
$("#mainmenu").find(".item").removeClass("active");
|
||||||
$(targetBtn).addClass("active");
|
$(targetBtn).addClass("active");
|
||||||
$(".functiontab").hide();
|
$(".functiontab").hide();
|
||||||
|
if (tabSwitchEventBind[tabID]){
|
||||||
|
tabSwitchEventBind[tabID]();
|
||||||
|
}
|
||||||
$("#" + tabID).fadeIn('fast', function(){
|
$("#" + tabID).fadeIn('fast', function(){
|
||||||
if (tabSwitchEventBind[tabID]){
|
|
||||||
tabSwitchEventBind[tabID]();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
$('html,body').animate({scrollTop: 0}, 'fast');
|
$('html,body').animate({scrollTop: 0}, 'fast');
|
||||||
window.location.hash = tabID;
|
window.location.hash = tabID;
|
||||||
|
@ -356,10 +356,6 @@ body{
|
|||||||
color: var(--item_color);
|
color: var(--item_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.menu .item:hover{
|
|
||||||
color: var(--item_color_select) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.segment{
|
.ui.segment{
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user