feat: monitor peers in logs, README, Status
Signed-off-by: HeshamTB <hishaminv@gmail.com>
This commit is contained in:
		
							parent
							
								
									4bab068c10
								
							
						
					
					
						commit
						ed0fcb59eb
					
				@ -1,5 +1,8 @@
 | 
				
			|||||||
# hvpn-node3
 | 
					# hvpn-node3
 | 
				
			||||||
 | 
					hvpn is a basic HTTP API service that manages wireguard VPN. Can be part of part of
 | 
				
			||||||
 | 
					a larger system of services. The program itself does not route and manage the
 | 
				
			||||||
 | 
					VPN traffic; but the underlying host and kernel wiregaurd driver. hvpn only
 | 
				
			||||||
 | 
					exposes the state and allows changes to be applied.
 | 
				
			||||||
## Build
 | 
					## Build
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
cd cmd/hvpn-node && go build .
 | 
					cd cmd/hvpn-node && go build .
 | 
				
			||||||
 | 
				
			|||||||
@ -55,6 +55,8 @@ func main() {
 | 
				
			|||||||
func run(ctx *cli.Context) {
 | 
					func run(ctx *cli.Context) {
 | 
				
			||||||
    slog.Debug("Starting run()")
 | 
					    slog.Debug("Starting run()")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hvpnnode3.StartMonitor(wgLink, *slog.Default())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    apiMux := http.NewServeMux()
 | 
					    apiMux := http.NewServeMux()
 | 
				
			||||||
    apiMux.HandleFunc("GET /node", hvpnnode3.HandleGetNodeInfo(wgLink))
 | 
					    apiMux.HandleFunc("GET /node", hvpnnode3.HandleGetNodeInfo(wgLink))
 | 
				
			||||||
    apiMux.HandleFunc("GET /peer/{pubkey}", hvpnnode3.HandleGetPeer(wgLink))
 | 
					    apiMux.HandleFunc("GET /peer/{pubkey}", hvpnnode3.HandleGetPeer(wgLink))
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										5
									
								
								const.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								const.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					package hvpnnode3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
					    CONTENT_JSON = "application/json"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										17
									
								
								handlers.go
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								handlers.go
									
									
									
									
									
								
							@ -7,6 +7,7 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"log/slog"
 | 
						"log/slog"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/felixge/httpsnoop"
 | 
						"github.com/felixge/httpsnoop"
 | 
				
			||||||
	"github.com/google/uuid"
 | 
						"github.com/google/uuid"
 | 
				
			||||||
@ -119,15 +120,8 @@ func HandlePostPeer(wgLink *WGLink) http.HandlerFunc {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        if exists {
 | 
					        if exists {
 | 
				
			||||||
            debugf("Peer %s already exists", reqID, peerRequest.PublicKey)
 | 
					            debugf("Peer %s already exists", reqID, peerRequest.PublicKey)
 | 
				
			||||||
            w.WriteHeader(http.StatusFound)
 | 
					            w.Header().Add("Location", fmt.Sprintf("/peer/%s", url.QueryEscape(peerRequest.PublicKey)))
 | 
				
			||||||
            peer, err := wgLink.GetPeer(peerRequest.PublicKey)
 | 
					            w.WriteHeader(http.StatusConflict)
 | 
				
			||||||
            if err != nil {
 | 
					 | 
				
			||||||
                slog.Error(err.Error())
 | 
					 | 
				
			||||||
                return
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            json.NewEncoder(w).Encode(
 | 
					 | 
				
			||||||
                proto.WgPeerToPeer(*peer),
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -140,7 +134,9 @@ func HandlePostPeer(wgLink *WGLink) http.HandlerFunc {
 | 
				
			|||||||
            )
 | 
					            )
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        debugf("Allocated IP: %s", reqID, peer.AllowedIPs[0].IP.String())
 | 
					        infof("Allocated IP: %s", reqID, peer.AllowedIPs[0].IP.String())
 | 
				
			||||||
 | 
					        infof("Peer %s added", reqID, peerRequest.PublicKey)
 | 
				
			||||||
 | 
					        w.Header().Set("Content-Type", CONTENT_JSON)
 | 
				
			||||||
        w.WriteHeader(http.StatusCreated)
 | 
					        w.WriteHeader(http.StatusCreated)
 | 
				
			||||||
        json.NewEncoder(w).Encode(
 | 
					        json.NewEncoder(w).Encode(
 | 
				
			||||||
            proto.WgPeerToPeer(*peer),
 | 
					            proto.WgPeerToPeer(*peer),
 | 
				
			||||||
@ -174,6 +170,7 @@ func HandleDeletePeer(wg *WGLink) http.HandlerFunc {
 | 
				
			|||||||
            )
 | 
					            )
 | 
				
			||||||
            slog.Error(err.Error())
 | 
					            slog.Error(err.Error())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        w.WriteHeader(http.StatusNoContent)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										61
									
								
								monitor.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								monitor.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					package hvpnnode3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"log/slog"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var log slog.Logger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func StartMonitor(wg *WGLink, log slog.Logger) {
 | 
				
			||||||
 | 
					    go monitor(wg, log)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func monitor(wg *WGLink, log slog.Logger) {
 | 
				
			||||||
 | 
					    log.Info("[WGMonitor] Starting")
 | 
				
			||||||
 | 
					    for {
 | 
				
			||||||
 | 
					        time.Sleep(time.Second * 5)
 | 
				
			||||||
 | 
					        peers, err := wg.GetAllPeers()
 | 
				
			||||||
 | 
					        if err != nil {
 | 
				
			||||||
 | 
					            log.Error("[WGMonitor] " + err.Error())
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        activepeers, err := getActivePeers(peers)
 | 
				
			||||||
 | 
					        if err != nil {
 | 
				
			||||||
 | 
					            log.Error("[WGMonitor] " + err.Error())
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sb := strings.Builder{}
 | 
				
			||||||
 | 
					        sb.WriteString(fmt.Sprintf("Peers: %d ", len(peers)))
 | 
				
			||||||
 | 
					        sb.WriteString(fmt.Sprintf("Active peers: %d ", len(activepeers)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var totalRx int64
 | 
				
			||||||
 | 
					        var totalTx int64
 | 
				
			||||||
 | 
					        for _, peer := range activepeers {
 | 
				
			||||||
 | 
					            totalRx += peer.ReceiveBytes
 | 
				
			||||||
 | 
					            totalTx += peer.TransmitBytes
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        sb.WriteString(fmt.Sprintf("TX: %d RX: %d", totalTx, totalRx))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        log.Info("[WGMonitor] " + sb.String())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getActivePeers(peers []wgtypes.Peer) ([]wgtypes.Peer, error) {
 | 
				
			||||||
 | 
					    active := make([]wgtypes.Peer, 0)
 | 
				
			||||||
 | 
					    for _, peer := range peers {
 | 
				
			||||||
 | 
					        if peer.LastHandshakeTime.IsZero() {
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
 | 
					        } else if time.Now().UTC().Sub(peer.LastHandshakeTime.UTC()) < time.Duration(4 * time.Minute) {
 | 
				
			||||||
 | 
					            active = append(active, peer)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return active, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user