computer logo Welcome to Jon's Tools
random jigs from a K12 IT professional

tls.page

Posted on July 8th, 2025 by Jon

I'm excited to finally get to the blog-post phase of a project I've been working on for a while: tls.page. It's a web-based tool designed to simplify obtaining TLS certificates in a particular set of use cases.


The Challenge of TLS for Internal and IP-Based Services

screenshot of Chrome showing a certificate warning for a self-signed certificate

TLS is a cornerstone of web security. For public-facing websites, acquiring a TLS certificate has become a streamlined process, often requiring no configuration at all thanks to built-in ACME support. However, the situation is often more complex for services not directly exposed to the public internet. This includes development servers, internal admin interfaces, IoT devices, or services typically accessed via an IP address.

In these scenarios, self-signed certificates are a common workaround. While they provide encryption, they produce browser trust warnings and can complicate the distribution of trust to clients and users. tls.page aims to offer an alternative by making it easier to obtain publicly-trusted certificates for these scenarios.


How tls.page Works

Screenshot showing the Chrome certificate viewer. The URL and SHA-256 fingerprint are highlighted, showing that the fingerprint is contained in the hostname.

The fundamental concept of tls.page is to link the domain name directly to the cryptographic identity of a server - specifically the hash (also called fingerprint) of it's public key.

Upon generating a key pair, tls.page utilizes the fingerprint of the public key to formulate a unique domain name. For instance, if a public key's SHA-256 fingerprint is "023a94162e786117eb399ad0f81db5fc5cbb9de2bff459f61c885b4e0df2c786", tls.page will issue a wildcard certificate for "*.023a94162e786117eb399ad0f81db5fc.5cbb9de2bff459f61c885b4e0df2c786.tls.page". The fingerprint is hex-encoded, and split in half to comply with the 63-character limit for DNS labels. DNS for the domain is configured such that there is a subdomain for any possible IPv4 or IPv6 address. For example:

  • "127-0-0-1.your-fingerprint.tls.page" resolves to 127.0.0.1
  • "0--1.your-fingerprint.tls.page" resolves to ::1
    • you could probably use "--1.your-fingerprint.tls.page" as well, but technically DNS labels shouldn't start with a dash

Security Considerations

Using tls.page implies a shift in the security verification model. Users are unlikely to recognize or memorize a lengthy, fingerprint-based domain such as 203-0-113-1.023a94162e786117eb399ad0f81db5fc.5cbb9de2bff459f61c885b4e0df2c786.tls.page in the same way they recognize common domain names.

However, in many of the intended use cases for tls.page, direct URL entry by users is not typical. Instead, users might be:

  • Clicking a link shared via email.
  • Accessing a service through a link on another secure (HTTPS-enabled) internal platform.
  • Connecting using a link provided during an SSH session.

In these situations, the primary security assurance comes from the authenticity of the link itself. If you trust the source of the link, you can trust you're connecting to the right place. Put another way, tls.page enables key-pinned-links, where the domain name intrinsically vouches for the public key.

For scenarios involving manual URL entry from a display (e.g., an IoT device), these long domains can be impractical. However, integration with a URL shortening service could potentially address this.


Key Features

tls.page incorporates several features to enhance its utility and reliability:

  • WASM-based in-browser client: Enables client-side keypair generation, ensuring private keys do not need to leave the user's machine if this method is chosen.
  • Downloadable CLI tool: Offers a command-line interface for interaction.
  • Flexible HTTP API (docs): If you do everything locally (either yourself or via one of the provided tools) the only endpoint you need is /cert-from-csr.
  • Go library: A Go library is available for integrating tls.page functionality into Go applications.
  • Efficient Issuance: Certificates are typically issued within 2-5 minutes.
  • ZeroSSL CA: Certificates are provided by ZeroSSL.
  • Redundancy: The service operates on three nodes (Ionos in Germany, Oracle Cloud in the US, and a home server) for improved availability.
  • Minimal Cloud Dependencies: Relies only on the CA (ZeroSSL) as an external cloud service.
  • Security Measures:
    • DNSSEC is implemented for the tls.page domain.
    • HSTS Preloaded TLD so browsers don't attempt a connection over insecure HTTP.
    • CAA (Certificate Authority Authorization) records are configured to ensure that only certificates adhering to the "public key in the domain name" principle are issued.
    • Certificate Transparency (CT) Log monitoring is active to detect any certificates that might deviate from this principle.
  • Open Source: The server-side code is publicly available on GitHub: https://github.com/9072997/tlspage/tree/main/server.

Why I Built This

XKCD comic 974

tls.page started as a personal project to address a recurring need I had. I wanted quick, trusted TLS certificates for internal projects, development servers, or devices on my local network. Existing solutions felt too cumbersome, and I wound up with a lot of things using self-signed certificates. Developing tls.page was an interesting challenge, and it felt like something that ought to exist.


Exploring tls.page

If this functionality seems relevant to your work or projects, I encourage you to explore tls.page. The website, API, and client are available for use. For those interested in the underlying implementation, the source code is accessible on GitHub. Feedback is always welcome via the comments below or github issues.


I did kind of a brain-dump, then asked Google Gemini to structure it into a blog post, then re-wrote a lot of it. Depending on your definition this might be AI generated content.


CertView

Posted on May 29th, 2025 by Jon

There are a bunch of tools that let you view a x509 certificate. Now I have one. I mostly made it for myself. It's only distinguishing feature is that it will include human readable names for CT-logs. I was trying to figure out what was going on with CT-logs in the Let's Encrypt staging environment. Using openssl to get the hex log-id, then converting that to base64, then searching for it in the list of known logs was getting tedious, so I made this tool to do it for me. It accepts PEM or DER encoded certificates.

screenshot of certview with CT-log names highlighted

EmptyBox

Posted on April 17th, 2025 by Jon

Continuing the trend of ripping off other people's ideas for simple hosted services, I am hosting something inspired by Voidpop (github link), the hosted version of which appears to have gone offline is back online now. This does exactly the same thing, except it is written in go because I find hosting go binaries easier. 99% of the work is handled by the very handy POPgun library. Some small tweaks to the sample back end, and it's a functioning Voidpop clone.

Why?

AFAIK, there is no way to configure Thunderbird to send an email via an SMTP server without giving it a POP3 or IMAP server for incoming mail. I am told Outlook has the same problem. This makes sense for normal email client use; if you're setting up an email account you would expect to be able to receive email somehow. I needed to be able to format a district-wide announcement email to be sent to a bunch of parents via our mass-mailing SMTP server though, and it would have been really nice to be able to just compose/format that message in Thunderbird and send it to our SMTP server. Voidpop facilitated this (and still does if you want to self-host a copy), and now EmptyBox does as well. Just put in emptybox.jons.tools as the POP3 server with the default port of 110. It will accept any username and password and present an empty inbox.

Server: emptybox.jons.tools
Port: 110
Encryption: none
Username: anything
Password: anything


CanYouSeeMe

Posted on March 18th, 2025 by Jon

CanYouSeeMe is a tool that allows you to check how certain aspects of your network appear from the outside. The first feature (and the only one available currently) is the ability to view files in the .well-known directory for a website.

How to Use

To use this service, make an HTTP (or HTTPS) request to:

http://canyouseeme.jons.tools/well-known/{your-url}

For example, to view Gmail's STS policy from the point of view of this webserver, you would use:

http://canyouseeme.jons.tools/well-known/https://mta-sts.gmail.com/.well-known/mta-sts.txt

The response is capped at 1KB to ensure efficient usage and to avoid overloading the server.

Why Use This Tool?

This tool is particularly useful for pre-validation in a way that won't threaten rate limits. For example, if you are trying to issue a certificate from Let's Encrypt, you can do a pre-check with this tool to make sure your site is visible from the outside before making the real request. This helps avoid exhausting API limits.


Redirect

Posted on January 17th, 2025 by Jon

Redirect.name is cool as heck. It strikes me as one of those “do one thing well” tools that just works. It has one mildly bothersome limitation though. It doesn’t support HTTPS. I was using this tool on a project, and I was getting complaints from people who’s browsers were defaulting to HTTPS (idk what the rules are for when this happens). I decided that I could either set up some sort of one-off domain forwarding thing for this project, or I could just host a fork of redirect.name with HTTPS support. It doesn’t have a documentation page (other than this blog post), but it works exactly like holic’s original version. Just use redirect.jons.tools in place of alias.redirect.name (or if you must use an A record, 206.217.136.59). Source code is here.