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:
Jens L 2023-08-31 13:46:00 +02:00 committed by GitHub
parent 6163f29aa0
commit f57b3efcaa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 101 additions and 24 deletions

View file

@ -26,4 +26,11 @@ class Migration(migrations.Migration):
fields=["key"], name="authentik_e_key_523e13_hash" fields=["key"], name="authentik_e_key_523e13_hash"
), ),
), ),
migrations.AlterModelOptions(
name="licenseusage",
options={
"verbose_name": "License Usage",
"verbose_name_plural": "License Usage Records",
},
),
] ]

View file

@ -15,6 +15,7 @@ from django.contrib.postgres.indexes import HashIndex
from django.db import models from django.db import models
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import gettext as _
from guardian.shortcuts import get_anonymous_user from guardian.shortcuts import get_anonymous_user
from jwt import PyJWTError, decode, get_unverified_header from jwt import PyJWTError, decode, get_unverified_header
from rest_framework.exceptions import ValidationError from rest_framework.exceptions import ValidationError
@ -187,3 +188,7 @@ class LicenseUsage(ExpiringModel):
within_limits = models.BooleanField() within_limits = models.BooleanField()
record_date = models.DateTimeField(auto_now_add=True) record_date = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = _("License Usage")
verbose_name_plural = _("License Usage Records")

View file

@ -84,6 +84,9 @@ ldap:
tls: tls:
ciphers: null ciphers: null
reputation:
expiry: 86400
cookie_domain: null cookie_domain: null
disable_update_check: false disable_update_check: false
disable_startup_analytics: false disable_startup_analytics: false

View file

@ -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",
},
),
]

View file

@ -1,13 +1,17 @@
"""authentik reputation request policy""" """authentik reputation request policy"""
from datetime import timedelta
from uuid import uuid4 from uuid import uuid4
from django.db import models from django.db import models
from django.db.models import Sum from django.db.models import Sum
from django.db.models.query_utils import Q from django.db.models.query_utils import Q
from django.utils.timezone import now
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from rest_framework.serializers import BaseSerializer from rest_framework.serializers import BaseSerializer
from structlog import get_logger 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.models import SerializerModel
from authentik.lib.utils.http import get_client_ip from authentik.lib.utils.http import get_client_ip
from authentik.policies.models import Policy from authentik.policies.models import Policy
@ -17,6 +21,11 @@ LOGGER = get_logger()
CACHE_KEY_PREFIX = "goauthentik.io/policies/reputation/scores/" 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): class ReputationPolicy(Policy):
"""Return true if request IP/target username's score is below a certain threshold""" """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") verbose_name_plural = _("Reputation Policies")
class Reputation(SerializerModel): class Reputation(ExpiringModel, SerializerModel):
"""Reputation for user and or IP.""" """Reputation for user and or IP."""
reputation_uuid = models.UUIDField(primary_key=True, unique=True, default=uuid4) 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) ip_geo_data = models.JSONField(default=dict)
score = models.BigIntegerField(default=0) score = models.BigIntegerField(default=0)
expires = models.DateTimeField(default=reputation_expiry)
updated = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now_add=True)
@property @property
@ -81,4 +92,6 @@ class Reputation(SerializerModel):
return f"Reputation {self.identifier}/{self.ip} @ {self.score}" return f"Reputation {self.identifier}/{self.ip} @ {self.score}"
class Meta: class Meta:
verbose_name = _("Reputation Score")
verbose_name_plural = _("Reputation Scores")
unique_together = ("identifier", "ip") unique_together = ("identifier", "ip")

View file

@ -30,7 +30,7 @@ def check_plex_token(self: MonitoredTask, source_slug: int):
self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, ["Plex token is valid."])) self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, ["Plex token is valid."]))
except RequestException as exc: except RequestException as exc:
error = exception_to_string(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") error = error.replace(source.plex_token, "$PLEX_TOKEN")
self.set_status( self.set_status(
TaskResult( TaskResult(

View file

@ -12961,7 +12961,7 @@ paths:
schema: schema:
type: string type: string
format: uuid format: uuid
description: A UUID string identifying this reputation. description: A UUID string identifying this Reputation Score.
required: true required: true
tags: tags:
- policies - policies
@ -12995,7 +12995,7 @@ paths:
schema: schema:
type: string type: string
format: uuid format: uuid
description: A UUID string identifying this reputation. description: A UUID string identifying this Reputation Score.
required: true required: true
tags: tags:
- policies - policies
@ -13026,7 +13026,7 @@ paths:
schema: schema:
type: string type: string
format: uuid format: uuid
description: A UUID string identifying this reputation. description: A UUID string identifying this Reputation Score.
required: true required: true
tags: tags:
- policies - policies
@ -29523,7 +29523,7 @@ components:
* `authentik_policies_expression.expressionpolicy` - Expression Policy * `authentik_policies_expression.expressionpolicy` - Expression Policy
* `authentik_policies_password.passwordpolicy` - Password Policy * `authentik_policies_password.passwordpolicy` - Password Policy
* `authentik_policies_reputation.reputationpolicy` - Reputation Policy * `authentik_policies_reputation.reputationpolicy` - Reputation Policy
* `authentik_policies_reputation.reputation` - reputation * `authentik_policies_reputation.reputation` - Reputation Score
* `authentik_policies.policybinding` - Policy Binding * `authentik_policies.policybinding` - Policy Binding
* `authentik_providers_ldap.ldapprovider` - LDAP Provider * `authentik_providers_ldap.ldapprovider` - LDAP Provider
* `authentik_providers_oauth2.scopemapping` - Scope Mapping * `authentik_providers_oauth2.scopemapping` - Scope Mapping
@ -29713,7 +29713,7 @@ components:
* `authentik_policies_expression.expressionpolicy` - Expression Policy * `authentik_policies_expression.expressionpolicy` - Expression Policy
* `authentik_policies_password.passwordpolicy` - Password Policy * `authentik_policies_password.passwordpolicy` - Password Policy
* `authentik_policies_reputation.reputationpolicy` - Reputation Policy * `authentik_policies_reputation.reputationpolicy` - Reputation Policy
* `authentik_policies_reputation.reputation` - reputation * `authentik_policies_reputation.reputation` - Reputation Score
* `authentik_policies.policybinding` - Policy Binding * `authentik_policies.policybinding` - Policy Binding
* `authentik_providers_ldap.ldapprovider` - LDAP Provider * `authentik_providers_ldap.ldapprovider` - LDAP Provider
* `authentik_providers_oauth2.scopemapping` - Scope Mapping * `authentik_providers_oauth2.scopemapping` - Scope Mapping
@ -31943,7 +31943,7 @@ components:
* `authentik_policies_expression.expressionpolicy` - Expression Policy * `authentik_policies_expression.expressionpolicy` - Expression Policy
* `authentik_policies_password.passwordpolicy` - Password Policy * `authentik_policies_password.passwordpolicy` - Password Policy
* `authentik_policies_reputation.reputationpolicy` - Reputation Policy * `authentik_policies_reputation.reputationpolicy` - Reputation Policy
* `authentik_policies_reputation.reputation` - reputation * `authentik_policies_reputation.reputation` - Reputation Score
* `authentik_policies.policybinding` - Policy Binding * `authentik_policies.policybinding` - Policy Binding
* `authentik_providers_ldap.ldapprovider` - LDAP Provider * `authentik_providers_ldap.ldapprovider` - LDAP Provider
* `authentik_providers_oauth2.scopemapping` - Scope Mapping * `authentik_providers_oauth2.scopemapping` - Scope Mapping
@ -34930,7 +34930,7 @@ components:
* `authentik_policies_expression.expressionpolicy` - Expression Policy * `authentik_policies_expression.expressionpolicy` - Expression Policy
* `authentik_policies_password.passwordpolicy` - Password Policy * `authentik_policies_password.passwordpolicy` - Password Policy
* `authentik_policies_reputation.reputationpolicy` - Reputation Policy * `authentik_policies_reputation.reputationpolicy` - Reputation Policy
* `authentik_policies_reputation.reputation` - reputation * `authentik_policies_reputation.reputation` - Reputation Score
* `authentik_policies.policybinding` - Policy Binding * `authentik_policies.policybinding` - Policy Binding
* `authentik_providers_ldap.ldapprovider` - LDAP Provider * `authentik_providers_ldap.ldapprovider` - LDAP Provider
* `authentik_providers_oauth2.scopemapping` - Scope Mapping * `authentik_providers_oauth2.scopemapping` - Scope Mapping

View file

@ -258,16 +258,18 @@ new?labels=bug,from_authentik&title=${encodeURIComponent(title)}
return html` <div class="pf-c-card__title">${msg("Secret:")}</div> return html` <div class="pf-c-card__title">${msg("Secret:")}</div>
${this.getModelInfo(this.event.context.secret as EventModel)}`; ${this.getModelInfo(this.event.context.secret as EventModel)}`;
case EventActions.SystemException: case EventActions.SystemException:
return html` <a return html`<div class="pf-l-flex">
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">
<div class="pf-l-flex__item"> <div class="pf-l-flex__item">
<div class="pf-c-card__title">${msg("Exception")}</div> <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"> <div class="pf-c-card__body">
<pre>${this.event.context.message}</pre> <pre>${this.event.context.message}</pre>
</div> </div>

View file

@ -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_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 - `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 ## Listen Setting
- `AUTHENTIK_LISTEN__HTTP`: Listening address:port (e.g. `0.0.0.0:9000`) for HTTP (Server and Proxy outpost) - `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 (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 (LDAP 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 (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 (All) - `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 (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 (Server) - `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`. 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`. 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` ### `AUTHENTIK_WEB__WORKERS`
:::info :::info