A lot of this seems to rely on the premise:
Net effect of these issues: most people don’t actually use SemVer consistently[1]
…but I don’t think that’s been true in my experience in npm-land, any project that claims to follow semver but publishes breaking changes outside of a major version intentionally would not have many users.
[1] If people were using SemVer as per the spec, you’d be seeing a lot more code at version 37.y.z.
I do see a fair amount of semver projects at the double-digit major versions. Also, it’s common to try to bundle releasing breaking changes, with the idea being that it’s easier for users to consume several breaking changes all at once, instead of having to digest a major version for every breaking change.
Semver is pretty sweet, when used correctly, you have a good idea of what is safe to upgrade and when you really should go read the changelog, just from the version number. Plus, it discourages the useless sentimentality about version numbers, something users oughtta be trained out of. “Break Versioning” solves a problem that I haven’t really encountered.
One thing I don’t like about the way people use semver is the number of projects that stay at 0.x even when they have thousands of users and compatibility is obviously a major concern.
I wish such people took responsibility for their API and started versioning it correctly. But it’s not a semver problem, and the proposal doesn’t really solve it—those people are intentionally not putting effort in marking breaking changes.
Is Docker a hard requirement? I’d love to see an article on getting Mailu running on FreeBSD or HardenedBSD. But if Docker’s a hard requirement, then software portability’s a no-go.
It saddens me when developers choose Docker, which in reality is an “open source vendor lock-in” tool. Enforcing the use of Docker places arbitrary limits on how the project can be used.
Software monocultures are bad.
Assuming:
Why should they bend over backwards to make deployment harder and less maintainable, especially when Docker has significant mindshare already? This seems like the kind of portability that maintainers don’t like to hear; it feels like kneecapping yourself for a small few. (I say this as someone who ports software to weird platforms professionally and runs FreeBSD on a server.)
Disclaimer: I’ve used Docker (well, podman) once, and because the alternative was installing Db2 myself.
I generally don’t like to use Docker even on Linux because it trades off a little bit of complexity of running serverd
and setting up cgroups vs. a the massive beast that is Docker and its 90M dockerd
that needs to run as root and does all sorts of automagic stuff. dockerd is exactly the sort of thing I would put in a container, ironically.
runc is okay though, and what I use if I really want to run a container image.
Docker services are also like blue/red “functions” we’ve had here previously. Have fun trying to talk from a docker container to a mariadb instance on your host etc, you’ll end up making the mariadb server also a container, just so you don’t have to deal with changing the docker owned iptable rules and stuff like “what is the IP address of my container/host”. And if you’re running a good proxmox cluster you’ll already have a multitude of VMs to isolate services but don’t want to have a host with a VM with a docker container, just because somebody decided it’s funnier for deployment to them. You can “easily” package something debian native into docker, but the other way around is annoying as hell. Even worse: most of the time such a project may not even have any kind of docs about what you need if you’re trying to setup this by yourself. And I’ve been the producer of such a project once, it’s still annoying as hell for people that do not just stuff everything into docker.
Docker images are less locked in than you think (or then this comment makes it look like). The actual image format is an open specification and can be converted or used directly with other container orchestration tools.
Except if you don’t want any fancy orchestration tools because you’re running a bunch of VMs with KVM & Ceph as an HA cluster.
Sure, but I said less locked in, not “Not locked in at all”.
That said, I wonder how hard would be to convert a dockerfile or an OCI image into a VM image … Maybe there’s even something out there already
From my point of view, I’d build something like this in Docker because… well, I know how to use Docker, everyone I’ll share my project with knows how to use Docker. I’m actually not well versed in the alternatives. What would you recommend someone to use who wants to set up a project like Mailu, that isn’t Docker?
I’m primarily a BSD user, where Docker’s not supported. I haven’t run Linux in any serious capacity in well over a decade. I get that projects like this have a bunch of moving parts. Shell scripts and configuration management tools can help simplify things.
If I wanted to use Mailu on the BSDs, I’d have a lot of headaches ahead of me. And, even then, I might fail if there’s dependencies on other Linux-only projects (for example: SystemD).
I’m not a fan either but in this case it solves a problem. “A set of n packages (not sure if they are all packaged for this OS version) with m configs that all play well together.”
There’s also sovereign which solves the same problem for one host OS version via an ansible playbook, but even if your OS of choice has all the packages, most seem to lack this “I want a dedicated set of configs”.
A set of n packages (not sure if they are all packaged for this OS version)
I’m a huge fan of helping out with the package system. For me, if the project in question doesn’t exist in the package repo, the project won’t get used at all. Everything must reside in the package repo for me. If it’s not there, then I add it.
Basically this is a guide to setting up Mailu: https://mailu.io/1.7/
Mailu looks interesting but I’m running all of the same major pieces myself on a $5 VPS. (Plus some other services.) It only has 1G of memory so I can’t really afford the overhead of docker. But I’ll definitely give it some serious thought when it’s time to rearrange the deck chairs.
I assume the author’s definition of self-hosted is “running everything off a raspberry pi hanging off residential cable internet” because any reasonable VPS provider is going to have clean IP blocks and will help you if their IPs are blacklisted anywhere. Thus negating the need to rely on a third-party outgoing relay.
A good chunk of the article is spent configuring a backup SMTP server and syncing IMAP… I feel like the author didn’t know that SMTP is already a store-and-forward system… Yes, you can have multiple incoming SMTP servers for high-availability but unless you’re a big company or an ISP you probably don’t need them. If your mail server is down, any RFC-compatible system will queue and retry delivery, usually for up to 24 hours.
Also fetching mail from the backup server via IMAP seems bonkers to me… again, SMTP is store-and-forward, the backup server can simply be a relay that delivers to your main server and just holds it in a queue when the main server can’t be reached.
Mailu looks interesting but I’m running all of the same major pieces myself on a $5 VPS. (Plus some other services.) It only has 1G of memory so I can’t really afford the overhead of docker.
What overhead? It’s just a glorified fork with chroot?
I feel like the author didn’t know that SMTP is already a store-and-forward system
I did in fact know this 🙂 But it’s not enough for my scenario. To expand, my personal self-hosted setup runs off of a machine in my house. It’s possible that if I were outside of the country and something catastrophic happened, it could be offline for an indeterminate amount of time. Possibly weeks. MTAs will stop retrying after some time and bounce the mail. So for my scenario, having a reliable backup MX is crucial.
I had an interesting discussion on Reddit about exactly this, with some anecdotes about how common MTAs handle downed MX servers: https://reddit.com/r/selfhosted/comments/ogdheh/setting_up_reliable_deliverable_selfhosted_email/h4itjr5
the backup server can simply be a relay that delivers to your main server and just holds it in a queue when the main server can’t be reached.
An SMTP relay with a infinite retention time would be a good way to achieve this as well. Though, with Google Workspaces already set up on all my domains, I didn’t want to spend additional effort reconfiguring all my MX records to point to a separate SMTP server, let alone paying for/setting up such a service. So this bonkers IMAP setup was the way for me!
Historically, spammers would target lower priority MX because they would often not have the anti spam measures configured. It looks like in your scenario you won’t get your own anti spam measures applied, but you will get Google’s, whether you want it or not.
It only has 1G of memory so I can’t really afford the overhead of docker.
I’ve forgotten how much memory my VPS has but it’s not likely more than 2G and I think we are running a couple of Docker containers. Is the daemon really RAM hungry?
I checked on one of my VPSs and it uses 50MB. I don’t think that that is too bad. Could be less, sure, but not the end of the world.
It only has 1G of memory so I can’t really afford the overhead of docker.
I’ve run multiple docker containers on a host with 1G of memory. Other than the daemon itself, each container is just a wrapper for cgroups.
“Open-source email software is complicated to set up if you were not a sysadmin in the 90’s.”
vs
“Mailu is a simple yet full-featured mail server as a set of Docker images.”
Unsurprisingly I see dovecot, postfix, nginx, rspamd in the repo.
I looked at Mailu briefly. Yes, it seems to just repackage all the standard e-mail services.
There’s also Maddy which seems to be a totally integrated server implementation.
I currently run all my e-mail on an OpenBSD VM using opensmtpd, but I want to move it to my main/dedicated Linux server and have been looking at both Mailu and Maddy.
There are several more, yes. I’ve only looked at sovereign, mailcow and docker-mailserver (I use the latter).
Hah, I guess you’re right, Mailu is open source too. “Open-source email software is complicated to set up” was referring to manually setting up all of those services, which I think is still complex. Luckily, all the 90’s sysadmins got together and pre-configured the Mailu images to all talk to each other and to have reasonable defaults.
So not strictly related to the content of this specific article but: what’s with the term “footgun”?
The phrase “shooting yourself in the foot” does not mean there’s some magical gun always aimed at your foot called a “footgun” that goes off unexpectedly. It means you mishandled something and made a mistake. The term “footgun” makes it sound like the interpretation is “ah, there’s literally nothing I could’ve done to prevent this ¯\_(ツ)_/¯” when that is, in general, not the case.
A footgun is a common term, it’s for when something seems to be explicitly designed for a user to shoot themselves in the foot with. The design of the gun leads itself to mishandling. In this article, Docker port exposure is a footgun, since in normal usage it bypasses the firewall completely, which is a dangerous default behavior that the user does not expect.
No mention of https://to./?
That was the first TLD site I ever heard of, it used to be a url shortener, but today it seems like it’s defunct since the certificate is expired and the home page 404’s.
I am sorry, but if you still do not know about multi-byte characters in 2020, you should really not be writing software. The 1990ies have long passed in which you could assume 1 byte == 1 char.
https://jvns.ca/blog/2017/04/27/no-feigning-surprise/
Nobody was born knowing about multi-byte characters. There’s always new people just learning about it, and probably lots of programmers that never got the memo.
The famous joel article on unicode is almost old enough to vote in most countries (17 years). There is really no excuse to be oblivious to this: https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/
This is esp. problematic if you read the last paragraph where the author gives encryption/decryption as an example. If somebody really is messing with low level crypto apis, they have to know this. There is no excuse. Really.
Junior Programmers aren’t born having read a Joel Spolsky blog post. There are, forever, people just being exposed to the idea of multibyte characters for the first time. Particularly if, like a lot of juniors are, they’re steered towards something like the K&R C book as a “good” learning resource.
Whether or not this blog post in particular is a good introduction to the topic is kind of a side-point. What was being pointed out to you was that everyone in 2020 is supposed to have learned this topic at some point in the past is beyond silly. There are always new learners.
Right, but this author is purporting to be able to guide others through this stuff. If they haven’t worked with it enough to see the low-hanging edge cases, they should qualify their article with “I just started working on this stuff, I’m not an expert and you shouldn’t take this as a definitive guide.” That’s a standard I apply to myself as well.
We should perhaps not expect newcomers to know about encoding issues, but we should expect the tools they (and the rest of us) use to handle it with a minimum of bad surprises.
That’s a little harsh, everyone has to learn sometime. I didn’t learn about character encoding on my first day of writing code, it took getting bitten in the ass by multibyte encoding a few times before I got the hang of it.
Here is another good intro to multibyte encoding for anyone who wants to learn more: https://betterexplained.com/articles/unicode/
I didn’t learn about character encoding on my first day of writing code, it took getting bitten in the ass by multibyte encoding a few times before I got the hang of it.
Right, but you’re not the one writing and publishing an article that you intend for people to use as a reference for this type of stuff. People are responsible for what they publish, and I hold this author responsible to supply their writing with the caveat that their advice is incomplete, out-of-date, or hobby-level—based, I presume, on limited reading & experience with this stuff in the field.
I’m sure that if I knew you well enough, I could find three things you didn’t know that respected developers would say means “you should really not be writing software”.
Yes it’s 2020, but also, yes, people still get this wrong. 90% of packages addressed to me mangle my city (Zürich) visibly on the delivery slip, so do many local(!) food delivery services.
Every time I make a payment with Apple Pay, the local(!) App messes up my city name in a notification (the wallet app gets it right).
Every week I’m handling support issues with vendors delivering data to our platform with encoding issues.
Every week somebody in my team comes to me with questions about encoding issues (even though by now they should know better)
This is a hard problem. This is also a surprising problem (after all „it’s just strings“).
It’s good when people learn about this. It’s good when they communicate about this. The more people write about this, the more will get it right in the future.
We are SO far removed from these issues being consistently solved all throughout
I know all that. My first name has an accented character in it. I get broken emails all the time. That still does NOT make it okay. People that write software have to know some fundamental things and character encodings is one of them. I consider it as fundamental as understanding how floats work in a computer and that they are not precise and what problems that causes.
The article being discussed is not good and factually wrong in a few places. It is also not written in a style that makes it sound like somebody is documenting their learnings. It is written as stating facts. The tone makes a big difference.
There’s a difference between knowing there’s a difference, which I suspect is reasonably common knowledge, and knowing what the difference is.
There are very few things that every software developer needs to know–fewer than most lists suggest, at least. Multi-byte encodings and unicode have are about as good a candidate as exists for being included in that list.
However, people come to software through all different paths. There’s no credential or exam you have to pass. Some people just start scripting, or writing mathematical/statistical code, and wander into doing things. Many of them will be capable of doing useful and interesting things, but are missing this very important piece of knowledge.
What does getting cranky in the comments do to improve that situation? Absolutely nothing.
There’s no credential or exam you have to pass.
I think that this is one of the problems with our industry. People with zero proof of knowledge are fuzzing around with things they do not understand. I am not talking about hobbyists here, but about people writing software that is being used by people to run critical infrastructure. There is no other technical profession where that is okay.
I think our field is big and fast enough that dealing with things we don’t understand don’t yet understand has just become part of the job description.
I discovered was that all of the existing methods rely on using the Raspberry Pi Zero as a USB host, which disables using the onboard USB port for other purposes. Additionally, this method does not work on other boards, like the Raspberry Pi 3B+.
(surely you mean “as a device/gadget”, the host is the.. host, the normal computer that devices attach to)
On the Pi 4, the Type C port acts as a device, so you could go with the 4. I think the previous similar project posted here did.
Yep, just had a 3B+ laying around, so that constrained the project. Thanks for pointing out the typo, I’ll fix it in the next edit.
TinyPilot that was the project discussed previously here:
https://lobste.rs/s/j1xznn/tinypilot_build_kvm_over_ip_for_under_100
https://lobste.rs/s/okwdyd/tinypilot_s_new_design_v2_raspberry_pi
It specifically requires the Pi 4 as the USB C port supports OTG and this is utilised to provide the keyboard capability as @myfreeweb mentions. Using this feature doesn’t impact the other USB ports on the board like on the RPi Zero.
I am testing a similar setup on an Orange Pi Zero which provides OTG on the Micro USB port, while also providing a standard USB port for the HDMI capture device:
https://www.orangepi.com/index.php?route=product/product&product_id=844
I took a much simpler approach to this same problem. I have a home network including a consumer-grade PC that acts like a server. To remotely control power, I use a remote power switch (with side benefit that it also measures Kw hours for monitoring power usage). So I can always force a power reboot. I configure my server to wake on power in the BIOS. And then, as a backup, I keep a Raspberry Pi on the LAN via Ethernet. Since the server is also on Ethernet, I have a small script on the Pi that can issue a Wake-On-LAN packet to the server via etherwake. So, if the server is down, I have a couple options: cycle its power source, or remotely wake it over LAN via the Pi. This also allows me to keep the server in a “sleep” state when unused, so it only consumes a couple watts, and wake it via the Pi when needed.
I realize this isn’t a true “LOM” system but it’s good enough and notably requires no hardware beyond a remotely-controllable power strip (of which there are myriad) and a basic Raspberry Pi. For extra points, I also set up both of these devices via ZeroTier so they are easy to access outside of my LAN.
Ooh, wake on LAN, that’s an interesting idea. You can use that to boot too, right? I might have to try that if I ever do a Pilo v2.
Yep! With a good BIOS, which is most modern ones, and especially with Ethernet built into the Mobo, it’ll handle booting and wake from sleep. And etherwake, as a CLI tool, couldn’t be simpler. You just need to be on the same LAN as the computer and you run etherwake <macaddress>
, and that’s that. To sleep the computer, I use a bash script wrapping systemd sleep commands on the host itself, executed via ssh.
So, uhh…. what now? Shut down the Internet until this is fixed? Disconnect your wifi router? Never log on to another web site again?
It doesn’t matter at all unless you trust that certificate, or whoever published it. It’s just a self-signed certificate that is valid for any domain. If you don’t trust it, then you don’t trust it, and it will be invalid for any use where you come across it.
Gotcha; I missed the critical detail that it’s self-signed. So to use this in an attack you’d have to trick someone into trusting the cert for some trivial site first.
Exactly. And then they would have to serve some content with that cert that the target would access. There’s essentially no practical way this could be used in an attack except for a man-in-the-middle attack, but you would still need to get the target to trust the certificate first.
Trusting the cert is easy with technical people. I link you guys to my site, with a self signed cert like this. You accept it because you want to see my tech content.
This is a huge issue.
Here’s what I think @indirection is getting at:
However, I would hope SSL overrides are hostnane-specific to prevent this type of attack…
I missed the critical detail that it’s self-signed
You didn’t quite miss it, it’s been misleadingly described by the submitter — they never explicitly mention that this is merely a self-signed certificate, neither in the title here, nor in the GitHub repository. To the contrary, “tested working in Chrome, Firefox” is a false statement, because this self-signed certificate won’t work in either (because, self-signed, duh).
I never say that it’s signed by a CA either 😅 I wasn’t trying to mislead folks, but some seem to have interpreted “SSL certificate” as meaning “CA-issued SSL certificate”. It does work in Chrome and Firefox insofar as it is correctly matched against domain names and is valid for all of them.
This isn’t signed by a trusted CA, so this specific cert can’t intercept all your traffic. However, all it takes is one bad CA to issue a cert like this and… yeah, shut down the Internet.
Or any CA operating under a hostile government, or any CA that’s been hacked. See DigiNotar for just one example of a CA that has issued malicious wildcard certs.
And as you can see it was removed from all browser’s trust stores and soon declared bankrupt (hence, death wish). And that wasn’t even deliberate. I can’t see a CA willfully destroying their own business. Yes, it’s a huge problem if this happens though, and isn’t announced to the public, as the case in the article.
Normally, certificates are doing three separate things here:
Most people who are against HTTPS ignore the second point by banging on about how nobody’s reading your webpages and nobody cares, when ISPs have, historically, been quite happy to inject ads into webpages, which HTTPS prevents. This strikes at the third point… except that it doesn’t. It’s self-signed, which defeats the whole mechanism by which you use a certificate to ensure you’re communicating with the entity you think you are. The weird wildcard stuff doesn’t make it any less secure on that front, since anyone can make their own self-signed certificate without wildcards and it would be just as insecure.
If you could get a CA to sign this, it would be dangerous indeed, but CAs have signed bad certificates before. Again, a certificate can be bad and can get signed by an incompetent or corrupt CA without any wildcards.
So this is a neat trick. I’m not sure it demonstrates any weakness which didn’t exist already.
Should be subtitled: Why wildcard certs are a bad idea. As a friend once put it: “I don’t trust anyone with the last name of Rose, I trust Matt Rose”
Convenient for development, convenient for vanity URLs, but questionable for production use.
Also, this cert does cause Chrome to frequently crash, presumably because of the wild amount of wildcard matching.
What kind of crash are we talking about? Do you have to trust the certificate or does it crash on the man-in-the-middle warning page? That could be an opportunity for a pretty bad DoS vulnerability.
I didn’t spend too much time investigating it. After a few navigations on a site using this cert, Chrome just exited. It was after trusting the certificate.
Okay. I’ll test it in an ASAN build.
Edit: I can’t get it to crash either before or after trusting the certificate. Arch Linux, Chromium 83.0.4103.56 ASAN, and the following HTTP server:
package main
import (
"io"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", ExampleHandler)
log.Println("** Service Started on Port 8443 **")
err := http.ListenAndServeTLS(":8443", "one-cert.crt", "one-cert.key", nil)
if err != nil {
log.Fatal(err)
}
}
func ExampleHandler(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "heh")
}
Still interesting to explore nonetheless.
The RFC explicitly forbids this kind of use, only allowing the lowest identifier to be a wildcard, and only if it is not a public suffix itself.
This is very surprising that browsers don’t match on this properly.
While it’s a little easier for you to write “the RFC”, it would be helpful for you to mention which RFC for those of us reading.
https://tools.ietf.org/html/rfc6125#section-6.4.3 says SHOULD.
What are you talking about?
The Certification Authority (CA)/Browser Forum baseline requirements (11.1.3) require that before issuing a wildcard certificate, Certificate Authorities ensure that such a certificate is not issued for entries in the Mozilla PSL, e.g. *.co.uk,or that the entity actually owns the entirety of the public suffix
Please read all sub-threads before posting a reply :)
This is an requirement for CA’s, not user agents. This certificate would not be issued by a (public) CA, but it is not invalid for browsers. It is perfectly valid for private CA’s to do this, e.g. so you could MITM all of your workers traffic.
There are two kinds of public suffixes – those defined by ICANN, also included in the public suffix list, and the not really official private definitions in the public suffix list.
And quoting the ICANN advisory on this:
The Certification Authority (CA)/Browser Forum baseline requirements (11.1.3) require that before issuing a wildcard certificate, Certificate Authorities ensure that such a certificate is not issued for entries in the Mozilla PSL, e.g. *.co.uk,or that the entity actually owns the entirety of the public suffix
So while it’s not an RFC, it’s still a standard – and an even stronger at that
it’s still a standard – and an even stronger at that
You are confused. That is not a quote from a standard for web browsers or TLS implementations, but for people who want to make a certificate signing authority that CA/B members (like Mozilla, Google, Microsoft, and so on) would include in their web browsers.
There are lots of reasons to make certificates that Mozilla (For example) would not include in the Firefox web browser, and it is required that valid TLS implementations interpret them according to the actual standard where that’s broader than what you’re reading here.
Sounds like a political limitation, not a technical limitation. Unless SSL consumers start to enforce this on their end, it wouldn’t prevent a malicious CA from issuing a cert like this that could be used to MITM all traffic.
Sounds like a political limitation, not a technical limitation.
That’s the state of web PKI in a single sentence.
That’s exactly the point – I was expecting browsers to actually implement this spec and verify this for certificates (as I already do this in a limited way in Quasseldroid)
Shouldn’t it be possible to automate short lived TLS certs that are bonded only to a specific local domain name? Why is a wild-wildcard TLS cert seen as an acceptable approach?
At a prior employer, we a DNS record wildcard for localhost.$domain.com
and an ELB with security group access only from our office IPs bonded to our *.$domain.com
TLS certificate so we could allow CORs for local development and be HTTPS. That still raised some eyebrows but was considered acceptable on grounds that we firewalled off access to the ELB. It would’ve been even better with a split-horizon DNS to keep access solely in office/in VPN (we were in adtech and unsafe to a degree for “get shit done” - I don’t endorse public A records pointing to 127.0.0.1).
Shouldn’t it be possible to automate short lived TLS certs that are bonded only to a specific local domain name?
Yeah, this is what most HTTPS intercepting proxies end up doing. I created this wild-wildcard cert while I was working on intercepting HTTPS traffic and noticed that generating a new cert for each domain was a little expensive.
Unfortunately (or fortunately, depending on how much you hate ugly hacks 😁), this cert can’t be used in the real world because it eventually crashes Chrome, and presumably other parts of the HTTP stack will have trouble coping as well.
This is… cool?! Too bad I ditched Spotify and offlined all my music. Maybe you can extend this to Last.fm too?
Yeah, I might fork it to support Last.fm on a separate instance. Allowing users to pick one or the other is more complexity than I’m willing to invest time in 😅
Some alternatives:
On Linux, the CLI commands
nload
andwatch lsof
can be used to accomplish a similar task.On Windows,
resmon.exe
will give you information on live connections and in/out packets/bytes.