activity: fix IP parsing, drop all columns with malformed ips

This commit is contained in:
Matthew Penner 2023-01-24 14:36:18 -07:00
parent a36cab1783
commit 18de96d7b8
No known key found for this signature in database
3 changed files with 39 additions and 39 deletions

View File

@ -2,6 +2,7 @@ package cron
import ( import (
"context" "context"
"net"
"emperror.dev/errors" "emperror.dev/errors"
@ -17,9 +18,9 @@ type activityCron struct {
max int max int
} }
// Run executes the cronjob and ensures we fetch and send all of the stored activity to the // Run executes the cronjob and ensures we fetch and send all the stored activity to the
// Panel instance. Once activity is sent it is deleted from the local database instance. Any // Panel instance. Once activity is sent it is deleted from the local database instance. Any
// SFTP specific events are not handled in this cron, they're handled seperately to account // SFTP specific events are not handled in this cron, they're handled separately to account
// for de-duplication and event merging. // for de-duplication and event merging.
func (ac *activityCron) Run(ctx context.Context) error { func (ac *activityCron) Run(ctx context.Context) error {
// Don't execute this cron if there is currently one running. Once this task is completed // Don't execute this cron if there is currently one running. Once this task is completed
@ -34,7 +35,6 @@ func (ac *activityCron) Run(ctx context.Context) error {
Where("event NOT LIKE ?", "server:sftp.%"). Where("event NOT LIKE ?", "server:sftp.%").
Limit(ac.max). Limit(ac.max).
Find(&activity) Find(&activity)
if tx.Error != nil { if tx.Error != nil {
return errors.WithStack(tx.Error) return errors.WithStack(tx.Error)
} }
@ -42,15 +42,42 @@ func (ac *activityCron) Run(ctx context.Context) error {
return nil return nil
} }
if err := ac.manager.Client().SendActivityLogs(ctx, activity); err != nil { // ids to delete from the database.
ids := make([]int, 0, len(activity))
// activities to send to the panel.
activities := make([]models.Activity, 0, len(activity))
for _, v := range activity {
// Delete any activity that has an invalid IP address. This is a fix for
// a bug that truncated the last octet of an IPv6 address in the database.
if err := net.ParseIP(v.IP); err != nil {
ids = append(ids, v.ID)
continue
}
activities = append(activities, v)
}
if len(ids) > 0 {
tx = database.Instance().WithContext(ctx).Where("id IN ?", ids).Delete(&models.Activity{})
if tx.Error != nil {
return errors.WithStack(tx.Error)
}
}
if len(activities) == 0 {
return nil
}
if err := ac.manager.Client().SendActivityLogs(ctx, activities); err != nil {
return errors.WrapIf(err, "cron: failed to send activity events to Panel") return errors.WrapIf(err, "cron: failed to send activity events to Panel")
} }
var ids []int // Add all the successful activities to the list of IDs to delete.
for _, v := range activity { ids = make([]int, len(activities))
ids = append(ids, v.ID) for i, v := range activities {
ids[i] = v.ID
} }
// Delete all the activities that were sent to the Panel (or that were invalid).
tx = database.Instance().WithContext(ctx).Where("id IN ?", ids).Delete(&models.Activity{}) tx = database.Instance().WithContext(ctx).Where("id IN ?", ids).Delete(&models.Activity{})
if tx.Error != nil { if tx.Error != nil {
return errors.WithStack(tx.Error) return errors.WithStack(tx.Error)

View File

@ -1,11 +1,11 @@
package models package models
import ( import (
"net"
"strings"
"time" "time"
"gorm.io/gorm" "gorm.io/gorm"
"github.com/pterodactyl/wings/system"
) )
type Event string type Event string
@ -57,7 +57,9 @@ func (a Activity) SetUser(u string) *Activity {
// is trimmed down to remove any extraneous data, and the timestamp is set to the current // is trimmed down to remove any extraneous data, and the timestamp is set to the current
// system time and then stored as UTC. // system time and then stored as UTC.
func (a *Activity) BeforeCreate(_ *gorm.DB) error { func (a *Activity) BeforeCreate(_ *gorm.DB) error {
a.IP = system.TrimIPSuffix(a.IP) if ip, _, err := net.SplitHostPort(strings.TrimSpace(a.IP)); err == nil {
a.IP = ip
}
if a.Timestamp.IsZero() { if a.Timestamp.IsZero() {
a.Timestamp = time.Now() a.Timestamp = time.Now()
} }

View File

@ -1,29 +0,0 @@
package system
import (
"math/rand"
"regexp"
"strings"
)
var ipTrimRegex = regexp.MustCompile(`(:\d*)?$`)
const characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
// RandomString generates a random string of alpha-numeric characters using a
// pseudo-random number generator. The output of this function IS NOT cryptographically
// secure, it is used solely for generating random strings outside a security context.
func RandomString(n int) string {
var b strings.Builder
b.Grow(n)
for i := 0; i < n; i++ {
b.WriteByte(characters[rand.Intn(len(characters))])
}
return b.String()
}
// TrimIPSuffix removes the internal port value from an IP address to ensure we're only
// ever working directly with the IP address.
func TrimIPSuffix(s string) string {
return ipTrimRegex.ReplaceAllString(s, "")
}