[HN Gopher] Uacme: ACMEv2 client written in plain C with minimal...
       ___________________________________________________________________
        
       Uacme: ACMEv2 client written in plain C with minimal dependencies
        
       Author : robalni
       Score  : 91 points
       Date   : 2022-08-21 14:20 UTC (8 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | matthews2 wrote:
       | Cool! I hadn't seen tls-alpn-01 for authentication before.
       | 
       | Instead of using the ualpn daemon to respond to the challenges
       | and proxying all other connections through to nginx, would it be
       | possible to do it solely in nginx?
        
       | johnklos wrote:
       | One of the things I don't like about Github is that, while they
       | do list languages used, they don't have a section for listing
       | dependencies. Some (Ok, many) projects don't list dependencies
       | and assume we're all OK with so many that we don't deserve to
       | know and are expected to just pipe a URL to a shell to install
       | them all.
       | 
       | We need more projects like this, because many of us would like
       | clean, reproducible environments that won't be in dependency hell
       | every few years when an update to one dependency isn't compatible
       | with updates to others.
        
       | robalni wrote:
       | I found this project while looking for a way to renew my SSL
       | certificate without having to use certbot which has a lot of
       | dependencies including python. This program is really small and
       | simple and does exactly what I need. It's perfect.
        
         | LinuxBender wrote:
         | If you like minimal dependencies another one to take a peek at
         | may be acme.sh [1]. It depends on bash, openssl and curl. It
         | seems to work fine in _ash_ as well. It has code to handle most
         | API 's and most importantly to me is the great documentation.
         | 
         | In the same spirit of minimal and light weight there is also
         | testssh.sh [2] for testing TLS on HTTPS/SMTPS servers that also
         | depends on bash and openssl.
         | 
         | [1] - https://github.com/acmesh-official/acme.sh
         | 
         | [2] - https://github.com/drwetter/testssl.sh
        
           | dividuum wrote:
           | Personally, I'm a fan of https://github.com/diafygi/acme-
           | tiny. 200 lines of python without any additional python
           | requirements and only the openssl binary as external
           | dependency.
        
             | frutiger wrote:
             | I will plug my own Python program
             | https://github.com/frutiger/concorde, which does depend on
             | `requests` and `cryptography`.
        
             | yonrg wrote:
             | This! Thanks for also mentioning it. So plain easy and just
             | does what I need! Thanks to the author for publishing it.
             | 
             | I maintain my own patch, so tiny-acme supports an '--
             | outfile' option (it originally only writes to stdout). This
             | comes in handy when it is run by systemd service/timer.
             | 
             | The pull request is on hold, because the code then exceeds
             | then 200 lines threshold :shrug:
        
               | Klasiaster wrote:
               | You can directly redirect the service's output to a file:
               | https://www.freedesktop.org/software/systemd/man/systemd.
               | exe...
        
             | ori_b wrote:
             | If we're plugging implementations, I tend to use the
             | single-file implementation that ships with 9front. I wrote
             | the first cut, but it's been improved heavily by others:
             | 
             | http://man.9front.org/8/acmed
             | 
             | http://git.9front.org/plan9front/plan9front/HEAD/sys/src/cm
             | d...
             | 
             | It works quite well, and if you mount your unix machines
             | via sshfs, it's pretty easy to dump the certs into the
             | right place with them.
             | 
             | And unlike most ACME clients, it works seamlessly with DNS
             | authentication, which allows you to easily grab wildcard
             | certs.
        
           | encryptluks2 wrote:
           | I'd prefer to use a C, Go, or Rust app at this point. I love
           | shell scripts because it was one of the first scripting
           | languages I learned, but I'd trust a developer capable of
           | writing C, Go or Rust to do a better job and make something
           | more optimized than what is within the scope of Posix shell
           | scripting.
        
             | vladvasiliu wrote:
             | There's step-cli that's just a single go executable:
             | https://github.com/smallstep/cli
             | 
             | They also provide a CA to go with it, if you need internal
             | certs.
        
               | encryptluks2 wrote:
               | Thanks. I actually have this installed. It does so many
               | things and is pretty incredible!
        
             | newman314 wrote:
             | I use https://github.com/go-acme/lego, single Go binary.
        
             | FpUser wrote:
             | To me it is a utility stuff. As long as it does the job
             | (and acme.sh does it just fine) and does not require
             | pulling down half of the Internet for dependencies I would
             | not give rat's ass about what language has been used to
             | write it.
        
             | jamespo wrote:
             | I don't think optimization really matters to most people
             | for a tool that does automated cert requests.
        
               | encryptluks2 wrote:
               | It is to an extent. I'm not saying acme.sh is bad just
               | that if there is a tool in Go, Rust or C that does the
               | same thing and is more efficient then I'm picking
               | something that isn't wrapped in a bunch of shell code.
               | Same with tiny webservers.
        
         | megous wrote:
         | Dehydrated is good for this, too https://dehydrated.io/
        
           | prpl wrote:
           | I used dehydrated pretty effectively (along with openssl) to
           | renew and sync certs between several layers of
           | proxies/loadbalancers. I ended up creating a nice k8s
           | deployment with CronJob to implement this with ingress-nginx.
        
         | sashk wrote:
         | I'm using lego - https://github.com/go-acme/lego for this,
         | single binary works great.
        
           | zaroth wrote:
           | This is the joy of static linking!
           | 
           | In the end does anyone really care if it's a 10MB tarball
           | versus a 330kb tarball?
        
             | goodpoint wrote:
             | Yes, very much so. Maintaining the security of OSes where
             | many applications statically link thousands of dependencies
             | is impossible.
        
             | 1over137 wrote:
             | Yes, many of us care.
        
             | memco wrote:
             | You care when you need to deploy stuff to remote servers
             | the time difference between 10MB and 330kb. There's also
             | data transfer costs to consider.
             | 
             | I never had a problem with how long it took to install
             | dependencies until I had to do it multiple times over in
             | quick succession.
        
               | lapser wrote:
               | Why wouldn't you upload the file to all the servers, and
               | then deploy them all in succession, rather than upload
               | and deploy in sequence?
        
         | m_sahaf wrote:
         | You can use Caddy to automatically fetch certs and keep them
         | renewed without much hassle[0].
         | 
         | Disclaimer: I'm affiliated with Caddy
         | 
         | [0]: https://caddy.community/t/using-caddy-to-keep-
         | certificates-r...
        
           | goodpoint wrote:
           | I'd rater use Nginx. At least it's not a statically linked
           | blob.
        
             | francislavoie wrote:
             | Static linking is a huge advantage. I don't understand the
             | point you're trying to make.
        
           | lapser wrote:
           | Caddy is great for web servers, but it's still not possible
           | to have it run commands post certificate provisioning. So
           | it's kind of a non-starter for anything but web-servers as
           | there is no way to tell a different system to reload certs.
        
             | francislavoie wrote:
             | We're working on this! Hoping to have our new event
             | dispatching system ready in the next few months. This'll
             | let you hook into the post-issuance event and do whatever
             | you want afterwards.
        
               | lapser wrote:
               | Yeah! I saw the PR. Looking forward!
        
           | MatthiasPortzel wrote:
           | Apache also provides a 1-at party ACME client in the form of
           | a module, mod_md.
        
           | mccorrinall wrote:
           | Not affiliated with caddy, but caddy is awesome! I use it all
           | the time.
        
           | qbasic_forever wrote:
           | Yeah IMHO this is the way to go. Individual web apps managing
           | their own SSL certs is a longterm mess. Only your proxy or
           | HTTP gateway/router should ever touch or know about SSL
           | certs.
        
       | losingom wrote:
       | If you want to be super minimal, I prefer acme.sh[1] instead. It
       | even comes preconfigured for various DNS providers[2], and you
       | can even create your own hook if there isn't already one[3].
       | 
       | [1] https://github.com/acmesh-official/acme.sh
       | 
       | [2] https://github.com/acmesh-official/acme.sh/wiki/dnsapi
       | 
       | [3] https://github.com/acmesh-official/acme.sh/wiki/DNS-API-
       | Dev-...
        
         | thayne wrote:
         | If you have over a thousand lines of bash (or any other kind of
         | shell code really), that is a pretty big red flag that you
         | probably shouldn't be using bash IMO.
        
           | superkuh wrote:
           | On the otherhand, if you're a user and not a developer, you
           | know something written in bash will be written to run on any
           | machine out there. Doesn't matter if it's old or new. Whereas
           | if it's written in C++xx or Rust or the like it'll only
           | compile/run on rolling release distros (or for the 3 months
           | after a normal distro is released that it's up to date).
        
             | nicoburns wrote:
             | It might only _compile_ on a machine with a recent compiler
             | if it's aggressive with using new language features, but
             | why would need to compile a Rust /C++ version from source?
             | A compiler binary will run jut fine on old distro versions.
        
             | steveklabnik wrote:
             | Bash isn't on non-UNIX machines by default. I could run a C
             | or Rust produced binary just fine, but I couldn't run that
             | shell script.
        
           | delusional wrote:
           | If you want to issue a certificate in an environment where
           | you only have a shell, it's the only language you can use.
           | 
           | Sometimes you write in shell because it's the lowest common
           | denominator.
        
             | encryptluks2 wrote:
             | If you only have shell on your servers then it is time to
             | start looking for a new job.
        
               | throw0101a wrote:
               | > _If you only have shell on your servers then it is time
               | to start looking for a new job._
               | 
               | Perhaps you wish to have "real" certs on appliances like
               | F5s and Isilons (FreeBSD-based) where you can't install
               | extra stuff, but where _curl_ and _openssl_ (and _bash_ /
               | _zsh_ ) are present.
               | 
               | Or perhaps you want to run simple software that you can
               | actually audit. While "over a thousand lines of bash" may
               | take a little while to examine, good luck auditing Zope,
               | which is what _certbot_ pulls in as a dependency:
               | 
               | * https://packages.debian.org/bullseye/python3-certbot
               | 
               | * https://packages.ubuntu.com/jammy/python3-certbot
        
               | delusional wrote:
               | Not everything I do is a job.
        
             | thayne wrote:
             | Well, if you have to use shell that's one thing, but I
             | would be hesitant to use such a large shell script for
             | something as important as certificate issuance in an
             | environment where I didn't have to.
        
         | zdw wrote:
         | I use this and it's pretty great.
         | 
         | Also it can be highly locked down - run as it's own
         | unprivileged user, with access only to directories served by
         | another webserver for the ACME handshake, storing certs, and a
         | tightly restricted sudoer to restart the webserver on cert
         | cycle.
        
         | throw0101a wrote:
         | > _It even comes preconfigured for various DNS providers[2]_
         | 
         | Also, CLI utility that supports a bunch of APIs:
         | 
         | * https://github.com/AnalogJ/lexicon
        
       | christophilus wrote:
       | Someone needs to tell the Manjaro folks about this.
        
       | jeffbee wrote:
       | Security software written in C, with no unit tests. You cannot
       | run away from this software fast enough. I cannot think of any
       | worse idea than "I wrote my own base64 codec in bare C without
       | tests and without code review". "Minimal dependencies" does not
       | even begin to make up for how bad this idea is. It would be
       | strongly preferable to depend on third-party code that has been
       | reviewed, tested, and implemented in a reasonable language.
        
       | ape4 wrote:
       | I really appreciate the limited dependencies. The readme says it
       | needs only "libcurl and one of GnuTLS, OpenSSL or mbedTLS"
        
       | kazinator wrote:
       | No, I _want_ my Debian machine polluted with Snap garbage to run
       | Certbot. Find someone _sane_ to promote this to. :)
        
         | [deleted]
        
         | 9dev wrote:
         | Right? It's so ridiculous how you're supposed to use Snap to
         | install certbot. The (well, one of..) GitHub discussion is just
         | beyond the pale:
         | 
         | https://github.com/certbot/certbot/issues/8345#issuecomment-...
        
           | kazinator wrote:
           | I really hate how all that junk urinates into /etc, which
           | should be treated as immutable by applications. Changing
           | state should go into /var/run.
        
             | Denvercoder9 wrote:
             | /var/run isn't really suitable for certificates, as it's
             | allowed to get cleared on every boot. /var/lib would be the
             | better alternative.
        
           | vbezhenar wrote:
           | Just install docker or k8s and use certbot image.
        
             | goodpoint wrote:
             | Poe's law detected.
        
             | deathanatos wrote:
             | I know you jest, but if you're in k8s, I'd check out cert-
             | manager (https://cert-manager.io/). It works quite well,
             | and as it integrates w/ k8s, it stores the cert in a Secret
             | where an Ingress picks it up automatically, and it solves
             | the whole multiple-replicas-all-need-the-cert problem that
             | I have w/ certbot.
             | 
             | (I agree, while certbot works, it's a bit of a usability
             | nightmare.)
        
             | jabbany wrote:
             | The thread above has mentioned a very real problem with
             | snap running on OpenVZ. It requires either squashfs as a
             | kernel module or FUSE+squashfuse. Many OpenVZ hosts will
             | not provide either and docker/k8s is obviously out if you
             | are already operating inside a container...
             | 
             | Like, squashfs is great and all and packaged app images are
             | an acceptable way of delivering desktop apps... but there's
             | so much lossage here when certbot indirectly requires both
             | just for an install.
             | 
             | (I ended up going with acme.sh instead.)
        
               | yakubin wrote:
               | I think vbezhenar was just joking.
        
               | jabbany wrote:
               | Frankly at this point I'd happily accept it if certbot
               | required docker or k8s over snap.
               | 
               | At least then I know I'll have to run it in a container
               | (and give up then) instead of waste hours figuring out
               | why I get a snap error message when I try to run/install
               | certbot before finally coming to the conclusion it is
               | impossible.
        
             | zdw wrote:
             | And have docker insert firewall rules in ways you didn't
             | expect on a production server? Sounds fun.
             | 
             | The solution is frequently _less software_ , not more.
        
               | vbezhenar wrote:
               | Well, podman then? I think it's pretty much user-space
               | and does not tinker with system settings.
        
       | vbezhenar wrote:
       | https://man.openbsd.org/acme-client.1 is similar. I'm not sure if
       | it was ported to Linux.
        
         | yakubin wrote:
         | I've recently spent some time sandboxing nginx on my web server
         | by running the master process as the user www-data instead of
         | root, adding some seccomp filters through systemd and writing a
         | custom AppArmor profile[1]. And the hardest part was dealing
         | with certbot actually. Not least because it's written in
         | Python, and so adding capabilities to the script itself didn't
         | do a thing. They needed to be added to the Python interpreter
         | executable[2]. The whole thing seemed more complicated than its
         | worth. I've looked briefly at what supposedly configuring an
         | OpenBSD server with OpenBSD httpd + OpenBSD's acme-client would
         | look like, and it seems so much easier and the secure
         | configuration is the official one, so I'd need to worry much
         | less about updates breaking my stuff.
         | 
         | So I'm considering moving to OpenBSD for my web server. The
         | only thing giving me pause currently is that I saw no mention
         | of HTTP/2 support, so I suspect there is none. Although maybe I
         | don't need it. We'll see.
         | 
         | [1]: That last apart I actually already had, but it needed some
         | tweaking this time, because I moved nginx's PID file to its own
         | runtime directory created by systemd, instead of allowing it to
         | write to /run as root.
         | 
         | [2]: Of course only for testing. I revoked them after verifying
         | that everything works. And now they're only assigned
         | dynamically by systemd when the service is run.
        
         | gray_-_wolf wrote:
         | It was, I maintain a port here [0]. Release tarballs can be
         | downloaded here [1], I plan to add them to the git tags but did
         | not get to it yet. For example alpine linux ships it in the
         | repositories [2].
         | 
         | 0: https://git.sr.ht/~graywolf/acme-client-portable
         | 
         | 1: https://data.wolfsden.cz/sources/
         | 
         | 2: https://pkgs.alpinelinux.org/packages?name=acme-
         | client&branc...
        
         | messe wrote:
         | Quite reliable as well. I haven't touched my acme-client.conf
         | since 2019.
         | 
         | Admittedly, I haven't updated my blog since then, but
         | goddammit, my SSL certs are still valid! _Cough_ Manjaro
         | _Cough_
        
       | adancalderon wrote:
       | Been ussing this script https://github.com/srvrco/getssl
        
       ___________________________________________________________________
       (page generated 2022-08-21 23:00 UTC)