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