package main import ( "context" "encoding/json" "github.com/rs/zerolog" "github.com/rs/zerolog/log" "keksvpn/pkg/ipfunc" "keksvpn/pkg/wgfunc" "net/http" "os" "os/signal" "time" ) var wgServer wgfunc.WireGuard var ipSubnet ipfunc.IPSubnet var publickey string var privatekey string var mux *http.ServeMux var serverip string func main() { log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) ctx, cancel := context.WithCancel(context.Background()) go func() { oscall := <-c log.Printf("system call:%+v", oscall) cancel() }() setupWireguard() defer func() { down() }() setupHTTPServer() runHTTPServer(ctx) } type PeerRequest struct { PublicKey string `json:"publicKey"` } type PeerResponse struct { IP string `json:"ip"` PublicKey string `json:"publicKey"` AllowedIPs []string `json:"allowedIPs"` } func setupHTTPServer() { mux = http.NewServeMux() mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { writer.Write([]byte("ok")) }) mux.HandleFunc("/peer", func(writer http.ResponseWriter, request *http.Request) { var r = PeerRequest{} err := json.NewDecoder(request.Body).Decode(&r) if err != nil { http.Error(writer, err.Error(), http.StatusBadRequest) return } peerIP, err := ipSubnet.GetNextFreeIP() if err != nil { http.Error(writer, err.Error(), http.StatusBadRequest) return } peerConfig := wgfunc.PeerConfig{ PublicKey: r.PublicKey, PreSharedKey: "", AllowedIPs: []string{peerIP + "/32"}, Endpoint: "", } wgServer.AddPeer(peerConfig) res := PeerResponse{ IP: peerIP + "/32", PublicKey: publickey, AllowedIPs: []string{serverip+"/24"}, } byteRes, err := json.Marshal(res) if err != nil { http.Error(writer, err.Error(), http.StatusBadRequest) return } writer.Write(byteRes) }) } func runHTTPServer(ctx context.Context) { var err error log.Info().Msg("Start HTTP Server") srv := &http.Server{ Addr: ":8080", Handler: mux, } go func() { if err = srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatal().Err(err).Msg("Error running HTTP Server") } }() log.Debug().Msg("HTTP Server started") <-ctx.Done() log.Debug().Msg("HTTP Server stopping") ctxShutDown, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer func() { cancel() }() if err = srv.Shutdown(ctxShutDown); err != nil { log.Fatal().Err(err).Msg("Error stop HTTP Server") } } func setKeys() { var err error publickey, privatekey, err = wgfunc.GenerateKeyPair() if err != nil { panic(err) } } func setupWireguard() { var err error setKeys() ipSubnet, err = ipfunc.NewIPSubnet("10.0.4.0/24") if err != nil { panic(err) } serverip, err = ipSubnet.GetNextFreeIP() if err != nil { panic(err) } serverConfig := wgfunc.WireGuardConfig{ Name: "wgSampleServer", IPRanges: []string{serverip + "/24"}, Port: 51820, PrivateKey: privatekey, } wgServer, err = wgfunc.NewWireGuard(serverConfig) if err != nil { panic(err) } err = wgServer.Up() if err != nil { panic(err) } } func down() { log.Debug().Msg("Stop Wireguard Server") wgServer.Down() }