# getssl: a single bash script that obtains and renews Let's Encrypt certificates remotely

> A GPL licensed shell client for the Let's Encrypt ACME server, built for the case where you cannot or would rather not run a certificate client on the machine serving the site.

**srvrco/getssl** — obtain free SSL certificates from letsencrypt ACME server  Suitable for automating the process on remote servers. 

- Repository: https://github.com/srvrco/getssl
- Stars: 2,231 · Forks: 389
- Language: Shell
- License: GPL-3.0
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/srvrco-getssl

## Written in bash so it runs anywhere a shell exists

The design constraint is stated in the features list first: getssl is bash, so it runs on virtually all unix machines, including BSD, most Linux distributions and macOS. There is no Python interpreter to install and no daemon to supervise, and the whole program lives in a single executable file at the root of the repository. The overview section makes the same point by describing it as written in standard bash so it can run on a server, a desktop computer, or even a virtualbox.

The feature list is organised around remote operation, which is the actual reason to reach for this rather than a more conventional ACME client. The tokens used to validate domain ownership, and the certificates themselves, can be copied automatically to remote servers via ssh, sftp or ftp, and the script does not need to run on the server at all. The README gives the motivating case directly: this is useful if you cannot run such scripts on the server itself, such as a shared host. Everything else in the list supports unattended operation, including running as a daily cron job, automatic renewals, an optional self update for bug fixes, and reloading the affected services such as apache, nginx or postfix after a new certificate lands.

Two features go beyond issuing certificates. The first is a check that certificates are actually loaded: after installing a new certificate, getssl tests the configured port to confirm the certificate being served is the one just installed. That catches the common failure where a service is still serving a cached or old file. The second is per-certificate configuration through a simple config file, which is what lets one certificate cover multiple domains across multiple servers. Both HTTP and DNS challenges are supported with a full ACME implementation, and the script also advertises ACME v1 and v2 support, while noting that v1 is deprecated and clients will use v2 automatically.

## Installing from RPM and DEB packages or the raw script

Prebuilt packages are published for both major Linux packaging systems, and the README names the specific distributions each targets: RPM for RedHat, CentOS, SuSe, Oracle Linux and AWS Linux, and DEB for Debian and Ubuntu. Each release ships a binary package and a source package, using `noarch` for the RPM since the script is architecture independent:

```sh
rpm -i getssl-2.52-1.noarch.rpm
```

```sh
dpkg -i getssl_2.52-1_all.deb
```

Removal is equally conventional, `rpm -e getssl` and `dpkg -r getssl`. The Makefile shows how little the install actually does: it installs the single `getssl` script to `/usr/bin/getssl`, creates `/usr/share/getssl`, and then copies every `*_scripts` directory into that share directory. That loop is the reason `dns_scripts/` and `other_scripts/` exist as separate directories, since DNS challenge providers are inherently a long tail and each one needs its own small script. The GPL-3.0 header sits at the top of the Makefile, matching what GitHub reports for the repository.

For platforms without RPM or DEB packages, the README points to a manual installation section for building and installing straight from git sources. The tree also carries packaging and operations files beyond the Makefile: `getssl.spec` for RPM spec generation, `debbuild.patch` and `BUILDING-PACKAGES.md` for the Debian build, `RELEASE.md` for the release process, `getssl.crontab` for the scheduled run, and `getssl.logrotate` for log rotation. Those two last files are a good sign of operational maturity, since a cron driven client that never rotates its log is a nuisance waiting to happen.

## A CLI where the certificate options read plainly

The help output in the README is the fastest way to understand the interface, and it is a conventional GNU style flag set with a domain argument. The flags worth knowing first are the ones that control what actually happens on a run: `-c` creates default config files, `-f` forces renewal and overrides expiry checks, `-i` installs certificates and reloads the service, and `-r` revokes a given certificate and key.

```sh
Usage: getssl [-h|--help] [-d|--debug] [-c|--create] [-f|--force] [-a|--all] [-q|--quiet] [-Q|--mute] [-u|--upgrade] [-X|--experimental tag] [-U|--nocheck] [-r|--revoke cert key] [-w working_dir] [--preferred-chain chain] domain   
```

The last group is how you operate this in production. `-q` limits output to errors, successful certificates and upgrades, `-Q` mutes even the upgrade notification, `-u` upgrades getssl if a newer version exists and works with or without a domain argument, `-X` pins an upgrade to a specific experimental tag, and `-U` skips the update check entirely. That last pair matters most in environments with no outbound access to the update source, since a client that phones home on every run is a problem in a locked down network. The `--preferred-chain` option covers the common case of a server that needs a specific intermediate chain.

The README's table of contents shows the rest of the surface area, and it is longer than you would expect: sections on wildcard certificates, ISPConfig, automating updates, custom configuration templates, a full list of configuration variables, a `Server-Types` section for the port check behaviour, certificate revocation, elliptic curve keys, preferred chain, whether to include the root certificate in the full chain, and Windows Server with IIS support.

## Testing against Pebble instead of a staging ACME server

The most interesting infrastructure in the repository is the test setup, because it does not hit Let's Encrypt at all. There is a `docker-compose.yml` that runs Pebble, Let's Encrypt's own ACME test server, along with `pebble-challtestsrv` for challenge testing, on a private bridge network:

```yaml
services:
  pebble:
    image: ghcr.io/letsencrypt/pebble:latest
    # TODO enable -strict
    command: -dnsserver 10.30.50.3:53
    environment:
      # with Go 1.13.x which defaults TLS 1.3 to on
      GODEBUG: "tls13=1"
      PEBBLE_ALTERNATE_ROOTS: 2
      PEBBLE_VA_SLEEPTIME: 1
```

Both services get fixed IPs inside a `10.30.50.0/24` subnet, which is what lets a DNS challenge resolve against a private resolver rather than the public internet. The `pebble-certificates/` directory is mounted in as a volume for local certificate material. A `test/` directory holds the actual test suite, and a badge in the README runs the whole thing on Pebble, with a second badge for shellcheck. The 2.50 release notes record moving from Docker Hub to GitHub Container Registry for the Pebble image, which is the sort of change that breaks CI quietly if nobody is watching it.

The release history shows an active project with a broad contributor base. v2.52 from July 2026 makes ECDSA the default key algorithm and handles a missing auth link response without failing. v2.51 in June 2026 adds ARI support for certificate renewal and improves profile support. v2.50 in June 2026 adds Route53 bash scripts and INWX API ACME scripts, which is exactly the long-tail pattern the Makefile's `*_scripts` loop is designed for. Contributors in these entries include @timkimber, @kenh, @xyide, @DO1JLR, @combolek and @allgeyer, and the last push was 2026-09-23. Two documentation caveats belong here rather than being buried: the help output embedded in the README still prints `getssl ver. 2.36` even though 2.52 is current, and the quick start directs people to download packages from a different GitHub organisation, `github.com/jeffmerkey/getssl/releases`, while the repository and the package URLs themselves live under `srvrco/getssl`.

## Conclusion

getssl earns its place in a specific and common situation: you need a certificate for a machine you administer from elsewhere, so validation tokens and the resulting files get copied over ssh, sftp or ftp rather than being created in place. Everything else about it follows from being a single bash script with no runtime dependency, which is why it runs on BSD, most Linux distributions and macOS, and why both RPM and DEB packages are published alongside the raw script. The self update and the post-install port check are the features that go beyond a plain ACME client, since both answer questions a bare client leaves open. Two documentation caveats are worth knowing: the help output embedded in the README still reports version 2.36 while the current release is 2.52, and the package download links point at a different GitHub organisation than the repository itself. Install the binary package, drop a config file per certificate, and put it in cron.

## FAQ

### How do I install getssl?

Install the prebuilt package with rpm -i getssl-2.52-1.noarch.rpm on RPM distributions or dpkg -i getssl_2.52-1_all.deb on Debian and Ubuntu. On other platforms, build it from the git sources and follow the manual installation section.

### Can getssl get a certificate for a remote server I do not have shell on?

Yes. That is a headline feature. Validation tokens and certificates can be copied automatically over ssh, sftp or ftp, so getssl does not need to run on the server serving the site.

### How do I automate getssl certificate renewals?

Run it from a daily cron job, which is what the getssl.crontab file in the repository is for. Add the -q flag to limit output to errors, successes and upgrade notices, and -U to skip the update check.

### Does getssl verify that my server is actually serving the new certificate?

Yes. After installing a certificate, getssl tests the port you configured under its Server-Types section to confirm the certificate in use is the one just installed.

## Sources

- [Issues](https://github.com/srvrco/getssl/issues)
- [License: GPL-3.0](https://github.com/srvrco/getssl/blob/master/LICENSE)
- [README](https://github.com/srvrco/getssl/blob/master/README.md)
- [Releases](https://github.com/srvrco/getssl/releases)
- [srvrco/getssl on GitHub](https://github.com/srvrco/getssl)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/srvrco-getssl
