Select Page

How to create a WildDuck DKIM key for a new domain

After adding a new domain to the WildDuck configuration you might also want to create a DKIM key for that domain.

A new DKIM key can be created via API.
I’m using Insomnia and I have created a POST request posting to /remote-api/dkim API URL and configured the X-Access-Token header with the authentication accessToken value from /etc/wildduck/wildduck-webmail.toml (see the [api] section in that file):

Then in the Query tab we can add a selector of our choice and the domain name:

Now we can press Send and copy the value (e.g. v=DKIM1;t=s;p=...) from the Preview tab into our new TXT DNS record.

Magento customers unable to place new orders

Multiple users have reported issues with Magento 2 (see GitHub magento2/issues/23618 or magento2/issues/23908) where customers are unable to proceed with their orders during checkout due to apparent problems with their shipping address.

In those cases, the customers will see a message stating Unable to save shipping information. Please check input data. OR The shipping information was unable to be saved. Verify the input data and try again.. E.g.:

Despite the screenshot above, the address might be correct and customer can’t do anything to unlock the situation hence leading to frustration.

Looking in the logs at var/log/exception.log, multiple related `Invalid customer address id` records can be noted. E.g.:

main.CRITICAL: Invalid customer address id 691 {"exception":"[object] (Magento\\Framework\\Exception\\NoSuchEntityException(code: 0): Invalid customer address id 691 at /vendor/magento/module-quote/Model/QuoteAddressValidator.php:77)"} []

Please note that the ID above is not che customer ID but the customer address ID that can be found in the `customer_address_entity` table. E.g.:

SELECT * FROM magentoDBname.customer_address_entity WHERE entity_id = 691;

This problem appears to be due to a bug occurring when particular conditions are met (see Stack Overflow). Sadly reading from those reports in GitHub and elsewhere, Adobe don’t appear to have figured out a resolution for this edge issue which seems to still affect the most recent versions.

Some code changes have been suggested by users to fix the problem while my preferred, albeit temporary, solution is that of updating the SQL code for those affected users (so we don’t change the Magento core code).

If curious, we can find the affected customers with:

SELECT entity_id, customer_id FROM quote WHERE customer_id != 0 AND customer_is_guest = 1;

We could instead find more details with:

SELECT a.entity_id, a.customer_id, b.firstname, b.lastname, b.email FROM quote a, customer_entity b WHERE a.customer_id != 0 AND customer_is_guest = 1 AND a.customer_id = b.entity_id;

And fix them with:

UPDATE quote SET customer_is_guest = 0 WHERE customer_id != 0 AND customer_is_guest = 1;

 

Useful bookmarks

Azure alerts to Microsoft Teams (and Slack)

I found myself in the position of having to get Azure Monitor alerts notifications into Microsoft Teams. So I thought it would be as easy as creating an Incoming Webhook in Teams and adding its URL to an Azure Action Group, right? Wrong!

After trying that in vain, I’ve ended up “googling” on this subject only to find out that the best way to achieve this is using an Azure Logic App. I’ve also seen others using Function Apps while the easiest approach of them all is that of relying on an alert management system similar to PagerDuty (etc.) or a better monitoring solution.
The only problem with the easiest approach is that the organisation needs to be willing to pay for the tool unless you’re in the fortunate position to have one already, which I wasn’t. Hence, let’s go down the complicated route, the way Microsoft likes to do things anyway (private joke).

One of the most common results when looking for a Logic App approach is this article by Bruno Gabrielli, https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/azure-monitor-alert-notification-via-teams/ba-p/2507676
However, like other attempts on this subject, I don’t think that guide is stupid-proof as I still wasted hours until I’ve eventually figured out how to get it done. So I thought will write down something which I hope might help me (or someone else) if I have to do this again at a later stage.

Logic App

Let’s create a Logic App based on a Consumption plan (I’ve seen reports that this is not going to work with a Standard plan):

Once created and accessed, we are greeted by a Logic App Designer with a few proposed triggers to choose from. Let’s pick “When a HTTP request is received”.

Past the following JSON schema and click Next step (you might want other payloads depending on the type of alert you want to send to Teams):

{
    "properties": {
        "data": {
            "properties": {
                "context": {
                    "properties": {
                        "condition": {
                            "properties": {
                                "allOf": {
                                    "items": {
                                        "properties": {
                                            "dimensions": {
                                                "items": {
                                                    "properties": {
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "value": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "required": [
                                                        "name",
                                                        "value"
                                                    ],
                                                    "type": "object"
                                                },
                                                "type": "array"
                                            },
                                            "metricName": {
                                                "type": "string"
                                            },
                                            "metricValue": {
                                                "type": "integer"
                                            },
                                            "operator": {
                                                "type": "string"
                                            },
                                            "threshold": {
                                                "type": "string"
                                            },
                                            "timeAggregation": {
                                                "type": "string"
                                            }
                                        },
                                        "required": [
                                            "metricName",
                                            "dimensions",
                                            "operator",
                                            "threshold",
                                            "timeAggregation",
                                            "metricValue"
                                        ],
                                        "type": "object"
                                    },
                                    "type": "array"
                                },
                                "windowSize": {
                                    "type": "string"
                                }
                            },
                            "type": "object"
                        },
                        "conditionType": {
                            "type": "string"
                        },
                        "description": {
                            "type": "string"
                        },
                        "id": {
                            "type": "string"
                        },
                        "name": {
                            "type": "string"
                        },
                        "portalLink": {
                            "type": "string"
                        },
                        "resourceGroupName": {
                            "type": "string"
                        },
                        "resourceId": {
                            "type": "string"
                        },
                        "resourceName": {
                            "type": "string"
                        },
                        "resourceType": {
                            "type": "string"
                        },
                        "subscriptionId": {
                            "type": "string"
                        },
                        "timestamp": {
                            "type": "string"
                        }
                    },
                    "type": "object"
                },
                "properties": {
                    "properties": {
                        "key1": {
                            "type": "string"
                        },
                        "key2": {
                            "type": "string"
                        }
                    },
                    "type": "object"
                },
                "status": {
                    "type": "string"
                },
                "version": {
                    "type": "string"
                }
            },
            "type": "object"
        },
        "schemaId": {
            "type": "string"
        }
    },
    "type": "object"
}

In the Next step search for Condition. Pick Control and choose Condition, select a status dynamic content and set it is equal to Activated.

Continue and add Teams actions (Post message in a chat or channel) to both True and False conditions (you can do the same with Slack and also send notifications to multiple channels at the same time).

Now, here you can go ahead and complete the Message with dynamic content and/or expressions.
In my case, I wanted a clickable link to the Azure alert. The URL is given by the portalLink dynamic content, however, that doesn’t come clickable in Teams and I’ve only been able to render that clickable by editing the Logic App’s messageBody section via the code view.
Essentially, my messageBody in the True condition looks like this:
"messageBody": "<p>🚨 Azure <strong></strong><strong>@{triggerBody()?['data']?['context']?['name']}</strong><strong></strong><br>\n@{triggerBody()?['data']?['context']?['description']}.<br>\n<a href=\"@{triggerBody()?['data']?['context']?['portalLink']}\">@{triggerBody()?['data']?['context']?['portalLink']}</a></p>",
Then for False I simply have:
"messageBody": "<p>The Azure <strong>@{triggerBody()?['data']?['context']?['name']}</strong> is now <span style=\"color: rgb(65,168,95)\"><strong>Resolved ✔</strong></span><br>\n<a href=\"@{triggerBody()?['data']?['context']?['portalLink']}\">@{triggerBody()?['data']?['context']?['portalLink']}</a></p>",

With all that Saved, we can move on to the Alert.

Alert Rule

For this exercise, I have created a ping URL test from within an App Insights’ Availability and by default that created me an alert for it. Let’s edit this alert rule and add an Action Group:

Now you can either choose an existing Action Group or create a new one which is what I’m doing. Either way, we need to go to the Actions tab and choose Webhook.

You might be tempted to pick the Logic App instead of a Webhook and that’s what you’ll also find in some guides. However, I’ve wasted a lot of time on that and never had it to work as the alerts, although sent to Teams, were coming through empty.
Once Webhook is selected, we have to paste the “HTTP POST URL” from the first Logic App step.

Please note that you do not need to enable the “common alert schema”:

With the alert rule now saved you have it bound to an Action Group coupled with the Webhook pointing at the Logic App HTTP POST URL trigger.
So let’s do some testing.

Teams

As mentioned, in my example I’m using a simple ping URL test against an App Service. I’m going to stop the App Service and once the thresholds are reached I am expecting a notification to my chosen Teams channel.
Here we go:

Starting the App Service back should now trigger a “resolved” notification back to my Teams channel:

How to add multiple domains to WildDuck Webmail?

How to add multiple domains to WildDuck Webmail?

WildDuck is a simple mail server solution and is often accompanied by the WildDuck Webmail service. While you can create email addresses with any domain via both the WildDuck’s API and the Webmail GUI, when it comes to aliases and the ease of use of the user interface, by default you’re only limited to the one you’ve initially configured.

To add further domains to choose from when creating alias addresses, edit the wildduck-webmail.toml file (it is located in /etc/wildduck/) and add your additional domains in the domains=[] array like so:

[service]
...
# allowed domains for new addresses
domains=["oviliz.com","seconddomain.com"]

Restart the webmail service with systemctl restart wildduck-webmail and you’re good to go.

Now if you want to also create a separate DKIM key and DNS record, follow this short guide.