Lcl.host: fast, easy HTTPS in your local dev environment
anchor.dev
anchor.dev
So don’t use this unless you don’t mind it breaking randomly whenever there’s an update.
This probably falls in the same boat. :)
i.e. I don't think that the authors of this tool wanted to have developers be forced to use the latest version of their tool.
It's probably that they didn't think about it when they wrote the code, but now they know and hopefully this gets fixed in the next release?
There are some bugs that are just hard to find until they're out there.
Also, I echo the other people saying that the typeface you chose for the website is very difficult to read.
Mozilla bricked SSL certificates that are mandatory for everything, including Browser Extensions.
There is a flag for about:config to unbrick it. Problem is though, that this lasts less than a second because of the remote settings service running in a loop. If you block that services domain with a host firewall (like opensnitch), Firefox will do an endless for loop using 100% CPU load trying to request the shavar and other services domains.
So, effectively, you cannot run an old Firefox version, and especially not a version that uses the old bundled mozilla certificate (which is all provided download variants).
That's what the previous commenter was (likely) referring to.
Font are ugly but it loaded HN just fine.
> Firefox 53 from 2017
not the same. I was talking about post-quantum Firefox releases, which added the mentioned dependencies on Mozilla's SSL certificate.
(The grandparent's comment was also about post-quantum, obviously)
Snakeoil certificates in Enterprise licensing might disagree with this statement, which in my opinion is pretty identical to Mozilla's approach to have control over "who is allowed to use when" of their software.
It's also not a few specific releases over time, it's all releases after Browser Extension signatures were introduced as being mandatory, which made the rest of the Browser rely heavily on their certificate management servers.
I'm not saying it's malicious intent, what I am saying is that this could've been implemented in a much better manner, which wouldn't rely on a centralized certificate signing service.
> This CA has some restrictions though: it can only issue certificates for subdomains of lcl.host and localhost, but that’s all you need for local development.
Localias, on the other hand, lets you use any custom domain you'd like. And if you use a domain ending in .local, it will broadcast over mDNS so that you can easily connect to that server from any other device on your wifi network (like your phone.)
Localias also allows you to share your configuration with your entire development team by committing a .localias.yaml file to the root of your git repo. This makes sharing links with each other super convenient.
Always nice to see another competitor in the space; if you're interested in this, please check out Localias as well!
Localias wraps Caddy to handle all the cert provision; I believe Caddy uses mkcert. I haven't seen any bug reports about yet, but if you give it a try and run into an issue I would be happy to help fix it.
This sound like a security feature, not (just) an annoying restriction. Though an attack model for a local CA is a bit flimsy.
Admittedly an external attacker getting close enough to sign a cert using such a CA, in order to trick me into something, means they probably have such high access already that they don't really need the CA to do that or worse, so perhaps it is unnecessary caution.
With chrome, that's something like:
google-chrome
--user-data-dir="${HOME}/.config/ourlocaldev/google-chrome"
--install-autogenerated-theme=85,63,9
--host-rules="MAP * 127.0.0.1, EXCLUDE localhost, EXCLUDE fonts.googleapis.com, EXCLUDE fonts.gstatic.com"
--ignore-certificate-errors-spki-list="0oKw9nasIS7qRQD1CYXe5bmi22/mnHjZP++f6G+VM88="
"https://my.dev.thing"
This will launch a separate copy of chrome with a fresh/separate profile. It will have a different colour (RGB values set in there) so it's visually distinct when it's running and I don't get the windows mixed up. Any request made from the browser will be rewritten to connect to 127.0.0.1 (except a couple google font domains).The danger if someone got their hands on my local key/cert is basically nil. They would only be able to MITM connections from this one specific browser window to localhost. And that browser is incapable of connecting to anything besides localhost. I can never accidentally open my banking site in there. Also fresh profile so no saved passwords, credit cards, or anything else.
(As an added benefit, I don't really need to worry about reconfiguring URLs for projects. If I open "testing.mysite.com" in that browser, it will force the connection to localhost, so I can just run my services at our test URLs and steal configs as-is from the testing environment. Taking it further, I then have a controller set up in k3s/Rancher Desktop that rewrites the service on all annotated ingresses to point to its own service, which runs nginx, which the controller then configures to proxy the requests on to the local service or the actual upstream testing service depending on whether the local container is running. It also configures CoreDNS to point the upstream URLs at the same proxy. End result is that from the browser or anything running in k3s you can hit our testing URLs and it will hit your local container if it's running or fall back to the testing environment if not.)
If you want to try the browser thing, you can generate the fingerprint for a certificate with:
echo "" |
openssl s_client -connect 127.0.0.1:443 -prexit 2>/dev/null |
openssl x509 -pubkey -noout -in /dev/stdin |
openssl pkey -pubin -outform der |
openssl dgst -sha256 -binary |
openssl enc -base64It'd be annoying if you need to make a new localhost certificate, but totally manageable.
If you have appropriate permissions on the private keys, it would require the same level of access to read the private key as it would for the attacker to create their own CA and install it on your PC.
My general rule of thumb is to use private certificates unless a) users interact with it directly, cuz they won't install my cert, or b) financial or other highly sensitive data flows through it. I'm not convinced that commercial CAs are more secure, but for the price of an SSL cert, it's worth it to have it not be my fault if something happens.
Then point your server to the output files. If you want, you can also modify `/etc/hosts` to point a "production name" to localhost (something I actually don't do and never wrote a script for). Far fewer moving parts than the OP. (parts of Simpatico uses subtle.crypto and so requires https to run even locally)
For dev at least it’s mostly because web browsers treat localhost as a special domain that gets the HTTPS treatment even when loaded over HTTP.
I have set up local HTTPS certs before now, can’t remember exactly what required it. But I still load most web projects on localhost over HTTP just out of habit.
localhost with HTTP should be sufficient for most things. It's when you start doing stuff like "app.localhost" like what was mentioned in the article which, despite it having "localhost" is not the same as http://localhost.
Develop basic in local and do all the hostname + https on actual server where you can easily do something like letsencrypt route DNS to it.
I use traefik to serve my apps in dev, which generates self-signed certs by default if you don't hook it up to ACME. Slightly more cumbersome because it means clicking through a warning screen and disabling verification in CLI tools (actually those are where I do drop to plain http). I'm sure this lcl.host product smooths this process considerably, but when it comes to local dev tools, I have an absolute requirement that they actually run locally and don't tether me to some cloud service, so I'll be sticking with traefik regardless for now.
And localhost
https://developer.mozilla.org/en-US/docs/Web/Security/Secure...
But then, trouble begins. You have to configure every server to use the certificate (or use a proxy) and every client to accept the certificate. Sometimes the proxies eat headers, or they have trouble with WebSockets and hot reloading or whatever.
We also use IPs instead of domains to find our locally running prod servers so that our customers don't have to configure anything DNS on their maybe-offline WiFi network. We also have to test with external devices, such as iPads. How do you automate getting your certificate onto them?
..And then your IP changes and all is lost again.
Yeah, if you have a 50 line Svelte "app" that you serve as site it's easy. But who does that?
Really?
> You have to configure every server to use the certificate
A couple of lines in apache/nginx/other config? The same lines each time. You probably don't want your dev box to be doing things required for LE renewal (allowing external in for HTTP(S) validation, making public DNS changes for DNS01, …) but I have a small container doing that and other boxes pull the resulting cert from there (a small cron task, again the same in each instance).
> and every client to accept the certificate
> external devices, such as iPads. How do you [get] your certificate onto them?
I suggested using a public name and an LE cert or similar. Clients will trust without extra effort.
> We also use IPs instead of domains
I did say “more devs don't” not “all devs don't”, there will of course be special cases. Though using addresses rather than names just feels broken.
> And then your IP changes and all is lost again
That is an argument against using address based config rather than name based config, not an argument against using HTTPS!
FYI, you can get Lets Encrypt certs easily on non-public hosts by using the DNS-01 challenges. They rely on setting particular DNS records rather than HTTP responses, so they don't rely on public IPs
Using http with localhost is a mostly security context, but it has some quirks[0]. Using https://localhost will give you the full security context but then you're typically stuck either dealing with certs manually or using a proxy, like caddy. lcl.host should simplify your setup.
We're big fans of caddy by the way and even sponsor the project. Matt's doing amazing work over there.
Anchor has a neat product. They're making internal TLS more accessible to more developers who don't necessarily need a separate web server. They're doing local TLS just about as best as possible from what I can see.
IMO this has more utility than mkcert -- which is a great tool by Filippo and Caddy shares some of its underlying library for its own auto-trusted internal CA -- because, like Caddy, Anchor fully automates the certificates instead of just generating them and needing a cron job. It's more hands-off and higher-level, allowing you to get more done with less effort.
* Windows is the easiest... by far. There is only one trust store and its extremely easy to access at different levels of trust. Firefox has its own trust store so you can either add your certs to both the Windows store AND the Firefox trust store or flip a config in Firefox to tell it to use the Windows trust store like everyone else.
* Linux is a challenge because you have to add your certificates to the OS trust store and then each browser has their own trust stores.
* MacOS is pretty close to impossible, at least fully automated. If the cert is not registered with a third party of the OS's choosing the cert will not be trusted in the browser. The way around this is to manually add your localhost cert chain to the MacOS keychain.
If anybody wants an example here is something I wrote a ways back in JS (but please be warned its specific to my application:
* Build the certificate chain - https://github.com/prettydiff/share-file-systems/blob/master...
* Install the cert by OS type - https://github.com/prettydiff/share-file-systems/blob/master...
That second sample also installs pcap so that I can serve on localhost over ports 80/443.
I could be wrong, but I could have sworn Firefox trusts the OS' certificate store. Maybe it's just been too long since I've done it.
Were you using the package manager packages? I'm a little surprised if the distro packages don't configure Firefox to use the OS trust store. I would not be surprised if the binaries Firefox provides directly don't trust the OS package store. They probably shouldn't, given that the path to the OS trust store is configurable. I think Ubuntu and Fedora use slightly different paths.
Seems like a security nightmare to try guessing at what directory has the OS trust store. Better to leave it to the package maintainers to specifically customize it for their distro's patterns.
I think a better approach is to get a domain name and a Let's Encrypt certificate. There's lots of tooling for this, and it matches production. I built https://www.getlocalcert.net/ to act as free, Let's Encrypt compatible subdomain service specifically for these sorts of challenges.
“service-a.lcl.host:443300“ so when inside the container, won’t that resolve to 127.0.0.1 which is the container internal loopback interface not the docker host’s interface? Hence trying to connect to itself not its sibling.
Shameless plug: https://github.com/jrz/container-shell in combination with orbstack. Isolated dev environment, easy to use, local tools, https on https://xxxxx.orb
What is the difference between this and LE if true?
I would like to use a .test domain. I use that currently and just click "proceed anyway" whenever the warning pops up and It's pretty often lately.
Just yesterday, I needed it for a hackathon, but had to switch to a cloud IDE instead.
Why use any service for this?
I think I've seen some different cache behaviors.
Secure cookies (and maybe same/cross site stuff?)