keksvpn/cmd/sample-server/main.go

178 lines
3.2 KiB
Go

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()
}