Skip to content

Commit 60be83c

Browse files
committed
Added configuration parameters
1 parent 8f6271a commit 60be83c

File tree

7 files changed

+94
-47
lines changed

7 files changed

+94
-47
lines changed

conf/documentation.conf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1880,6 +1880,19 @@ description=<<EOT
18801880
The size of the queue for each worker.
18811881
EOT
18821882

1883+
[radius_configuration.pfacct_rate_limit]
1884+
type=toggle
1885+
options=enable|disabled
1886+
description=<<EOT
1887+
Enable the rate limiting on pfacct to prevent hammering httpd.aaa
1888+
EOT
1889+
1890+
[radius_configuration.pfacct_rate_limit_cache_ttl]
1891+
type=numeric
1892+
description=<<EOT
1893+
If rate limiting on pfacct is enabled, the Time to Live value in minutes represent the time of the accounting cache
1894+
EOT
1895+
18831896
[dns_configuration.record_dns_in_sql]
18841897
type=toggle
18851898
options=enabled|disabled

conf/pf.conf.defaults

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,14 @@ pfacct_workers = 0
14181418
#
14191419
# The size of the queue for each worker.
14201420
pfacct_work_queue_size = 1000
1421+
# radius_configuration.pfacct_rate_limit
1422+
#
1423+
# Enable the rate limiting on pfacct to prevent hammering httpd.aaa
1424+
pfacct_rate_limit=disabled
1425+
# radius_configuration.pfacct_rate_limit_cache_ttl
1426+
#
1427+
# If rate limiting on pfacct is enabled, the Time to Live value in minutes represent the time of the accounting cache
1428+
pfacct_rate_limit_cache_ttl=5
14211429

14221430
[dns_configuration]
14231431
#

go/cmd/pfacct/pfacct.go

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -38,33 +38,35 @@ type radiusRequest struct {
3838

3939
type PfAcct struct {
4040
RadiusStatements
41-
TimeDuration time.Duration
42-
Db *sql.DB
43-
AllowedNetworks []net.IPNet
44-
NetFlowPort string
45-
NetFlowAddress string
46-
Management pfconfigdriver.ManagementNetwork
47-
AAAClient *jsonrpc2.Client
48-
LoggerCtx context.Context
49-
Dispatcher *Dispatcher
50-
SwitchInfoCache *cache.Cache
51-
NodeSessionCache *cache.Cache
52-
AcctSessionCache *cache.Cache
53-
RateLimit *cache.Cache
54-
MacNas *cache.Cache
55-
StatsdAddress string
56-
StatsdOption statsd.Option
57-
StatsdClient *statsd.Client
58-
radiusRequests []chan<- radiusRequest
59-
overflows []atomic.Int64
60-
localSecret string
61-
StatsdOnce tryableonce.TryableOnce
62-
isProxied bool
63-
radiusdAcctEnabled bool
64-
AllNetworks bool
65-
ProcessBandwidthAcct bool
66-
RadiusWorkers int
67-
RadiusWorkQueueSize int
41+
TimeDuration time.Duration
42+
Db *sql.DB
43+
AllowedNetworks []net.IPNet
44+
NetFlowPort string
45+
NetFlowAddress string
46+
Management pfconfigdriver.ManagementNetwork
47+
AAAClient *jsonrpc2.Client
48+
LoggerCtx context.Context
49+
Dispatcher *Dispatcher
50+
SwitchInfoCache *cache.Cache
51+
NodeSessionCache *cache.Cache
52+
AcctSessionCache *cache.Cache
53+
RateLimitCache *cache.Cache
54+
MacNasCache *cache.Cache
55+
RateLimit bool
56+
PfacctRateLimitCacheTtl int
57+
StatsdAddress string
58+
StatsdOption statsd.Option
59+
StatsdClient *statsd.Client
60+
radiusRequests []chan<- radiusRequest
61+
overflows []atomic.Int64
62+
localSecret string
63+
StatsdOnce tryableonce.TryableOnce
64+
isProxied bool
65+
radiusdAcctEnabled bool
66+
AllNetworks bool
67+
ProcessBandwidthAcct bool
68+
RadiusWorkers int
69+
RadiusWorkQueueSize int
6870
}
6971

7072
func NewPfAcct() *PfAcct {
@@ -92,8 +94,7 @@ func NewPfAcct() *PfAcct {
9294
pfAcct.SwitchInfoCache = cache.New(5*time.Minute, 10*time.Minute)
9395
pfAcct.NodeSessionCache = cache.New(cache.NoExpiration, cache.NoExpiration)
9496
pfAcct.AcctSessionCache = cache.New(5*time.Minute, 10*time.Minute)
95-
pfAcct.RateLimit = cache.New(5*time.Minute, 10*time.Minute)
96-
pfAcct.MacNas = cache.New(5*time.Minute, 10*time.Minute)
97+
9798
pfAcct.LoggerCtx = ctx
9899
pfAcct.RadiusStatements.Setup(pfAcct.Db)
99100

@@ -172,6 +173,10 @@ func (pfAcct *PfAcct) SetupConfig(ctx context.Context) {
172173
var RadiusConfiguration pfconfigdriver.PfConfRadiusConfiguration
173174
pfconfigdriver.FetchDecodeSocket(ctx, &RadiusConfiguration)
174175
pfAcct.ProcessBandwidthAcct = sharedutils.IsEnabled(RadiusConfiguration.ProcessBandwidthAccounting)
176+
pfAcct.RateLimit = sharedutils.IsEnabled(RadiusConfiguration.PfacctRateLimit)
177+
pfAcct.PfacctRateLimitCacheTtl = RadiusConfiguration.PfacctRateLimitCacheTtl
178+
pfAcct.RateLimitCache = cache.New(time.Duration(RadiusConfiguration.PfacctRateLimitCacheTtl)*time.Minute, 10*time.Minute)
179+
pfAcct.MacNasCache = cache.New(time.Duration(RadiusConfiguration.PfacctRateLimitCacheTtl)*time.Minute, 10*time.Minute)
175180

176181
if !pfAcct.ProcessBandwidthAcct {
177182
logInfo(ctx, "Not processing bandwidth accounting records. To enable set radius_configuration.process_bandwidth_accounting = enabled")

go/cmd/pfacct/radius.go

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ func (h *PfAcct) sendRadiusAccountingCall(r *radius.Request) {
335335

336336
status := rfc2866.AcctStatusType_Get(r.Packet)
337337

338-
if h.rateLimit(attr, status) {
338+
if h.RateLimit && h.rateLimit(attr, status) {
339339
if err := h.AAAClient.Notify(ctx, "radius_accounting", attr); err != nil {
340340
logError(ctx, err.Error())
341341
}
@@ -359,39 +359,41 @@ func (h *PfAcct) rateLimit(attr map[string]interface{}, status rfc2866.AcctStatu
359359
macAddress, _ = mac.NewFromString(CallingStationId.(string))
360360
}
361361

362-
macOldLocation, macOldLocationExists := h.MacNas.Get(macAddress.String())
362+
macOldLocation, macOldLocationExists := h.MacNasCache.Get(macAddress.String())
363363

364364
// Generate the keys
365365
if CalledStationIdExists {
366366
key = rfc2866.AcctStatusType_Strings[status] + "-" + CalledStationId.(string) + "-" + CallingStationId.(string)
367367
keyStart = "Start" + "-" + CalledStationId.(string) + "-" + CallingStationId.(string)
368368
macLocValue = CalledStationId.(string)
369-
// h.MacNas.Set(macAddress.String(), CalledStationId, 5*time.Minute)
370369

371370
} else if NasIPExists {
372371
key = rfc2866.AcctStatusType_Strings[status] + "-" + NasIp.(string) + "-" + CallingStationId.(string)
373372
keyStart = "Start" + "-" + NasIp.(string) + "-" + CallingStationId.(string)
374373
macLocValue = NasIp.(string)
375-
// h.MacNas.Set(macAddress.String(), CalledStationId, 5*time.Minute)
376374
} else {
377375
return true
378376
}
379377

380378
if rfc2866.AcctStatusType_Strings[status] == "Start" {
381-
ip, exists := h.RateLimit.Get(key)
379+
ip, exists := h.RateLimitCache.Get(key)
382380
if !exists {
383-
h.RateLimit.Set(key, FramedIPAddress, 5*time.Minute)
381+
if FramedIPAddressExists {
382+
h.RateLimitCache.Set(key, FramedIPAddress, time.Duration(h.PfacctRateLimitCacheTtl)*time.Minute)
383+
} else {
384+
h.RateLimitCache.Set(key, "0.0.0.0", time.Duration(h.PfacctRateLimitCacheTtl)*time.Minute)
385+
}
384386
// Purge old Start entry
385387
if macOldLocationExists && macOldLocation != macLocValue {
386388
// Replace the location
387-
h.MacNas.Set(macAddress.String(), macLocValue, 5*time.Minute)
388-
h.RateLimit.Delete("Start" + macOldLocation.(string) + CallingStationId.(string))
389+
h.MacNasCache.Set(macAddress.String(), macLocValue, time.Duration(h.PfacctRateLimitCacheTtl)*time.Minute)
390+
h.RateLimitCache.Delete("Start" + "-" + macOldLocation.(string) + "-" + CallingStationId.(string))
389391
}
390392
return true
391393
} else {
392394
if FramedIPAddressExists && FramedIPAddress != ip.(string) {
393-
h.RateLimit.Set(key, FramedIPAddress, 5*time.Minute)
394-
h.MacNas.Set(macAddress.String(), macLocValue, 5*time.Minute)
395+
h.RateLimitCache.Set(key, FramedIPAddress, time.Duration(h.PfacctRateLimitCacheTtl)*time.Minute)
396+
h.MacNasCache.Set(macAddress.String(), macLocValue, time.Duration(h.PfacctRateLimitCacheTtl)*time.Minute)
395397
return true
396398
} else {
397399
return false
@@ -400,11 +402,11 @@ func (h *PfAcct) rateLimit(attr map[string]interface{}, status rfc2866.AcctStatu
400402
}
401403
if rfc2866.AcctStatusType_Strings[status] == "Interim-Update" {
402404
// Verify that we already got a start
403-
ip, exists := h.RateLimit.Get(keyStart)
405+
ip, exists := h.RateLimitCache.Get(keyStart)
404406
if exists {
405407
if FramedIPAddressExists && FramedIPAddress != ip.(string) {
406-
h.RateLimit.Set(key, FramedIPAddress, 5*time.Minute)
407-
h.MacNas.Set(macAddress.String(), macLocValue, 5*time.Minute)
408+
h.RateLimitCache.Set(keyStart, FramedIPAddress, time.Duration(h.PfacctRateLimitCacheTtl)*time.Minute)
409+
h.MacNasCache.Set(macAddress.String(), macLocValue, time.Duration(h.PfacctRateLimitCacheTtl)*time.Minute)
408410
return true
409411
} else {
410412
return false
@@ -413,17 +415,16 @@ func (h *PfAcct) rateLimit(attr map[string]interface{}, status rfc2866.AcctStatu
413415
}
414416
if rfc2866.AcctStatusType_Strings[status] == "Stop" {
415417
// Verify that we already got a start
416-
ip, exists := h.RateLimit.Get(keyStart)
418+
ip, exists := h.RateLimitCache.Get(keyStart)
417419
if exists {
418420
if FramedIPAddressExists && FramedIPAddress != ip.(string) {
419-
h.RateLimit.Set(key, FramedIPAddress, 5*time.Minute)
420-
h.MacNas.Set(macAddress.String(), macLocValue, 5*time.Minute)
421+
h.RateLimitCache.Set(keyStart, FramedIPAddress, time.Duration(h.PfacctRateLimitCacheTtl)*time.Minute)
422+
h.MacNasCache.Set(macAddress.String(), macLocValue, time.Duration(h.PfacctRateLimitCacheTtl)*time.Minute)
421423
return true
422424
} else {
423425
return false
424426
}
425427
}
426-
427428
}
428429
return false
429430
}

go/pfconfigdriver/structs.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,8 @@ type PfConfRadiusConfiguration struct {
711711
ProcessBandwidthAccounting string `json:"process_bandwidth_accounting"`
712712
PfacctWorkers string `json:"pfacct_workers"`
713713
PfacctWorkQueueSize string `json:"pfacct_work_queue_size"`
714+
PfacctRateLimit string `json:"pfacct_rate_limit"`
715+
PfacctRateLimitCacheTtl int `json:"pfacct_rate_limit_cache_ttl"`
714716
}
715717

716718
type PfQueueConfig struct {

html/pfappserver/root/src/views/Configuration/radius/general/_components/TheForm.vue

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,18 @@
104104
:text="$i18n.t('The size of the queue for each worker. Requires a restart of pfacct to be effective')"
105105
/>
106106

107+
<form-group-pfacct-rate-limit namespace="pfacct_rate_limit"
108+
:column-label="$i18n.t('Pfacct Rate Limiting')"
109+
:text="$i18n.t('Enable the rate limiting in pfacct to avoid hammering httpd.aaa. Requires a restart of pfacct to be effective')"
110+
enabled-value="enabled"
111+
disabled-value="disabled"
112+
/>
113+
114+
<form-group-pfacct-rate-limit-cache-ttl namespace="pfacct_rate_limit_cache_ttl"
115+
:column-label="$i18n.t('Pfacct Rate Limiting Time to Live')"
116+
:text="$i18n.t('Time to Live value in minutes, should be a little bit more than the Interim Update value. Requires a restart of pfacct to be effective')"
117+
/>
118+
107119
<form-group-radius-attributes namespace="radius_attributes"
108120
:column-label="$i18n.t('RADIUS attributes')"
109121
:text="$i18n.t('List of RADIUS attributes that can be used in the sources configuration.')"
@@ -159,6 +171,8 @@ import {
159171
FormGroupNtlmRedisCache,
160172
FormGroupPfacctWorkers,
161173
FormGroupPfacctWorkQueueSize,
174+
FormGroupPfacctRateLimit,
175+
FormGroupPfacctRateLimitCacheTtl,
162176
FormGroupProcessBandwidthAccounting,
163177
FormGroupRadiusAttributes,
164178
FormGroupRecordAccountingInSql,
@@ -188,7 +202,9 @@ const components = {
188202
FormGroupProcessBandwidthAccounting,
189203
FormGroupUsernameAttributes,
190204
FormGroupPfacctWorkers,
191-
FormGroupPfacctWorkQueueSize
205+
FormGroupPfacctWorkQueueSize,
206+
FormGroupPfacctRateLimit,
207+
FormGroupPfacctRateLimitCacheTtl
192208
}
193209
194210
export const props = {

html/pfappserver/root/src/views/Configuration/radius/general/_components/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ export {
3030
BaseFormGroupTextarea as FormGroupUsernameAttributes,
3131
BaseFormGroupInputNumber as FormGroupPfacctWorkers,
3232
BaseFormGroupInputNumber as FormGroupPfacctWorkQueueSize,
33+
BaseFormGroupSwitch as FormGroupPfacctRateLimit,
34+
BaseFormGroupInputNumber as FormGroupPfacctRateLimitCacheTtl,
3335

3436
BaseViewResource as BaseView,
3537
TheForm,

0 commit comments

Comments
 (0)