WIP: create new peers server-side
Creates a new peer server-side.
    - Gen keys
    - Allocate IP
    - Add to WG Link
    - Respond with a read wg config for the client to use
			
			
This commit is contained in:
		
							parent
							
								
									d6aa213461
								
							
						
					
					
						commit
						8e798706e3
					
				@ -65,6 +65,7 @@ func run(ctx *cli.Context) {
 | 
				
			|||||||
    apiMux.HandleFunc("POST /peer", hvpnnode3.HandlePostPeer(wgLink))
 | 
					    apiMux.HandleFunc("POST /peer", hvpnnode3.HandlePostPeer(wgLink))
 | 
				
			||||||
    apiMux.HandleFunc("DELETE /peer/{pubkey}", hvpnnode3.HandleDeletePeer(wgLink))
 | 
					    apiMux.HandleFunc("DELETE /peer/{pubkey}", hvpnnode3.HandleDeletePeer(wgLink))
 | 
				
			||||||
    apiMux.HandleFunc("GET /peers", hvpnnode3.HandleGetPeers(wgLink))
 | 
					    apiMux.HandleFunc("GET /peers", hvpnnode3.HandleGetPeers(wgLink))
 | 
				
			||||||
 | 
					    apiMux.HandleFunc("GET /peer/new", hvpnnode3.HandleGetCreatePeer(wgLink))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var handler http.Handler = apiMux
 | 
					    var handler http.Handler = apiMux
 | 
				
			||||||
    handler = hvpnnode3.HttpAuthToken(handler, ctx.String("http-api-key"))
 | 
					    handler = hvpnnode3.HttpAuthToken(handler, ctx.String("http-api-key"))
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								const.go
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								const.go
									
									
									
									
									
								
							@ -1,5 +1,17 @@
 | 
				
			|||||||
package hvpnnode3
 | 
					package hvpnnode3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "net"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
    CONTENT_JSON = "application/json"
 | 
					    CONTENT_JSON = "application/json"
 | 
				
			||||||
 | 
					    CONTENT_OCTET = "application/octet-stream"
 | 
				
			||||||
 | 
					    CONTENT_PLAIN_TEXT = "text/plain"
 | 
				
			||||||
 | 
					    WG_CLIENT_MTU = 1380
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
					    WG_CLIENT_DNS = []net.IP{
 | 
				
			||||||
 | 
					        net.ParseIP("1.1.1.1"),
 | 
				
			||||||
 | 
					        net.ParseIP("8.8.8.8"),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										29
									
								
								handlers.go
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								handlers.go
									
									
									
									
									
								
							@ -8,12 +8,14 @@ import (
 | 
				
			|||||||
	"log/slog"
 | 
						"log/slog"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
 | 
						"text/template"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/felixge/httpsnoop"
 | 
						"github.com/felixge/httpsnoop"
 | 
				
			||||||
	"github.com/google/uuid"
 | 
						"github.com/google/uuid"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"gitea.hbanafa.com/HeshamTB/hvpn-node3/proto"
 | 
						"gitea.hbanafa.com/HeshamTB/hvpn-node3/proto"
 | 
				
			||||||
 | 
						"gitea.hbanafa.com/HeshamTB/hvpn-node3/templates"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CtxKey string
 | 
					type CtxKey string
 | 
				
			||||||
@ -176,6 +178,33 @@ func HandleDeletePeer(wg *WGLink) http.HandlerFunc {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func HandleGetCreatePeer(wg *WGLink) http.HandlerFunc {
 | 
				
			||||||
 | 
					    return func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
					        newPeer, err := wg.CreateNewPeer()
 | 
				
			||||||
 | 
					        if err != nil {
 | 
				
			||||||
 | 
					            slog.Error(err.Error())
 | 
				
			||||||
 | 
					            w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tmpl, err := template.New("client.ini").Parse(templates.ClientINI)
 | 
				
			||||||
 | 
					        if err != nil {
 | 
				
			||||||
 | 
					            slog.Error(err.Error())
 | 
				
			||||||
 | 
					            w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        w.Header().Add("Content-Type", CONTENT_PLAIN_TEXT)
 | 
				
			||||||
 | 
					        err = tmpl.Execute(w, newPeer)
 | 
				
			||||||
 | 
					        if err != nil {
 | 
				
			||||||
 | 
					            slog.Error(err.Error())
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO: Add peer to device
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func HttpLogHandler2(h http.Handler) http.Handler {
 | 
					func HttpLogHandler2(h http.Handler) http.Handler {
 | 
				
			||||||
    // https://blog.kowalczyk.info/article/e00e89c3841e4f8c8c769a78b8a90b47/logging-http-requests-in-go.html
 | 
					    // https://blog.kowalczyk.info/article/e00e89c3841e4f8c8c769a78b8a90b47/logging-http-requests-in-go.html
 | 
				
			||||||
    fn := func(w http.ResponseWriter, r* http.Request) {
 | 
					    fn := func(w http.ResponseWriter, r* http.Request) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										59
									
								
								link.go
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								link.go
									
									
									
									
									
								
							@ -2,6 +2,7 @@ package hvpnnode3
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
@ -245,6 +246,64 @@ func (wg *WGLink) GetAllPeers() ([]wgtypes.Peer, error) {
 | 
				
			|||||||
    return dev.Peers, nil
 | 
					    return dev.Peers, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (wg *WGLink) GetPublicKey() (*wgtypes.Key, error) {
 | 
				
			||||||
 | 
					    dev, err := wg.Device(wg.Name)
 | 
				
			||||||
 | 
					    if err != nil {
 | 
				
			||||||
 | 
					        return nil, err
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return &dev.PublicKey, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A peer config has it's own private key and the server node (peer section) endpoint and public key
 | 
				
			||||||
 | 
					type NewPeer struct {
 | 
				
			||||||
 | 
					    Peer wgtypes.Peer // The server as a peer 
 | 
				
			||||||
 | 
					    PrivateKey wgtypes.Key
 | 
				
			||||||
 | 
					    Address net.IP
 | 
				
			||||||
 | 
					    DNS []net.IP
 | 
				
			||||||
 | 
					    MTU uint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Endpoint string // Domain name and port
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create a new peer. Used for server-side clinet config generation
 | 
				
			||||||
 | 
					// Peer is not added to the wglink
 | 
				
			||||||
 | 
					func (wg *WGLink) CreateNewPeer() (*NewPeer, error) {
 | 
				
			||||||
 | 
					    dev, err := wg.Device(wg.Name)
 | 
				
			||||||
 | 
					    if err != nil {
 | 
				
			||||||
 | 
					        return nil, err
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    privKey, err := wgtypes.GeneratePrivateKey()
 | 
				
			||||||
 | 
					    if err != nil {
 | 
				
			||||||
 | 
					        return nil, err
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    serverPubkey, err := wg.GetPublicKey()
 | 
				
			||||||
 | 
					    if err != nil {
 | 
				
			||||||
 | 
					        return nil, err
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ip, err := wg.Allocate()
 | 
				
			||||||
 | 
					    if err != nil {
 | 
				
			||||||
 | 
					        return nil, err
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    peer := NewPeer{
 | 
				
			||||||
 | 
					        Address: ip,
 | 
				
			||||||
 | 
					        DNS: WG_CLIENT_DNS,
 | 
				
			||||||
 | 
					        PrivateKey: privKey,
 | 
				
			||||||
 | 
					        MTU: WG_CLIENT_MTU,
 | 
				
			||||||
 | 
					        Peer: wgtypes.Peer{
 | 
				
			||||||
 | 
					            PublicKey: *serverPubkey,
 | 
				
			||||||
 | 
					            AllowedIPs: []net.IPNet{wg.Network()},
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        Endpoint: fmt.Sprintf("%s:%d", wg.Endpoint, dev.ListenPort),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return &peer, nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func createARemovePeerCfg(publickey wgtypes.Key) wgtypes.Config {
 | 
					func createARemovePeerCfg(publickey wgtypes.Key) wgtypes.Config {
 | 
				
			||||||
    rmPeerCfg := wgtypes.PeerConfig{
 | 
					    rmPeerCfg := wgtypes.PeerConfig{
 | 
				
			||||||
        Remove: true,
 | 
					        Remove: true,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								templates/client.ini.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								templates/client.ini.tmpl
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					[Interface]
 | 
				
			||||||
 | 
					Address = {{ .Address }}/24
 | 
				
			||||||
 | 
					PrivateKey = {{ .PrivateKey }} 
 | 
				
			||||||
 | 
					DNS = {{$dnss := .DNS}}{{range $index, $element := .DNS}}{{if $index}}, {{end}}{{$element.String}}{{end}}
 | 
				
			||||||
 | 
					MTU = {{ .MTU }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Peer]
 | 
				
			||||||
 | 
					PublicKey = {{ .Peer.PublicKey }}
 | 
				
			||||||
 | 
					Endpoint = {{ .Endpoint }}
 | 
				
			||||||
 | 
					AllowedIPs = 0.0.0.0/0, ::0/0
 | 
				
			||||||
 | 
					PersistentKeepalive = 25
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								templates/templates.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								templates/templates.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					package templates
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import _ "embed"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//go:embed client.ini.tmpl 
 | 
				
			||||||
 | 
					var ClientINI string
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user