178 lines
No EOL
3.2 KiB
Go
178 lines
No EOL
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()
|
|
} |