Files
n8n-workspace/Fritzbox-Support-Log.json
2001-01-01 00:00:00 +00:00

82 lines
6.5 KiB
JSON

{
"updatedAt": "2026-09-06T20:22:12.839Z",
"createdAt": "2026-09-06T20:08:23.583Z",
"id": "ZVa4FYBh3wEEWea6",
"name": "Fritzbox-Support-Log",
"active": false,
"isArchived": false,
"nodes": [
{
"parameters": {
"language": "pythonNative",
"pythonCode": "import re\nimport base64\n\ndef sanitize_fritzbox_support_data(text: str) -> str:\n if not text:\n return \"\"\n\n # 1. Passwörter, Hashes, PSK, Auth-Tokens in Key-Value-Strukturen\n secret_keys = [\n r'password', r'passwd', r'secret', r'pskvalue', r'key', r'wpa_key',\n r'pin', r'token', r'auth_token', r'credential', r'sip_password',\n r'cwmp_auth_password', r'ppp_password'\n ]\n for key in secret_keys:\n pattern = rf'(?i)([\"\\']?{key}[\"\\']?\\s*[:=]\\s*)([\"\\'])(.*?)([\"\\'])'\n text = re.sub(pattern, r'\\1\\2[REDACTED_SECRET]\\4', text)\n pattern_bare = rf'(?i)([\"\\']?{key}[\"\\']?\\s*[:=]\\s*)([^\"\\';\\s,]+)'\n text = re.sub(pattern_bare, r'\\1[REDACTED_SECRET]', text)\n\n # 2. MyFRITZ! Domains\n text = re.sub(r'\\b[a-z0-9]{16,}\\.myfritz\\.net\\b', '[MYFRITZ_DOMAIN_REDACTED]', text, flags=re.IGNORECASE)\n\n # 3. DynDNS-Adressen\n text = re.sub(\n r'\\b[a-zA-Z0-9_\\-\\.]+\\.(?:dyndns\\.(?:org|net)|ddns\\.net|spdns\\.de|duckdns\\.org|no-ip\\.(?:biz|org|info))\\b',\n '[DYNDNS_DOMAIN_REDACTED]',\n text,\n flags=re.IGNORECASE\n )\n\n # 4. E-Mail-Adressen\n text = re.sub(r'\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b', '[EMAIL_REDACTED]', text)\n\n # 5. MAC-Adressen\n text = re.sub(r'\\b(?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]{2})\\b', '[MAC_ADDRESS_REDACTED]', text)\n\n # 6. IPv6-Adressen\n ipv6_pattern = r'\\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\b|\\b(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)\\b'\n text = re.sub(ipv6_pattern, '[IPV6_REDACTED]', text)\n\n # 7. IPv4-Adressen\n def mask_ip(match):\n ip = match.group(0)\n parts = ip.split('.')\n if any(int(p) > 255 for p in parts):\n return ip\n if ip.startswith(('192.168.', '10.', '172.16.')):\n return '[LOCAL_IP_REDACTED]'\n if ip in ('127.0.0.1', '0.0.0.0'):\n return ip\n return '[PUBLIC_IP_REDACTED]'\n\n text = re.sub(r'\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b', mask_ip, text)\n\n # 8. Telefonnummern & SIP-Kennungen\n text = re.sub(r'(?i)(number|msn|caller|called|dial|target|sip_user)\\s*[:=]\\s*[\"\\']?(\\+?[0-9\\s\\-\\/\\(\\)]{4,25})[\"\\']?',\n r'\\1=\"[PHONE_NUMBER_REDACTED]\"', text)\n text = re.sub(r'\\b(?:\\+49|0049|0)[1-9][0-9\\s\\/\\-]{5,15}\\b', '[PHONE_NUMBER_REDACTED]', text)\n\n # 9. Seriennummern & AVM-Hardware-IDs\n text = re.sub(r'\\b[A-Z][0-9]{3}\\.[0-9]{3}\\.[0-9]{2}\\.[0-9]{6}\\b', '[SERIAL_NUMBER_REDACTED]', text)\n text = re.sub(r'(?i)(serialnumber|serial_number|cwmp_id|mac_dsl)\\s*[:=]\\s*[\"\\']?([^\"\\';\\s]+)[\"\\']?',\n r'\\1=\"[SERIAL_REDACTED]\"', text)\n\n # 10. WLAN-Namen (SSID)\n text = re.sub(r'(?i)(ssid\\s*[:=]\\s*[\"\\'])(.*?)([\"\\'])', r'\\1[WLAN_SSID_REDACTED]\\3', text)\n\n return text\n\n\noutput_items = []\n\nfor item in _items:\n raw_text = \"\"\n # Binärdaten der hochgeladenen Datei holen\n if 'binary' in item and len(item['binary']) > 0:\n first_key = list(item['binary'].keys())[0]\n raw_b64 = item['binary'][first_key]['data']\n raw_bytes = base64.b64decode(raw_b64)\n \n # Kodierung erkennen (FRITZ!Box nutzt UTF-8 oder ISO-8859-1)\n try:\n raw_text = raw_bytes.decode('utf-8')\n except UnicodeDecodeError:\n raw_text = raw_bytes.decode('iso-8859-1', errors='replace')\n else:\n raw_text = item.get('json', {}).get('text', '')\n\n # Anonymisieren\n clean_text = sanitize_fritzbox_support_data(raw_text)\n\n # Wieder zurück in n8n-Binärdaten konvertieren\n clean_bytes = clean_text.encode('utf-8')\n clean_b64 = base64.b64encode(clean_bytes).Es scheint, als ob der Kontext aus einer vorherigen Unterhaltung fehlt. \n\nUm welches Thema oder welche Aufgabe geht es genau, und was beinhaltete **Methode 2**? Gib mir kurz ein Stichwort oder die Details, dann legen wir direkt damit los!"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
224,
0
],
"id": "bfbdc381-8e7d-4235-a384-7fbc26390249",
"name": "Code in Python"
},
{
"parameters": {
"formTitle": "Fritzbox-Annonymizer",
"formFields": {
"values": [
{
"fieldLabel": "Fritzbox-Support-File",
"fieldType": "file"
}
]
},
"responseMode": "lastNode",
"options": {}
},
"type": "n8n-nodes-base.formTrigger",
"typeVersion": 2.5,
"position": [
0,
0
],
"id": "bc0ec24d-ce45-41b0-9eb2-991962a078a7",
"name": "On form submission",
"webhookId": "6ae502da-3a92-4cd2-a790-5ecdab69d6b6"
}
],
"connections": {
"On form submission": {
"main": [
[
{
"node": "Code in Python",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"binaryMode": "separate"
},
"staticData": null,
"meta": null,
"pinData": {},
"versionId": "1e6147d7-6a5f-49dc-b7af-012e454c03f1",
"activeVersionId": null,
"triggerCount": 0,
"shared": [
{
"updatedAt": "2026-09-06T20:08:23.587Z",
"createdAt": "2026-09-06T20:08:23.587Z",
"role": "workflow:owner",
"workflowId": "ZVa4FYBh3wEEWea6",
"projectId": "cSAaWNJydnksD5EB"
}
],
"activeVersion": null,
"tags": []
}