Postfix Subject/Header-rewrite based on destination address

I write this article because it was really hartd to find anything useful for this problem.

I wanted to add an [External]-String to the subject for all incoming external mails in our postfix relay server which is also filtering spam. While this is pretty simple if you want to do it with every incoming mail by using smtp_header_checks, it gets ugly if you want to exclude some mail addresses from this rule. I first tried to do it with transport rules but didn’t like the complexity of configuration over several files. Another idea was to use alterMIME. Since its development is stuck for over a decade now, I decided against it.

After a lot of searching I found a thread in the german debianforum which described a solution based on mimedefang. Its integration in postfix is based on milters. So it is easy to use. I will show how to use it on a ubuntu machine

Now lets start with the howto

First install mimedefang

apt install mimedefang

then enable a tcp-listener socket in /etc/default/mimedefang by adding the following line to the file

SOCKET=inet:17889

Now you have to create the a script file in perl what actualy does the rewriting. This sample taken from the forum thread only rewrites mail for a specific domain. It can be easily modified to do specifc rewrites

It has to have the following name: /etc/mail/mimedefang-filter

# -*- Perl -*-

# -- values from the template

$AdminAddress = 'postmaster@localhost';
$DaemonAddress = 'mailer-daemon@localhost';
$Stupidity{"NoMultipleInlines"} = 0;

# ---------------------------

sub filter_end {
    my($entity) = @_;
    for ($count=0;$myRecipient=$entity->head->get("To",$count);$count++) {
        if($myRecipient =~ m/\<[^@]+\@mydomain.com\>/) {
            $sbj = $entity->head->get("Subject",0);
            action_change_header("Subject","[External] $sbj");
            break;
        }
   }
}


# DO NOT delete the next line, or Perl will complain.
1;

Now the mimedefang service hase to be enabled and started

systemctl enable mimedefang.service
systemctl start mimedefang.service

For postfix to use mimedefang simply add it to you milter in postfix main.cf

# if mimedefang is the only milter
smtpd_milters = inet:localhost:17889
# rspamd + mimedefang
smtpd_milters = inet:localhost:11332, inet:localhost:17889

then restart postfix and you are good to go.

systemctl start postfix.service

If you make any modifications to the filterscript you have to restart mimedefang.

If anything is unclear please add a comment and I try to write a more detailed version

January 2024 Security update fails (KB5034441 and KB5034439) Windows 10 and Windows 2022

We discovered that a security update on Windows 10(KB5034441 ) and Windows Server 2022(KB5034439) fails with a Download error – 0x80070643.

Thanks to a reddit thread I discovered that this error message is wrong. This update tries to patch the recovery partition and fails to do so because it is to small. I was able to fix all machines so far by resizing the recovery partiton from 578MB to 878MB with GParted started from res rescuezilla media.

Afterwards the Update ran successfuly.

Smartmeter Stromzähler ESPHome und SML für Homeassistant auslesen

Da aktuell die meisten Projekte zum Auslesen von Stromzählern mit dem SML-Protokoll und ESP32/ ESP8266 aus Tasmota beruhen, hier mal meine Erfolgreiche Implementation mit ESPHome.

Ich habe mir die TTL-Version des Volkszählers auf eBay besorgt und mit einem Wemos D1 mini verbunden. Ground und Spannung kommen an die 5V und Ground vom ESP RX und TX-Leitungen des Volkszählers über kreuz an die RX/TX-Pins des ESP.

Hier sind meine YAML-Einstellungen um den Stromzähler auszulesen.

uart:
  id: uart_bus
  tx_pin: 1
  rx_pin: 3
  baud_rate: 9600
  debug:

sml:
  id: mysml
  uart_id: uart_bus

sensor:
  - platform: sml
    name: "Total energy"
    sml_id: mysml
    obis_code: "1-0:1.8.0"
    unit_of_measurement: kWh
    accuracy_decimals: 0
    device_class: energy
    state_class: total_increasing
    filters:
      - throttle_average: 60s

Ich habe beim Suchen ein Beispiel gefunden, was die UART-Baudrate auf 300 hatte. Damit kamen im Debug-Log des ESP zwar ständig UART-Daten, aber keine dekodierten SML-Daten. Toll war aber, dass man sehen konnte, dass der Zähler etwas sendet. Beim Abnehmen des Sensors vom Zähler ist das UART-Log sofort ruhig geworden. Nach dem Umstellen auf 9600 Baud dekodierte er dann sofort die UART-Daten zu SML. Dann kann man auch sehen, welche OBIS-Codes der Zähler sendet. Das sieht dann bei mir so aus:

[16:40:14][D][sml:065]: OBIS info:
[16:40:14][D][sml:071]:   (0a014546521901d94a67) 1-0:96.50.1 [0x12345]
[16:40:14][D][sml:071]:   (0a014546521901d94a67) 1-0:96.1.0 [0x013124234]
[16:40:14][D][sml:071]:   (0a014546521901d94a67) 1-0:1.8.0 [0x31ba]
[16:40:14][D][sml:071]:   (0a014546521901d94a67) 1-0:0.2.0 [0x31234345]
[16:40:14][D][sml:071]:   (0a014546521901d94a67) 1-0:96.90.2 [0xa90a]
[16:40:14][D][sml:071]:   (0a014546521901d94a67) 1-0:97.97.0 [0x0000]
[16:40:14][D][sml:071]:   (0a014546521901d94a67) 1-0:96.50.1 [0x12345677898]

Mit dieser Info kann man dann auf der Tasmota-SML-Seite nachschauen, ob die einzelnen OBIS-Werte nützlich sind. Leider gibt mein Zähler nicht die aktuelle Wirkleistung aus. Hier muss ich mir wohl noch die PIN meines Zählers von meiner Netzgesellschaft holen.

Mein ESP8266 hängt aktuell an einer Powerbank, da ich keine Steckdose in der Nähe des Zählers habe. Mal sehen wie lange das hält.

Update

Nach einer Woche kam jetzt die PIN für meinen Stromzähler. Durch das aktivieren des erweiterten Modus bei meinem Stromzähler tauchte nun auch die aktuelle Wirkleistung auf. Das ist echt toll. Auch der Zählerstand hat plötzlich drei Nachkommastellen. Das führte dazu, dass ich nach der Umstellung die Wert nochmal anpassen musste.

uart:
  id: uart_bus
  tx_pin: 1
  rx_pin: 3
  baud_rate: 9600
  debug:

sml:
  id: mysml
  uart_id: uart_bus

sensor:
  - platform: sml
    name: "Total energy"
    sml_id: mysml
    obis_code: "1-0:1.8.0"
    unit_of_measurement: kWh
    accuracy_decimals: 3
    device_class: energy
    state_class: total_increasing
    filters:
      - multiply: 0.0001
      - throttle_average: 300s
  - platform: sml
    name: "Current Power"
    sml_id: mysml
    obis_code: "1-0:16.7.0"
    unit_of_measurement: W
    accuracy_decimals: 0
    device_class: power
    state_class: measurement
  - platform: sml
    name: "Current Voltage"
    sml_id: mysml
    obis_code: "1-0:32.7.0"
    unit_of_measurement: V
    accuracy_decimals: 1
    device_class: voltage
    state_class: measurement    
    filters:
      - multiply: 0.1
  - platform: sml
    name: "Current Current"
    sml_id: mysml
    obis_code: "1-0:31.7.0"
    unit_of_measurement: A
    accuracy_decimals: 2
    device_class: current
    state_class: measurement    
    filters:
      - multiply: 0.01
  - platform: sml
    name: "Current Frequency"
    sml_id: mysml
    obis_code: "1-0:14.7.0"
    unit_of_measurement: Hz
    accuracy_decimals: 3
    device_class: frequency
    state_class: measurement    
    filters:
      - multiply: 0.1

Lenovo Thinkstation P620 supports 1TB of RAM?

Just in case anyone tries to find out if the great Lenovo Workstation P620 supports 1TB of RAM. I got you covered. Yes it does!

The documentation of Lenovo says different things. The Maintenance Manual talks about a maximum of 512GB. The marketing tech specs are allowing 1TB. I found proof for support in the BIOS-Update history.

To achieve this you need 8 x 128GB RDIMMs. But normally 128GB-RDIMMs are LRDIMMs. The CPU supports LRDIMMs but not the mainboard of the P620.

So you have to find the unicorn. And that is from Samsung Its correct product number is: M393AAG40M32-CAE. Thats a 128GB DDR4-3200 Registered DIMM with ECC.

Maybe this article save someone a little headache because it is not the cheapest RAM available.

Paperless-ngx auf Synology

Da ich noch keine kurze Anleitung zum Installieren von paperless-ngx in der normalen Docker-Umgebung auf der Synology gefunden habe, kommt hier eine.

Ich gehe davon aus, dass Docker-Paket installiert ist und funktioniert.

  1. Verzeichnis anlegen um alle relevanten Daten von paperless-ngx außerhalb des Docker-Containers zu lagern. Das wird im docker-Ordner gemacht damit der Container dann auch Schreibrechte hat.

2.Download der benötigten Docker-Images

Zum Betrieb von paperless-nx benötigen wir die beiden Images redis und paperlessngx/paperless-ngx. Diese findet man im Registry-Bereich in Docker.

paperless-ngx in der Registry
Das redis-Paket in der Registry

Wenn der Download fertig ist, findet man sie unter Image

Meine Docker-Images

3. Redis-Container erzeugen

paperless benötigt redis um zu funktionieren. Deshalb erzeugen wir den Container mit dem Launch-Knopf während das Redis-Image markiert ist.

Auf der ersten Seite des Assistenten müssen wir die Netzwerkanbindung des Containers wählen. Ich wähle hier immer “Use same network as Docker Host”

Auswahl der Netzwerkanbindung

Alle anderen Einstellungen auf den Folgeseiten einfach auf den Standardeinstellungen stehen lassen und auch den Container danach starten lassen.

4. paperless-ngx-Container erzeugen.

Hierzu auch den Lauch-Knopf drücken während paperlessngx/paperless-ngx markiert ist.

Auf der ersten Wizard-Seite wieder die zweite Option auswählen:

Auf der zweiten Seite drücken wir den “Advanced Settings”-Knopf.

In dem Menü müssen wir zwei Umgebungsvariablen hinzufügen um uns später mit einem Admin-User einloggen zu können In der Variable PAPERLESS_ADMIN_USER kommt der Nutzername des ersten Benutzers rein.

PAPERLESS_ADMIN_PASSWORD enthält das Passwort

zwei Variablen um Paperless den Nutzer mitzuteilen.

Auf der Folgeseite kommen dann die Volume Settings. Hier fügen wir das in Schritt 1 angelegte Verzeichnis an zwei Stellen im Container ein. Dadurch kann dann der komplette Container gelöscht werden und trotzdem sind noch alle Daten da. Hier drücken wir also den “Add Folder”-Knopf und wählen dann den paperless-Ordner aus

als Mount-Path kommt /usr/src/paperless/media/ rein. Danach fügen wir den selben Ordner nochmal hinzu und wählen als Mount-Path stattdessen /usr/src/paperless/data/

Mount-Paths

Auf der Summary-Seite einfach Done drücken und der paperless-ngx-Container sollte loslaufen. Den Erfolg können wir auf der Container-Seite überprüfen.

Laufende Container auf der Synology

Sollte irgendetwas nicht in Ordnung sein, beendet sich der Container nach einigen Sekunden wieder. Den Fehler kann man dann auf dem Log-Tab der Container-Details erlesen.

Wenn alles geklappt hat, können wir uns mit den vorher festgelegten Zugangsdaten auf dem Webinterface von Paperless einloggen. Das finden wir unter Port 8000 der Synology

Exchange Powershell: list all Mailboxes with GUID

I ran in to the problem identifying a mailbox by a partial GUID.

If Outlook has a synchonization problem it gives you the url with a partial GUID. With the following comand you can list all mailboxes.

Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox,SharedMailbox | Select-Object UserPrincipalName, ExchangeGuid

Windows 11 slow internet connection Dell/Killer Network

After updating to Windows 11 I experienced a very laggy browser on all my favourite websites. But every speed test I did was ok. After some digging, I found the solution in the Microsoft Techcommunity. In a lot of Dell PCs they use Killer Network Adapters. My XPS 8940 has a builtin Killer E2600. After disabling the Killer Network Service all was ok again.

Telekom SIP 1TR119 CompanyFlex legt auf mit Reason: SIP;cause=404;text=”Not Found (1:27)”

Heute mal in anderer Sprache, da die betroffen Nutzer am ehesten aus dem deutschem Sprachraum kommen.

Wir haben einem CompanyFlex oder im Telekom-Fachchinesisch 1TR119 ausprobiert. Hier litten wir unter häufigen Gesprächsabbrüchen. Diese wurden immer von der Telekomseite verursacht und hatten folgenden Grund drin:

Reason: SIP;cause=404;text=”Not Found (1:27)”

wie zum Beispiel in folgendem Bye:

BYE sip:+49190000000123@192.168.1.2:5060;transport=tcp SIP/2.0
Max-Forwards: 70
Via: SIP/2.0/TLS 217.0.137.51:5061;branch=z9hG4bKg3Zqkv7iscypm2yeo4cl9nwd182p3bgqb
To: <sip:+49190000000123@tel.t-online.de:5060>;tag=WRIRDULZNU
From: <sip:+493012345@tel.t-online.de:5060;transport=tls>;tag=h7g4Esbg_898065121-1618311345090
Call-ID: c875dd16cf44479e828473e429de19e6
CSeq: 1 BYE
Reason: SIP;cause=404;text="Not Found (1:27)"
Content-Length: 0

Grund hierfür war das Verhalten des SIP-Stacks bei der Registrierung an tel.t-online.de. Das ist mittlerweile ja kein A sondern ein SRV basierter Eintrag im DNS. Dieser sieht bei SIP mit TLS und TCP dann so aus:

dig srv _sips._tcp.tel.t-online.de

;; ANSWER SECTION:
_sips._tcp.tel.t-online.de. 3600 IN SRV 10 0 5061 do-eps-100.edns.t-ipnet.de.
_sips._tcp.tel.t-online.de. 3600 IN SRV 20 0 5061 h2-eps-100.edns.t-ipnet.de.
_sips._tcp.tel.t-online.de. 3600 IN SRV 30 0 5061 d-eps-100.edns.t-ipnet.de.

Hier bekommt man 3 mögliche Anmeldeserver. Sollte der SIP-Stack sich während eines laufenden Gesprächs an einem anderen Server anmelden, weil zum Beispiel die Telekom die Prioritäten der SRV-Records ändert, dann beendet der vorherige Registrierungsserver und damit auch SIP-Session-Partner nach einem Timeout das Gespräch. Ein schneller Test und provisorische Problembehebung ist der Eintrag eines der Ergebnisse des SRV-Lookups wie zum Beispiel do-eps-100.edns.t-ipnet.de. Das ist natürlich keine Dauerlösung, da die Einträge jederzeit wechseln können. Eigentlich müsste der SIP-Stack hier solange am Erstregistrierungsserver dran bleiben, bis er aus der SRV-Liste verschwindet oder unerreichbar ist. Andererseits könnte die Deutsche Telekom die bestehenden Gespräche auch weiterlaufen lassen.

Ich vermute, dass das auch bei DeutschlandLAN-Anschlüssen nach 1TR114 und 1TR118 passieren kann. Je nach Protokoll muss hier die Frage nach den SRV-Records aber auch nach SIP und UDP erfolgen. Das sieht dann so aus:

dig srv _sip._udp.tel.t-online.de

;; ANSWER SECTION:
_sip._udp.tel.t-online.de. 3368 IN SRV 30 0 5060 d-epp-100.edns.t-ipnet.de.
_sip._udp.tel.t-online.de. 3368 IN SRV 10 0 5060 do-epp-100.edns.t-ipnet.de.
_sip._udp.tel.t-online.de. 3368 IN SRV 20 0 5060 h2-epp-100.edns.t-ipnet.de.

Migrate linux bare metal server to proxmox Container

Today I had to migrate a bare metal linux machine to an proxmox lxc container. I googled a bit an found a nice shore tar command in the proxmox forum but I had to add some excludes

cd /

tar -cvpzf backup.tar.gz –exclude=/backup.tar.gz –exclude=/proc –exclude=/dev –exclude=/sys /

Without excluding dev, proc and sys the tar command tried to compress some virtual 128TB Files in the proc file system. In the new container those directories aren’t needed anyway. Next time I don’t need to google this 🙂

The tar.gz can be copied to the template directory of the proxmox server. Afterwards you can deploy an new container with this template. If you get errors extracting the template. you have to uncheck the “Unpriviliged Container”-Box

firewalld: open port for single ip (or how to limit access to checkmk-agent to a single ip)

Newer versions of checkmk-agent for linux started to use systemd instead of xinetd to spawn the agent. So you loose the ability to limit access through a simple config file.

My Solution was with a rule in firewalld. You have to use a rich rule. Sadly thats not as easy as the usual firewalld stuff…

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="11.22.33.44/32" port protocol="tcp" port=6556 accept'

Afterwards simply restart firewalld or reload rules.