policies/reputation: fix reputation not expiring (#6714)
* policies/reputation: fix reputation not expiring Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix some verbose names for models Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
6163f29aa0
commit
f57b3efcaa
|
@ -26,4 +26,11 @@ class Migration(migrations.Migration):
|
|||
fields=["key"], name="authentik_e_key_523e13_hash"
|
||||
),
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name="licenseusage",
|
||||
options={
|
||||
"verbose_name": "License Usage",
|
||||
"verbose_name_plural": "License Usage Records",
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -15,6 +15,7 @@ from django.contrib.postgres.indexes import HashIndex
|
|||
from django.db import models
|
||||
from django.db.models.query import QuerySet
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext as _
|
||||
from guardian.shortcuts import get_anonymous_user
|
||||
from jwt import PyJWTError, decode, get_unverified_header
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
@ -187,3 +188,7 @@ class LicenseUsage(ExpiringModel):
|
|||
within_limits = models.BooleanField()
|
||||
|
||||
record_date = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("License Usage")
|
||||
verbose_name_plural = _("License Usage Records")
|
||||
|
|
|
@ -84,6 +84,9 @@ ldap:
|
|||
tls:
|
||||
ciphers: null
|
||||
|
||||
reputation:
|
||||
expiry: 86400
|
||||
|
||||
cookie_domain: null
|
||||
disable_update_check: false
|
||||
disable_startup_analytics: false
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 4.2.4 on 2023-08-31 10:42
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
import authentik.policies.reputation.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("authentik_policies_reputation", "0004_reputationpolicy_authentik_p_policy__8f0d70_idx"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="reputation",
|
||||
name="expires",
|
||||
field=models.DateTimeField(
|
||||
default=authentik.policies.reputation.models.reputation_expiry
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="reputation",
|
||||
name="expiring",
|
||||
field=models.BooleanField(default=True),
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name="reputation",
|
||||
options={
|
||||
"verbose_name": "Reputation Score",
|
||||
"verbose_name_plural": "Reputation Scores",
|
||||
},
|
||||
),
|
||||
]
|
|
@ -1,13 +1,17 @@
|
|||
"""authentik reputation request policy"""
|
||||
from datetime import timedelta
|
||||
from uuid import uuid4
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Sum
|
||||
from django.db.models.query_utils import Q
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext as _
|
||||
from rest_framework.serializers import BaseSerializer
|
||||
from structlog import get_logger
|
||||
|
||||
from authentik.core.models import ExpiringModel
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.lib.models import SerializerModel
|
||||
from authentik.lib.utils.http import get_client_ip
|
||||
from authentik.policies.models import Policy
|
||||
|
@ -17,6 +21,11 @@ LOGGER = get_logger()
|
|||
CACHE_KEY_PREFIX = "goauthentik.io/policies/reputation/scores/"
|
||||
|
||||
|
||||
def reputation_expiry():
|
||||
"""Reputation expiry"""
|
||||
return now() + timedelta(seconds=CONFIG.get_int("reputation.expiry"))
|
||||
|
||||
|
||||
class ReputationPolicy(Policy):
|
||||
"""Return true if request IP/target username's score is below a certain threshold"""
|
||||
|
||||
|
@ -59,7 +68,7 @@ class ReputationPolicy(Policy):
|
|||
verbose_name_plural = _("Reputation Policies")
|
||||
|
||||
|
||||
class Reputation(SerializerModel):
|
||||
class Reputation(ExpiringModel, SerializerModel):
|
||||
"""Reputation for user and or IP."""
|
||||
|
||||
reputation_uuid = models.UUIDField(primary_key=True, unique=True, default=uuid4)
|
||||
|
@ -69,6 +78,8 @@ class Reputation(SerializerModel):
|
|||
ip_geo_data = models.JSONField(default=dict)
|
||||
score = models.BigIntegerField(default=0)
|
||||
|
||||
expires = models.DateTimeField(default=reputation_expiry)
|
||||
|
||||
updated = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
@property
|
||||
|
@ -81,4 +92,6 @@ class Reputation(SerializerModel):
|
|||
return f"Reputation {self.identifier}/{self.ip} @ {self.score}"
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Reputation Score")
|
||||
verbose_name_plural = _("Reputation Scores")
|
||||
unique_together = ("identifier", "ip")
|
||||
|
|
|
@ -30,7 +30,7 @@ def check_plex_token(self: MonitoredTask, source_slug: int):
|
|||
self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, ["Plex token is valid."]))
|
||||
except RequestException as exc:
|
||||
error = exception_to_string(exc)
|
||||
if len(source.plex_token) < 1:
|
||||
if len(source.plex_token) > 0:
|
||||
error = error.replace(source.plex_token, "$PLEX_TOKEN")
|
||||
self.set_status(
|
||||
TaskResult(
|
||||
|
|
14
schema.yml
14
schema.yml
|
@ -12961,7 +12961,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
description: A UUID string identifying this reputation.
|
||||
description: A UUID string identifying this Reputation Score.
|
||||
required: true
|
||||
tags:
|
||||
- policies
|
||||
|
@ -12995,7 +12995,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
description: A UUID string identifying this reputation.
|
||||
description: A UUID string identifying this Reputation Score.
|
||||
required: true
|
||||
tags:
|
||||
- policies
|
||||
|
@ -13026,7 +13026,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
description: A UUID string identifying this reputation.
|
||||
description: A UUID string identifying this Reputation Score.
|
||||
required: true
|
||||
tags:
|
||||
- policies
|
||||
|
@ -29523,7 +29523,7 @@ components:
|
|||
* `authentik_policies_expression.expressionpolicy` - Expression Policy
|
||||
* `authentik_policies_password.passwordpolicy` - Password Policy
|
||||
* `authentik_policies_reputation.reputationpolicy` - Reputation Policy
|
||||
* `authentik_policies_reputation.reputation` - reputation
|
||||
* `authentik_policies_reputation.reputation` - Reputation Score
|
||||
* `authentik_policies.policybinding` - Policy Binding
|
||||
* `authentik_providers_ldap.ldapprovider` - LDAP Provider
|
||||
* `authentik_providers_oauth2.scopemapping` - Scope Mapping
|
||||
|
@ -29713,7 +29713,7 @@ components:
|
|||
* `authentik_policies_expression.expressionpolicy` - Expression Policy
|
||||
* `authentik_policies_password.passwordpolicy` - Password Policy
|
||||
* `authentik_policies_reputation.reputationpolicy` - Reputation Policy
|
||||
* `authentik_policies_reputation.reputation` - reputation
|
||||
* `authentik_policies_reputation.reputation` - Reputation Score
|
||||
* `authentik_policies.policybinding` - Policy Binding
|
||||
* `authentik_providers_ldap.ldapprovider` - LDAP Provider
|
||||
* `authentik_providers_oauth2.scopemapping` - Scope Mapping
|
||||
|
@ -31943,7 +31943,7 @@ components:
|
|||
* `authentik_policies_expression.expressionpolicy` - Expression Policy
|
||||
* `authentik_policies_password.passwordpolicy` - Password Policy
|
||||
* `authentik_policies_reputation.reputationpolicy` - Reputation Policy
|
||||
* `authentik_policies_reputation.reputation` - reputation
|
||||
* `authentik_policies_reputation.reputation` - Reputation Score
|
||||
* `authentik_policies.policybinding` - Policy Binding
|
||||
* `authentik_providers_ldap.ldapprovider` - LDAP Provider
|
||||
* `authentik_providers_oauth2.scopemapping` - Scope Mapping
|
||||
|
@ -34930,7 +34930,7 @@ components:
|
|||
* `authentik_policies_expression.expressionpolicy` - Expression Policy
|
||||
* `authentik_policies_password.passwordpolicy` - Password Policy
|
||||
* `authentik_policies_reputation.reputationpolicy` - Reputation Policy
|
||||
* `authentik_policies_reputation.reputation` - reputation
|
||||
* `authentik_policies_reputation.reputation` - Reputation Score
|
||||
* `authentik_policies.policybinding` - Policy Binding
|
||||
* `authentik_providers_ldap.ldapprovider` - LDAP Provider
|
||||
* `authentik_providers_oauth2.scopemapping` - Scope Mapping
|
||||
|
|
|
@ -258,16 +258,18 @@ new?labels=bug,from_authentik&title=${encodeURIComponent(title)}
|
|||
return html` <div class="pf-c-card__title">${msg("Secret:")}</div>
|
||||
${this.getModelInfo(this.event.context.secret as EventModel)}`;
|
||||
case EventActions.SystemException:
|
||||
return html` <a
|
||||
class="pf-c-button pf-m-primary"
|
||||
target="_blank"
|
||||
href=${this.buildGitHubIssueUrl(this.event.context)}
|
||||
>
|
||||
${msg("Open issue on GitHub...")}
|
||||
</a>
|
||||
<div class="pf-l-flex">
|
||||
return html`<div class="pf-l-flex">
|
||||
<div class="pf-l-flex__item">
|
||||
<div class="pf-c-card__title">${msg("Exception")}</div>
|
||||
<div class="pf-c-card__title">
|
||||
<a
|
||||
class="pf-c-button pf-m-primary"
|
||||
target="_blank"
|
||||
href=${this.buildGitHubIssueUrl(this.event.context)}
|
||||
>
|
||||
${msg("Open issue on GitHub...")}
|
||||
</a>
|
||||
</div>
|
||||
<div class="pf-c-card__body">
|
||||
<pre>${this.event.context.message}</pre>
|
||||
</div>
|
||||
|
|
|
@ -51,15 +51,19 @@ kubectl exec -it deployment/authentik-worker -c authentik -- ak dump_config
|
|||
- `AUTHENTIK_REDIS__CACHE_TIMEOUT_POLICIES`: Timeout for cached policies until they expire in seconds, defaults to 300
|
||||
- `AUTHENTIK_REDIS__CACHE_TIMEOUT_REPUTATION`: Timeout for cached reputation until they expire in seconds, defaults to 300
|
||||
|
||||
:::info
|
||||
`AUTHENTIK_REDIS__CACHE_TIMEOUT_REPUTATION` only applies to the cache expiry, see [`AUTHENTIK_REPUTATION__EXPIRY`](#authentik_reputation__expiry) to control how long reputation is persisted for.
|
||||
:::
|
||||
|
||||
## Listen Setting
|
||||
|
||||
- `AUTHENTIK_LISTEN__HTTP`: Listening address:port (e.g. `0.0.0.0:9000`) for HTTP (Server and Proxy outpost)
|
||||
- `AUTHENTIK_LISTEN__HTTPS`: Listening address:port (e.g. `0.0.0.0:9443`) for HTTPS (Server and Proxy outpost)
|
||||
- `AUTHENTIK_LISTEN__LDAP`: Listening address:port (e.g. `0.0.0.0:3389`) for LDAP (LDAP outpost)
|
||||
- `AUTHENTIK_LISTEN__LDAPS`: Listening address:port (e.g. `0.0.0.0:6636`) for LDAPS (LDAP outpost)
|
||||
- `AUTHENTIK_LISTEN__METRICS`: Listening address:port (e.g. `0.0.0.0:9300`) for Prometheus metrics (All)
|
||||
- `AUTHENTIK_LISTEN__DEBUG`: Listening address:port (e.g. `0.0.0.0:9900`) for Go Debugging metrics (All)
|
||||
- `AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS`: List of CIDRs that proxy headers should be accepted from (Server)
|
||||
- `AUTHENTIK_LISTEN__HTTP`: Listening address:port (e.g. `0.0.0.0:9000`) for HTTP (Applies to Server and Proxy outpost)
|
||||
- `AUTHENTIK_LISTEN__HTTPS`: Listening address:port (e.g. `0.0.0.0:9443`) for HTTPS (Applies to Server and Proxy outpost)
|
||||
- `AUTHENTIK_LISTEN__LDAP`: Listening address:port (e.g. `0.0.0.0:3389`) for LDAP (Applies to LDAP outpost)
|
||||
- `AUTHENTIK_LISTEN__LDAPS`: Listening address:port (e.g. `0.0.0.0:6636`) for LDAPS (Applies to LDAP outpost)
|
||||
- `AUTHENTIK_LISTEN__METRICS`: Listening address:port (e.g. `0.0.0.0:9300`) for Prometheus metrics (Applies to All)
|
||||
- `AUTHENTIK_LISTEN__DEBUG`: Listening address:port (e.g. `0.0.0.0:9900`) for Go Debugging metrics (Applies to All)
|
||||
- `AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS`: List of CIDRs that proxy headers should be accepted from (Applies to Server)
|
||||
|
||||
Defaults to `127.0.0.0/8`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fe80::/10`, `::1/128`.
|
||||
|
||||
|
@ -297,6 +301,16 @@ Allows configuration of TLS Cliphers for LDAP connections used by LDAP sources.
|
|||
|
||||
Defaults to `null`.
|
||||
|
||||
### `AUTHENTIK_REPUTATION__EXPIRY`
|
||||
|
||||
:::info
|
||||
Requires authentik 2023.8.2
|
||||
:::
|
||||
|
||||
Configure how long reputation scores should be saved for in seconds. Note that this is different than [`AUTHENTIK_REDIS__CACHE_TIMEOUT_REPUTATION`](#redis-settings), as reputation is saved to the database every 5 minutes.
|
||||
|
||||
Defaults to `86400`.
|
||||
|
||||
### `AUTHENTIK_WEB__WORKERS`
|
||||
|
||||
:::info
|
||||
|
|
Reference in New Issue