Archive

Archive for July, 2024

Warning: Unverified sender in emails from #AWS #SES to #Microsoft365

If you see this text:

Warning: Unverified sender : This message may not be sent by the sender that’s displayed. If you aren’t certain this message is safe, please be cautious when interacting with this email, and avoid clicking on any links or downloading attachments that are on it

Appearing on emails sent via AWS SES to Microsoft 365 Accounts, then there is a simple fix, that you can do – which is to apply DKIM to the domain.

I found that manually supplying the DKIM public/private key was easiest.

So. I created a keypair as follows;

openssl genrsa -out dkim_private.pem 2048
openssl rsa -in dkim_private.pem -pubout -out dkim_public.pem

Then, created a TXT DNS record on the domain named default._domainkey.<mydomain>.com

The records should look like this (using the public key, with spaces removed)

v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2uRIflp/tyXzZDgJ6WxEXoqh5jw==

Then, going in to AWS SES, I add a new identity, select domain, then press “Advanced DKIM”, then Provide DKIM authentication token (BYODKIM) – Then paste the private key, with spaces removed.

AWS then goes and checks your DNS, and hopefully within a few minutes you should get an email starting “DKIM setup SUCCESS”

Once that is in place, any email you send via SES on that domain will be DKIM signed, and trusted by Microsoft365, hopefully getting your delivery rate up!

https://www.smtpjs.com/

Categories: Uncategorized

Handling a System.Net.ProtocolViolationException on a webserver in C#

So, it’s actually been a while since I actually wrote a post about Network Programming in C#, like what the blog is called. But this is an interesting case of a crashing server, and how to fix it.

So, I have a self-written HTTP server, proxied to the world via IIS, but every so often it would crash, and since the service was set to auto-restart, about a minute later it would come back up again. But I couldn’t see the pattern why. I was monitoring the service using UptimeRobot, and it was reporting the service was always down. Now, “Always” is a bit suspect. It went down often, but not “always”.

So, I noticed that UptimeRobot makes HTTP HEAD requests rather than HTTP GET requests, and of course, I always tested my server with HTTP GET. And guess what, a HTTP HEAD request would crash the service, and windows would restart it again a minute later.

To test for HTTP HEAD requests, I used the curl -I flag, which issues a HTTP HEAD, and it crashed the server, with this in the event log:


Exception Info: System.Net.ProtocolViolationException
at System.Net.HttpResponseStream.BeginWrite(Byte[], Int32, Int32, System.AsyncCallback, System.Object)
at System.IO.Stream+<>c.b__53_0(System.IO.Stream, ReadWriteParameters, System.AsyncCallback, System.Object)

So, I created my own minimal server in a console app, so I could test it, without the complexity of the full server.

using System;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace ServerTest
{
    class HttpServer
    {
        public static readonly HttpListener Listener = new HttpListener();
  
        public static string PageData = $"service running";

        public static async Task HandleIncomingConnections()
        {   
            while (true)
            {
                try
                {
                    // Will wait here until we hear from a connection
                    var ctx = await Listener.GetContextAsync();
                    _ = Task.Run(() => HandleConnection(ctx));
                }
                catch (Exception ex)
                {
                    // Handle or log the exception as needed
                    Console.WriteLine($"Error handling connection: {ex.Message}");
                    // Optionally, you could continue to listen for new connections
                    // Or you could break out of the loop depending on your error handling strategy
                }
            }
        }

        private static async void HandleConnection(HttpListenerContext ctx)
        {
            // Peel out the requests and response objects
            var req = ctx.Request;
            var resp = ctx.Response;
            var response = PageData;
            // Write the response info
            var data = Encoding.UTF8.GetBytes(response);
            resp.ContentType = "text/html";
            resp.ContentEncoding = Encoding.UTF8;
            resp.ContentLength64 = data.LongLength;
            if (req.HttpMethod == "GET")
            {
                // Write out to the response stream (asynchronously), then close it
                await resp.OutputStream.WriteAsync(data, 0, data.Length);
            }

            resp.Close();
        }

    }
}

What I’ve highlighted in bold was the fix. What was happening was that the HEAD request was not expeciting a response, but I was proving one, so I checked to see if the HTTP verb was GET, and writing the response, otherwise not.

And, this worked! after months, if not years of an intermittent bug that was so hard to catch.

Categories: Uncategorized