Skip to content

Commit

Permalink
Merge branch 'master' into more-test-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
timkimber authored Sep 26, 2024
2 parents ffdfb09 + 7a6147a commit 734f221
Show file tree
Hide file tree
Showing 21 changed files with 660 additions and 77 deletions.
98 changes: 46 additions & 52 deletions README
Original file line number Diff line number Diff line change
@@ -1,77 +1,71 @@


GETSSL

# GETSSL

[Run all tests] [shellcheck]

Obtain SSL certificates from the letsencrypt.org ACME server. Suitable
for automating the process on remote servers.


Table of Contents

- Upgrade broken in v2.43
- Features
- Overview
- Quick Start Guide
- Manual Installation
- Getting started
- Detailed guide to getting started with more examples
- Wildcard certificates
- ISPConfig
- Automating updates
- Structure
- Server-Types
- Revoke a certificate
- Elliptic curve keys
- Preferred Chain
- Include Root certificate in full chain
- Windows Server and IIS Support
- Building getssl as an RPM Package (Redhat/CentOS/SuSe/Oracle/AWS)
- Building getssl as a Debian Package (Debian/Ubuntu)
- Issues / problems / help

Table of Contents

- Upgrade broken in v2.43
- Features
- Overview
- Quick Start Guide
- Manual Installation
- Getting started
- Detailed guide to getting started with more examples
- Wildcard certificates
- ISPConfig
- Automating updates
- Structure
- Server-Types
- Revoke a certificate
- Elliptic curve keys
- Preferred Chain
- Include Root certificate in full chain
- Windows Server and IIS Support
- Building getssl as an RPM Package (Redhat/CentOS/SuSe/Oracle/AWS)
- Building getssl as a Debian Package (Debian/Ubuntu)
- Issues / problems / help

Upgrade broken in v2.43

The automatic upgrade in v2.43 is broken as the url is incorrect. If you
have this version installed you’ll need to manually upgrade using:
curl --silent --user-agent getssl/manual https://raw.githubusercontent.com/srvrco/getssl/latest/getssl --output getssl

curl --silent --user-agent getssl/manual <https://raw.githubusercontent.com/srvrco/getssl/latest/getssl> --output getssl

Features

- BASH - It runs on virtually all unix machines, including BSD, most
- BASH - It runs on virtually all unix machines, including BSD, most
Linux distributions, macOS.
- GET CERTIFICATES FOR REMOTE SERVERS - The tokens used to provide
- GET CERTIFICATES FOR REMOTE SERVERS - The tokens used to provide
validation of domain ownership, and the certificates themselves can
be automatically copied to remote servers (via ssh, sftp or ftp for
tokens). The script doesn’t need to run on the server itself. This
can be useful if you don’t have access to run such scripts on the
server itself, e.g. if it’s a shared server.
- RUNS AS A DAILY CRON - so certificates will be automatically renewed
- RUNS AS A DAILY CRON - so certificates will be automatically renewed
when required.
- AUTOMATIC CERTIFICATE RENEWALS
- CHECKS CERTIFICATES ARE CORRECTLY LOADED - After installation of a
- AUTOMATIC CERTIFICATE RENEWALS
- CHECKS CERTIFICATES ARE CORRECTLY LOADED - After installation of a
new certificate it will test the port specified ( see Server-Types
for options ) that the certificate is actually being used correctly.
- AUTOMATICALLY UPDATES - The script can automatically update itself
- AUTOMATICALLY UPDATES - The script can automatically update itself
with bug fixes etc if required.
- EXTENSIVELY CONFIGURABLE - With a simple configuration file for each
- EXTENSIVELY CONFIGURABLE - With a simple configuration file for each
certificate it is possible to configure it exactly for your needs,
whether a simple single domain or multiple domains across multiple
servers on the same certificate.
- SUPPORTS HTTP AND DNS CHALLENGES - Full ACME implementation
- SIMPLE AND EASY TO USE
- DETAILED DEBUG INFO - Whilst it shouldn’t be needed, detailed debug
- SUPPORTS HTTP AND DNS CHALLENGES - Full ACME implementation
- SIMPLE AND EASY TO USE
- DETAILED DEBUG INFO - Whilst it shouldn’t be needed, detailed debug
information is available.
- RELOAD SERVICES - After a new certificate is obtained then the
- RELOAD SERVICES - After a new certificate is obtained then the
relevant services (e.g. apache/nginx/postfix) can be reloaded.
- ACME V1 AND V2 - Supports both ACME versions 1 and 2 (note ACMEv1 is
- ACME V1 AND V2 - Supports both ACME versions 1 and 2 (note ACMEv1 is
deprecated and clients will automatically use v2)


Overview

GetSSL was written in standard bash ( so it can be run on a server, a
Expand Down Expand Up @@ -163,7 +157,7 @@ INSTALLING SOURCE PACKAGES
To install the source package with the rpm package manager for RedHat,
CentOS, SuSe, Oracle Linux, or AWS Linux distributions:

rpm -i getssl-2.47-1.src.rpm
rpm -i getssl-2.47-1.src.rpm

_(Note: rpm installs the source code files in /root/rpmbuild/ as top
directory for RedHat, CentOS, Oracle Linux, and AWS Linux platforms.
Expand All @@ -183,12 +177,12 @@ SPECS and SOURCES directory tree structure. Subsequently, an SDEB can
also be extracted and installed with the TAR -XVF COMMAND or the files
listed with the TAR -TVF COMMAND:

[root@localhost getssl]$ tar -tvf /root/debbuild/SDEBS/getssl-2.47-1.sdeb
[root@localhost getssl]$ tar -tvf /root/debbuild/SDEBS/getssl-2.47-1.sdeb
-rw-r--r-- root/root 1772110 2022-10-12 20:42 SOURCES/getssl-2.47.tar.gz
-rw-r--r-- root/root 192 2022-08-02 15:02 SOURCES/getssl.crontab
-rw-r--r-- root/root 126 2022-08-02 15:02 SOURCES/getssl.logrotate
-rw-r--r-- root/root 1537 2022-08-02 15:02 SPECS/getssl.spec
[root@localhost getssl]$
[root@localhost getssl]$

For building or rebuilding RPMS or DEB Packages after you have installed
the associated source packages on your platform, refer to the following:
Expand Down Expand Up @@ -473,21 +467,21 @@ certificate is installed correctly

Server-Type Port Extra
------------------ ------ --------------
https 443
https 443
ftp 21 FTP Explicit
ftpi 990 FTP Implicit
imap 143 StartTLS
imaps 993
imaps 993
pop3 110 StartTLS
pop3s 995
pop3s 995
smtp 25 StartTLS
smtps_deprecated 465
smtps_deprecated 465
smtps 587 StartTLS
smtp_submission 587 StartTLS
xmpp 5222 StartTLS
xmpps 5269
ldaps 636
port number
xmpps 5269
ldaps 636
port number


Revoke a certificate
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ For example, the release v2.49 contains the following packages in the release se

### **Debian Based Packages (Debian, Ubuntu)**

- [getssl_2.49-1_all.deb](https://github.com/srvrco/getssl/releases/download/2.49/getssl_2.49-1_all.deb) (binary)
- [getssl_2.49-1_all.deb](https://github.com/srvrco/getssl/releases/download/v2.49/getssl_2.49-1_all.deb) (binary)

### **Installing Binary Packages**

Expand Down
12 changes: 11 additions & 1 deletion dns_scripts/GoDaddy-README.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
---------------------------------------------------------------------------
NOTE: GoDaddy updated their domain API requirements in 2024!

It's now required to have at least 10-50 domains in your account.
Another option is to purchase the "Discount Domain Club" (Premium!)
to gain access to the API.

Source: https://www.reddit.com/r/godaddy/comments/1bl0f5r/
---------------------------------------------------------------------------

Using GoDaddy DNS for LetsEncrypt domain validation.

Quick guide to setting up getssl for domain validation of
Expand All @@ -22,7 +32,7 @@ There are two prerequisites to using getssl with GoDaddy DNS:

With those in hand, the installation procedure is:

1) Put JSON.sh in the getssl DNS scripts directory
1) Put JSON.sh in the getssl DNS scripts directory
Default: /usr/share/getssl/dns_scripts

2) Open your config file (the global file in ~/.getssl/getssl.cfg
Expand Down
62 changes: 62 additions & 0 deletions dns_scripts/INWX-README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
## Using INWX DNS for LetsEncrypt domain validation

### Install Requirements

The INWX API Python3 script requires two Python packages:

```bash
pip3 install INWX.Domrobot tldextract
```

You could install it for the user running getssl, or you could create a python3 venv.

```bash
# install python3 venv apt packages
sudo apt install python3 python3-venv

# Create venv
python3 -m venv venv

# activate venv
source venv/bin/activate

# install requirements
pip3 install INWX.Domrobot tldextract
```

If you are installing the Python packages in venv, you should make sure that you either
you either enable the venv before running getssl, or you
add the venv to the ``DNS_ADD_COMMAND'' and ``DNS_DEL_COMMAND'' commands.
See example below.

### Enabling the scripts

Set the following options in `getssl.cfg` (either global or domain-specific):

```
VALIDATE_VIA_DNS="true"
DNS_ADD_COMMAND="/usr/share/getssl/dns_scripts/dns_add_inwx.py"
DNS_DEL_COMMAND="/usr/share/getssl/dns_scripts/dns_del_inwx.py"
```

If you are using a python3 venv as described above, this is an example of how to include it:

```
VALIDATE_VIA_DNS="true"
DNS_ADD_COMMAND="/path/to/venv/bin/python3 /usr/share/getssl/dns_scripts/dns_add_inwx.py"
DNS_DEL_COMMAND="/path/to/venv/bin/python3 /usr/share/getssl/dns_scripts/dns_del_inwx.py"
```

*Obviously the "/path/to/venv" needs to be replaced with the actual path to your venv, e.g. "/home/getssl/venv".*

### Authentication

Your INWX credentials will be used to authenticate to INWX.
If you are using a second factor, please have a look at the [INWX Domrobot Pthon3 Client](https://github.com/inwx/python-client) as it is currently not implemented in the inwx api script.

Set the following options in the domain-specific `getssl.cfg` or make sure these enviroment variables are present.

```
export INWX_USERNAME="your_inwx_username"
export INWX_PASSWORD="..."
```
37 changes: 37 additions & 0 deletions dns_scripts/Route53-README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Using Route53 BASH scripts for LetsEncrypt domain validation.

## Quick guide to setting up getssl for domain validation of Route53 DNS domains.

There a few prerequisites to using getssl with Route53 DNS:

1. You will need to set up an IAM user with the necessary permissions to modify resource records in the hosted zone.

- route53:ListHostedZones
- route53:ChangeResourceRecordSets

1. You will need the AWS CLI Client installed on your machine.

1. You will need to configure the client for the IAM user that has permission to modify the resource records.

With those in hand, the installation procedure is:

1. Open your config file (the global file in ~/.getssl/getssl.cfg
or the per-account file in ~/.getssl/example.net/getssl.cfg)

1. Set the following options:

- VALIDATE_VIA_DNS="true"
- DNS_ADD_COMMAND="/usr/share/getssl/dns_scripts/dns_add_route53"
- DNS_DEL_COMMAND="/usr/share/getssl/dns_scripts/dns_del_route53"

The AWS CLI profile to use (will use _default_ if not specified)

- export AWS*CLI_PROFILE="\_profile name*"

1. Set any other options that you wish (per the standard
directions.) Use the test CA to make sure that
everything is setup correctly.

That's it. getssl example.net will now validate with DNS.

There are additional options, which are documented in `dns_route53 -h`
93 changes: 93 additions & 0 deletions dns_scripts/dns_add_inwx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script to Set TXT Record at INWX using the API
This script requires the pip packages INWX.Domrobot and tldextract
This script is using enviroment variables to get inwx credentials
"""

import sys
import os
import argparse
from INWX.Domrobot import ApiClient
import tldextract

# Create Parser-Objekt
parser = argparse.ArgumentParser(
description='Using the INWX API to change DNS TXT Records for the ACME DNS-01 Challange',
epilog= "The environment variables 'INWX_USERNAME' and 'INWX_PASSWORD' are required too")

# Adding Args
parser.add_argument('fulldomain', type=str, help='The full domain to add TXT Record.')
parser.add_argument('token', type=str, help='The ACME DNS-01 token.')
parser.add_argument('--debug', action='store_true', help='Enable debug mode.')

# Parsing Args
args = parser.parse_args()
INWX_FULLDOMAIN = args.fulldomain
ACME_TOKEN = args.token
DEBUG = args.debug

# Parsing ENV
INWX_USERNAME = os.getenv('INWX_USERNAME', '')
INWX_PASSWORD = os.getenv('INWX_PASSWORD', '')

# Splitting Domain
domain = tldextract.extract(INWX_FULLDOMAIN)
INWX_SUBDOMAIN = domain.subdomain
INWX_DOMAIN = f"{domain.domain}.{domain.suffix}"

# Check if either environment variable is empty and handle the error
if not INWX_USERNAME or not INWX_PASSWORD:
print("Error: The following environment variables are required and cannot be empty:")
if not INWX_USERNAME:
print(" - INWX_USERNAME: Your INWX account username.")
if not INWX_PASSWORD:
print(" - INWX_PASSWORD: Your INWX account password.")
sys.exit(1)

if DEBUG:
print(f'FQDN: {INWX_FULLDOMAIN}')
print(f'Domain: {INWX_DOMAIN}')
print(f'Subdomain: {INWX_SUBDOMAIN}')
print(f'Token: {ACME_TOKEN}')
print(f'User: {INWX_USERNAME}')
print(f'Password: {INWX_PASSWORD}')

# By default the ApiClient uses the test api (OT&E).
# If you want to use the production/live api we have a
# constant named API_LIVE_URL in the ApiClient class.
# Just set api_url=ApiClient.API_LIVE_URL and you're good.
# api_client = ApiClient(api_url=ApiClient.API_OTE_URL, debug_mode=DEBUG)
api_client = ApiClient(api_url=ApiClient.API_LIVE_URL, debug_mode=DEBUG)

# If you have 2fa enabled, take a look at the documentation of the ApiClient#login method
# to get further information about the login, especially the shared_secret parameter.
login_result = api_client.login(INWX_USERNAME, INWX_PASSWORD)

# login was successful
if login_result['code'] == 1000:

# Make an api call and save the result in a variable.
# We want to create a new nameserver record, so we call the api method nameserver.createRecord.
# See https://www.inwx.de/en/help/apidoc/f/ch02s15.html#nameserver.createRecord for parameters
# ApiClient#call_api returns the api response as a dict.
if INWX_SUBDOMAIN == '':
domain_entry_result = api_client.call_api(api_method='nameserver.createRecord', method_params={'domain': INWX_DOMAIN, 'name': '_acme-challenge', 'type': 'TXT', 'content': ACME_TOKEN}) # pylint: disable=C0301
else:
domain_entry_result = api_client.call_api(api_method='nameserver.createRecord', method_params={'domain': INWX_DOMAIN, 'name': f'_acme-challenge.{INWX_SUBDOMAIN}', 'type': 'TXT', 'content': ACME_TOKEN}) # pylint: disable=C0301

# With or without successful check, we perform a logout.
api_client.logout()

# validating return code
if domain_entry_result['code'] == 2302:
sys.exit(f"{domain_entry_result['msg']}.\nTry nameserver.updateRecord or nameserver.deleteRecord instead") # pylint: disable=C0301
elif domain_entry_result['code'] == 1000:
if DEBUG:
print(domain_entry_result['msg'])
sys.exit()
else:
sys.exit(domain_entry_result)
else:
sys.exit('Api login error. Code: ' + str(login_result['code']) + ' Message: ' + login_result['msg']) # pylint: disable=C0301
Loading

0 comments on commit 734f221

Please sign in to comment.