From cb15e4db25147240125cad4ffa77c31428d240dd Mon Sep 17 00:00:00 2001 From: Ari Archer Date: Wed, 21 Aug 2024 11:30:18 +0300 Subject: [PATCH] update @ Wed Aug 21 11:30:18 EEST 2024 Signed-off-by: Ari Archer --- blog.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/blog.json b/blog.json index 7fbd4ea..ee8d12a 100644 --- a/blog.json +++ b/blog.json @@ -128,6 +128,25 @@ "top-words": 64, "top-tags": 64, "posts": { + "openpgpkey-records-are-cool": { + "title": "OPENPGPKEY records are cool", + "description": "Dive into the world of email security with the OPENPGPKEY DNS record! This powerful tool is essential for encryption and authentication in today's digital landscape. I'll break down the specifications from RFC 7929, guide you through creating your own OPENPGPKEY record generator, and highlight common mistakes to avoid that were made by others. This guide will help you to understand the OPENPGPKEY record. Join me in making the internet and email a more secure place!", + "content": "OPENPGPKEY are a nice feature of modern DNS for email encryption and authentication. Let's see what talk there is about it!\n\n**Correction**: I have reinterpreted the RFC, and I figured out my original interpretation of it was wrong. I have done this in a short period (around an ahour) and I have republished the corrected version.\n\n## OPENPGPKEY DNS record\n\nI just found out about OPENPGPKEY records in modern DNS while exploring the [deSEC homepage](https://desec.io/).\nI logged into my deSEC account and there it was - OPENPGPKEY DNS record type.\n\nWell, I wondered - what is it, and how can I set it up.\n\nWhich led me to multiple articles and generators, which then led me to the RFC document at .\n\nI began hand-crafting my own OPENPGPKEY record generator based off the RFC.\n\n## OPENPGPKEY record generator\n\nI read the intro of the aforementioned RFC until I found this:\n\n> 3. Location of the OPENPGPKEY Record\n>\n> The DNS does not allow the use of all characters that are supported\n> in the \"local-part\" of email addresses as defined in [RFC5322] and\n> [RFC6530]. Therefore, email addresses are mapped into DNS using the\n> following method:\n>\n> 1. The \"left-hand side\" of the email address, called the \"local-\n> part\" in both the mail message format definition [RFC5322] and in\n> the specification for internationalized email [RFC6530]) is\n> encoded in UTF-8 (or its subset ASCII). If the local-part is\n> written in another charset, it MUST be converted to UTF-8.\n>\n> 2. The local-part is first canonicalized using the following rules.\n> If the local-part is unquoted, any comments and/or folding\n> whitespace (CFWS) around dots (\".\") is removed. Any enclosing\n> double quotes are removed. Any literal quoting is removed.\n>\n> 3. If the local-part contains any non-ASCII characters, it SHOULD be\n> normalized using the Unicode Normalization Form C from\n> [Unicode90]. Recommended normalization rules can be found in\n> Section 10.1 of [RFC6530].\n>\n> 4. The local-part is hashed using the SHA2-256 [RFC5754] algorithm,\n> with the hash truncated to 28 octets and represented in its\n> hexadecimal representation, to become the left-most label in the\n> prepared domain name.\n>\n> 5. The string \"_openpgpkey\" becomes the second left-most label in\n> the prepared domain name.\n>\n> 6. The domain name (the \"right-hand side\" of the email address,\n> called the \"domain\" in [RFC5322]) is appended to the result of\n> step 2 to complete the prepared domain name.\n>\n> For example, to request an OPENPGPKEY resource record for a user\n> whose email address is \"hugh@example.com\", an OPENPGPKEY query would\n> be placed for the following QNAME: \"c93f1e400f26708f98cb19d936620da35\n> eec8f72e57f9eec01c1afd6._openpgpkey.example.com\". The corresponding\n> RR in the example.com zone might look like (key shortened for\n> formatting):\n>\n> c9[..]d6._openpgpkey.example.com. IN OPENPGPKEY \\\n\nBased off this part alone pretty much, I made a shell script that generated\na valid output! It is located at \nlicensed under the public domain (CC0) and it looks like this:\n\n #!/usr/bin/env sh\n\n ...\n\n set -eu\n\n main() {\n if [ \"$#\" -ne 2 ]; then\n {\n echo \"Generates an OPENPGPKEY DNS record based off your Email and a Public GPG key ID.\"\n echo \"Usage: $0 \"\n } >&2\n return 1\n fi\n\n # Confirm user localpart\n\n localpart=\"$(printf -- '%s' \"$1\" | cut -d'@' -f1 | tr '[:upper:]' '[:lower:]')\"\n\n printf -- \" * Your email username (localpart) is '\\033[1m%s\\033[0m', correct? In lowecase, enter either 'y' (for yes) or 'n' (for no): \" \"$localpart\"\n read -r yn\n if [ \"$yn\" -ne 'y' ]; then\n echo \" * Incorrect information provided.\" >&2\n return 1\n fi\n\n # Localpart digest is the SHA256 hex digest truncated to 28 octets\n localpart_digest=\"$(printf -- '%s' \"$localpart\" | sha256sum | cut -d' ' -f1 | cut -c1-56)\"\n\n # And the value has to be the base64-encoded public key, exported as binary\n gpg_public_key_b64=\"$(gpg --export --export-options export-minimal,no-export-attributes -- \"$2\" | base64 -w 0)\"\n\n printf '\\n\\033[32m%s\\033[0m._openpgpkey. \\033[90mIN OPENPGPKEY\\033[0m \\033[1m%s\\033[0m\\n' \"$localpart_digest\" \"$gpg_public_key_b64\"\n }\n\n main \"$@\"\n\n(`...` just signifies the cut out status message, author, and license)\n\nThe main functionality is located in two lines of code:\n\n # Localpart digest is the SHA256 hex digest truncated to 28 octets\n localpart_digest=\"$(printf -- '%s' \"$localpart\" | sha256sum | cut -d' ' -f1 | cut -c1-28)\"\n\n # And the value has to be the base64-encoded public key, exported as binary\n gpg_public_key_b64=\"$(gpg --export --export-options export-minimal,no-export-attributes -- \"$2\" | base64 -w 0)\"\n\n`localpart_digest` SHA-256 hex digest of the localpart (username) of an email address (for example hi@ari.lt becomes just 'hi').\nAs per the RFC point 3.4 it is truncated to 28 octets (or 56 hex bytes), for which we use the `cut` utility.\n\n`gpg_public_key_b64` is the public key encoded in base64, pretty self-explanatory. It exports solely the key by using\nGPG options, ignoring all attributes and only exporting the essential parts of the key, and then encoding it in a single-line\nof base64.\n\nAfter which, we just print out the DNS record in a pretty way :D\n\n ._openpgpkey. IN OPENPGPKEY \n\nAnd now, you can even verify my key this way by checking the OPENPGPKEY records on `d2efaa6dd6ae6136c19944fae329efd3fb2babe1e6eec26982a422aa._openpgpkey.ari.lt` :)\n\nPeace :)", + "keywords": [ + "dns record generator", + "email encryption", + "modern dns features", + "gpg public key", + "email authentication", + "rfc 7929", + "openpgpkey dns records", + "openpgpkey setup", + "dns security", + "local-part hashing" + ], + "created": 1724215850.778874, + "edited": 1724218215.188544 + }, "ariweb-status-page": { "title": "ari-web status page", "description": "Ari-web status hosted by FSKY: status.ari.lt :)",