mirror of https://github.com/h44z/wg-portal.git
				
				
				
			peer expiry feature: expiration check
This commit is contained in:
		
							parent
							
								
									6f4af97024
								
							
						
					
					
						commit
						4a0e773d96
					
				|  | @ -67,10 +67,11 @@ type Config struct { | |||
| 		EditableKeys            bool   `yaml:"editableKeys" envconfig:"EDITABLE_KEYS"` | ||||
| 		CreateDefaultPeer       bool   `yaml:"createDefaultPeer" envconfig:"CREATE_DEFAULT_PEER"` | ||||
| 		SelfProvisioningAllowed bool   `yaml:"selfProvisioning" envconfig:"SELF_PROVISIONING"` | ||||
| 		WGExoprterFriendlyNames bool   `yaml:"wgExporterFriendlyNames" envconfig:"WG_EXPORTER_FRIENDLY_NAMES"` | ||||
| 		WGExporterFriendlyNames bool   `yaml:"wgExporterFriendlyNames" envconfig:"WG_EXPORTER_FRIENDLY_NAMES"` | ||||
| 		LdapEnabled             bool   `yaml:"ldapEnabled" envconfig:"LDAP_ENABLED"` | ||||
| 		SessionSecret           string `yaml:"sessionSecret" envconfig:"SESSION_SECRET"` | ||||
| 		LogoUrl                 string `yaml:"logoUrl" envconfig:"LOGO_URL"` | ||||
| 		BackgroundTaskInterval  int    `yaml:"backgroundTaskInterval" envconfig:"BACKGROUND_TASK_INTERVAL"` // in seconds
 | ||||
| 	} `yaml:"core"` | ||||
| 	Database common.DatabaseConfig `yaml:"database"` | ||||
| 	Email    common.MailConfig     `yaml:"email"` | ||||
|  | @ -92,8 +93,9 @@ func NewConfig() *Config { | |||
| 	cfg.Core.AdminPassword = "wgportal" | ||||
| 	cfg.Core.LdapEnabled = false | ||||
| 	cfg.Core.EditableKeys = true | ||||
| 	cfg.Core.WGExoprterFriendlyNames = false | ||||
| 	cfg.Core.WGExporterFriendlyNames = false | ||||
| 	cfg.Core.SessionSecret = "secret" | ||||
| 	cfg.Core.BackgroundTaskInterval = 15 * 60 // 15 minutes
 | ||||
| 
 | ||||
| 	cfg.Database.Typ = "sqlite" | ||||
| 	cfg.Database.Database = "data/wg_portal.db" | ||||
|  |  | |||
|  | @ -112,7 +112,7 @@ func (s *Server) GetInterfaceConfig(c *gin.Context) { | |||
| 	currentSession := GetSessionData(c) | ||||
| 	device := s.peers.GetDevice(currentSession.DeviceName) | ||||
| 	peers := s.peers.GetActivePeers(device.DeviceName) | ||||
| 	cfg, err := device.GetConfigFile(peers, s.config.Core.WGExoprterFriendlyNames) | ||||
| 	cfg, err := device.GetConfigFile(peers, s.config.Core.WGExporterFriendlyNames) | ||||
| 	if err != nil { | ||||
| 		s.GetHandleError(c, http.StatusInternalServerError, "ConfigFile error", err.Error()) | ||||
| 		return | ||||
|  |  | |||
|  | @ -216,6 +216,8 @@ func (s *Server) Run() { | |||
| 		go s.SyncLdapWithUserDatabase() | ||||
| 	} | ||||
| 
 | ||||
| 	go s.RunBackgroundTasks(s.ctx) | ||||
| 
 | ||||
| 	// Run web service
 | ||||
| 	srv := &http.Server{ | ||||
| 		Addr:    s.config.Core.ListeningAddress, | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| package server | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"crypto/md5" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
|  | @ -205,7 +206,7 @@ func (s *Server) WriteWireGuardConfigFile(device string) error { | |||
| 	} | ||||
| 
 | ||||
| 	dev := s.peers.GetDevice(device) | ||||
| 	cfg, err := dev.GetConfigFile(s.peers.GetActivePeers(device), s.config.Core.WGExoprterFriendlyNames) | ||||
| 	cfg, err := dev.GetConfigFile(s.peers.GetActivePeers(device), s.config.Core.WGExporterFriendlyNames) | ||||
| 	if err != nil { | ||||
| 		return errors.WithMessage(err, "failed to get config file") | ||||
| 	} | ||||
|  | @ -374,3 +375,60 @@ func (s *Server) GetDeviceNames() map[string]string { | |||
| 
 | ||||
| 	return devNames | ||||
| } | ||||
| 
 | ||||
| func (s *Server) RunBackgroundTasks(ctx context.Context) { | ||||
| 	running := true | ||||
| 	for running { | ||||
| 		select { | ||||
| 		case <-ctx.Done(): | ||||
| 			running = false | ||||
| 			continue | ||||
| 		case <-time.After(time.Duration(s.config.Core.BackgroundTaskInterval) * time.Second): | ||||
| 			// sleep completed, select will stop blocking
 | ||||
| 		} | ||||
| 
 | ||||
| 		logrus.Debug("running periodic background tasks...") | ||||
| 
 | ||||
| 		err := s.checkExpiredPeers() | ||||
| 		if err != nil { | ||||
| 			logrus.Errorf("failed to check expired peers: %v", err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (s *Server) checkExpiredPeers() error { | ||||
| 	now := time.Now() | ||||
| 
 | ||||
| 	for _, devName := range s.wg.Cfg.DeviceNames { | ||||
| 		changed := false | ||||
| 		peers := s.peers.GetAllPeers(devName) | ||||
| 		for _, peer := range peers { | ||||
| 			if peer.IsExpired() && !peer.IsDeactivated() { | ||||
| 				changed = true | ||||
| 
 | ||||
| 				peer.UpdatedAt = now | ||||
| 				peer.DeactivatedAt = &now | ||||
| 				peer.DeactivatedReason = "expired" | ||||
| 
 | ||||
| 				res := s.db.Save(&peer) | ||||
| 				if res.Error != nil { | ||||
| 					return fmt.Errorf("failed save expired peer %s: %w", peer.PublicKey, res.Error) | ||||
| 				} | ||||
| 
 | ||||
| 				err := s.wg.RemovePeer(peer.DeviceName, peer.PublicKey) | ||||
| 				if err != nil { | ||||
| 					return fmt.Errorf("failed to expire peer %s: %w", peer.PublicKey, err) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if changed { | ||||
| 			err := s.WriteWireGuardConfigFile(devName) | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("failed to persist config for interface %s: %w", devName, err) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
|  |  | |||
|  | @ -255,6 +255,20 @@ func (p Peer) WillExpire() bool { | |||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func (p Peer) IsExpired() bool { | ||||
| 	if p.ExpiresAt == nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	if p.ExpiresAt.Before(time.Now()) { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func (p Peer) IsDeactivated() bool { | ||||
| 	return p.DeactivatedAt != nil | ||||
| } | ||||
| 
 | ||||
| func (p Peer) GetConfigFileName() string { | ||||
| 	reg := regexp.MustCompile("[^a-zA-Z0-9_-]+") | ||||
| 	return reg.ReplaceAllString(strings.ReplaceAll(p.Identifier, " ", "-"), "") + ".conf" | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue