feat: grace period for new peers as a new evection policy
Signed-off-by: HeshamTB <hishaminv@gmail.com>
This commit is contained in:
parent
8e798706e3
commit
7d1a0cdbdc
@ -180,6 +180,8 @@ func HandleDeletePeer(wg *WGLink) http.HandlerFunc {
|
|||||||
|
|
||||||
func HandleGetCreatePeer(wg *WGLink) http.HandlerFunc {
|
func HandleGetCreatePeer(wg *WGLink) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
reqId := r.Context().Value(CtxReqID).(uuid.UUID)
|
||||||
|
info("Create peer", reqId)
|
||||||
newPeer, err := wg.CreateNewPeer()
|
newPeer, err := wg.CreateNewPeer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error(err.Error())
|
slog.Error(err.Error())
|
||||||
@ -200,8 +202,6 @@ func HandleGetCreatePeer(wg *WGLink) http.HandlerFunc {
|
|||||||
slog.Error(err.Error())
|
slog.Error(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add peer to device
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
link.go
15
link.go
@ -20,6 +20,7 @@ type WGLink struct {
|
|||||||
*netlink.LinkAttrs
|
*netlink.LinkAttrs
|
||||||
*wgctrl.Client
|
*wgctrl.Client
|
||||||
IPPool
|
IPPool
|
||||||
|
meta *PeerMeta
|
||||||
Endpoint string // Endpoint for clients to use when connecting to this link. Has no effect.
|
Endpoint string // Endpoint for clients to use when connecting to this link. Has no effect.
|
||||||
StartedAT time.Time
|
StartedAT time.Time
|
||||||
lock *sync.Mutex
|
lock *sync.Mutex
|
||||||
@ -60,6 +61,7 @@ func InitWGLink(ifName string, privateKey *wgtypes.Key, port int, endpoint strin
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wg.meta = NewPeerMeta()
|
||||||
wg.lock = &sync.Mutex{}
|
wg.lock = &sync.Mutex{}
|
||||||
|
|
||||||
return &wg, netlink.LinkSetUp(&wg)
|
return &wg, netlink.LinkSetUp(&wg)
|
||||||
@ -146,6 +148,8 @@ func (wg *WGLink) AddPeer(publicKey string) (*wgtypes.Peer, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wg.meta.AddPeer(pubKey)
|
||||||
|
|
||||||
return wg.getPeer(pubKey)
|
return wg.getPeer(pubKey)
|
||||||
}
|
}
|
||||||
@ -175,6 +179,8 @@ func (wg *WGLink) deletePeer(publickey wgtypes.Key) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wg.meta.DeletePeer(publickey)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +264,7 @@ func (wg *WGLink) GetPublicKey() (*wgtypes.Key, error) {
|
|||||||
type NewPeer struct {
|
type NewPeer struct {
|
||||||
Peer wgtypes.Peer // The server as a peer
|
Peer wgtypes.Peer // The server as a peer
|
||||||
PrivateKey wgtypes.Key
|
PrivateKey wgtypes.Key
|
||||||
Address net.IP
|
Address net.IPNet
|
||||||
DNS []net.IP
|
DNS []net.IP
|
||||||
MTU uint
|
MTU uint
|
||||||
|
|
||||||
@ -266,7 +272,7 @@ type NewPeer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new peer. Used for server-side clinet config generation
|
// Create a new peer. Used for server-side clinet config generation
|
||||||
// Peer is not added to the wglink
|
// New peer is added to the wireguard device
|
||||||
func (wg *WGLink) CreateNewPeer() (*NewPeer, error) {
|
func (wg *WGLink) CreateNewPeer() (*NewPeer, error) {
|
||||||
dev, err := wg.Device(wg.Name)
|
dev, err := wg.Device(wg.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -283,19 +289,18 @@ func (wg *WGLink) CreateNewPeer() (*NewPeer, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ip, err := wg.Allocate()
|
wgPeer, err := wg.AddPeer(privKey.PublicKey().String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
peer := NewPeer{
|
peer := NewPeer{
|
||||||
Address: ip,
|
Address: wgPeer.AllowedIPs[0],
|
||||||
DNS: WG_CLIENT_DNS,
|
DNS: WG_CLIENT_DNS,
|
||||||
PrivateKey: privKey,
|
PrivateKey: privKey,
|
||||||
MTU: WG_CLIENT_MTU,
|
MTU: WG_CLIENT_MTU,
|
||||||
Peer: wgtypes.Peer{
|
Peer: wgtypes.Peer{
|
||||||
PublicKey: *serverPubkey,
|
PublicKey: *serverPubkey,
|
||||||
AllowedIPs: []net.IPNet{wg.Network()},
|
|
||||||
},
|
},
|
||||||
Endpoint: fmt.Sprintf("%s:%d", wg.Endpoint, dev.ListenPort),
|
Endpoint: fmt.Sprintf("%s:%d", wg.Endpoint, dev.ListenPort),
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ func monitor(wg *WGLink, log slog.Logger) {
|
|||||||
for _, peer := range peers {
|
for _, peer := range peers {
|
||||||
totalRx += peer.ReceiveBytes
|
totalRx += peer.ReceiveBytes
|
||||||
totalTx += peer.TransmitBytes
|
totalTx += peer.TransmitBytes
|
||||||
if !isActive(peer) {
|
if !isActive(peer, wg) {
|
||||||
log.Info(
|
log.Info(
|
||||||
fmt.Sprintf("[WGMonitor] Evecting peer %s", peer.PublicKey.String()),
|
fmt.Sprintf("[WGMonitor] Evecting peer %s", peer.PublicKey.String()),
|
||||||
)
|
)
|
||||||
@ -48,8 +48,11 @@ func monitor(wg *WGLink, log slog.Logger) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isActive(peer wgtypes.Peer) bool {
|
func isActive(peer wgtypes.Peer, wg *WGLink) bool {
|
||||||
if peer.LastHandshakeTime.IsZero() {
|
if peer.LastHandshakeTime.IsZero() {
|
||||||
|
if time.Since(wg.meta.TimeAdded(peer.PublicKey)) < time.Duration(4 * time.Minute) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
} else if time.Since(peer.LastHandshakeTime.UTC()) < time.Duration(4 * time.Minute) {
|
} else if time.Since(peer.LastHandshakeTime.UTC()) < time.Duration(4 * time.Minute) {
|
||||||
return true
|
return true
|
||||||
|
54
peer_meta.go
Normal file
54
peer_meta.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package hvpnnode3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Contians data about peers
|
||||||
|
type PeerData struct {
|
||||||
|
addedOn time.Time
|
||||||
|
deleted bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic implementaion to track peers based on public keys. Thraed safe.
|
||||||
|
type PeerMeta struct {
|
||||||
|
data map[wgtypes.Key]PeerData
|
||||||
|
rwl *sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPeerMeta() *PeerMeta {
|
||||||
|
meta := new(PeerMeta)
|
||||||
|
meta.data = make(map[wgtypes.Key]PeerData)
|
||||||
|
meta.rwl = new(sync.RWMutex)
|
||||||
|
return meta
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *PeerMeta) AddPeer(publicKey wgtypes.Key) {
|
||||||
|
m.rwl.Lock()
|
||||||
|
m.data[publicKey] = PeerData{
|
||||||
|
addedOn: time.Now().UTC(),
|
||||||
|
deleted: false,
|
||||||
|
}
|
||||||
|
m.rwl.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *PeerMeta) DeletePeer(publicKey wgtypes.Key) {
|
||||||
|
m.rwl.Lock()
|
||||||
|
d := m.data[publicKey]
|
||||||
|
d.deleted = true
|
||||||
|
m.rwl.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *PeerMeta) TimeAdded(publicKey wgtypes.Key) time.Time {
|
||||||
|
m.rwl.RLock()
|
||||||
|
t := m.data[publicKey].addedOn
|
||||||
|
m.rwl.RUnlock()
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
[Interface]
|
[Interface]
|
||||||
Address = {{ .Address }}/24
|
Address = {{ .Address }}
|
||||||
PrivateKey = {{ .PrivateKey }}
|
PrivateKey = {{ .PrivateKey }}
|
||||||
DNS = {{$dnss := .DNS}}{{range $index, $element := .DNS}}{{if $index}}, {{end}}{{$element.String}}{{end}}
|
DNS = {{$dnss := .DNS}}{{range $index, $element := .DNS}}{{if $index}}, {{end}}{{$element.String}}{{end}}
|
||||||
MTU = {{ .MTU }}
|
MTU = {{ .MTU }}
|
||||||
|
Loading…
Reference in New Issue
Block a user