Browse Source

Merge branch 'master' into route53-bash

pull/850/head
Steve Kennedy 2 years ago
committed by Steve Kennedy
parent
commit
e2339fad21
92 changed files with 3563 additions and 424 deletions
  1. +127
    -0
      .github/workflows/release-and-package.yml
  2. +29
    -27
      .github/workflows/run-tests-pebble.yml
  3. +7
    -5
      .github/workflows/run-tests-staging-acmedns.yml
  4. +3
    -11
      .github/workflows/run-tests-staging-duckdns.yml
  5. +3
    -11
      .github/workflows/run-tests-staging-dynu.yml
  6. +6
    -4
      .github/workflows/shellcheck.yml
  7. +2
    -0
      .gitignore
  8. +964
    -0
      README
  9. +547
    -31
      README.md
  10. +38
    -0
      RELEASE.md
  11. +48
    -0
      common.shrc
  12. +11
    -0
      debbuild.patch
  13. +8
    -4
      dns_scripts/Cloudflare-README.md
  14. +22
    -12
      dns_scripts/dns_add_acmedns
  15. +1
    -1
      dns_scripts/dns_add_azure
  16. +1
    -1
      dns_scripts/dns_add_del_aliyun.sh
  17. +7
    -0
      dns_scripts/dns_add_dnsmasq
  18. +1
    -1
      dns_scripts/dns_add_dnspod
  19. +1
    -1
      dns_scripts/dns_add_duckdns
  20. +1
    -1
      dns_scripts/dns_add_godaddy
  21. +50
    -0
      dns_scripts/dns_add_hetzner
  22. +86
    -0
      dns_scripts/dns_add_hostway
  23. +1
    -1
      dns_scripts/dns_add_ionos
  24. +44
    -0
      dns_scripts/dns_add_ispconfig
  25. +1
    -1
      dns_scripts/dns_add_joker
  26. +27
    -16
      dns_scripts/dns_add_linode
  27. +1
    -1
      dns_scripts/dns_add_manual
  28. +30
    -0
      dns_scripts/dns_add_ns1
  29. +1
    -1
      dns_scripts/dns_add_nsupdate
  30. +1
    -1
      dns_scripts/dns_add_ovh
  31. +1
    -1
      dns_scripts/dns_add_pdns-mysql
  32. +30
    -0
      dns_scripts/dns_add_vultr
  33. +39
    -0
      dns_scripts/dns_add_windows_dns_server
  34. +8
    -35
      dns_scripts/dns_del_acmedns
  35. +7
    -0
      dns_scripts/dns_del_dnsmasq
  36. +1
    -1
      dns_scripts/dns_del_dnspod
  37. +1
    -1
      dns_scripts/dns_del_duckdns
  38. +1
    -1
      dns_scripts/dns_del_godaddy
  39. +57
    -0
      dns_scripts/dns_del_hetzner
  40. +66
    -0
      dns_scripts/dns_del_hostway
  41. +1
    -1
      dns_scripts/dns_del_ionos
  42. +44
    -0
      dns_scripts/dns_del_ispconfig
  43. +1
    -1
      dns_scripts/dns_del_joker
  44. +29
    -21
      dns_scripts/dns_del_linode
  45. +1
    -1
      dns_scripts/dns_del_manual
  46. +26
    -0
      dns_scripts/dns_del_ns1
  47. +1
    -1
      dns_scripts/dns_del_nsupdate
  48. +1
    -1
      dns_scripts/dns_del_ovh
  49. +1
    -1
      dns_scripts/dns_del_pdns-mysql
  50. +26
    -0
      dns_scripts/dns_del_vultr
  51. +39
    -0
      dns_scripts/dns_del_windows_dns_server
  52. +15
    -17
      dns_scripts/dns_godaddy
  53. +140
    -0
      dns_scripts/ispconfig_soap.php
  54. +191
    -100
      getssl
  55. +3
    -0
      getssl.crontab
  56. +9
    -0
      getssl.logrotate
  57. +59
    -0
      getssl.spec
  58. +1
    -1
      other_scripts/cpanel_cert_upload
  59. +95
    -0
      other_scripts/iis_install_certeficate.ps1
  60. +49
    -0
      test/0-test-usage.bats
  61. +18
    -6
      test/11-test--install.bats
  62. +0
    -33
      test/32-test-upgrade.bats
  63. +214
    -8
      test/34-ftp-passive.bats
  64. +167
    -0
      test/34-ftp-ports.bats
  65. +1
    -1
      test/40-cname-dns01-nslookup.bats
  66. +32
    -0
      test/41-show-account-id.bats
  67. +1
    -1
      test/Dockerfile-alpine
  68. +1
    -1
      test/Dockerfile-bash4-0
  69. +1
    -1
      test/Dockerfile-bash4-2
  70. +1
    -1
      test/Dockerfile-bash5-0
  71. +1
    -1
      test/Dockerfile-centos7
  72. +1
    -2
      test/Dockerfile-centos7-duckdns
  73. +1
    -2
      test/Dockerfile-centos7-dynu
  74. +5
    -1
      test/Dockerfile-centos8
  75. +1
    -1
      test/Dockerfile-debian
  76. +1
    -1
      test/Dockerfile-rockylinux8
  77. +1
    -1
      test/Dockerfile-ubuntu
  78. +1
    -1
      test/Dockerfile-ubuntu-acmedns
  79. +1
    -2
      test/Dockerfile-ubuntu-duckdns
  80. +1
    -2
      test/Dockerfile-ubuntu-dynu
  81. +1
    -1
      test/Dockerfile-ubuntu14
  82. +1
    -1
      test/Dockerfile-ubuntu16
  83. +1
    -1
      test/Dockerfile-ubuntu18
  84. +5
    -5
      test/README-Testing.md
  85. +9
    -4
      test/restart-ftpd
  86. +3
    -3
      test/restart-nginx
  87. +8
    -1
      test/run-test.cmd
  88. +9
    -0
      test/test-config/alpine-supervisord.conf
  89. +44
    -7
      test/test_helper.bash
  90. +5
    -5
      test/u1-test-get_auth_dns-dig.bats
  91. +5
    -5
      test/u2-test-get_auth_dns-drill.bats
  92. +10
    -10
      test/u7-test-get_auth_dns-nslookup.bats

+ 127
- 0
.github/workflows/release-and-package.yml View File

@ -0,0 +1,127 @@
# ==========================
# Can test locally using act (https://github.com/nektos/act)
# ==========================
# ./bin/act -s GITHUB_TOKEN=<fine-grained-token> --directory runner --workflows "../.github/workflows/" -e ../payloads.json --no-skip-checkout -j deploy
#
# where payloads.json is:
# {
# "inputs": {
# "tags": "2.47"
# }
# }
#
# ==========================
# Can debug remotely on github actions instance by uncommenting the 'tmate' section below
# ==========================
name: Deploy getssl
on:
workflow_dispatch:
inputs:
tags:
description: 'Tag to deploy, e.g. 2.47'
required: true
type: string
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: prepare
# Keep the outputs persistent outside the docker container to use for the other steps
run: |
mkdir -p ${{ github.workspace }}/bin
mkdir -p ${{ github.workspace }}/debbuild/BUILD
mkdir -p ${{ github.workspace }}/debbuild/DEBS/all
mkdir -p ${{ github.workspace }}/debbuild/SDEBS
mkdir -p ${{ github.workspace }}/debbuild/SOURCES
mkdir -p ${{ github.workspace }}/debbuild/SPECS
mkdir -p ${{ github.workspace }}/rpmbuild/SOURCES
mkdir -p ${{ github.workspace }}/rpmbuild/RPMS/noarch
mkdir -p ${{ github.workspace }}/rpmbuild/RPMS/SRPMS
- name: Checkout
uses: actions/checkout@v3
with:
path: source
- name: Get version number
id: get_version
run: |
echo "VERSION=$(bash ${{ github.workspace }}/source/getssl --version)" >> $GITHUB_OUTPUT
- name: Get release
id: get_release
run: |
echo "RELEASE=$(grep Release source/getssl.spec | awk '{ print $2 }')" >> $GITHUB_OUTPUT
- name: Check version matches tag
run: |
if [ "${{ steps.get_version.outputs.VERSION }}" != "getssl V${{ github.event.inputs.tags }}" ]; then
echo "Version number in getssl (${{ steps.get_version.outputs.VERSION }}) does not match tag (getssl V${{ github.event.inputs.tags }})"
exit 1
fi
- name: build .deb package
id: build_deb
run: |
sudo apt-get update -qq
sudo apt-get install --no-install-recommends -qq -y build-essential devscripts debhelper pax liblocale-gettext-perl wget
wget https://github.com/debbuild/debbuild/releases/download/22.02.1/debbuild_22.02.1-0ubuntu20.04_all.deb
sudo dpkg --install debbuild_22.02.1-0ubuntu20.04_all.deb
# Line 1959 has an extra ")" bracket
sudo chmod +w /usr/bin/debbuild
sudo patch /usr/bin/debbuild < ${GITHUB_WORKSPACE}/source/debbuild.patch
tar --absolute-names -czf ${GITHUB_WORKSPACE}/getssl-${{ github.event.inputs.tags }}.tar.gz ${GITHUB_WORKSPACE}/source/* --transform "s,${GITHUB_WORKSPACE}/source,getssl-${{ github.event.inputs.tags }},"
tar --absolute-names -cf ${GITHUB_WORKSPACE}/debbuild/SDEBS/getssl-${{ github.event.inputs.tags }}.sdeb ${GITHUB_WORKSPACE}/getssl-${{ github.event.inputs.tags }}.tar.gz --transform "s,${GITHUB_WORKSPACE},SOURCES,"
tar --append -f ${GITHUB_WORKSPACE}/debbuild/SDEBS/getssl-${{ github.event.inputs.tags }}.sdeb -C ${GITHUB_WORKSPACE}/source getssl.crontab getssl.logrotate --transform 's,^,SOURCES/,'
tar --append -f ${GITHUB_WORKSPACE}/debbuild/SDEBS/getssl-${{ github.event.inputs.tags }}.sdeb -C ${GITHUB_WORKSPACE}/source getssl.spec --transform 's,^,SPECS/,'
ln -s ${GITHUB_WORKSPACE}/debbuild ${HOME}/debbuild
/usr/bin/debbuild -vv --install ${GITHUB_WORKSPACE}/debbuild/SDEBS/getssl-${{ github.event.inputs.tags }}.sdeb
/usr/bin/debbuild -vv -ba ${GITHUB_WORKSPACE}/debbuild/SPECS/getssl.spec
echo "getssl_deb=${GITHUB_WORKSPACE}/debbuild/DEBS/all/getssl_${{ github.event.inputs.tags }}-${{ steps.get_release.outputs.RELEASE }}_all.deb" >> $GITHUB_OUTPUT
# *** Uncomment this to debug remotely ***
# - name: Setup tmate session
# if: ${{ failure() }}
# uses: mxschmitt/action-tmate@v3
- name: build .rpm package
id: build_rpm
if: ${{ success() }}
uses: addnab/docker-run-action@v3
with:
image: rockylinux:8
options: -v ${{ github.workspace }}:/root -e GITHUB_REF=${{ github.ref }}
run: |
yum install -y rpm-build make
tar -czf /root/rpmbuild/SOURCES/getssl-${{ github.event.inputs.tags }}.tar.gz /root/source/* --transform "s/root\/source\//getssl-${{ github.event.inputs.tags }}\//"
cp /root/source/getssl.crontab /root/rpmbuild/SOURCES
cp /root/source/getssl.logrotate /root/rpmbuild/SOURCES
rpmbuild -ba /root/source/getssl.spec
- name: output .rpm packages
id: output_rpm
if: ${{ success() }}
run: |
echo "getssl_rpm=${GITHUB_WORKSPACE}/rpmbuild/RPMS/noarch/getssl-${{ github.event.inputs.tags }}-${{ steps.get_release.outputs.RELEASE }}.noarch.rpm" >> $GITHUB_OUTPUT
echo "getssl_srpm=${GITHUB_WORKSPACE}/rpmbuild/SRPMS/getssl-${{ github.event.inputs.tags }}-${{ steps.get_release.outputs.RELEASE }}.src.rpm" >> $GITHUB_OUTPUT
- name: create_release
id: create_release
if: ${{ success() }}
uses: ncipollo/release-action@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag: ${{ github.event.inputs.tags }}
name: Draft Release ${{ github.event.inputs.tags }}
generateReleaseNotes: true
draft: true
prerelease: false
artifacts: |
${{ steps.build_deb.outputs.getssl_deb }}
${{ steps.output_rpm.outputs.getssl_rpm }}
${{ steps.output_rpm.outputs.getssl_srpm }}

+ 29
- 27
.github/workflows/run-tests-pebble.yml View File

@ -6,16 +6,18 @@ on:
branches:
- master
pull_request:
paths-ignore:
- '.github/workflows/*'
branches:
- master
workflow_dispatch:
branches:
- master
schedule:
- cron: '15 3 5 * *'
jobs:
test-alpine:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Alpine
@ -23,7 +25,7 @@ jobs:
test-bash-4-0:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Alpine using Bash 4.0
@ -31,7 +33,7 @@ jobs:
test-bash-4-2:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Alpine using Bash 4.2
@ -39,31 +41,31 @@ jobs:
test-bash-5-0:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Alpine using Bash 5
run: test/run-test.sh bash5-0
test-centos6:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on CentOS6
run: test/run-test.sh centos6
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on CentOS6
run: test/run-test.sh centos6
test-centos7:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on CentOS7
run: test/run-test.sh centos7
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on CentOS7
run: test/run-test.sh centos7
test-centos8:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on CentOS8
@ -71,7 +73,7 @@ jobs:
test-debian:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Debian
@ -79,7 +81,7 @@ jobs:
test-rockylinux8:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on RockyLinux8
@ -87,7 +89,7 @@ jobs:
test-ubuntu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Ubuntu
@ -95,7 +97,7 @@ jobs:
test-ubuntu14:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Ubuntu14
@ -103,7 +105,7 @@ jobs:
test-ubuntu16:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Ubuntu16
@ -111,7 +113,7 @@ jobs:
test-ubuntu18:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Ubuntu18


+ 7
- 5
.github/workflows/run-tests-staging-acmedns.yml View File

@ -1,4 +1,4 @@
name: Run all tests using Dynu and acmedns
name: Run tests against Staging server using acmedns
on:
push:
paths-ignore:
@ -6,19 +6,21 @@ on:
branches:
- master
pull_request:
paths-ignore:
- '.github/workflows/*'
branches:
- master
workflow_dispatch:
branches:
- master
env:
DYNU_API_KEY: ${{ secrets.DYNU_API_KEY == '' && '65cXefd35XbYf36546eg5dYcZT6X52Y2' || secrets.DYNU_API_KEY }}
jobs:
test-ubuntu-acmedns:
runs-on: ubuntu-latest
if: always()
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Ubuntu against Staging using acmedns


+ 3
- 11
.github/workflows/run-tests-staging-duckdns.yml View File

@ -1,13 +1,5 @@
name: Run all tests using DuckDNS
name: Run tests against Staging server using DuckDNS
on:
push:
paths-ignore:
- '.github/workflows/*'
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
branches:
- master
@ -17,7 +9,7 @@ jobs:
test-centos7-duckdns:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on CentOS7 against Staging using DuckDNS
@ -27,7 +19,7 @@ jobs:
if: always()
needs: test-centos7-duckdns
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Ubuntu against Staging using DuckDNS


+ 3
- 11
.github/workflows/run-tests-staging-dynu.yml View File

@ -1,13 +1,5 @@
name: Run all tests using Dynu
name: Run tests against Staging server using Dynu
on:
push:
paths-ignore:
- '.github/workflows/*'
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
branches:
- master
@ -17,7 +9,7 @@ jobs:
test-centos7-dynu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on CentOS7 against Staging using Dynu
@ -27,7 +19,7 @@ jobs:
if: always()
needs: test-centos7-dynu
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Ubuntu against Staging using Dynu


+ 6
- 4
.github/workflows/shellcheck.yml View File

@ -4,18 +4,20 @@ on:
push:
paths-ignore:
- '.github/workflows/*'
branches: [ master ]
branches:
- master
pull_request:
branches: [ master ]
workflow_dispatch:
paths-ignore:
- '.github/workflows/*'
branches:
- master
workflow_dispatch:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Lint check
uses: azohra/shell-linter@latest
with:


+ 2
- 0
.gitignore View File

@ -8,3 +8,5 @@
*.orig
JSON.sh
.vscode/settings.json
push.json
bin/

+ 964
- 0
README View File

@ -0,0 +1,964 @@
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
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
Features
- BASH - It runs on virtually all unix machines, including BSD, most
Linux distributions, macOS.
- 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
when required.
- 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
with bug fixes etc if required.
- 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
information is available.
- 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
deprecated and clients will automatically use v2)
Overview
GetSSL was written in standard bash ( so it can be run on a server, a
desktop computer, or even a virtualbox) and add the checks, and
certificates to a remote server ( providing you have a ssh with key,
sftp or ftp access to the remote server).
```getssl -h getssl ver. 2.36 Obtain SSL certificates from the
letsencrypt.org ACME server
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
Options: -a, –all Check all certificates -d, –debug Output debug
information -c, –create Create default config files -f, –force Force
renewal of cert (overrides expiry checks) -h, –help Display this help
message and exit -i, –install Install certificates and reload service
-q, –quiet Quiet mode (only outputs on error, success of new cert, or
getssl was upgraded) -Q, –mute Like -q, but also mute notification about
successful upgrade -r, –revoke “cert” “key” [CA_server] Revoke a
certificate (the cert and key are required) -u, –upgrade Upgrade getssl
if a more recent version is available - can be used with or without
domain(s) -X –experimental tag Allow upgrade to a specified version of
getssl -U, –nocheck Do not check if a more recent version is available
-v –version Display current version of getssl -w working_dir “Working
directory” –preferred-chain “chain” Use an alternate chain for the
certificate ```
Quick Start Guide
You can download precompiled RPM packages and Debian (DEB) packages from
the release page for this project, or you can manually build and install
the program from the git sources.
If you want to manually install the program from scratch with the git
sources rather than use the pre-compiled RPMS and DEB packages, or if
your target platform does not support Linux RPM or DEB packages, then
please skip to the section Manual Installation for instructions on
installing the getssl program manually.
Packages are provided in binary and source versions, and can be
downloaded and installed directly or rebuilt. Package types are Red Hat
Package Manager (RPM) packages and Debian (DEB) packages for binary
installation and Source RPM packages (SRPMS) and Debbuild SDEB packages
for source code installation.
RPM and DEB packages for each release include a binary architecture
specific package and a source package which can be downloaded and
built/rebuilt and which contains the source code.
For example, the release v2.47 contains the following packages in the
release section:
RPM BASED PACKAGES (REDHAT, CENTOS, SUSE, ORACLE LINUX, AWS LINUX)
- getssl-2.47-1.src.rpm (source)
- getssl-2.47-1.noarch.rpm (binary)
DEBIAN BASED PACKAGES (DEBIAN, UBUNTU)
- getssl-2.47-1.sdeb (source)
- getssl_2.47-1_all.deb (binary)
INSTALLING BINARY PACKAGES
To install the binary package with the rpm package manager for RedHat,
CentOS, SuSe, Oracle Linux, or AWS Linux distributions:
rpm -i getssl-2.47-1.noarch.rpm
To deinstall the RPM binary package:
rpm -e getssl
To install the binary package with the Debian dpkg package manager for
Debian and Ubuntu Linux distributions:
dpkg -i getssl_2.47-1_all.deb
To deinstall the Debian dpkg binary package:
dpkg -r getssl
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
_(Note: rpm installs the source code files in /root/rpmbuild/ as top
directory for RedHat, CentOS, Oracle Linux, and AWS Linux platforms.
SuSe platforms install the source code files in /usr/src/packages/)_
To install the source package with the Debbuild package tool for Debian
or Ubuntu Linux distributions:
debbuild -i getssl-2.47-1.sdeb
_(Note: Debbuild installs the source code files in /root/debbuild/ as
top directory)_
One item of note is that SDEB packages are actually just tar.gz archives
renamed with an .sdeb file extension with the files organized into a
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
-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]$
For building or rebuilding RPMS or DEB Packages after you have installed
the associated source packages on your platform, refer to the following:
- Building getssl as an RPM Package (Redhat/CentOS/SuSe/Oracle/AWS)
- Building getssl as a Debian Package (Debian/Ubuntu)
Manual Installation
Since the script is only one file, you can use the following command for
a quick installation of GetSSL only:
curl --silent https://raw.githubusercontent.com/srvrco/getssl/latest/getssl > getssl ; chmod 700 getssl
This will copy the getssl Bash script to the current location and change
the permissions to make it executable for you.
For a more comprehensive installation (e.g. install also helper scripts)
use the provided Makefile with each release tarball. Use the install
target.
You’ll find the latest version in the git repository:
git clone https://github.com/srvrco/getssl.git
For Arch Linux there are packages in the AUR, see here and there.
If you use puppet, there is a GetSSL Puppet module by dthielking
Getting started
Once you have obtained the script (see Installation above), the next
step is to use
./getssl -c yourdomain.com
where yourdomain.com is the primary domain name that you want to create
a certificate for. This will create the following folders and files.
~/.getssl
~/.getssl/getssl.cfg
~/.getssl/yourdomain.com
~/.getssl/yourdomain.com/getssl.cfg
You can then edit ~/.getssl/getssl.cfg to set the values you want as the
default for the majority of your certificates.
Then edit ~/.getssl/yourdomain.com/getssl.cfg to have the values you
want for this specific domain (make sure to uncomment and specify
correct ACL option, since it is required).
You can then just run:
getssl yourdomain.com
and it should run, providing output like:
Registering account
Verify each domain
Verifying yourdomain.com
Verified yourdomain.com
Verifying www.yourdomain.com
Verified www.yourdomain.com
Verification completed, obtaining certificate.
Certificate saved in /home/user/.getssl/yourdomain.com/yourdomain.com.crt
The intermediate CA cert is in /home/user/.getssl/yourdomain.com/chain.crt
copying domain certificate to ssh:server5:/home/yourdomain/ssl/domain.crt
copying private key to ssh:server5:/home/yourdomain/ssl/domain.key
copying CA certificate to ssh:server5:/home/yourdomain/ssl/chain.crt
reloading SSL services
THIS WILL (BY DEFAULT) USE THE STAGING SERVER, SO SHOULD GIVE YOU A
CERTIFICATE THAT ISN’T TRUSTED ( FAKE LET’S ENCRYPT). Change the server
in your config file to get a fully valid certificate.
NOTE: Verification is done via port 80 (http), port 443 (https) or dns.
The certificate can be used (and checked with getssl) on alternate
ports.
Detailed guide to getting started with more examples
Guide to getting a certificate for example.com and www.example.com
Wildcard certificates
getssl supports creating wildcard certificates, i.e. __.example.com_
which allows a single certificate to be used for any domain under
_example.com_, e.g. _www.example.com_, _mail.example.com*. These must be
validated using the dns-01 method.
A _partial_ example getssl.cfg file is:
VALIDATE_VIA_DNS=true
export CPANEL_USERNAME=''
export CPANEL_URL='https://www.cpanel.host:2083'
export CPANEL_APITOKEN='1ABC2DEF3GHI4JKL5MNO6PQR7STU8VWX9YZA'
DNS_ADD_COMMAND=/home/root/getssl/dns_scripts/dns_add_cpanel
DNS_DEL_COMMAND=/home/root/getssl/dns_scripts/dns_del_cpanel
ISPConfig
There is a need to create a remote user in ISPConfig to enable the
remote API access.
You need to go to System -> Remote Users and then enable the features
for the remote user such as DNS zone functions.
PHP is required to exeucte soap functions in file ispconfig_soap.php.
DNS_ADD_COMMAND="/home/root/getssl/dns_scripts/dns_add_ispconfig"
DNS_DEL_COMMAND="/home/root/getssl/dns_scripts/dns_del_ispconfig"
export ISPCONFIG_REMOTE_USER_NAME="ussename"
export ISPCONFIG_REMOTE_USER_PASSWORD="password"
export ISPCONFIG_SOAP_LOCATION="https://localhost:8080/remote/index.php"
export ISPCONFIG_SOAP_URL="https://localhost:8080/remote/"
Create the wildcard certificate (need to use quotes to prevent
globbing):
getssl "*.example.domain"
You can renew the certificate using getssl -a to renew all configured
certificates.
You can also specify additional domains in the SANS line, e.g.
SANS="www.test.example.com". This cannot contain any of the domains
which would be covered by the wildcard certificate.
Automating updates
I use the following CRON job
23 5 * * * /root/scripts/getssl -u -a -q
The cron will automatically update getssl and renew any certificates,
only giving output if there are issues / errors.
- The -u flag updates getssl if there is a more recent version
available.
- The -a flag automatically renews any certificates that are due for
renewal.
- The -q flag is “quiet” so that it only outputs and emails me if
there was an error / issue.
Structure
The design aim was to provide flexibility in running the code. The
default working directory is ~/.getssl (which can be modified via the
command line).
Within the WORKING DIRECTORY is a config file getssl.cfg which is a
simple bash file containing variables, an example of which is:
# Uncomment and modify any variables you need
# The staging server is best for testing (hence set as default)
CA="https://acme-staging-v02.api.letsencrypt.org"
# This server issues full certificates, however has rate limits
#CA="https://acme-v02.api.letsencrypt.org"
AGREEMENT="https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf"
# Set an email address associated with your account - generally set at account level rather than domain.
ACCOUNT_EMAIL="me@example.com"
ACCOUNT_KEY_LENGTH=4096
ACCOUNT_KEY="/home/user/.getssl/account.key"
PRIVATE_KEY_ALG="rsa"
# The time period within which you want to allow renewal of a certificate - this prevents hitting some of the rate limits.
RENEW_ALLOW="30"
# openssl config file. The default should work in most cases.
SSLCONF="/usr/lib/ssl/openssl.cnf"
then, within the WORKING DIRECTORY there will be a folder for each
certificate (based on its domain name). Within that folder will be a
config file (again called getssl.cfg). An example of which is:
# Uncomment and modify any variables you need
# see https://github.com/srvrco/getssl/wiki/Config-variables for details
# see https://github.com/srvrco/getssl/wiki/Example-config-files for example configs
#
# The staging server is best for testing
#CA="https://acme-staging-v02.api.letsencrypt.org"
# This server issues full certificates, however has rate limits
#CA="https://acme-v02.api.letsencrypt.org"
#AGREEMENT="https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf"
PRIVATE_KEY_ALG="rsa"
# Additional domains - this could be multiple domains / subdomains in a comma separated list
SANS="www.example.org"
# Acme Challenge Location. The first line for the domain, the following ones for each additional domain.
# If these start with ssh: then the next variable is assumed to be the hostname and the rest the location.
# An ssh key will be needed to provide you with access to the remote server.
# Optionally, you can specify a different userid for ssh/scp to use on the remote server before the @ sign.
# If left blank, the username on the local server will be used to authenticate against the remote server.
# If these start with ftp: then the next variables are ftpuserid:ftppassword:servername:ACL_location
# These should be of the form "/path/to/your/website/folder/.well-known/acme-challenge"
# where "/path/to/your/website/folder/" is the path, on your web server, to the web root for your domain.
#ACL=('/var/www/${DOMAIN}/web/.well-known/acme-challenge'
# 'ssh:server5:/var/www/${DOMAIN}/web/.well-known/acme-challenge'
# 'ssh:sshuserid@server5:/var/www/${DOMAIN}/web/.well-known/acme-challenge'
# 'ftp:ftpuserid:ftppassword:${DOMAIN}:/web/.well-known/acme-challenge')
# Location for all your certs, these can either be on the server (so full path name) or using ssh as for the ACL
DOMAIN_CERT_LOCATION="ssh:server5:/etc/ssl/domain.crt"
DOMAIN_KEY_LOCATION="ssh:server5:/etc/ssl/domain.key"
#CA_CERT_LOCATION="/etc/ssl/chain.crt"
#DOMAIN_CHAIN_LOCATION="" this is the domain cert and CA cert
#DOMAIN_PEM_LOCATION="" this is the domain_key. domain cert and CA cert
# The command needed to reload apache / nginx or whatever you use.
# Several (ssh) commands may be given using a bash array:
# RELOAD_CMD=('ssh:sshuserid@server5:systemctl reload httpd' 'logger getssl for server5 efficient.')
RELOAD_CMD="service apache2 reload"
# Define the server type. This can be https, ftp, ftpi, imap, imaps, pop3, pop3s, smtp,
# smtps_deprecated, smtps, smtp_submission, xmpp, xmpps, ldaps or a port number which
# will be checked for certificate expiry and also will be checked after
# an update to confirm correct certificate is running (if CHECK_REMOTE) is set to true
#SERVER_TYPE="https"
#CHECK_REMOTE="true"
If a location for a file starts with ssh: it is assumed the next part of
the file is the hostname, followed by a colon, and then the path. Files
will be securely copied using scp, and it assumes that you have a key on
the server (for passwordless access). You can set the user, port etc for
the server in your .ssh/config file.
If an ACL starts with ftp: or sftp: it as assumed that the line is in
the format “ftp:UserID:Password:servername:/path/to/acme-challenge”.
sftp requires sshpass. Note: FTP can be used for copying tokens only and
can NOT be used for uploading private key or certificates as it’s not a
secure method of transfer.
ssh can also be used for the reload command if using on remote servers.
Multiple locations can be defined for a file by separating the locations
with a semi-colon.
A typical config file for example.com and www.example.com on the same
server would be:
# uncomment and modify any variables you need
# The staging server is best for testing
CA="https://acme-staging-v02.api.letsencrypt.org"
# This server issues full certificates, however has rate limits
#CA="https://acme-v02.api.letsencrypt.org"
# additional domains - this could be multiple domains / subdomains in a comma separated list
SANS="www.example.com"
#Acme Challenge Location. The first line for the domain, the following ones for each additional domain
ACL=('/var/www/example.com/web/.well-known/acme-challenge')
USE_SINGLE_ACL="true"
DOMAIN_CERT_LOCATION="/etc/ssl/example.com.crt"
DOMAIN_KEY_LOCATION="/etc/ssl/example.com.key"
CA_CERT_LOCATION="/etc/ssl/example.com.bundle"
RELOAD_CMD="service apache2 reload"
Server-Types
OpenSSL has built-in support for getting the certificate from a number
of SSL services these are available in getssl to check if the
certificate is installed correctly
Server-Type Port Extra
------------------ ------ --------------
https 443
ftp 21 FTP Explicit
ftpi 990 FTP Implicit
imap 143 StartTLS
imaps 993
pop3 110 StartTLS
pop3s 995
smtp 25 StartTLS
smtps_deprecated 465
smtps 587 StartTLS
smtp_submission 587 StartTLS
xmpp 5222 StartTLS
xmpps 5269
ldaps 636
port number
Revoke a certificate
In general revoking a certificate is not required.
Usage: getssl -r path/to/cert path/to/key [CA_server]
You need to specify both the certificate you want to revoke, and the
account or private domain key which was used to sign / obtain the
original certificate. The CA_server is an optional parameter and
defaults to Let’s Encrypt (“https://acme-v02.api.letsencrypt.org”) as
that is currently the only Certificate Authority using the ACME
protocol.
Elliptic curve keys
You can use Elliptic curve keys for both the account key and the domain
key (different of course, don’t use the same key for both). prime256v1
(NIST P-256) and secp384r1 (NIST P-384) are both fully supported.
secp521r1 (NIST P-521) is included in the code, but not currently
supported by Let’s Encrypt).
Preferred Chain
If a CA offers multiple chains then it is possible to select which chain
is used by using the PREFERRED_CHAIN variable in getssl.cfg or
specifying --preferred-chain in the call to getssl
This uses wildcard matching so requesting “X1” returns the first
certificate returned by the CA which contains the text “X1”, Note you
may need to escape any characters which special characters, e.g.
PREFERRED_CHAIN="\(STAGING\) Doctored Durian Root CA X3"
- Staging options are: “(STAGING) Doctored Durian Root CA X3” and
“(STAGING) Pretend Pear X1”
- Production options are: “ISRG Root X1” and “ISRG Root X2”
Include Root certificate in full chain
Some servers, including those that use Java keystores, will not accept a
server certificate if it cannot valid the full chain of signers.
Specifically, Nutanix Prism (Element and Central) will not accept the
fullchain.crt until the root CA’s certificate has been appended to it
manually.
If your application requires the full chain, i.e. including the root
certificate of the CA, then this can be included in the fullchain.crt
file by adding the following line to getssl.cfg
FULL_CHAIN_INCLUDE_ROOT="true"
Windows Server and IIS Support
SYSTEM AND SOFTWARE REQUIREMENTS:
- Windows Server with DNS and IIS services
- One of
- WSL Windows Sub for Linux
- Ubuntu or any other distro
- gettssl can be installed inside WSL or using /mnt/ path to
windows
- Bash - gettssl should be installed in Windows
- Git Bash - https://git-scm.com/downloads
- Rtools4.0 - https://cran.r-project.org/bin/windows/Rtools/
WSL
- Installing and configuring WSL 2
- Add remove Windows features and choose “Windows for sub Linux”
- Install a distro like Ubuntu or any other Linux platform
- If newly added to the system a reboot is required to
continue
- wsl –install -d ubuntu
- Any user will work
- Copying files to WSL
- From Windows open Windows Explorer and browse to
\\wsl$\Ubuntu\home\user\ and then place the getssl files
and folders .getssl and getssl into users home directory
\\wsl$\Ubuntu\home\user\.getssl . or in Windows
- Open cmd in Widnows and type
wsl -d Ubuntu /bin/bash /home/UserName/getssl/getssl domain.eu && exit
- Using a specific distro if not set as default in WSL then
use the wsl -d distro command
NOTES:
- While configuring WSL please do check the /etc/hosts file if the
IP of the domain is correct since it overrides the DNS server.
- Make sure running version 2.
GIT BASH - MINGW64_NT
- Install git GIT Bash
- "C:\Program Files\Git\bin\bash.exe" --login -i -- path_to/getssl/getssl domain.eu
RTOOLS BASH - MSYS_NT
- Make sure that the path of \rtools42\usr\bin in Windows system
environment variables is right before c:\windows\system32\ so that
getssl will use the Rtools applications instead of Windows
applications such as sort.exe that crashes or speify full path to
sort.
- \rtools42\usr\bin\bash.exe \Users\Administrator\getssl\getssl domain.eu 2>&1 1>out.txt
UPDATING DNS TXT RECORDS
- Using PowerShell to add and delete _acme-challenge records
- dns_add_windows_dnsserver
- dns_del_windows_dnsserver
NOTES: The script supports optional second level TLDs.
sub.domain.co.uk You can update the reqexp .(co|com).uk to fit your
needs.
IIS INTERNET INFORMATION SERVICE
- Under folder other_scripts you can find a PowerSheell script
iis_install_certeficate.ps1 which generates PFX certificate to be
installed in IIS and binds the domains to the PFX certificate.
- WSL
- RELOAD_CMD=("powershell.exe -ExecutionPolicy Bypass -File "\\\\wsl$\\Ubuntu\\home\\user\\getssl\\other_scripts\\iis_install_certeficate.ps1" "domain.eu" "IIS SiteName" "\\\\wsl$\\Ubuntu\\home\\user\\ssl\\" "path_to_ssl_dir" )
- GIT and Rtools4 Bash
- RELOAD_CMD=("powershell.exe /c/Users/Administrator/getssl/other_scripts/iis_install_certeficate.ps1 domain.eu domain path_to_ssl_dir")
Building as an RPM Package
In order to build getssl as an RPM, the program must be compressed into
a tar.gz file and the tar.gz file named to match the versioning
information contained in the associated .spec file.
Spec files are special files which contain instructions on how to build
a particular package from a source code archive. On Red Hat, CentOS,
Oracle Linux, and AWS Linux systems, RPMS are built in the
/root/rpmbuild/ top directory. SuSe systems build RPMS in the
/usr/src/packages/ as top directory. These “top directories” will
contain BUILD, BUILDROOT, SPECS, RPMS, SRPMS, and SOURCES
subdirectories.
The SPECS directory contains the *.spec files used to build RPMS and
SRPMS packages. The SOURCES subdirectory will contain the soure code
archive file referred to in the *.spec file used to build the RPM
package.
See the Quick Start Guide on instructions for installing the source rpm
which installs both the .spec file and source archive file (tar.gz) into
the rpm build top directory (i.e. /root/rpmbuild/). You should have
previously installed the src.rpm file before attempting to build the
rpm. You can also manually install the .spec file into the <top
directory>/SPECS/ directory and the source code tarball in the <top
directory/SOURCES/ directory, then attempt to build the rpm package.
To build getssl using the rpm tool, change directories (cd) into the
/root/rpmbuild/SPECS/ directory (/usr/src/packages/SPECS/ for SuSe) and
enter the following command:
rpmbuild -ba getssl.spec <enter>
The program should output the following if the build is successful and
verify that the program wrote both the RPMS and SRPMS packages:
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.BYQw0V
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd /root/rpmbuild/BUILD
+ rm -rf getssl-2.47
+ /usr/bin/gzip -dc /root/rpmbuild/SOURCES/getssl-2.47.tar.gz
+ /usr/bin/tar -xof -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd getssl-2.47
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.xpA456
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd getssl-2.47
+ exit 0
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.zQs24R
+ umask 022
+ cd /root/rpmbuild/BUILD
+ '[' /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64 '!=' / ']'
+ rm -rf /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64
++ dirname /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64
+ mkdir -p /root/rpmbuild/BUILDROOT
+ mkdir /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64
+ cd getssl-2.47
+ '[' -n /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64 -a /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64 '!=' / ']'
+ /usr/bin/rm -rf /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64
+ /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/bin
+ /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts
+ /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/other_scripts
+ /usr/bin/make DESTDIR=/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64 install
mkdir -p /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64
install -Dvm755 getssl /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/bin/getssl
'getssl' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/bin/getssl'
install -dvm755 /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl
for dir in *_scripts; do install -dv /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/$dir; install -pv $dir/* /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/$dir/; done
'dns_scripts/Azure-README.txt' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/Azure-README.txt'
'dns_scripts/Cloudflare-README.md' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/Cloudflare-README.md'
'dns_scripts/DNS_IONOS.md' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/DNS_IONOS.md'
'dns_scripts/DNS_ROUTE53.md' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/DNS_ROUTE53.md'
'dns_scripts/GoDaddy-README.txt' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/GoDaddy-README.txt'
'dns_scripts/dns_add_acmedns' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_acmedns'
'dns_scripts/dns_add_azure' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_azure'
'dns_scripts/dns_add_challtestsrv' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_challtestsrv'
'dns_scripts/dns_add_clouddns' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_clouddns'
'dns_scripts/dns_add_cloudflare' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_cloudflare'
'dns_scripts/dns_add_cpanel' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_cpanel'
'dns_scripts/dns_add_del_aliyun.sh' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_del_aliyun.sh'
'dns_scripts/dns_add_dnspod' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_dnspod'
'dns_scripts/dns_add_duckdns' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_duckdns'
'dns_scripts/dns_add_dynu' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_dynu'
'dns_scripts/dns_add_godaddy' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_godaddy'
'dns_scripts/dns_add_hostway' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_hostway'
'dns_scripts/dns_add_ionos' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_ionos'
'dns_scripts/dns_add_ispconfig' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_ispconfig'
'dns_scripts/dns_add_joker' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_joker'
'dns_scripts/dns_add_lexicon' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_lexicon'
'dns_scripts/dns_add_linode' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_linode'
'dns_scripts/dns_add_manual' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_manual'
'dns_scripts/dns_add_nsupdate' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_nsupdate'
'dns_scripts/dns_add_ovh' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_ovh'
'dns_scripts/dns_add_pdns-mysql' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_pdns-mysql'
'dns_scripts/dns_add_vultr' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_vultr'
'dns_scripts/dns_add_windows_dns_server' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_add_windows_dns_server'
'dns_scripts/dns_del_acmedns' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_acmedns'
'dns_scripts/dns_del_azure' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_azure'
'dns_scripts/dns_del_challtestsrv' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_challtestsrv'
'dns_scripts/dns_del_clouddns' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_clouddns'
'dns_scripts/dns_del_cloudflare' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_cloudflare'
'dns_scripts/dns_del_cpanel' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_cpanel'
'dns_scripts/dns_del_dnspod' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_dnspod'
'dns_scripts/dns_del_duckdns' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_duckdns'
'dns_scripts/dns_del_dynu' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_dynu'
'dns_scripts/dns_del_godaddy' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_godaddy'
'dns_scripts/dns_del_hostway' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_hostway'
'dns_scripts/dns_del_ionos' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_ionos'
'dns_scripts/dns_del_ispconfig' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_ispconfig'
'dns_scripts/dns_del_joker' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_joker'
'dns_scripts/dns_del_lexicon' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_lexicon'
'dns_scripts/dns_del_linode' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_linode'
'dns_scripts/dns_del_manual' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_manual'
'dns_scripts/dns_del_nsupdate' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_nsupdate'
'dns_scripts/dns_del_ovh' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_ovh'
'dns_scripts/dns_del_pdns-mysql' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_pdns-mysql'
'dns_scripts/dns_del_vultr' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_vultr'
'dns_scripts/dns_del_windows_dns_server' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_del_windows_dns_server'
'dns_scripts/dns_freedns.sh' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_freedns.sh'
'dns_scripts/dns_godaddy' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_godaddy'
'dns_scripts/dns_route53.py' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/dns_route53.py'
'dns_scripts/ispconfig_soap.php' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/dns_scripts/ispconfig_soap.php'
'other_scripts/cpanel_cert_upload' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/other_scripts/cpanel_cert_upload'
'other_scripts/iis_install_certeficate.ps1' -> '/root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/usr/share/getssl/other_scripts/iis_install_certeficate.ps1'
+ install -Dpm 644 /root/rpmbuild/SOURCES/getssl.crontab /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/etc/cron.d/getssl
+ install -Dpm 644 /root/rpmbuild/SOURCES/getssl.logrotate /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64/etc/logrotate.d/getssl
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-ldconfig
/sbin/ldconfig: Warning: ignoring configuration file that cannot be opened: /etc/ld.so.conf: No such file or directory
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/brp-strip /usr/bin/strip
+ /usr/lib/rpm/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
+ /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile '' 1
+ /usr/lib/rpm/brp-python-hardlink
+ /usr/bin/true
Processing files: getssl-2.47-1.noarch
Provides: getssl = 2.47-1
Requires(interp): /bin/sh /bin/sh /bin/sh /bin/sh
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires(pre): /bin/sh
Requires(post): /bin/sh
Requires(preun): /bin/sh
Requires(postun): /bin/sh
Requires: /bin/bash /usr/bin/env
Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64
Wrote: /root/rpmbuild/SRPMS/getssl-2.47-1.src.rpm
Wrote: /root/rpmbuild/RPMS/noarch/getssl-2.47-1.noarch.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.hgma8Q
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd getssl-2.47
+ /usr/bin/rm -rf /root/rpmbuild/BUILDROOT/getssl-2.47-1.x86_64
+ exit 0
Building as a Debian Package
In order to build getssl as a Debian package, the program must be
compressed into a tar.gz file and the tar.gz file named to match the
versioning information contained in the associated .spec file. Spec
files are special files which contain instructions on how to build a
particular package from a source code archive.
Debian Packages can be built using a utility called “debbuild” and use a
top directory structure which is similar to that used by the RPM tool
but using /root/debbuild/ as the “top directory”. These “top
directories” will contain BUILD, BUILDROOT, SPECS, DEBS, SDEBS, and
SOURCES subdirectories and follows a similar layout that is used for RPM
files.
The SPECS directory contains the *.spec files used to build DEB and SDEB
packages. The SOURCES subdirectory will contain the soure code archive
file referred to in the *.spec file used to build the DEB and SDEB
packages.
See the Quick Start Guide on instructions for installing the source SDEB
which installs both the .spec file and source archive file (tar.gz) into
the debbuild top directory (i.e. /root/debbuild/). You should have
previously installed the SDEB file before attempting to build the DEB
package. You can also manually install the .spec file into the <top
directory>/SPECS/ directory and the source code tarball in the <top
directory/SOURCES/ directory, then attempt to build the DEB package.
To build getssl using debbuild, change directories (cd) into the
/root/debbuild/SPECS/ directory and enter the following command:
debbuild -vv -ba getssl.spec <enter>
The program should output the following if the build is successful and
verify that the program wrote both the DEB and SDEB packages:
This is debbuild, version 22.02.1\ndebconfigdir:/usr/lib/debbuild\nsysconfdir:/etc\n
Lua: No Lua module loaded
Executing (%prep): /bin/sh -e /var/tmp/deb-tmp.prep.92007
+ umask 022
+ cd /root/debbuild/BUILD
+ /bin/rm -rf getssl-2.47
+ /bin/gzip -dc /root/debbuild/SOURCES/getssl-2.47.tar.gz
+ /bin/tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd getssl-2.47
+ /bin/chmod -Rf a+rX,u+w,go-w .
+ exit 0
Executing (%build): /bin/sh -e /var/tmp/deb-tmp.build.40956
+ umask 022
+ cd /root/debbuild/BUILD
+ cd getssl-2.47
+ exit 0
Executing (%install): /bin/sh -e /var/tmp/deb-tmp.install.36647
+ umask 022
+ cd /root/debbuild/BUILD
+ cd getssl-2.47
+ '[' -n /root/debbuild/BUILDROOT/getssl-2.47-1.amd64 -a /root/debbuild/BUILDROOT/getssl-2.47-1.amd64 '!=' / ']'
+ /bin/rm -rf /root/debbuild/BUILDROOT/getssl-2.47-1.amd64
+ /bin/mkdir -p /root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/bin
+ /bin/mkdir -p /root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts
+ /bin/mkdir -p /root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/other_scripts
+ /usr/bin/make DESTDIR=/root/debbuild/BUILDROOT/getssl-2.47-1.amd64 install
mkdir -p /root/debbuild/BUILDROOT/getssl-2.47-1.amd64
install -Dvm755 getssl /root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/bin/getssl
'getssl' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/bin/getssl'
install -dvm755 /root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl
for dir in *_scripts; do install -dv /root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/$dir; install -pv $dir/* /root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/$dir/; done
'dns_scripts/Azure-README.txt' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/Azure-README.txt'
'dns_scripts/Cloudflare-README.md' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/Cloudflare-README.md'
'dns_scripts/DNS_IONOS.md' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/DNS_IONOS.md'
'dns_scripts/DNS_ROUTE53.md' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/DNS_ROUTE53.md'
'dns_scripts/GoDaddy-README.txt' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/GoDaddy-README.txt'
'dns_scripts/dns_add_acmedns' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_acmedns'
'dns_scripts/dns_add_azure' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_azure'
'dns_scripts/dns_add_challtestsrv' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_challtestsrv'
'dns_scripts/dns_add_clouddns' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_clouddns'
'dns_scripts/dns_add_cloudflare' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_cloudflare'
'dns_scripts/dns_add_cpanel' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_cpanel'
'dns_scripts/dns_add_del_aliyun.sh' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_del_aliyun.sh'
'dns_scripts/dns_add_dnspod' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_dnspod'
'dns_scripts/dns_add_duckdns' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_duckdns'
'dns_scripts/dns_add_dynu' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_dynu'
'dns_scripts/dns_add_godaddy' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_godaddy'
'dns_scripts/dns_add_hostway' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_hostway'
'dns_scripts/dns_add_ionos' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_ionos'
'dns_scripts/dns_add_ispconfig' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_ispconfig'
'dns_scripts/dns_add_joker' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_joker'
'dns_scripts/dns_add_lexicon' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_lexicon'
'dns_scripts/dns_add_linode' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_linode'
'dns_scripts/dns_add_manual' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_manual'
'dns_scripts/dns_add_nsupdate' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_nsupdate'
'dns_scripts/dns_add_ovh' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_ovh'
'dns_scripts/dns_add_pdns-mysql' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_pdns-mysql'
'dns_scripts/dns_add_vultr' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_vultr'
'dns_scripts/dns_add_windows_dns_server' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_add_windows_dns_server'
'dns_scripts/dns_del_acmedns' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_acmedns'
'dns_scripts/dns_del_azure' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_azure'
'dns_scripts/dns_del_challtestsrv' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_challtestsrv'
'dns_scripts/dns_del_clouddns' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_clouddns'
'dns_scripts/dns_del_cloudflare' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_cloudflare'
'dns_scripts/dns_del_cpanel' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_cpanel'
'dns_scripts/dns_del_dnspod' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_dnspod'
'dns_scripts/dns_del_duckdns' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_duckdns'
'dns_scripts/dns_del_dynu' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_dynu'
'dns_scripts/dns_del_godaddy' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_godaddy'
'dns_scripts/dns_del_hostway' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_hostway'
'dns_scripts/dns_del_ionos' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_ionos'
'dns_scripts/dns_del_ispconfig' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_ispconfig'
'dns_scripts/dns_del_joker' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_joker'
'dns_scripts/dns_del_lexicon' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_lexicon'
'dns_scripts/dns_del_linode' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_linode'
'dns_scripts/dns_del_manual' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_manual'
'dns_scripts/dns_del_nsupdate' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_nsupdate'
'dns_scripts/dns_del_ovh' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_ovh'
'dns_scripts/dns_del_pdns-mysql' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_pdns-mysql'
'dns_scripts/dns_del_vultr' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_vultr'
'dns_scripts/dns_del_windows_dns_server' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_del_windows_dns_server'
'dns_scripts/dns_freedns.sh' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_freedns.sh'
'dns_scripts/dns_godaddy' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_godaddy'
'dns_scripts/dns_route53.py' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/dns_route53.py'
'dns_scripts/ispconfig_soap.php' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/dns_scripts/ispconfig_soap.php'
'other_scripts/cpanel_cert_upload' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/other_scripts/cpanel_cert_upload'
'other_scripts/iis_install_certeficate.ps1' -> '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/usr/share/getssl/other_scripts/iis_install_certeficate.ps1'
+ install -Dpm 644 /root/debbuild/SOURCES/getssl.crontab /root/debbuild/BUILDROOT/getssl-2.47-1.amd64/etc/cron.d/getssl
+ install -Dpm 644 /root/debbuild/SOURCES/getssl.logrotate /root/debbuild/BUILDROOT/getssl-2.47-1.amd64/etc/logrotate.d/getssl
+ exit 0
Checking library requirements...
Executing (package-creation): /bin/sh -e /var/tmp/deb-tmp.pkg.6107 for getssl
+ umask 022
+ cd /root/debbuild/BUILD
+ /usr/bin/fakeroot -- /usr/bin/dpkg-deb -b /root/debbuild/BUILDROOT/getssl-2.47-1.amd64/main /root/debbuild/DEBS/all/getssl_2.47-1_all.deb
dpkg-deb: warning: parsing file '/root/debbuild/BUILDROOT/getssl-2.47-1.amd64/main/DEBIAN/control' near line 10 package 'getssl':
missing 'Maintainer' field
dpkg-deb: warning: ignoring 1 warning about the control file(s)
dpkg-deb: building package 'getssl' in '/root/debbuild/DEBS/all/getssl_2.47-1_all.deb'.
+ exit 0
Executing (%clean): /bin/sh -e /var/tmp/deb-tmp.clean.52780
+ umask 022
+ cd /root/debbuild/BUILD
+ '[' /root/debbuild/BUILDROOT/getssl-2.47-1.amd64 '!=' / ']'
+ /bin/rm -rf /root/debbuild/BUILDROOT/getssl-2.47-1.amd64
+ exit 0
Wrote source package getssl-2.47-1.sdeb in /root/debbuild/SDEBS.
Wrote binary package getssl_2.47-1_all.deb in /root/debbuild/DEBS/all
Issues / problems / help
If you have any issues, please log them at
https://github.com/srvrco/getssl/issues
There are additional help pages on the wiki
If you have any suggestions for improvements then pull requests are
welcomed, or raise an issue.

+ 547
- 31
README.md View File

@ -1,24 +1,31 @@
# getssl <!-- omit in toc -->
![Run all tests](https://github.com/srvrco/getssl/workflows/Run%20all%20tests/badge.svg) ![shellcheck](https://github.com/srvrco/getssl/workflows/shellcheck/badge.svg)
![Run all tests on Pebble](https://github.com/srvrco/getssl/actions/workflows/run-tests-pebble.yml/badge.svg) ![shellcheck](https://github.com/srvrco/getssl/workflows/shellcheck/badge.svg)
Obtain SSL certificates from the letsencrypt.org ACME server. Suitable
for automating the process on remote servers.
## Table of Contents <!-- omit in toc -->
- [Upgrade broken in v2.43](#upgrade-broken-in-v243)
- [Features](#features)
- [Installation](#installation)
- [Overview](#overview)
- [Quick Start Guide](#quick-start-guide)
- [Manual Installation](#manual-installation)
- [Getting started](#getting-started)
- [Detailed guide to getting started with more examples](#detailed-guide-to-getting-started-with-more-examples)
- [Wildcard certificates](#wildcard-certificates)
- [ISPConfig](#ispconfig)
- [Automating updates](#automating-updates)
- [Structure](#structure)
- [Custom template for configuration](#custom-template-for-configuration)
- [Server-Types](#server-types)
- [Revoke a certificate](#revoke-a-certificate)
- [Elliptic curve keys](#elliptic-curve-keys)
- [Preferred Chain](#preferred-chain)
- [Include Root certificate in full chain](#include-root-certificate-in-full-chain)
- [Windows Server and IIS Support](#windows-server-and-iis-support)
- [Building getssl as an RPM Package (Redhat/CentOS/SuSe/Oracle/AWS)](#building-as-an-rpm-package)
- [Building getssl as a Debian Package (Debian/Ubuntu)](#building-as-a-debian-package)
- [Issues / problems / help](#issues--problems--help)
## Upgrade broken in v2.43
@ -57,35 +64,6 @@ The automatic upgrade in v2.43 is broken as the url is incorrect. If you have t
relevant services (e.g. apache/nginx/postfix) can be reloaded.
* **ACME v1 and V2** - Supports both ACME versions 1 and 2 (note ACMEv1 is deprecated and clients will automatically use v2)
## Installation
Since the script is only one file, you can use the following command for
a quick installation of GetSSL only:
```sh
curl --silent https://raw.githubusercontent.com/srvrco/getssl/latest/getssl > getssl ; chmod 700 getssl
```
This will copy the getssl Bash script to the current location and change
the permissions to make it executable for you.
For a more comprehensive installation (e.g. install also helper scripts)
use the provided Makefile with each release tarball. Use the `install`
target.
You'll find the latest version in the git repository:
```sh
git clone https://github.com/srvrco/getssl.git
```
For Arch Linux there are packages in the AUR, see
[here](https://aur.archlinux.org/packages/getssl/) and
[there](https://aur.archlinux.org/packages/getssl-git/).
If you use puppet, there is a [GetSSL Puppet
module](https://github.com/dthielking/puppet_getssl) by dthielking
## Overview
GetSSL was written in standard bash ( so it can be run on a server, a
@ -117,6 +95,114 @@ Options:
--preferred-chain "chain" Use an alternate chain for the certificate
```
## Quick Start Guide
You can download precompiled RPM packages and Debian (DEB) packages from
the [release page](https://github.com/jeffmerkey/getssl/releases) for
this project, or you can manually build and install the program from the git sources.
If you want to manually install the program from scratch with the git sources rather than use the pre-compiled RPMS and DEB packages, or if your target platform does not support Linux RPM or DEB packages, then please skip to the section [Manual Installation](#manual-installation) for instructions on installing the getssl program manually.
Packages are provided in binary and source versions, and can be downloaded and
installed directly or rebuilt. Package types are
Red Hat Package Manager (RPM) packages and Debian (DEB) packages for binary installation and
Source RPM packages (SRPMS) and Debbuild SDEB packages for source code installation.
RPM and DEB packages for each release include a binary architecture specific package
and a source package which can be downloaded and built/rebuilt and which contains the source code.
For example, the release v2.49 contains the following packages in the release section:
### **RPM Based Packages (RedHat, CentOS, SuSe, Oracle Linux, AWS Linux)**
- [getssl-2.49-1.src.rpm](https://github.com/srvrco/getssl/releases/download/2.49/getssl-2.49-1.src.rpm) (source)
- [getssl-2.49-1.noarch.rpm](https://github.com/srvrco/getssl/releases/download/2.49/getssl-2.49-1.noarch.rpm) (binary)
### **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)
### **Installing Binary Packages**
To install the binary package with the rpm package manager for RedHat, CentOS, SuSe, Oracle Linux, or AWS Linux distributions:
```sh
rpm -i getssl-2.49-1.noarch.rpm
```
To deinstall the RPM binary package:
```sh
rpm -e getssl
```
To install the binary package with the Debian dpkg package manager for Debian and Ubuntu Linux distributions:
```sh
dpkg -i getssl_2.49-1_all.deb
```
To deinstall the Debian dpkg binary package:
```sh
dpkg -r getssl
```
### **Installing Source Packages**
To install the source package with the rpm package manager for RedHat, CentOS, SuSe, Oracle Linux, or AWS Linux distributions:
```sh
rpm -i getssl-2.48-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. SuSe platforms install the source code files in /usr/src/packages/)*
To install the source package with the Debbuild package tool for Debian or Ubuntu Linux distributions:
```sh
debbuild -i getssl-2.49-1.sdeb
```
*(Note: Debbuild installs the source code files in /root/debbuild/ as top directory)*
One item of note is that SDEB packages are actually just tar.gz archives renamed with an .sdeb file extension with the files organized into a 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**:
```sh
[root@localhost getssl]$ tar -tvf /root/debbuild/SDEBS/getssl-2.49-1.sdeb
-rw-r--r-- root/root 1772110 2022-10-12 20:42 SOURCES/getssl-2.49.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]$
```
For building or rebuilding RPMS or DEB Packages after you have installed the associated source packages on your platform, refer to the following:
- [Building getssl as an RPM Package (Redhat/CentOS/SuSe/Oracle/AWS)](#building-as-an-rpm-package)
- [Building getssl as a Debian Package (Debian/Ubuntu)](#building-as-a-debian-package)
## Manual Installation
Since the script is only one file, you can use the following command for
a quick installation of GetSSL only:
```sh
curl --silent https://raw.githubusercontent.com/srvrco/getssl/latest/getssl > getssl ; chmod 700 getssl
```
This will copy the getssl Bash script to the current location and change
the permissions to make it executable for you.
For a more comprehensive installation (e.g. install also helper scripts)
use the provided Makefile with each release tarball. Use the `install`
target.
You'll find the latest version in the git repository:
```sh
git clone https://github.com/srvrco/getssl.git
```
For Arch Linux there are packages in the AUR, see
[here](https://aur.archlinux.org/packages/getssl/) and
[there](https://aur.archlinux.org/packages/getssl-git/).
If you use puppet, there is a [GetSSL Puppet
module](https://github.com/dthielking/puppet_getssl) by dthielking
## Getting started
Once you have obtained the script (see Installation above), the next step is to use
@ -193,6 +279,25 @@ DNS_ADD_COMMAND=/home/root/getssl/dns_scripts/dns_add_cpanel
DNS_DEL_COMMAND=/home/root/getssl/dns_scripts/dns_del_cpanel
```
## ISPConfig
There is a need to create a remote user in `ISPConfig` to enable the remote API access.
You need to go to `System -> Remote Users` and then enable the features for the remote user such as `DNS zone functions`.
PHP is required to exeucte soap functions in file ispconfig_soap.php.
```sh
DNS_ADD_COMMAND="/home/root/getssl/dns_scripts/dns_add_ispconfig"
DNS_DEL_COMMAND="/home/root/getssl/dns_scripts/dns_del_ispconfig"
export ISPCONFIG_REMOTE_USER_NAME="ussename"
export ISPCONFIG_REMOTE_USER_PASSWORD="password"
export ISPCONFIG_SOAP_LOCATION="https://localhost:8080/remote/index.php"
export ISPCONFIG_SOAP_URL="https://localhost:8080/remote/"
```
Create the wildcard certificate (need to use quotes to prevent globbing):
```sh
@ -350,6 +455,42 @@ RELOAD_CMD="service apache2 reload"
```
## Custom template for configuration
You can create and customize a template that can be use to generate the `~/.getssl/yourdomain.com/getssl.cfg` config file, instead of the default one.
Create one of fhe following allowed locations, according to your getssl installation:
```sh
/etc/getssl/getssl_default.cfg
/path/of/your/getssl/installation/getssl_default.cfg
~/.getssl/getssl_default.cfg
```
And define the default values, optionally using the dynamic variables, as in the example below:
```sh
# Additional domains - this could be multiple domains / subdomains in a comma separated list
# Note: this is Additional domains - so should not include the primary domain.
SANS="${EX_SANS}"
ACL=('/home/myuser/${DOMAIN}/public_html/.well-known/acme-challenge')
USE_SINGLE_ACL="true"
RELOAD_CMD="sudo /bin/systemctl restart nginx.service"
# Define the server type. This can be https, ftp, ftpi, imap, imaps, pop3, pop3s, smtp,
# smtps_deprecated, smtps, smtp_submission, xmpp, xmpps, ldaps or a port number which
# will be checked for certificate expiry and also will be checked after
# an update to confirm correct certificate is running (if CHECK_REMOTE) is set to true
SERVER_TYPE="https"
#CHECK_REMOTE="true"
CHECK_REMOTE_WAIT="1" # wait 1 second before checking the remote server
```
## Server-Types
OpenSSL has built-in support for getting the certificate from a number of SSL services
@ -371,6 +512,7 @@ these are available in getssl to check if the certificate is installed correctly
| xmpp | 5222 | StartTLS |
| xmpps | 5269 | |
| ldaps | 636 | |
| postgres | 5432 | |
| port number | | |
## Revoke a certificate
@ -422,6 +564,380 @@ adding the following line to `getssl.cfg`
FULL_CHAIN_INCLUDE_ROOT="true"
```
## Windows Server and IIS Support
**System and software requirements**:
- Windows Server with DNS and IIS services
- One of
- WSL Windows Sub for Linux
- Ubuntu or any other distro
- gettssl can be installed inside WSL or using `/mnt/` path to windows
- Bash - gettssl should be installed in Windows
- Git Bash - <https://git-scm.com/downloads>
- Rtools4.0 - <https://cran.r-project.org/bin/windows/Rtools/>
**WSL**
- Installing and configuring WSL 2
- Add remove Windows features and choose "Windows for sub Linux"
- Install a distro like Ubuntu or any other Linux platform
- If newly added to the system a reboot is required to continue
- wsl --install -d ubuntu
- Any user will work
- Copying files to WSL
- From Windows open `Windows Explorer` and browse to `\\wsl$\Ubuntu\home\user\` and then place the getssl files and folders `.getssl` and `getssl` into users home directory `\\wsl$\Ubuntu\home\user\.getssl .` or in Windows
- Open `cmd` in Widnows and type\
`wsl -d Ubuntu /bin/bash /home/UserName/getssl/getssl domain.eu && exit`
- Using a specific distro if not set as default in WSL then use the `wsl -d distro` command
**Notes:**
- While configuring WSL please do check the `/etc/hosts` file if the IP of the domain is correct since it overrides the DNS server.
- Make sure running version 2.
**GIT Bash** - MINGW64_NT
- Install git GIT Bash
- `"C:\Program Files\Git\bin\bash.exe" --login -i -- path_to/getssl/getssl domain.eu`
**Rtools Bash** - MSYS_NT
- Make sure that the path of `\rtools42\usr\bin` in Windows system environment variables is right before `c:\windows\system32\` so that getssl will use the `Rtools` applications instead of Windows applications such as `sort.exe` that crashes or speify full path to sort.
- `\rtools42\usr\bin\bash.exe \Users\Administrator\getssl\getssl domain.eu 2>&1 1>out.txt`
**Updating DNS TXT records**
- Using `PowerShell` to add and delete `_acme-challenge` records
- dns_add_windows_dnsserver
- dns_del_windows_dnsserver
**Notes:** The script supports optional second level `TLDs`. `sub.domain.co.uk` You can update the reqexp `.(co|com).uk` to fit your needs.
**IIS internet information service**
- Under folder `other_scripts` you can find a `PowerSheell` script `iis_install_certeficate.ps1` which generates `PFX` certificate to be installed in `IIS` and binds the domains to the `PFX` certificate.
- WSL
- `RELOAD_CMD=("powershell.exe -ExecutionPolicy Bypass -File "\\\\wsl$\\Ubuntu\\home\\user\\getssl\\other_scripts\\iis_install_certeficate.ps1" "domain.eu" "IIS SiteName" "\\\\wsl$\\Ubuntu\\home\\user\\ssl\\" "path_to_ssl_dir" )`
- GIT and Rtools4 Bash
- `RELOAD_CMD=("powershell.exe /c/Users/Administrator/getssl/other_scripts/iis_install_certeficate.ps1 domain.eu domain path_to_ssl_dir")`
## Building as an RPM Package
In order to build getssl as an RPM, the program must be compressed into a tar.gz
file and the tar.gz file named to match the versioning information contained in the
associated .spec file.
Spec files are special files which contain instructions on how to build a particular package
from a source code archive. On Red Hat, CentOS, Oracle Linux, and AWS Linux systems, RPMS are built in the /root/rpmbuild/ top directory. SuSe systems build RPMS in the /usr/src/packages/ as top directory. These "top directories" will contain BUILD, BUILDROOT, SPECS, RPMS, SRPMS, and SOURCES subdirectories.
The SPECS directory contains the \*.spec files used to build RPMS and SRPMS packages. The SOURCES subdirectory will contain the soure code archive file referred to in the \*.spec file used to build the
RPM package.
See the [Quick Start Guide](#quick-start-guide) on instructions for installing the
source rpm which installs both the .spec file and source archive file (tar.gz) into
the rpm build top directory (i.e. /root/rpmbuild/). You should have previously
installed the src.rpm file before attempting to build the rpm. You can also
manually install the .spec file into the \<top directory\>/SPECS/ directory and
the source code tarball in the \<top directory\/SOURCES/ directory, then attempt
to build the rpm package.
To build getssl using the rpm tool, change directories (cd) into the /root/rpmbuild/SPECS/ directory (/usr/src/packages/SPECS/ for SuSe) and enter the following command:
```sh
rpmbuild -ba getssl.spec <enter>
```
The program should output the following if the build is successful and verify that the program
wrote both the RPMS and SRPMS packages:
```sh
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.BYQw0V
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd /root/rpmbuild/BUILD
+ rm -rf getssl-2.49
+ /usr/bin/gzip -dc /root/rpmbuild/SOURCES/getssl-2.49.tar.gz
+ /usr/bin/tar -xof -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd getssl-2.49
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.xpA456
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd getssl-2.49
+ exit 0
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.zQs24R
+ umask 022
+ cd /root/rpmbuild/BUILD
+ '[' /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64 '!=' / ']'
+ rm -rf /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64
++ dirname /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64
+ mkdir -p /root/rpmbuild/BUILDROOT
+ mkdir /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64
+ cd getssl-2.49
+ '[' -n /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64 -a /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64 '!=' / ']'
+ /usr/bin/rm -rf /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64
+ /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/bin
+ /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts
+ /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/other_scripts
+ /usr/bin/make DESTDIR=/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64 install
mkdir -p /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64
install -Dvm755 getssl /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/bin/getssl
'getssl' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/bin/getssl'
install -dvm755 /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl
for dir in *_scripts; do install -dv /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/$dir; install -pv $dir/* /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/$dir/; done
'dns_scripts/Azure-README.txt' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/Azure-README.txt'
'dns_scripts/Cloudflare-README.md' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/Cloudflare-README.md'
'dns_scripts/DNS_IONOS.md' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/DNS_IONOS.md'
'dns_scripts/DNS_ROUTE53.md' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/DNS_ROUTE53.md'
'dns_scripts/GoDaddy-README.txt' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/GoDaddy-README.txt'
'dns_scripts/dns_add_acmedns' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_acmedns'
'dns_scripts/dns_add_azure' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_azure'
'dns_scripts/dns_add_challtestsrv' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_challtestsrv'
'dns_scripts/dns_add_clouddns' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_clouddns'
'dns_scripts/dns_add_cloudflare' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_cloudflare'
'dns_scripts/dns_add_cpanel' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_cpanel'
'dns_scripts/dns_add_del_aliyun.sh' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_del_aliyun.sh'
'dns_scripts/dns_add_dnspod' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_dnspod'
'dns_scripts/dns_add_duckdns' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_duckdns'
'dns_scripts/dns_add_dynu' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_dynu'
'dns_scripts/dns_add_godaddy' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_godaddy'
'dns_scripts/dns_add_hostway' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_hostway'
'dns_scripts/dns_add_ionos' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_ionos'
'dns_scripts/dns_add_ispconfig' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_ispconfig'
'dns_scripts/dns_add_joker' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_joker'
'dns_scripts/dns_add_lexicon' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_lexicon'
'dns_scripts/dns_add_linode' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_linode'
'dns_scripts/dns_add_manual' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_manual'
'dns_scripts/dns_add_nsupdate' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_nsupdate'
'dns_scripts/dns_add_ovh' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_ovh'
'dns_scripts/dns_add_pdns-mysql' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_pdns-mysql'
'dns_scripts/dns_add_vultr' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_vultr'
'dns_scripts/dns_add_windows_dns_server' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_add_windows_dns_server'
'dns_scripts/dns_del_acmedns' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_acmedns'
'dns_scripts/dns_del_azure' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_azure'
'dns_scripts/dns_del_challtestsrv' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_challtestsrv'
'dns_scripts/dns_del_clouddns' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_clouddns'
'dns_scripts/dns_del_cloudflare' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_cloudflare'
'dns_scripts/dns_del_cpanel' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_cpanel'
'dns_scripts/dns_del_dnspod' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_dnspod'
'dns_scripts/dns_del_duckdns' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_duckdns'
'dns_scripts/dns_del_dynu' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_dynu'
'dns_scripts/dns_del_godaddy' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_godaddy'
'dns_scripts/dns_del_hostway' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_hostway'
'dns_scripts/dns_del_ionos' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_ionos'
'dns_scripts/dns_del_ispconfig' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_ispconfig'
'dns_scripts/dns_del_joker' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_joker'
'dns_scripts/dns_del_lexicon' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_lexicon'
'dns_scripts/dns_del_linode' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_linode'
'dns_scripts/dns_del_manual' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_manual'
'dns_scripts/dns_del_nsupdate' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_nsupdate'
'dns_scripts/dns_del_ovh' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_ovh'
'dns_scripts/dns_del_pdns-mysql' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_pdns-mysql'
'dns_scripts/dns_del_vultr' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_vultr'
'dns_scripts/dns_del_windows_dns_server' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_del_windows_dns_server'
'dns_scripts/dns_freedns.sh' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_freedns.sh'
'dns_scripts/dns_godaddy' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_godaddy'
'dns_scripts/dns_route53.py' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/dns_route53.py'
'dns_scripts/ispconfig_soap.php' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/dns_scripts/ispconfig_soap.php'
'other_scripts/cpanel_cert_upload' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/other_scripts/cpanel_cert_upload'
'other_scripts/iis_install_certeficate.ps1' -> '/root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/usr/share/getssl/other_scripts/iis_install_certeficate.ps1'
+ install -Dpm 644 /root/rpmbuild/SOURCES/getssl.crontab /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/etc/cron.d/getssl
+ install -Dpm 644 /root/rpmbuild/SOURCES/getssl.logrotate /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64/etc/logrotate.d/getssl
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-ldconfig
/sbin/ldconfig: Warning: ignoring configuration file that cannot be opened: /etc/ld.so.conf: No such file or directory
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/brp-strip /usr/bin/strip
+ /usr/lib/rpm/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
+ /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile '' 1
+ /usr/lib/rpm/brp-python-hardlink
+ /usr/bin/true
Processing files: getssl-2.49-1.noarch
Provides: getssl = 2.49-1
Requires(interp): /bin/sh /bin/sh /bin/sh /bin/sh
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires(pre): /bin/sh
Requires(post): /bin/sh
Requires(preun): /bin/sh
Requires(postun): /bin/sh
Requires: /bin/bash /usr/bin/env
Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64
Wrote: /root/rpmbuild/SRPMS/getssl-2.49-1.src.rpm
Wrote: /root/rpmbuild/RPMS/noarch/getssl-2.49-1.noarch.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.hgma8Q
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd getssl-2.49
+ /usr/bin/rm -rf /root/rpmbuild/BUILDROOT/getssl-2.49-1.x86_64
+ exit 0
```
## Building as a Debian Package
In order to build getssl as a Debian package, the program must be compressed into a tar.gz
file and the tar.gz file named to match the versioning information contained in the associated .spec file. Spec files are special files which contain instructions on how to build a particular package from a source code archive.
Debian Packages can be built using a utility called "debbuild" and use a top directory structure which is similar to that used by the RPM tool but using /root/debbuild/ as the "top directory". These "top directories" will contain BUILD, BUILDROOT, SPECS, DEBS, SDEBS, and SOURCES subdirectories and follows a similar layout that is used for RPM files.
The SPECS directory contains the \*.spec files used to build DEB and SDEB packages. The SOURCES subdirectory will contain the soure code archive file referred to in the \*.spec file used to build the
DEB and SDEB packages.
See the [Quick Start Guide](#quick-start-guide) on instructions for installing the
source SDEB which installs both the .spec file and source archive file (tar.gz) into
the debbuild top directory (i.e. /root/debbuild/). You should have previously installed
the SDEB file before attempting to build the DEB package. You can also manually
install the .spec file into the \<top directory\>/SPECS/ directory and the source
code tarball in the \<top directory\/SOURCES/ directory, then attempt to build the
DEB package.
To build getssl using debbuild, change directories (cd) into the /root/debbuild/SPECS/ directory and enter the following command:
```sh
debbuild -vv -ba getssl.spec <enter>
```
The program should output the following if the build is successful and verify that the program
wrote both the DEB and SDEB packages:
```sh
This is debbuild, version 22.02.1\ndebconfigdir:/usr/lib/debbuild\nsysconfdir:/etc\n
Lua: No Lua module loaded
Executing (%prep): /bin/sh -e /var/tmp/deb-tmp.prep.92007
+ umask 022
+ cd /root/debbuild/BUILD
+ /bin/rm -rf getssl-2.49
+ /bin/gzip -dc /root/debbuild/SOURCES/getssl-2.49.tar.gz
+ /bin/tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd getssl-2.49
+ /bin/chmod -Rf a+rX,u+w,go-w .
+ exit 0
Executing (%build): /bin/sh -e /var/tmp/deb-tmp.build.40956
+ umask 022
+ cd /root/debbuild/BUILD
+ cd getssl-2.49
+ exit 0
Executing (%install): /bin/sh -e /var/tmp/deb-tmp.install.36647
+ umask 022
+ cd /root/debbuild/BUILD
+ cd getssl-2.49
+ '[' -n /root/debbuild/BUILDROOT/getssl-2.49-1.amd64 -a /root/debbuild/BUILDROOT/getssl-2.49-1.amd64 '!=' / ']'
+ /bin/rm -rf /root/debbuild/BUILDROOT/getssl-2.49-1.amd64
+ /bin/mkdir -p /root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/bin
+ /bin/mkdir -p /root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts
+ /bin/mkdir -p /root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/other_scripts
+ /usr/bin/make DESTDIR=/root/debbuild/BUILDROOT/getssl-2.49-1.amd64 install
mkdir -p /root/debbuild/BUILDROOT/getssl-2.49-1.amd64
install -Dvm755 getssl /root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/bin/getssl
'getssl' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/bin/getssl'
install -dvm755 /root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl
for dir in *_scripts; do install -dv /root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/$dir; install -pv $dir/* /root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/$dir/; done
'dns_scripts/Azure-README.txt' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/Azure-README.txt'
'dns_scripts/Cloudflare-README.md' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/Cloudflare-README.md'
'dns_scripts/DNS_IONOS.md' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/DNS_IONOS.md'
'dns_scripts/DNS_ROUTE53.md' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/DNS_ROUTE53.md'
'dns_scripts/GoDaddy-README.txt' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/GoDaddy-README.txt'
'dns_scripts/dns_add_acmedns' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_acmedns'
'dns_scripts/dns_add_azure' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_azure'
'dns_scripts/dns_add_challtestsrv' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_challtestsrv'
'dns_scripts/dns_add_clouddns' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_clouddns'
'dns_scripts/dns_add_cloudflare' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_cloudflare'
'dns_scripts/dns_add_cpanel' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_cpanel'
'dns_scripts/dns_add_del_aliyun.sh' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_del_aliyun.sh'
'dns_scripts/dns_add_dnspod' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_dnspod'
'dns_scripts/dns_add_duckdns' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_duckdns'
'dns_scripts/dns_add_dynu' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_dynu'
'dns_scripts/dns_add_godaddy' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_godaddy'
'dns_scripts/dns_add_hostway' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_hostway'
'dns_scripts/dns_add_ionos' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_ionos'
'dns_scripts/dns_add_ispconfig' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_ispconfig'
'dns_scripts/dns_add_joker' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_joker'
'dns_scripts/dns_add_lexicon' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_lexicon'
'dns_scripts/dns_add_linode' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_linode'
'dns_scripts/dns_add_manual' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_manual'
'dns_scripts/dns_add_nsupdate' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_nsupdate'
'dns_scripts/dns_add_ovh' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_ovh'
'dns_scripts/dns_add_pdns-mysql' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_pdns-mysql'
'dns_scripts/dns_add_vultr' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_vultr'
'dns_scripts/dns_add_windows_dns_server' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_add_windows_dns_server'
'dns_scripts/dns_del_acmedns' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_acmedns'
'dns_scripts/dns_del_azure' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_azure'
'dns_scripts/dns_del_challtestsrv' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_challtestsrv'
'dns_scripts/dns_del_clouddns' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_clouddns'
'dns_scripts/dns_del_cloudflare' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_cloudflare'
'dns_scripts/dns_del_cpanel' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_cpanel'
'dns_scripts/dns_del_dnspod' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_dnspod'
'dns_scripts/dns_del_duckdns' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_duckdns'
'dns_scripts/dns_del_dynu' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_dynu'
'dns_scripts/dns_del_godaddy' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_godaddy'
'dns_scripts/dns_del_hostway' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_hostway'
'dns_scripts/dns_del_ionos' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_ionos'
'dns_scripts/dns_del_ispconfig' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_ispconfig'
'dns_scripts/dns_del_joker' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_joker'
'dns_scripts/dns_del_lexicon' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_lexicon'
'dns_scripts/dns_del_linode' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_linode'
'dns_scripts/dns_del_manual' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_manual'
'dns_scripts/dns_del_nsupdate' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_nsupdate'
'dns_scripts/dns_del_ovh' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_ovh'
'dns_scripts/dns_del_pdns-mysql' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_pdns-mysql'
'dns_scripts/dns_del_vultr' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_vultr'
'dns_scripts/dns_del_windows_dns_server' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_del_windows_dns_server'
'dns_scripts/dns_freedns.sh' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_freedns.sh'
'dns_scripts/dns_godaddy' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_godaddy'
'dns_scripts/dns_route53.py' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/dns_route53.py'
'dns_scripts/ispconfig_soap.php' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/dns_scripts/ispconfig_soap.php'
'other_scripts/cpanel_cert_upload' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/other_scripts/cpanel_cert_upload'
'other_scripts/iis_install_certeficate.ps1' -> '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/usr/share/getssl/other_scripts/iis_install_certeficate.ps1'
+ install -Dpm 644 /root/debbuild/SOURCES/getssl.crontab /root/debbuild/BUILDROOT/getssl-2.49-1.amd64/etc/cron.d/getssl
+ install -Dpm 644 /root/debbuild/SOURCES/getssl.logrotate /root/debbuild/BUILDROOT/getssl-2.49-1.amd64/etc/logrotate.d/getssl
+ exit 0
Checking library requirements...
Executing (package-creation): /bin/sh -e /var/tmp/deb-tmp.pkg.6107 for getssl
+ umask 022
+ cd /root/debbuild/BUILD
+ /usr/bin/fakeroot -- /usr/bin/dpkg-deb -b /root/debbuild/BUILDROOT/getssl-2.49-1.amd64/main /root/debbuild/DEBS/all/getssl_2.49-1_all.deb
dpkg-deb: warning: parsing file '/root/debbuild/BUILDROOT/getssl-2.49-1.amd64/main/DEBIAN/control' near line 10 package 'getssl':
missing 'Maintainer' field
dpkg-deb: warning: ignoring 1 warning about the control file(s)
dpkg-deb: building package 'getssl' in '/root/debbuild/DEBS/all/getssl_2.49-1_all.deb'.
+ exit 0
Executing (%clean): /bin/sh -e /var/tmp/deb-tmp.clean.52780
+ umask 022
+ cd /root/debbuild/BUILD
+ '[' /root/debbuild/BUILDROOT/getssl-2.49-1.amd64 '!=' / ']'
+ /bin/rm -rf /root/debbuild/BUILDROOT/getssl-2.49-1.amd64
+ exit 0
Wrote source package getssl-2.49-1.sdeb in /root/debbuild/SDEBS.
Wrote binary package getssl_2.49-1_all.deb in /root/debbuild/DEBS/all
```
## Issues / problems / help
If you have any issues, please log them at <https://github.com/srvrco/getssl/issues>


+ 38
- 0
RELEASE.md View File

@ -0,0 +1,38 @@
# How to do a release of getssl
## Update the version and tag the release
1. git pull
2. git branch -c release_2_nn
3. git switch release_2_nn
4. update VERSION in `getssl` and `getssl.spec`
5. git commit -m"Update version to v2.nn"
6. git tag -a v2.nn
7. git push origin release_2_nn
8. git push --tags
## Manually start the github release-and-package action
1. Build the .deb and .rpm packages
2. create a draft release containing the packages and the release note
3. **IMPORTANT** make sure that the release references tag **v**N.NN otherwise getssl -u fails!
## Can test the .deb file using the following steps
1. Change the status from draft to pre-release
2. Test that the package can be installed using a cloud instance
1. Start an Ubuntu ec2 instance from AWS Console (or Azure or Google Cloud)
2. Or use the instant-ec2.sh script from my Github gist to start an Ubuntu ec2 instance
1. `git clone git@gist.github.com:12c297e0645920c413273c9d15edbc68.git instant-ec2`
2. `./instant-ec2/instant-ec2.sh`
3. download the deb package
`wget https://github.com/srvrco/getssl/releases/download/v2.nn/getssl_2.nn-1_all.deb`
4. install the deb package
`dpkg -i getssl_2.nn-1_all.deb`
5. Check it's installed correctly
`getssl --version`
## Update the latest tag post-release
1. git tag -f -a latest
2. git push --force --tags

+ 48
- 0
common.shrc View File

@ -0,0 +1,48 @@
# Simple cURL wrapper to manage nicely error handling:
#
# * In case of success, just read body from stdout
# * In case of HTTP error (status >= 400), first stderr contains "HTTP status: XXX", then body
# * In case of other error, just print cURL error on stderr
#
# This function requires a temporary file. It's created under ${TEMP_DIR} if defined and not empty.
# Otherwise, it relies on `mktemp` defaults.
#
curl.do() {
local rc=0
local mktemp_opts=( '--suffix=.curl' )
[[ -z "${TEMP_DIR}" ]] || mktemp_opts+=( "--tempdir=${TEMP_DIR}" )
local curl_body_file=''
curl_body_file="$(mktemp "${mktemp_opts[@]}")" || {
rc=$?
echo "Unable to create temporary file for cURL output"
return $rc
} >&2
local curl_opts=(
--output "${curl_body_file}"
--write-out '%{http_code}'
--silent
--show-error
"$@"
)
local http_code=''
http_code="$(curl "${curl_opts[@]}")" || rc=$?
(( http_code < 400 )) || {
(( rc == 0 )) || rc=1
echo "HTTP status: ${http_code}"
} >&2
if [[ $rc == 0 ]]; then
cat "${curl_body_file}" || rc=$?
else
cat "${curl_body_file}" >&2
fi
rm -rf "${curl_body_file}" || {
(( rc == 0 )) || rc=1
echo "Unable to clear temporary file '${curl_body_file}'"
} >&2
return $rc
}

+ 11
- 0
debbuild.patch View File

@ -0,0 +1,11 @@
--- /usr/bin/debbuild 2022-11-11 15:34:22.529876000 +0000
+++ /usr/bin/debbuild.fix 2022-11-11 15:34:53.137410000 +0000
@@ -1956,7 +1956,7 @@
my $srcpkg = shift;
die _('Can\'t install ').$srcpkg."\n" unless $srcpkg =~ /\.sdeb$/;
$srcpkg = abs_path($srcpkg);
- system(expandmacros("cd %{_topdir}; %{__pax} -r -f $srcpkg)")) == 0 and
+ system(expandmacros("cd %{_topdir}; %{__pax} -r -f $srcpkg")) == 0 and
$finalmessages .= _('Extracted source package ').$srcpkg.
_(" to %{_topdir}.\n");
} # end install_sdeb()

+ 8
- 4
dns_scripts/Cloudflare-README.md View File

@ -38,14 +38,18 @@ Cloudflare provides a template for creating an API Token with access to edit
zone records. Tokens must be created with at least '**DNS:Edit** permissions
for the domain to add/delete records.
The API requires higher privileges to be able to list zones, therefore this
method also requires the **Zone ID** from the Overview tab in the Cloudflare
Dashboard.
Set the following options in the domain-specific `getssl.cfg`
```
export CF_API_TOKEN="..."
```
By default, the associated **Zone ID** is searched automatically. However, it
is also possible to configure the Zone ID manually. This might be necessary
if there are a lot of zones. You can find the Zone ID at the Overview tab in
the Cloudflare Dashboard.
```
export CF_ZONE_ID="..."
```


+ 22
- 12
dns_scripts/dns_add_acmedns View File

@ -1,19 +1,31 @@
#!/usr/bin/env bash
. "$(dirname "${BASH_SOURCE}")/../common.shrc" || {
echo "Unable to load shared Bash code"
exit 1
} >&2
# ACMEDNS env variables can be set in a config file at domain level
acme_config="$DOMAIN_DIR/acme-dns.cfg"
[ -s "$acme_config" ] && . "$acme_config"
# Need to add your API user and key below or set as env variable
apiuser=${ACMEDNS_API_USER:-''}
apikey=${ACMEDNS_API_KEY:-''}
apisubdomain=${ACMEDNS_SUBDOMAIN:-''}
# This script adds a token to acme-dns.io DNS for the ACME challenge
# usage dns_add_acme-dns "domain name" "token"
# return codes are;
# This script adds a token to an ACME DNS (default to acme-dns.io) for the ACME challenge
# usage: dns_add_acme-dns "domain name" "token"
# return codes are:
# 0 - success
# 1 - error returned from server
fulldomain="${1}"
token="${2}"
API='https://auth.acme-dns.io/update'
# You can set the env var ACMEDNS_URL to use a specific ACME-DNS server
# Otherwise we use acme-dns.io
API=${ACMEDNS_URL:-'https://auth.acme-dns.io'}/update
# Check initial parameters
if [[ -z "$fulldomain" ]]; then
@ -42,14 +54,12 @@ generate_post_data()
EOF
}
resp=$(curl --silent \
curl.do \
"${curl_params[@]}" \
-X POST "${API}" \
--data "$(generate_post_data)")
echo $resp
# If adding record failed (returned json includes "error" then print error message
if [[ "$resp" = *"\"error\""* ]]; then
echo "Error: DNS challenge not added: unknown error - ${resp}"
--data "$(generate_post_data)" \
>/dev/null || {
echo 'Error: DNS challenge not added: unknown error'
exit 1
fi
} >&2
exit 0

+ 1
- 1
dns_scripts/dns_add_azure View File

@ -37,4 +37,4 @@ recordset="_acme-challenge.${fulldomain/.$zone_id/}"
# E.g. domain = *.sub.example.com the recordset is _acme-challenge.sub
# domain = example.com the record set is _acme-challenge
[[ "$recordset" == "_acme-challenge.$fulldomain" ]] && recordset="_acme-challenge"
az network dns record-set txt add-record -g "$AZURE_RESOURCE_GROUP" -z "$zone_id" -n "$recordset" -v "$token"
az network dns record-set txt add-record -g "$AZURE_RESOURCE_GROUP" -z "$zone_id" -n "$recordset" --value="$token"

+ 1
- 1
dns_scripts/dns_add_del_aliyun.sh View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
#https://blog.aymar.cn
#https://protocol.aymar.cn
PROGNAME=${0##*/}


+ 7
- 0
dns_scripts/dns_add_dnsmasq View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
# Make sure you enable in the /etc/dnsmasq.conf this line conf-dir=/etc/dnsmasq.d/,*.conf
echo "txt-record=_acme-challenge.\${1},\$2" > /etc/dnsmasq.d/acme-challenge.conf
systemctl restart dnsmasq

+ 1
- 1
dns_scripts/dns_add_dnspod View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# need to add your email address and key to dnspod below
key=${DNSPOD_API_KEY:-}


+ 1
- 1
dns_scripts/dns_add_duckdns View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# need to add your Token for duckdns below
token=${DUCKDNS_TOKEN:-}


+ 1
- 1
dns_scripts/dns_add_godaddy View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Copyright (C) 2017, 2018 Timothe Litt litt at acm _dot org


+ 50
- 0
dns_scripts/dns_add_hetzner View File

@ -0,0 +1,50 @@
#!/usr/bin/env bash
fulldomain="${1}"
token="${2}"
api_url="https://dns.hetzner.com/api/v1"
api_key=${HETZNER_KEY:-''}
zone_id=${HETZNER_ZONE_ID:-''}
zone_name=${HETZNER_ZONE_NAME:-''}
# Verify that required parameters are set
if [[ -z "$fulldomain" ]]; then
echo "DNS script requires full domain name as first parameter"
exit 1
fi
if [[ -z "$token" ]]; then
echo "DNS script requires challenge token as second parameter"
exit 1
fi
if [[ -z "$HETZNER_KEY" ]]; then
echo "HETZNER_KEY variable not set"
exit 1
fi
if [[ -z "$HETZNER_ZONE_ID" && -z "$HETZNER_ZONE_NAME" ]] ; then
echo "HETZNER_ZONE_ID and HETZNER_ZONE_NAME variables not set"
exit 1
fi
# Get Zone ID if not set
if [[ -z "$HETZNER_ZONE_ID" ]] ; then
zone_id=$(curl --silent -X GET "$api_url/zones?name=$zone_name" -H 'Auth-API-Token: '"$api_key"'' | jq -r '.zones[0].id')
if [[ "$zone_id" == "null" ]] ; then
echo "Zone ID not found"
exit 1
fi
fi
txtname="_acme-challenge.$fulldomain."
# Create TXT record
response=$(curl --silent -X POST "$api_url/records" \
-H 'Content-Type: application/json' \
-H "Auth-API-Token: $api_key" \
-d '{"value": "'"$token"'","ttl": 60,"type": "TXT","name": "'"$txtname"'","zone_id": "'"$zone_id"'"}' \
-o /dev/null -w '%{http_code}')
if [[ "$response" != "200" ]] ; then
echo "Record not created"
echo "Response code: $response"
exit 1
fi

+ 86
- 0
dns_scripts/dns_add_hostway View File

@ -0,0 +1,86 @@
#!/usr/bin/env bash
# Need to add your API key below or set as env variable
apikey="$HOSTWAY_API_KEY"
# This script adds a token to dynu.com DNS for the ACME challenge
# usage dns_add_dynu "domain name" "token"
# return codes are;
# 0 - success
# 1 - error in input
# 2 - error within internal processing
# 3 - error in result ( domain not found in dynu.com etc)
fulldomain="${1}"
token="${2}"
API='https://api.hostway.com/dns'
# Check initial parameters
if [[ -z "$fulldomain" ]]; then
echo "DNS script requires full domain name as first parameter"
exit 1
fi
if [[ -z "$token" ]]; then
echo "DNS script requires challenge token as second parameter"
exit 1
fi
curl_params=( -H "accept: application/json" -H "Authorization: Basic $apikey" -H 'Content-Type: application/json charset=utf-8')
# Get domain id
# curl -X GET "https://api.hostway.com/dns/domain/"
resp=$(curl --silent "${curl_params[@]}" -X GET "$API/${fulldomain}")
# Match domain id
re="\"serial\":\s?([^}]*)"
if [[ "$resp" =~ $re ]]; then
domain_id="${BASH_REMATCH[1]}"
fi
if [[ -z "$domain_id" ]]; then
echo 'Domain name not found on your Hostway account'
exit 3
fi
# Check for existing _acme-challenge TXT record
# curl -X GET "https://api.hostway.com/dns/domain/records?filterType=TXT&page=1&pageSize=100"
resp=$(curl --silent "${curl_params[@]}" -X GET "$API/${fulldomain}/records?filterType=TXT")
re="\"id\":\s?([^}]*)"
if [[ "$resp" =~ $re ]]; then
record_id="${BASH_REMATCH[1]}"
fi
if [[ -z "$record_id" ]]; then
# Add new TXT challenge record
# curl -X POST https://api.hostway.com/dns/{domain}/records/{record_id} -d "{\"name\":\"_acme-challenge.{domain}\",\"type\":\"TXT\",\"ttl\":\"300\",\"data\":\"Test2\"}"
# Response is empty when successful
echo "Adding record for ${fulldomain}"
resp=$(curl --silent \
"${curl_params[@]}" \
-X POST "${API}/${fulldomain}/records" \
--data "{\"name\":\"_acme-challenge.${fulldomain}\",\"type\":\"TXT\",\"ttl\":\"300\",\"data\":\"$token\"}")
else
# Update existing record
# curl -X PUT https://api.hostway.com/dns/{domain}/records/{record_id} -d "{\"name\":\"_acme-challenge.{domain}\", \"data\":\"Test2\"}"
echo "Updating record for ${fulldomain}"
resp=$(curl --silent \
"${curl_params[@]}" \
-X PUT "${API}/${fulldomain}/records/${record_id}" \
--data "{\"name\":\"_acme-challenge.${fulldomain}\", \"data\":\"$token\"}")
fi
# Check if response data matches token
re="\"data\":\s?\"([^,]*)\""
if [[ "$resp" =~ $re ]]; then
if [[ ${BASH_REMATCH[1]} == "$token" ]]; then
token_match="$token ${BASH_REMATCH[1]}"
fi
fi
# If adding record failed (exception:) then print error message
if [[ -z "$token_match" && "$resp" != "" ]]; then
echo "Error: DNS challenge not added: unknown error - ${resp}"
exit 3
else
echo "Record added successfully for ${fulldomain}"
fi

+ 1
- 1
dns_scripts/dns_add_ionos View File

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
#
# Called as
#


+ 44
- 0
dns_scripts/dns_add_ispconfig View File

@ -0,0 +1,44 @@
#!/usr/bin/env bash
# Need to add your API key below or set as env variable
CURR_PATH="`dirname \"$0\"`"
ispconfig_user="$ISPCONFIG_REMOTE_USER_NAME"
ispconfig_pass="$ISPCONFIG_REMOTE_USER_PASSWORD"
soap_location="$ISPCONFIG_SOAP_LOCATION"
soap_uri="$ISPCONFIG_SOAP_URL"
# This script adds a token to ispconfig database DNS for the ACME challenge
# usage dns_add_ispconfig "domain name" "token"
# return codes are;
# 0 - success
# 1 - error in input
# 2 - error within internal processing
# 3 - error in result ( domain not found in dynu.com etc)
fulldomain="${1}"
token="${2}"
# Check initial parameters
if [[ -z "$fulldomain" ]]; then
echo "DNS script requires full domain name as first parameter"
exit 1
fi
if [[ -z "$token" ]]; then
echo "DNS script requires challenge token as second parameter"
exit 1
fi
response=$(php $CURR_PATH/ispconfig_soap.php \
--action="add" \
--domain="$fulldomain" \
--token="$token" \
--ispconfig_user="$ispconfig_user" \
--ispconfig_pass="$ispconfig_pass" \
--soap_location="$soap_location" \
--soap_uri="$soap_uri")
echo $response
exit 0

+ 1
- 1
dns_scripts/dns_add_joker View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
FULLDOMAIN=$1
TOKEN=$2


+ 27
- 16
dns_scripts/dns_add_linode View File

@ -1,8 +1,8 @@
#!/bin/bash
#!/usr/bin/env bash
fulldomain="${1}"
token="${2}"
api_url="https://api.linode.com/api/"
api_url="https://api.linode.com/v4"
api_key=${LINODE_KEY:-''}
# Verify that required parameters are set
@ -19,26 +19,37 @@ if [[ -z "$LINODE_KEY" ]]; then
exit 1
fi
domain_root=$(echo "$fulldomain" | awk -F\. '{print $(NF-1) FS $NF}')
domain=${fulldomain%.$domain_root}
txtname="_acme-challenge.$domain"
# Get Domain List
response=$(curl --silent ${api_url}/domains \
-H "User-Agent: getssl/0.1" -H "Authorization: Bearer ${api_key}")
# Get Domain ID
response=$(curl --silent -X POST "$api_url" \
-H "Accept: application/json" -H "User-Agent: getssl/0.1" -H "application/x-www-form-urlencoded" \
-d "api_key=${api_key}&api_action=domain.list" )
domain_id=$(echo "$response" | egrep -o "{\"DOMAIN\":\"$domain_root\".*\"DOMAINID\":([0-9]+)" | egrep -o "[0-9]+$")
if [[ $domain_id == "" ]]; then
# Get Domain ID for longest match
domain_root="$fulldomain"
domain=""
while [[ "$domain_root" == *.* ]] ; do
domain_id=$(echo "$response" | jq ".data[]? | select (.domain==\"$domain_root\") | .id")
if [[ "$domain_id" != "" ]] ; then
break
fi
domain_root=${domain_root#*.}
domain=${fulldomain%.$domain_root}
done
if [[ "$domain_id" == "" ]]; then
echo "Failed to fetch DomainID"
exit 1
fi
txtname="_acme-challenge${domain:+.$domain}"
# Create TXT record
response=$(curl --silent -X POST "$api_url" \
-H "Accept: application/json" -H "User-Agent: getssl/0.1" -H "application/x-www-form-urlencoded" \
-d "api_key=$api_key&api_action=domain.resource.create&DomainID=$domain_id&Type=TXT&Name=$txtname&Target=$token" )
errors=$(echo "$response" | egrep -o "\"ERRORARRAY\":\[.*\]")
if [[ $errors != "\"ERRORARRAY\":[]" ]]; then
response=$(curl --silent -X POST ${api_url}/domains/${domain_id}/records \
-H "Content-Type: application/json" -H "User-Agent: getssl/0.1" -H "Authorization: Bearer ${api_key}" \
-d '{"type": "TXT", "name": "'${txtname}'", "target": "'$token'", "ttl_sec": 30}')
errors=$(echo "$response" | jq ".errors[]?.reason")
if [[ "$errors" != "" ]]; then
echo "Something went wrong: $errors"
exit 1
fi

+ 1
- 1
dns_scripts/dns_add_manual View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
echo "In the DNS, a new TXT record needs to be created for;"
echo "_acme-challenge.${1}"


+ 30
- 0
dns_scripts/dns_add_ns1 View File

@ -0,0 +1,30 @@
#! /usr/bin/env bash
# NS1 Add DNS Record
if [[ -z "$NS1_API_KEY" ]]; then
echo "NS1_API_KEY variable not set"
exit 1
fi
api_url="https://api.nsone.net/v1/"
api_key=${NS1_API_KEY:-''}
domain="$1"
challenge="$2"
root=$(echo "$domain" | awk -F\. '{print $(NF-1) FS $NF}')
subdomain="_acme-challenge.${domain%}"
function create {
curl "${api_url}/zones/${root}/${subdomain}/TXT" -X DELETE \
--header "X-NSONE-Key: $api_key"
curl "${api_url}/zones/${root}/${subdomain}/TXT" -X PUT \
--header "X-NSONE-Key: $api_key" \
--header "Content-Type: application/json" \
--data "{ \"zone\": \"${root}\", \"domain\": \"${subdomain}\", \"type\": \"TXT\", \"answers\": [ { \"answer\": [ \"${challenge}\" ] } ] }"
}
create $root $subdomain

+ 1
- 1
dns_scripts/dns_add_nsupdate View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# example of script to add token to local dns using nsupdate


+ 1
- 1
dns_scripts/dns_add_ovh View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
domains=($(echo "$1"|sed -e 's/^\(\([a-zA-Z0-9.-]*\?\)\.\)*\([a-zA-Z0-9-]\+\.[a-zA-Z-]\+\)$/"\1" _acme-challenge.\2 \3/g'))
challenge="$2"


+ 1
- 1
dns_scripts/dns_add_pdns-mysql View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# You must either have a suitable ~/.my.cnf containing a user / pass
# for your mysql / mariadb database, OR you must uncomment the next line


+ 30
- 0
dns_scripts/dns_add_vultr View File

@ -0,0 +1,30 @@
#! /usr/bin/env bash
# Vultr Add DNS Record
api_url="https://api.vultr.com/v2"
api_key=${VULTR_API_KEY:-''}
domain="$1"
challenge="$2"
root=$(echo "$domain" | awk -F\. '{print $(NF-1) FS $NF}')
subdomain="_acme-challenge.${domain%.$root}"
if [[ -z "$VULTR_API_KEY" ]]; then
echo "VULTR_API_KEY variable not set"
exit 1
fi
function create {
curl "${api_url}/domains/$1/records" -s -o /dev/null -X POST -H "Authorization: Bearer ${VULTR_API_KEY}" -H "Content-Type: application/json" \
--data "{
\"name\" : \"$2\",
\"type\" : \"TXT\",
\"data\" : \"${challenge}\",
\"ttl\" : 300,
\"priority\" : 0
}"
}
create $root $subdomain

+ 39
- 0
dns_scripts/dns_add_windows_dns_server View File

@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Windows DNS server using powershell - dnscmd is going to be deprecated
# Using Windows Sublinux for executing windows commands
# dnscmd command will be depricated use powershell instead
regexp='[A-z0-9]+(\.(co|com))?\.\w+$'
fulldomain=${1}
# Get root domain api.[domain|.co|.uk]
rootdomain=$(echo "${fulldomain}" | grep -Eo "${regexp}")
# Exlude root domain [api].domain.com
subdomain=$(result=$(echo "${fulldomain}" | grep -Po '(.*)(?=\.[A-z0-9]+(\.(co|com))?\.\w+$)') && if [[ ${#result} -gt 0 ]]; then echo ".${result}"; else echo ""; fi)
token=${2}
nloop=1
retries=15 # Sometimes it fails
while [[ ${nloop} -le ${retries} ]]; do
# Add TXT record
echo "Tries ${nloop} out of ${retries}"
echo "Adding acme challenge record for ${fulldomain} with token ${token}"
cmd=(powershell.exe Add-DnsServerResourceRecord -DescriptiveText \'"${token}"\' -Name \'"_acme-challenge${subdomain}"\' -Txt -ZoneName \'"${rootdomain}"\' -TimeToLive 0:0:0:1)
echo "${cmd[@]}"
result_stderr=$({ "${cmd[@]}" ;} 2>&1)
if [[ ${#result_stderr} -eq 0 ]]; then
break
else
echo "${result_stderr}"
fi
nloop=$((nloop+1))
echo "Sleeping 5 seconds"
sleep 5
done

+ 8
- 35
dns_scripts/dns_del_acmedns View File

@ -1,11 +1,11 @@
#!/usr/bin/env bash
# Need to add your API user and key below or set as env variable
apiuser=${ACMEDNS_API_USER:-''}
apikey=${ACMEDNS_API_KEY:-''}
apisubdomain=${ACMEDNS_SUBDOMAIN:-''}
# This script adds a token to acme-dns.io DNS for the ACME challenge
# usage dns_add_acme-dns "domain name" "token"
# This script aims to delete a token to acme-dns DNS for the ACME challenge
# However, for now, acme-dns does not provide a delete API service.
# Its strategy is to update an existing record.
# So this call isn't relevant and must be neutral.
# usage dns_del_acmedns "domain name" "token"
# return codes are;
# 0 - success
# 1 - error returned from server
@ -13,8 +13,6 @@ apisubdomain=${ACMEDNS_SUBDOMAIN:-''}
fulldomain="${1}"
token="${2}"
API='https://auth.acme-dns.io/update'
# Check initial parameters
if [[ -z "$fulldomain" ]]; then
echo "DNS script requires full domain name as first parameter"
@ -25,31 +23,6 @@ if [[ -z "$token" ]]; then
exit 1
fi
curl_params=(
-H "accept: application/json"
-H "X-Api-Key: $apikey"
-H "X-Api-User: $apiuser"
-H 'Content-Type: application/json'
)
generate_post_data()
{
cat <<EOF
{
"subdomain": "$apisubdomain",
"txt": "$token"
}
EOF
}
# nothing to do
resp=$(curl --silent \
"${curl_params[@]}" \
-X POST "${API}" \
--data "$(generate_post_data)")
echo $resp
# If adding record failed (returned json includes "error" then print error message
if [[ "$resp" = *"\"error\""* ]]; then
echo "Error: DNS challenge not added: unknown error - ${resp}"
exit 1
fi
exit 0

+ 7
- 0
dns_scripts/dns_del_dnsmasq View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
# Make sure you enable in the /etc/dnsmasq.conf this line conf-dir=/etc/dnsmasq.d/,*.conf
echo "" > /etc/dnsmasq.d/acme-challenge.conf
systemctl restart dnsmasq

+ 1
- 1
dns_scripts/dns_del_dnspod View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# need to add your email address and key to dnspod below
key=${DNSPOD_API_KEY:-}


+ 1
- 1
dns_scripts/dns_del_duckdns View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# need to add your Token for duckdns below
token=${DUCKDNS_TOKEN:-}


+ 1
- 1
dns_scripts/dns_del_godaddy View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Copyright (C) 2017,2018 Timothe Litt litt at acm _dot org


+ 57
- 0
dns_scripts/dns_del_hetzner View File

@ -0,0 +1,57 @@
#!/usr/bin/env bash
fulldomain="${1}"
token="${2}"
api_url="https://dns.hetzner.com/api/v1"
api_key=${HETZNER_KEY:-''}
zone_id=${HETZNER_ZONE_ID:-''}
zone_name=${HETZNER_ZONE_NAME:-''}
# Verify that required parameters are set
if [[ -z "$fulldomain" ]]; then
echo "DNS script requires full domain name as first parameter"
exit 1
fi
if [[ -z "$token" ]]; then
echo "DNS script requires challenge token as second parameter"
exit 1
fi
if [[ -z "$HETZNER_KEY" ]]; then
echo "HETZNER_KEY variable not set"
exit 1
fi
if [[ -z "$HETZNER_ZONE_ID" && -z "$HETZNER_ZONE_NAME" ]] ; then
echo "HETZNER_ZONE_ID and HETZNER_ZONE_NAME variables not set"
exit 1
fi
# Get Zone ID if not set
if [[ -z "$HETZNER_ZONE_ID" ]] ; then
zone_id=$(curl --silent -X GET "$api_url/zones?name=$zone_name" -H 'Auth-API-Token: '"$api_key"'' | jq -r '.zones[0].id')
if [[ "$zone_id" == "null" ]] ; then
echo "Zone by name not found"
exit 1
fi
fi
# domain_root=$(echo "$fulldomain" | awk -F\. '{print $(NF-1) FS $NF FS}')
# domain=${fulldomain%.$domain_root}
txtname="_acme-challenge.$fulldomain."
record_id=$(curl --silent -X GET "$api_url/records?zone_id=$zone_id" -H "Auth-API-Token: $api_key" | jq -r '.records[] | select(.name=="'"$txtname"'") | .id')
if [[ "$record_id" == "null" ]] ; then
echo "Record not found"
exit 1
fi
# Create TXT record
response=$(curl --silent -X DELETE "$api_url/records/$record_id" -H "Auth-API-Token: $api_key" -o /dev/null -w '%{http_code}')
if [[ "$response" != "200" ]] ; then
echo "Record not deleted"
echo "Response code: $response"
exit 1
fi

+ 66
- 0
dns_scripts/dns_del_hostway View File

@ -0,0 +1,66 @@
#!/usr/bin/env bash
# Need to add your API key below or set as env variable
apikey="$HOSTWAY_API_KEY"
# This script adds a token to dynu.com DNS for the ACME challenge
# usage dns_add_dynu "domain name" "token"
# return codes are;
# 0 - success
# 1 - error in input
# 2 - error within internal processing
# 3 - error in result ( domain not found in dynu.com etc)
fulldomain="${1}"
token="${2}"
API='https://api.hostway.com/dns'
# Check initial parameters
if [[ -z "$fulldomain" ]]; then
echo "DNS script requires full domain name as first parameter"
exit 1
fi
if [[ -z "$token" ]]; then
echo "DNS script requires challenge token as second parameter"
exit 1
fi
curl_params=( -H "accept: application/json" -H "Authorization: Basic $apikey" -H 'Content-Type: application/json charset=utf-8')
# Get domain id
# curl -X GET "https://api.hostway.com/dns/domain/"
resp=$(curl --silent "${curl_params[@]}" -X GET "$API/${fulldomain}")
# Match domain id
re="\"serial\":\s?([^}]*)"
if [[ "$resp" =~ $re ]]; then
domain_id="${BASH_REMATCH[1]}"
fi
if [[ -z "$domain_id" ]]; then
echo 'Domain name not found on your Hostway account'
exit 3
fi
# Check for existing _acme-challenge TXT record
# curl -X GET "https://api.hostway.com/dns/domain/records?filterType=TXT&page=1&pageSize=100"
resp=$(curl --silent "${curl_params[@]}" -X GET "$API/${fulldomain}/records?filterType=TXT")
#re="\"id\":\s?([^}]*)"
re="(?<=_acme(.*)\"id\":\s?)[0-9]+(?=\})"
if [[ "$resp" =~ $re ]]; then
record_id="${BASH_REMATCH[1]}"
fi
if [[ -z "$record_id" ]]; then
echo "Not able to find a record to delete"
else
# Delete existing record
# curl -X DELETE https://api.hostway.com/dns/{domain}/records/{record_id}
resp=$(curl --silent \
"${curl_params[@]}" \
-X DELETE "${API}/${fulldomain}/records/${record_id}")
if [[ "$resp" == "" ]]; then
echo "Record deleted successfully for ${fulldomain}"
fi
fi

+ 1
- 1
dns_scripts/dns_del_ionos View File

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
#
# Called as
#


+ 44
- 0
dns_scripts/dns_del_ispconfig View File

@ -0,0 +1,44 @@
#!/usr/bin/env bash
# Need to add your API key below or set as env variable
CURR_PATH="`dirname \"$0\"`"
ispconfig_user="$ISPCONFIG_REMOTE_USER_NAME"
ispconfig_pass="$ISPCONFIG_REMOTE_USER_PASSWORD"
soap_location="$ISPCONFIG_SOAP_LOCATION"
soap_uri="$ISPCONFIG_SOAP_URL"
# This script adds a token to ispconfig database DNS for the ACME challenge
# usage dns_add_ispconfig "domain name" "token"
# return codes are;
# 0 - success
# 1 - error in input
# 2 - error within internal processing
# 3 - error in result ( domain not found in dynu.com etc)
fulldomain="${1}"
token="${2}"
# Check initial parameters
if [[ -z "$fulldomain" ]]; then
echo "DNS script requires full domain name as first parameter"
exit 1
fi
if [[ -z "$token" ]]; then
echo "DNS script requires challenge token as second parameter"
exit 1
fi
response=$(php $CURR_PATH/ispconfig_soap.php \
--action="del" \
--domain="$fulldomain" \
--token="$token" \
--ispconfig_user="$ispconfig_user" \
--ispconfig_pass="$ispconfig_pass" \
--soap_location="$soap_location" \
--soap_uri="$soap_uri")
echo $response
exit 0

+ 1
- 1
dns_scripts/dns_del_joker View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
FULLDOMAIN=$1
TOKEN=$2


+ 29
- 21
dns_scripts/dns_del_linode View File

@ -1,7 +1,7 @@
#!/bin/bash
#!/usr/bin/env bash
fulldomain="${1}"
api_url="https://api.linode.com/api/"
api_url="https://api.linode.com/v4"
api_key=${LINODE_KEY:-''}
# Verify that required parameters are set
@ -14,36 +14,44 @@ if [[ -z "$LINODE_KEY" ]]; then
exit 1
fi
domain_root=$(echo "$fulldomain" | awk -F\. '{print $(NF-1) FS $NF}')
domain=${fulldomain%.$domain_root}
txtname="_acme-challenge.$domain"
# Get Domain List
response=$(curl --silent ${api_url}/domains \
-H "User-Agent: getssl/0.1" -H "Authorization: Bearer ${api_key}")
# Get Domain ID
response=$(curl --silent -X POST "$api_url" \
-H "Accept: application/json" -H "User-Agent: getssl/0.1" -H "application/x-www-form-urlencoded" \
-d "api_key=${api_key}&api_action=domain.list" )
domain_id=$(echo "$response" | egrep -o "{\"DOMAIN\":\"$domain_root\".*\"DOMAINID\":([0-9]+)" | egrep -o "[0-9]+$")
if [[ $domain_id == "" ]]; then
# Get Domain ID for longest match
domain_root="$fulldomain"
domain=""
while [[ "$domain_root" == *.* ]] ; do
domain_id=$(echo "$response" | jq ".data[]? | select (.domain==\"$domain_root\") | .id")
if [[ "$domain_id" != "" ]] ; then
break
fi
domain_root=${domain_root#*.}
domain=${fulldomain%.$domain_root}
done
if [[ "$domain_id" == "" ]]; then
echo "Failed to fetch DomainID"
exit 1
fi
txtname="_acme-challenge${domain:+.$domain}"
# Get Resource ID
response=$(curl --silent -X POST "$api_url" \
-H "Accept: application/json" -H "User-Agent: getssl/0.1" -H "application/x-www-form-urlencoded" \
-d "api_key=${api_key}&api_action=domain.resource.list&DomainID=$domain_id" )
resource_id=$(echo "$response" | egrep -o "\"RESOURCEID\":[0-9]+,\"TYPE\":\"TXT\",\"NAME\":\"$txtname\"" | egrep -o "\"RESOURCEID\":[0-9]+" | egrep -o "[0-9]+$")
if [[ $resource_id == "" ]]; then
response=$(curl --silent ${api_url}/domains/${domain_id}/records \
-H "User-Agent: getssl/0.1" -H "Authorization: Bearer ${api_key}")
resource_id=$(echo "$response" | jq ".data[] | select (.name==\"$txtname\") | .id")
if [[ "$resource_id" == "" ]]; then
echo "Failed to fetch ResourceID"
exit 1
fi
# Delete TXT record
response=$(curl --silent -X POST "$api_url" \
-H "Accept: application/json" -H "User-Agent: getssl/0.1" -H "application/x-www-form-urlencoded" \
-d "api_key=$api_key&api_action=domain.resource.delete&DomainID=$domain_id&ResourceID=$resource_id" )
errors=$(echo "$response" | egrep -o "\"ERRORARRAY\":\[.*\]")
if [[ $errors != "\"ERRORARRAY\":[]" ]]; then
response=$(curl --silent -X DELETE ${api_url}/domains/${domain_id}/records/${resource_id} \
-H "User-Agent: getssl/0.1" -H "Authorization: Bearer ${api_key}")
errors=$(echo "$response" | jq ".errors[]?.reason")
if [[ "$errors" != "" ]]; then
echo "Something went wrong: $errors"
exit 1
fi

+ 1
- 1
dns_scripts/dns_del_manual View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
echo "In the DNS, the following DNS record should be deleted ;"
echo "_acme-challenge.${1}"


+ 26
- 0
dns_scripts/dns_del_ns1 View File

@ -0,0 +1,26 @@
#! /usr/bin/env bash
# NS1 Add DNS Record
if [[ -z "$NS1_API_KEY" ]]; then
echo "NS1_API_KEY variable not set"
exit 1
fi
api_url="https://api.nsone.net/v1/"
api_key=${NS1_API_KEY:-''}
domain="$1"
challenge="$2"
root=$(echo "$domain" | awk -F\. '{print $(NF-1) FS $NF}')
subdomain="_acme-challenge.${domain%}"
function delete {
curl "${api_url}/zones/${root}/${subdomain}/TXT" -X DELETE \
--header "X-NSONE-Key: $api_key"
}
delete $root $subdomain

+ 1
- 1
dns_scripts/dns_del_nsupdate View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# example of script to remove token from local dns using nsupdate


+ 1
- 1
dns_scripts/dns_del_ovh View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
domains=($(echo "$1"|sed -e 's/^\(\([a-zA-Z0-9.-]*\?\)\.\)*\([a-zA-Z0-9-]\+\.[a-zA-Z-]\+\)$/"\1" _acme-challenge.\2 \3/g'))
#challenge="$2"


+ 1
- 1
dns_scripts/dns_del_pdns-mysql View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# You must either have a suitable ~/.my.cnf containing a user / pass
# for your mysql / mariadb database, OR you must uncomment the next line


+ 26
- 0
dns_scripts/dns_del_vultr View File

@ -0,0 +1,26 @@
#! /usr/bin/env bash
# Vultr Delete DNS Record
# This script requires jq to be installed on the machine running it
api_url="https://api.vultr.com/v2"
api_key=${VULTR_API_KEY:-''}
domain="$1"
root=$(echo "$domain" | awk -F\. '{print $(NF-1) FS $NF}')
subdomain="_acme-challenge.${domain%.$root}"
if [[ -z "$VULTR_API_KEY" ]]; then
echo "VULTR_API_KEY variable not set"
exit 1
fi
function delete {
recordID=$(curl "${api_url}/domains/$1/records" --silent -X GET -H "Authorization: Bearer ${VULTR_API_KEY}" | jq -r ".records[] | select(.name==\"$2\").id")
curl "${api_url}/domains/$1/records/$recordID" -X DELETE -H "Authorization: Bearer ${VULTR_API_KEY}"
}
delete $root $subdomain

+ 39
- 0
dns_scripts/dns_del_windows_dns_server View File

@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Windows DNS server using powershell - dnscmd is going to be deprecated
# Using Windows Sublinux for executing windows commands
# dnscmd command will be depricated use powershell instead
regexp='[A-z0-9]+(\.(co|com))?\.\w+$'
fulldomain=${1}
# Get root domain api.[domain|.co|.uk]
rootdomain=$(echo "${fulldomain}" | grep -Eo "${regexp}")
# Exlude root domain [api].domain.com
subdomain=$(result=$(echo "${fulldomain}" | grep -Po '(.*)(?=\.[A-z0-9]+(\.(co|com))?\.\w+$)') && if [[ ${#result} -gt 0 ]]; then echo ".${result}"; else echo ""; fi)
token=${2}
nloop=1
retries=15 # Sometimes it fails
while [[ ${nloop} -le ${retries} ]]; do
# Delete TXT record
echo "Tries ${nloop} out of ${retries}"
echo "Deleting acme challenge record for ${fulldomain} with token ${token}"
cmd=(powershell.exe Remove-DnsServerResourceRecord -RRType TXT -Name \'"_acme-challenge${subdomain}"\' -ZoneName \'"${rootdomain}"\' -RecordData \'"${token}"\' -Force)
echo "${cmd[@]}"
result_stderr=$({ "${cmd[@]}" ;} 2>&1)
if [[ ${#result_stderr} -eq 0 ]]; then
break
else
echo "${result_stderr}"
fi
nloop=$((nloop+1))
echo "Sleeping 5 seconds"
sleep 5
done

+ 15
- 17
dns_scripts/dns_godaddy View File

@ -1,9 +1,9 @@
#!/bin/bash
#!/usr/bin/env bash
# Copyright (C) 2017,2018 Timothe Litt litt at acm _dot org
VERSION="2.0"
PROG="`basename $0`"
PROG="$(basename "$0")"
# This script is used to update TXT records in GoDaddy DNS server
# It depends on JSON.sh from https://github.com/dominictarr/JSON.sh
@ -27,11 +27,10 @@ GETJSON='https://github.com/dominictarr/JSON.sh'
VERB="y"
DEBUG="$GODADDY_DEBUG"
[ -z "$JSON" ] && JSON="$GODADDY_JSON"
[ -z "$JSON" ] && JSON="`dirname $0`/JSON.sh"
[ -z "$JSON" ] && JSON="$(dirname "$0")/JSON.sh"
while getopts 'dhj:k:s:t:qv' opt; do
case $opt in
b) GODADDY_BASE="$OPTARG" ;;
d) DEBUG="Y" ;;
j) JSON="$OPTARG" ;;
k) GODADDY_KEY="$OPTARG" ;;
@ -73,7 +72,7 @@ Arguments:
Options
-d Provide debugging output - all requests and responses
-h This help.
-j: Location of JSON.sh Default `dirname $0`/JSON.sh, or
-j: Location of JSON.sh Default $(dirname "$0")/JSON.sh, or
the GODADDY_JSON variable.
-k: The GoDaddy API key Default from GODADDY_KEY
-s: The GoDaddy API secret Default from GODADDY_SECRET
@ -112,7 +111,7 @@ shift $((OPTIND-1))
# we assume they'll be deleted later & don't want to strand them.
[[ "$JSON" =~ ^~ ]] && \
eval 'JSON=`readlink -nf ' $JSON '`'
eval 'JSON=`readlink -nf ' "$JSON" '`'
if [ ! -x "$JSON" ]; then
cat <<EOF >&2
$0: requires JSON.sh as "$JSON"
@ -148,7 +147,6 @@ if [ -z "$name" ]; then
echo "'name' parameter is required, see -h" >&2
exit 3
fi
! [[ "$name" =~ [.]$ ]] && name="${name}.${domain}."
data="$3"
if [ -z "$data" ]; then
echo "'data' parameter is required, see -h" >&2
@ -162,7 +160,7 @@ elif [ -z "$5" ]; then
elif ! [[ "$5" =~ ^[0-9]+$ ]]; then
echo "TTL $5 is not numeric" >&2
exit 3
elif [ $5 -lt 600 ]; then
elif [ "$5" -lt 600 ]; then
[ -n "$VERB" ] && \
echo "$5 is less than GoDaddy minimum of 600; increased to 600" >&2
ttl="600"
@ -173,14 +171,14 @@ fi
# --- Done with parameters
[ -n "$DEBUG" ] && \
echo "$PROG: $op $domain $name \"$data\" $ttl" >&2
echo "$PROG: $op $name \"$data\" $ttl" >&2
# Authorization header has secret and key
authhdr="Authorization: sso-key $GODADDY_KEY:$GODADDY_SECRET"
if [ -n "$TRACE" ]; then
function timestamp { local tm="`LC_TIME=C date '+%T.%N'`"
function timestamp { local tm="$(LC_TIME=C date '+%T.%N')"
local class="$1"; shift
echo "${tm:0:15} ** ${class}: $*" >>"$TRACE"
}
@ -264,7 +262,7 @@ EOF
break
fi
code="`echo "$response" | grep '"code":' | sed -e's/^.*"code":"//; s/\".*$//'`"
code="$(echo "$response" | grep '"code":' | sed -e's/^.*"code":"//; s/\".*$//')"
if [ "$code" = 'NOT_FOUND' ]; then
continue
fi
@ -309,11 +307,11 @@ EOF
exit $sts
fi
if ! echo "$result" | grep -q '^HTTP/.* 200 '; then
code="`echo "$result" | grep '"code":' | sed -e's/^.*"code":"//; s/\".*$//'`"
msg="`echo "$result" | grep '"message":' | sed -e's/^.*"message":"//; s/\".*$//'`"
code="$(echo "$result" | grep '"code":' | sed -e's/^.*"code":"//; s/\".*$//')"
msg="$(echo "$result" | grep '"message":' | sed -e's/^.*"message":"//; s/\".*$//')"
if [ "$code" = "DUPLICATE_RECORD" ]; then
if [ -n "$VERB" ]; then
echo "$msg in $domain" >&2
echo "$msg in $reqdomain" >&2
fi
exit 0 # Duplicate record is still success
fi
@ -349,9 +347,9 @@ $current
--------
EOF
if ! echo "$current" | grep -q '^HTTP/.* 200 '; then
code="`echo "$current" | grep '"code":' | sed -e's/^.*"code":"//; s/\".*$//'`"
msg="`echo "$current" | grep '"message":' | sed -e's/^.*"message":"//; s/\".*$//'`"
if ! echo "$current" | grep -q '^HTTP/.* 204 '; then
code="$(echo "$current" | grep '"code":' | sed -e's/^.*"code":"//; s/\".*$//')"
msg="$(echo "$current" | grep '"message":' | sed -e's/^.*"message":"//; s/\".*$//')"
echo "Request failed $msg" >&2
exit 1
fi


+ 140
- 0
dns_scripts/ispconfig_soap.php View File

@ -0,0 +1,140 @@
<?php
$args = getopt("", array("action:", "domain:", "token:", "ispconfig_user:", "ispconfig_pass:", "soap_location:", "soap_uri:"));
$action = $args["action"];
$fulldomain = $args["domain"];
$token = $args["token"];
$soap_location = $args["soap_location"];
$soap_uri = $args["soap_uri"];
$username = $args["ispconfig_user"];
$password = $args["ispconfig_pass"];
$client = new SoapClient(
null,
array(
'location' => $soap_location,
'uri' => $soap_uri,
'trace' => 1,
'exceptions' => 1,
'stream_context' => stream_context_create(
array(
'ssl' =>
array(
'verify_peer' => false,
'verify_peer_name' => false
)
)
)
)
);
try {
if ($session_id = $client->login($username, $password)) {
//echo 'Logged in successfully. Session ID:' . $session_id . '<br />';
}
// Get all zone
$zones = $client->dns_zone_get($session_id, -1);
$zone_id = 0;
$client_id = 0;
$server_id = 0;
foreach ($zones as $zone) {
// Find zone that needs to update
if (preg_match("/" . $zone["origin"] . "/", $fulldomain . ".")) {
$zone_id = $zone["id"];
$sys_userid = $zone["sys_userid"];
$server_id = $zone["server_id"];
}
}
//Get client id
$client_id = $client->client_get_id($session_id, $sys_userid);
if ($client_id == 0) {
exit;
}
// Get all domain records of type txt
// Bug it retrieves all domain records
$dns_records = $client->dns_txt_get($session_id, -1);
$dns_record_id = 0;
foreach ($dns_records as $dns_record) {
if ($dns_record["zone"] == $zone_id && $dns_record["type"] == "TXT" && $dns_record["name"] == "_acme-challenge.{$fulldomain}.") {
$dns_record_id = $dns_record["id"];
}
}
// Add if zero else update
$date = new DateTime();
switch ($action) {
case "add":
if ($dns_record_id == 0) {
$dns_record = array(
"server_id" => $server_id,
"zone" => $zone_id,
"name" => "_acme-challenge.{$fulldomain}.",
"type" => "txt",
"data" => $token,
"aux" => 111,
"ttl" => 300,
"active" => 'y',
"stamp" => date_format($date, 'Y-m-d H:i:s'),
"serial" => date_format($date, 'Ymds')
);
$result = $client->dns_txt_add($session_id, $client_id, $dns_record);
echo "Created record for domain {$fulldomain} with token $token\n";
} else {
$dns_record["data"] = $token;
$dns_record["stamp"] = date_format($date, 'Y-m-d H:i:s');
$dns_record["serial"] = date_format($date, 'YmdH');
$result = $client->dns_txt_update($session_id, $client_id, $dns_record_id, $dns_record);
echo "Updated the record for domain {$fulldomain} with token $token\n";
}
break;
case "del":
if ($dns_record_id > 0) {
$result = $client->dns_txt_delete($session_id, $dns_record_id);
if ($result) {
echo "The record was deleted from domain {$fulldomain} successfully\n";
} else {
echo "Failed to delete the record for domain {$fulldomain}\n";
}
} else {
echo "The record was not found for deletion\n";
}
break;
default:
echo "No action was specified as parameter\n";
break;
}
if ($client->logout($session_id)) {
//echo 'Logged out.<br />';
}
} catch (SoapFault $e) {
echo $client->__getLastResponse();
die('SOAP Error: ' . $e->getMessage());
}

+ 191
- 100
getssl View File

@ -279,6 +279,17 @@
# 2021-10-22 Copy fullchain to DOMAIN_CHAIN_LOCATION (amartin-git)
# 2021-11-10 Detect Solaris and use gnu tools (#701)(miesi)
# 2021-11-12 Support acme-dns and fix CNAME issues (#722)(#308)
# 2021-12-14 Enhancements for GoDaddy (support more levels of domain names, no longer require GODADDY_BASE, and actual deletion of resource records)
# 2021-12-22 Don't show usage if run with --upgrade (#728)
# 2021-12-23 Don't use +idnout if dig shows a warning (#688)
# 2022-01-06 Support --account-id (#716)(2.46)
# 2022-03-09 Support for ISPConfig API
# 2022-05-03 Windows Server and IIS support (2.47)
# 2022-05-18 Add FTP_ARGS
# 2022-11-01 Add FTP_PORT
# 2023-02-04 Create newline to ensure [SAN] section can be parsed (#792)(MRigal)
# 2023-02-22 Remove cronie from deb package dependencies (2.48)
# 2024-03-18 Refresh the TXT record if a CNAME is found (JoergBruce #828) (2.49)
# ----------------------------------------------------------------------------------------
case :$SHELLOPTS: in
@ -287,7 +298,7 @@ esac
PROGNAME=${0##*/}
PROGDIR="$(cd "$(dirname "$0")" || exit; pwd -P;)"
VERSION="2.45"
VERSION="2.49"
# defaults
ACCOUNT_KEY_LENGTH=4096
@ -312,6 +323,8 @@ DOMAIN_KEY_LENGTH=4096
DUAL_RSA_ECDSA="false"
FTP_OPTIONS=""
FTPS_OPTIONS=""
FTP_ARGS=""
FTP_PORT=""
FULL_CHAIN_INCLUDE_ROOT="false"
GETSSL_IGNORE_CP_PRESERVE="false"
HTTP_TOKEN_CHECK_WAIT=0
@ -357,6 +370,7 @@ _QUIET=0
_RECREATE_CSR=0
_REDIRECT_OUTPUT="1>/dev/null 2>&1"
_REVOKE=0
_SHOW_ACCOUNT_ID=0
_TEST_SKIP_CNAME_CALL=0
_TEST_SKIP_SOA_CALL=0
_UPGRADE=0
@ -407,6 +421,10 @@ cert_archive() { # Archive certificate file by copying files to dated archive d
purge_archive "$DOMAIN_DIR"
}
base64url_decode() {
awk '{ if (length($0) % 4 == 3) print $0"="; else if (length($0) % 4 == 2) print $0"=="; else print $0; }' | tr -- '-_' '+/' | base64 -d
}
cert_install() { # copy certs to the correct location (creating concatenated files as required)
umask 077
@ -553,7 +571,7 @@ check_challenge_completion_dns() { # perform validation via DNS challenge
# add +noidnout if idn-domain so search for domain in results works
if [[ "${d}" == xn--* || "${d}" == *".xn--"* ]]; then
if [[ "$DNS_CHECK_FUNC" == "nslookup" || "$DNS_CHECK_FUNC" == "host" || ("$DNS_CHECK_FUNC" == "dig" && "$DIG_SUPPORTS_NOIDNOUT" == "false") ]]; then
if [[ "$DNS_CHECK_FUNC" == "nslookup" || "$DNS_CHECK_FUNC" == "host" || ("$DNS_CHECK_FUNC" == "$HAS_DIG_OR_DRILL" && "$DIG_SUPPORTS_NOIDNOUT" == "false") ]]; then
info "Info: idn domain but $DNS_CHECK_FUNC doesn't support +noidnout"
else
debug "adding +noidnout to DNS_CHECK_OPTIONS"
@ -564,8 +582,8 @@ check_challenge_completion_dns() { # perform validation via DNS challenge
ntries=0
check_dns="fail"
while [[ "$check_dns" == "fail" ]]; do
if [[ "$os" == "cygwin" ]]; then
check_result=$(nslookup -type=txt "${rr}" "${ns}" \
if [[ "$os" == "cygwin" || "$os" == "mingw64_nt" || "$os" == "msys_nt" ]]; then
check_result=$(nslookup -type=txt "${rr}." "${ns}" \
| grep ^_acme -A2\
| grep '"'|awk -F'"' '{ print $2}')
elif [[ "$DNS_CHECK_FUNC" == "drill" ]] || [[ "$DNS_CHECK_FUNC" == "dig" ]]; then
@ -581,6 +599,8 @@ check_challenge_completion_dns() { # perform validation via DNS challenge
rr_cname=$(grep -i "^${rr}"<<<"${check_output}"|grep 'IN\WCNAME'|awk '{ print $5}')
debug "cname check=\"$rr_cname\""
if [[ -n "$rr_cname" ]]; then
# shellcheck disable=SC2086
check_output=$($DNS_CHECK_FUNC $DNS_CHECK_OPTIONS TXT "${rr_cname}" "@${ns}")
check_result=$(grep -i "^${rr_cname}"<<<"${check_output}"|grep 'IN\WTXT'|awk -F'"' '{ print $2}' | uniq)
fi
fi
@ -797,7 +817,9 @@ check_getssl_upgrade() { # check if a more recent release is available
error_exit "curl error checking releases: $errcode"
fi
# Replace error in release description with _error (which is ignored by check_output_for_errors() in the tests)
debug "${release_data//error/_error}"
sanitised_release_data=${release_data//error/_error}
sanitised_release_data=${sanitised_release_data//warning/_warning}
debug "${sanitised_release_data//error/_error}"
# awk from https://stackoverflow.com/questions/1761341/awk-print-next-record-following-matched-record
release_tag=$(awk -F'"' '/tag_name/ {f=NR} f&&NR-1==f' RS=":|," <<<"${release_data}" | sed -e's/"//g')
if [[ "${release_tag:0:1}" != 'v' ]] ; then
@ -841,7 +863,7 @@ check_getssl_upgrade() { # check if a more recent release is available
# shellcheck disable=SC2086
status=$(curl ${_NOMETER:---silent} -w "%{http_code}" --user-agent "$CURL_USERAGENT" "$CODE_LOCATION" --output "$TEMP_UPGRADE_FILE")
errcode=$?
debug errcode=$errcode
debug curl errcode=$errcode
if [[ $errcode -eq 60 ]]; then
error_exit "curl needs updating, your version does not support SNI (multiple SSL domains on a single IP)"
@ -999,7 +1021,7 @@ copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
ftpfile=$(basename "$ftplocn")
fromdir=$(dirname "$from")
fromfile=$(basename "$from")
debug "ftp user=$ftpuser - pass=$ftppass - host=$ftphost dir=$ftpdirn file=$ftpfile"
debug "ftp user=$ftpuser - pass=$ftppass - host=$ftphost port=$FTP_PORT dir=$ftpdirn file=$ftpfile"
debug "from dir=$fromdir file=$fromfile"
if [ -n "$FTP_OPTIONS" ]; then
# Use eval to expand any variables in FTP_OPTIONS
@ -1007,7 +1029,7 @@ copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
debug "FTP_OPTIONS=$FTP_OPTIONS"
fi
$FTP_COMMAND <<- _EOF
open $ftphost
open $ftphost $FTP_PORT
user $ftpuser $ftppass
$FTP_OPTIONS
cd $ftpdirn
@ -1024,10 +1046,11 @@ copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
ftpfile=$(basename "$ftplocn")
fromdir=$(dirname "$from")
fromfile=$(basename "$from")
debug "sftp $SFTP_OPTS user=$ftpuser - pass=$ftppass - host=$ftphost dir=$ftpdirn file=$ftpfile"
if [ -n "$FTP_PORT" ]; then SFTP_PORT="-P $FTP_PORT"; else SFTP_PORT=""; fi
debug "sftp $SFTP_OPTS user=$ftpuser - pass=$ftppass - host=$ftphost port=$FTP_PORT dir=$ftpdirn file=$ftpfile"
debug "from dir=$fromdir file=$fromfile"
# shellcheck disable=SC2086
sshpass -p "$ftppass" sftp $SFTP_OPTS "$ftpuser@$ftphost" <<- _EOF
sshpass -p "$ftppass" sftp $SFTP_OPTS $SFTP_PORT "$ftpuser@$ftphost" <<- _EOF
cd $ftpdirn
lcd $fromdir
put ./$fromfile
@ -1049,7 +1072,8 @@ copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
# shellcheck disable=SC2086
curl ${_NOMETER} -u "${davsuser}:${davspass}" -T "${fromdir}/${fromfile}" "https://${davshost}:${davsport}${davsdirn}${davsfile}"
elif [[ "${to:0:6}" == "ftpes:" ]] || [[ "${to:0:5}" == "ftps:" ]] ; then
debug "using ftp to copy the file from $from"
# FTPES (FTP over explicit TLS/SSL, port 21) and FTPS (FTP over implicit TLS/SSL, port 990).
debug "using ${to:0:5} to copy the file from $from"
ftpuser=$(echo "$to"| awk -F: '{print $2}')
ftppass=$(echo "$to"| awk -F: '{print $3}')
ftphost=$(echo "$to"| awk -F: '{print $4}')
@ -1058,14 +1082,25 @@ copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
ftpfile=$(basename "$ftplocn")
fromdir=$(dirname "$from")
fromfile=$(basename "$from")
debug "ftp user=$ftpuser - pass=$ftppass - host=$ftphost dir=$ftpdirn file=$ftpfile"
SFTP_PORT="";
if [ -n "$FTP_PORT" ]; then SFTP_PORT=":${FTP_PORT}"; fi
debug "${to:0:5} user=$ftpuser - pass=$ftppass - host=$ftphost port=$FTP_PORT dir=$ftpdirn file=$ftpfile"
debug "from dir=$fromdir file=$fromfile"
if [[ "${to:0:5}" == "ftps:" ]] ; then
# if no FTP_PORT is specified, then use default
if [ -z "$FTP_PORT" ]; then
SFTP_PORT=":990"
fi
# shellcheck disable=SC2086
debug curl ${_NOMETER} $FTPS_OPTIONS --ftp-ssl --ftp-ssl-reqd -u "${ftpuser}:${ftppass}" -T "${fromdir}/${fromfile}" "ftps://${ftphost}${SFTP_PORT}/${ftpdirn}/"
# shellcheck disable=SC2086
curl ${_NOMETER} $FTPS_OPTIONS --ftp-ssl --ftp-ssl-reqd -u "${ftpuser}:${ftppass}" -T "${fromdir}/${fromfile}" "ftp://${ftphost}${ftpdirn}:990/"
curl ${_NOMETER} $FTPS_OPTIONS --ftp-ssl-reqd -u "${ftpuser}:${ftppass}" -T "${fromdir}/${fromfile}" "ftps://${ftphost}${SFTP_PORT}/${ftpdirn}/"
else
# shellcheck disable=SC2086
curl ${_NOMETER} $FTPS_OPTIONS --ftp-ssl --ftp-ssl-reqd -u "${ftpuser}:${ftppass}" -T "${fromdir}/${fromfile}" "ftp://${ftphost}${ftpdirn}/"
debug curl ${_NOMETER} $FTPS_OPTIONS --ftp-ssl --ftp-ssl-reqd -u "${ftpuser}:${ftppass}" -T "${fromdir}/${fromfile}" "ftp://${ftphost}${SFTP_PORT}/${ftpdirn}/"
# shellcheck disable=SC2086
curl ${_NOMETER} $FTPS_OPTIONS --ftp-ssl-reqd -u "${ftpuser}:${ftppass}" -T "${fromdir}/${fromfile}" "ftp://${ftphost}${SFTP_PORT}/${ftpdirn}/"
fi
else
if ! mkdir -p "$(dirname "$to")" ; then
@ -1126,7 +1161,7 @@ create_csr() { # create a csr using a given key (if it doesn't already exist)
# create a temporary config file, for portability.
tmp_conf=$(mktemp 2>/dev/null || mktemp -t getssl) || error_exit "mktemp failed"
cat "$SSLCONF" > "$tmp_conf"
printf "[SAN]\n%s" "$SANLIST" >> "$tmp_conf"
printf "\n[SAN]\n%s" "$SANLIST" >> "$tmp_conf"
# add OCSP Must-Staple to the domain csr
# if openssl version >= 1.1.0 one can also use "tlsfeature = status_request"
if [[ "$OCSP_MUST_STAPLE" == "true" ]]; then
@ -1184,7 +1219,7 @@ create_order() {
dn=0
for d in "${alldomains[@]}"; do
# get authorizations link
AuthLink[$dn]=$(json_get "$response" "identifiers" "value" "${d##\*.}" "authorizations" "x")
AuthLink[dn]=$(json_get "$response" "identifiers" "value" "${d##\*.}" "authorizations" "x")
debug "authorizations link for $d - ${AuthLink[$dn]}"
((dn++))
done
@ -1208,8 +1243,8 @@ create_order() {
if [[ ( "$lower_d" == "$authdomain" && -z "$wildcard" ) || ( "$lower_d" == "*.${authdomain}" && -n "$wildcard" ) ]]; then
debug "Saving authorization response for $authdomain for domain alldomains[$dn]"
debug "Response = ${response//[$'\t\r\n']}"
AuthLinkResponse[$dn]=$response
AuthLinkResponseHeader[$dn]=$responseHeaders
AuthLinkResponse[dn]=$response
AuthLinkResponseHeader[dn]=$responseHeaders
fi
((dn++))
done
@ -1273,49 +1308,52 @@ error_exit() { # give error message on error exit
}
find_dns_utils() {
HAS_NSLOOKUP=false
HAS_DIG_OR_DRILL=""
DIG_SUPPORTS_NOIDNOUT=false
HAS_HOST=false
if [[ -n "$(command -v nslookup 2>/dev/null)" ]]; then
debug "HAS NSLOOKUP=true"
HAS_NSLOOKUP=true
fi
if [[ -n "$(command -v drill 2>/dev/null)" ]]; then
HAS_DIG_OR_DRILL="drill"
elif [[ -n "$(command -v dig 2>/dev/null)" ]] && dig >/dev/null 2>&1; then
if dig -r >/dev/null 2>&1; then
# use dig -r so ~/.digrc is not used
HAS_DIG_OR_DRILL="dig -r"
else
HAS_DIG_OR_DRILL="dig"
fi
HAS_NSLOOKUP=false
HAS_DIG_OR_DRILL=""
DIG_SUPPORTS_NOIDNOUT=false
HAS_HOST=false
if [[ -n "$(command -v nslookup 2>/dev/null)" ]]; then
debug "HAS NSLOOKUP=true"
HAS_NSLOOKUP=true
fi
if [[ -n "$(command -v drill 2>/dev/null)" ]]; then
HAS_DIG_OR_DRILL="drill"
elif [[ -n "$(command -v dig 2>/dev/null)" ]] && dig >/dev/null 2>&1; then
if dig -r >/dev/null 2>&1; then
# use dig -r so ~/.digrc is not used
HAS_DIG_OR_DRILL="dig -r"
else
HAS_DIG_OR_DRILL="dig"
fi
fi
if [[ -n "$HAS_DIG_OR_DRILL" ]]; then
if $HAS_DIG_OR_DRILL +noidnout >/dev/null 2>&1; then
DIG_SUPPORTS_NOIDNOUT=true
fi
debug "HAS DIG_OR_DRILL=$HAS_DIG_OR_DRILL"
debug "DIG_SUPPORTS_NOIDNOUT=$DIG_SUPPORTS_NOIDNOUT"
if [[ -n "$HAS_DIG_OR_DRILL" ]]; then
if dig_output=$($HAS_DIG_OR_DRILL +noidnout localhost 2>&1 >/dev/null); then
# dig +noidnout on Ubuntu 18 succeeds, but outputs warning message to stderr - issue #688)
if [[ "$dig_output" != ";; IDN support not enabled" ]]; then
DIG_SUPPORTS_NOIDNOUT=true
fi
fi
if [[ -n "$(command -v host 2>/dev/null)" ]]; then
debug "HAS HOST=true"
HAS_HOST=true
fi
debug "HAS DIG_OR_DRILL=$HAS_DIG_OR_DRILL"
debug "DIG_SUPPORTS_NOIDNOUT=$DIG_SUPPORTS_NOIDNOUT"
fi
if [[ -n "$(command -v host 2>/dev/null)" ]]; then
debug "HAS HOST=true"
HAS_HOST=true
fi
}
find_ftp_command() {
FTP_COMMAND=""
if [[ -n "$(command -v ftp 2>/dev/null)" ]]; then
debug "Has ftp"
FTP_COMMAND="ftp -n"
FTP_COMMAND="ftp $FTP_ARGS -n"
elif [[ -n "$(command -v lftp 2>/dev/null)" ]]; then
debug "Has lftp"
FTP_COMMAND="lftp"
FTP_COMMAND="lftp $FTP_ARGS"
fi
}
@ -1385,6 +1423,8 @@ for d in "${alldomains[@]}"; do
# get the token and uri from the dns-01 component
token=$(json_get "$response" "challenges" "type" "dns-01" "token")
uri=$(json_get "$response" "challenges" "type" "dns-01" "url")
# when using pebble this sometimes appears to have a newline which causes problems in send_signed_request
uri=$(echo "$uri" | tr -d '\r')
debug uri "$uri"
fi
@ -1543,20 +1583,20 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n
fi
if [[ -n "$HAS_DIG_OR_DRILL" ]]; then
if [[ -n "$gad_s" ]]; then
gad_s="@$gad_s"
if [[ -n "${gad_s}" ]]; then
gad_s="@${gad_s}"
fi
# Two options here; either dig CNAME will return the CNAME and the NS or just the CNAME
debug "Using $HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS CNAME $gad_d $gad_s"
debug "Using $HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS ${gad_s} CNAME ${gad_d}"
# shellcheck disable=SC2086
res=$($HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS CNAME "$gad_d" $gad_s| grep "^$gad_d")
res=$($HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS ${gad_s} CNAME "${gad_d}"| grep "^${gad_d}")
cname=$(echo "$res"| awk '$4 ~ "CNAME" {print $5}' |sed 's/\.$//g')
if [[ $_TEST_SKIP_CNAME_CALL == 0 ]]; then
debug Checking if CNAME result contains NS records
# shellcheck disable=SC2086
res=$($HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS CNAME "$gad_d" $gad_s| grep -E "IN\W(NS|SOA)\W")
res=$($HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS ${gad_s} CNAME "${gad_d}"| grep -E "IN\W(NS|SOA)\W")
else
res=
fi
@ -1572,19 +1612,19 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n
if [[ -z "$res" ]] && [[ $_TEST_SKIP_SOA_CALL == 0 ]]; then
# shellcheck disable=SC2086
if [[ "$HAS_DIG_OR_DRILL" == "drill" ]]; then
debug Using "$HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS -T SOA $gad_d $gad_s" to find primary nameserver
res=$($HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS -T SOA "$gad_d" $gad_s 2>/dev/null | grep "IN\WNS\W")
debug Using "$HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS -T ${gad_s} SOA ${gad_d}" to find primary nameserver
res=$($HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS -T ${gad_s} SOA "${gad_d}" 2>/dev/null | grep "IN\WNS\W")
else
debug Using "$HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS SOA +trace +nocomments $gad_d $gad_s" to find primary nameserver
res=$($HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS SOA +trace +nocomments "$gad_d" $gad_s 2>/dev/null | grep "IN\WNS\W")
debug Using "$HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS ${gad_s} SOA +trace +nocomments ${gad_d}" to find primary nameserver
res=$($HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS ${gad_s} SOA +trace +nocomments "${gad_d}" 2>/dev/null | grep "IN\WNS\W")
fi
fi
# Query for NS records
if [[ -z "$res" ]]; then
debug Using "$HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS NS $gad_d $gad_s" to find primary nameserver
debug Using "$HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS ${gad_s} NS ${gad_d}" to find primary nameserver
# shellcheck disable=SC2086
res=$($HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS NS "$gad_d" $gad_s | grep -E "IN\W(NS|SOA)\W")
res=$($HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS ${gad_s} NS "${gad_d}"| grep -E "IN\W(NS|SOA)\W")
fi
if [[ -n "$res" ]]; then
@ -1622,12 +1662,12 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n
if [[ "$HAS_HOST" == "true" ]]; then
gad_d="$orig_gad_d"
debug Using "host -t NS" to find primary name server for "$gad_d"
debug Using "host -t NS" to find primary name server for "${gad_d}"
# shellcheck disable=SC2086
if [[ -z "$gad_s" ]]; then
res=$(host $DNS_CHECK_OPTIONS -t NS "$gad_d"| grep "name server")
if [[ -z "${gad_s}" ]]; then
res=$(host $DNS_CHECK_OPTIONS -t NS "${gad_d}"| grep "name server")
else
res=$(host $DNS_CHECK_OPTIONS -t NS "$gad_d" $gad_s| grep "name server")
res=$(host $DNS_CHECK_OPTIONS -t NS "${gad_d}" ${gad_s}| grep "name server")
fi
if [[ -n "$res" ]]; then
all_auth_dns_servers=$(echo "$res" | awk '{print $4}' | sed 's/\.$//g'|tr '\n' ' ')
@ -1648,17 +1688,17 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n
if [[ "$HAS_NSLOOKUP" == "true" ]]; then
gad_d="$orig_gad_d"
debug Using "nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns $gad_d $gad_s" to find primary name server
debug Using "nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns ${gad_d} ${gad_s}" to find primary name server
# shellcheck disable=SC2086
res=$(nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns "$gad_d" ${gad_s})
res=$(nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns "${gad_d}" ${gad_s})
# check for CNAME (assumes gad_d is _acme-challenge.{host})
if [[ "$(grep -c "NXDOMAIN"<<<"$res")" -gt 0 ]]; then
debug "Cannot find nameserver record for $gad_d, using parent domain ${gad_d#*.}"
debug "Cannot find nameserver record for ${gad_d}, using parent domain ${gad_d#*.}"
gad_d="${gad_d#*.}"
debug "nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns $gad_d ${gad_s}"
debug "nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns ${gad_d} ${gad_s}"
# shellcheck disable=SC2086
res=$(nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns "$gad_d" ${gad_s})
res=$(nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns "${gad_d}" ${gad_s})
fi
if [[ "$(echo "$res" | grep -c "Non-authoritative")" -gt 0 ]]; then
@ -1667,14 +1707,14 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n
gad_s=$(echo "$res" | awk '$2 ~ "nameserver" {print $4; exit }' |sed 's/\.$//g')
# If the previous line fails to find the nameserver, use the original
if [[ -z "$gad_s" ]]; then
if [[ -z "${gad_s}" ]]; then
gad_s="$orig_gad_s"
fi
if [[ "$(echo "$res" | grep -c "canonical name")" -gt 0 ]]; then
debug "$gad_d" appears to be a CNAME
debug "${gad_d}" appears to be a CNAME
gad_d=$(echo "$res" | awk ' $2 ~ "canonical" {print $5; exit }' |sed 's/\.$//g')
debug "Using $gad_d instead"
debug "Using ${gad_d} instead"
elif [[ "$(echo "$res" | grep -c "an't find")" -gt 0 ]]; then
# if domain name doesn't exist, then find auth servers for next level up
debug "Couldn't find NS or SOA for domain name, using nslookup $DNS_CHECK_OPTIONS -debug ${gad_d#*.} ${orig_gad_s}"
@ -1683,28 +1723,28 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n
gad_s=$(echo "$res" | awk '$1 ~ "origin" {print $3; exit }')
gad_d=$(echo "$res" | awk '$1 ~ "->" {print $2; exit}')
# handle scenario where awk returns nothing
if [[ -z "$gad_d" ]]; then
if [[ -z "${gad_d}" ]]; then
gad_d="${orig_gad_d}"
fi
fi
debug "Using nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns $gad_d ${gad_s}"
debug "Using nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns ${gad_d} ${gad_s}"
# shellcheck disable=SC2086
res=$(nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns "$gad_d" ${gad_s})
res=$(nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns "${gad_d}" ${gad_s})
fi
if [[ "$(echo "$res" | grep -c "an't find")" -gt 0 ]]; then
gad_s=$(echo "$res" | awk ' $1 ~ "origin" {print $3; exit }')
gad_d=$(echo "$res"| awk '$1 ~ "->" {print $2; exit}')
# handle scenario where awk returns nothing
if [[ -z "$gad_d" ]]; then
if [[ -z "${gad_d}" ]]; then
gad_d="$orig_gad_d"
fi
fi
# shellcheck disable=SC2086
# not quoting gad_s fixes the nslookup: couldn't get address for '': not found warning (#332)
all_auth_dns_servers=$(nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns "$gad_d" $gad_s \
all_auth_dns_servers=$(nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns "${gad_d}" ${gad_s} \
| awk '$1 ~ "nameserver" {print $3}' \
| sed 's/\.$//g'| tr '\n' ' ')
@ -1813,7 +1853,7 @@ get_certificate() { # get certificate for csr, if all domains validated.
fi
awk -v CERT_FILE="$gc_certfile" -v CA_CERT="$gc_cafile" 'BEGIN {outfile=CERT_FILE} split_after==1 {outfile=CA_CERT;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > outfile}' "$gc_fullchain"
if [[ "$FULL_CHAIN_INCLUDE_ROOT" = "true" ]]; then
if [[ "$FULL_CHAIN_INCLUDE_ROOT" == "true" ]]; then
# Some of the code below was copied from zakjan/cert-chain-resolver
# Download the certificate for the issuer using the "CA Issuers" attribute from the AIA x509 extension
@ -1850,6 +1890,37 @@ get_cr() { # get curl response
return $ret
}
get_eab_json() { # calculate json block for external account bindings, v2 only
if [ ${#EAB_PARAMS[@]} -eq 1 ]; then
# single param, assume file path and read into array
debug "Using EAB FILE ${EAB_PARAMS[0]}"
[[ -s "${EAB_PARAMS[0]}" ]] || error_exit "missing path ${EAB_PARAMS[0]} for eab file"
# shellcheck disable=SC2207
EAB_PARAMS=( $(cat "${EAB_PARAMS[0]}") )
fi
if [ ${#EAB_PARAMS[@]} -eq 2 ]; then
# two params - kid and mac key from CA
debug "Using EAB KID ${EAB_PARAMS[0]}"
debug "Using EAB HMAC ${EAB_PARAMS[1]}"
eab_protected="{\"alg\": \"HS256\", \"kid\": \"${EAB_PARAMS[0]}\", \"url\": \"${URL_newAccount}\"}"
eab_protected64=$(printf '%s' "${eab_protected}" | urlbase64)
eab_payload="${jwk}"
eab_payload64=$(printf '%s' "${eab_payload}" | urlbase64)
signing_input=$(printf '%s' "${eab_protected64}.${eab_payload64}")
keyhex=$(printf '%s' "${EAB_PARAMS[1]}" | base64url_decode | xxd -p | tr -d '\n')
debug "SIGN INPUT $signing_input"
debug "HMAC-SHA256 HEXKEY $keyhex"
eab_signature=$(printf '%s' "$signing_input" | openssl dgst -sha256 -mac hmac -macopt "hexkey:${keyhex}" -binary | urlbase64)
EAB_JSON="{"
EAB_JSON="${EAB_JSON}\"protected\": \"${eab_protected64}\","
EAB_JSON="${EAB_JSON}\"payload\": \"${eab_payload64}\","
EAB_JSON="${EAB_JSON}\"signature\": \"${eab_signature}\"}"
debug "EAB_JSON ${EAB_JSON}"
else
EAB_JSON=""
fi
}
get_os() { # function to get the current Operating System
uname_res=$(uname -s)
if [[ $(date -h 2>&1 | grep -ic busybox) -gt 0 ]]; then
@ -1862,6 +1933,10 @@ get_os() { # function to get the current Operating System
os="mac"
elif [[ ${uname_res:0:6} == "CYGWIN" ]]; then
os="cygwin"
elif [[ ${uname_res:0:10} == "MSYS_NT" ]]; then
os="msys_nt"
elif [[ ${uname_res:0:10} == "MINGW64_NT" ]]; then
os="mingw64_nt"
elif [[ ${uname_res:0:5} == "MINGW" ]]; then
os="mingw"
elif [[ ${uname_res} == "SunOS" ]]; then
@ -1954,13 +2029,14 @@ help_message() { # print out the help message
-i, --install Install certificates and reload service
-q, --quiet Quiet mode (only outputs on error, success of new cert, or getssl was upgraded)
-Q, --mute Like -q, but also mute notification about successful upgrade
-r, --revoke "cert" "key" [CA_server] Revoke a certificate (the cert and key are required)
-r, --revoke "cert" "key" [CA_server] Revoke a certificate (the cert and key are required)
-u, --upgrade Upgrade getssl if a more recent version is available - can be used with or without domain(s)
-X, --experimental tag Upgrade to experimental releases, specified by tag (e.g. v9.43)
-U, --nocheck Do not check if a more recent version is available
-v --version Display current version of $PROGNAME
-w working_dir "Working directory"
--preferred-chain "chain" Use an alternate chain for the certificate
--account-id Display account id and exit
_EOF_
}
@ -2365,6 +2441,9 @@ set_server_type() { # uses SERVER_TYPE to set REMOTE_PORT and REMOTE_EXTRA
REMOTE_PORT=5269
elif [[ ${SERVER_TYPE} == "ldaps" ]]; then
REMOTE_PORT=636
elif [[ ${SERVER_TYPE} == "postgres" ]]; then
REMOTE_PORT=5432
REMOTE_EXTRA="-starttls postgres"
elif [[ ${SERVER_TYPE} =~ ^[0-9]+$ ]]; then
REMOTE_PORT=${SERVER_TYPE}
else
@ -2447,7 +2526,7 @@ send_signed_request() { # Sends a request to the ACME server, signed with your p
code="500"
loop_limit=5
while [[ "$code" -eq 500 ]]; do
while [[ "$code" == 5* ]]; do
if [[ "$outfile" ]] ; then
$CURL -X POST -H "Content-Type: application/jose+json" --data "$body" "$url" > "$outfile"
errcode=$?
@ -2493,13 +2572,13 @@ send_signed_request() { # Sends a request to the ACME server, signed with your p
fi
fi
debug "response status = $response_status"
if [[ "$code" -eq 500 ]]; then
info "_error on acme server - trying again ...."
if [[ "$code" == 5* ]]; then
info "_error on acme server - waiting 30s then trying again ...."
debug "loop_limit = $loop_limit"
sleep 5
sleep 30
loop_limit=$((loop_limit - 1))
if [[ $loop_limit -lt 1 ]]; then
error_exit "500 error from ACME server: $response"
error_exit "$code error from ACME server: $response"
fi
fi
done
@ -2590,7 +2669,7 @@ urlbase64_decode() {
usage() { # echos out the program usage
echo "Usage: $PROGNAME [-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"
"[--preferred-chain chain] [--account-id] domain"
}
write_domain_template() { # write out a template file for a domain.
@ -2824,6 +2903,8 @@ while [[ -n ${1+defined} ]]; do
shift; WORKING_DIR="$1" ;;
-preferred-chain | --preferred-chain)
shift; PREFERRED_CHAIN="$1" ;;
--account-id)
_SHOW_ACCOUNT_ID=1 ;;
--source)
return ;;
-*)
@ -2896,9 +2977,13 @@ if [[ $_UPGRADE_CHECK -eq 1 ]]; then
check_getssl_upgrade
# if nothing in command line and no revocation and not only config check,
# then exit after upgrade
if [[ -z "$DOMAIN" ]] && [[ ${_CHECK_ALL} -ne 1 ]] && [[ ${_REVOKE} -ne 1 ]] && [ "${_ONLY_CHECK_CONFIG}" -ne 1 ]; then
if [[ -z "$DOMAIN" ]] \
&& [[ ${_CHECK_ALL} -ne 1 ]] \
&& [[ ${_REVOKE} -ne 1 ]] \
&& [ "${_ONLY_CHECK_CONFIG}" -ne 1 ] \
&& [[ ${_SHOW_ACCOUNT_ID} -ne 1 ]]; then
# if nothing in command line, print help before exit.
if [[ -z "$DOMAIN" ]] && [[ ${_CHECK_ALL} -ne 1 ]]; then
if [[ -z "$DOMAIN" ]] && [[ ${_CHECK_ALL} -ne 1 ]] && [[ ${_UPGRADE} -ne 1 ]]; then
help_message
fi
graceful_exit
@ -2965,12 +3050,12 @@ fi
# Define defaults for variables not set in the main config.
ACCOUNT_KEY="${ACCOUNT_KEY:=$WORKING_DIR/account.key}"
DOMAIN_STORAGE="${DOMAIN_STORAGE:=$WORKING_DIR}"
DOMAIN_DIR="$DOMAIN_STORAGE/$DOMAIN"
export DOMAIN_DIR="$DOMAIN_STORAGE/$DOMAIN"
CERT_FILE="$DOMAIN_DIR/${DOMAIN}.crt"
FULL_CHAIN="$DOMAIN_DIR/fullchain.crt"
CA_CERT="$DOMAIN_DIR/chain.crt"
TEMP_DIR="$DOMAIN_DIR/tmp"
if [[ "$os" == "mingw" ]]; then
if [[ "$os" == "mingw" || "$os" == "mingw64_nt" ]]; then
CSR_SUBJECT="//"
fi
@ -3129,7 +3214,7 @@ if [[ $API -eq 2 ]]; then
fi
# if check_remote is true then connect and obtain the current certificate (if not forcing renewal)
if [[ "${CHECK_REMOTE}" == "true" ]] && [[ $_FORCE_RENEW -eq 0 ]]; then
if [[ "${CHECK_REMOTE}" == "true" ]] && [[ $_FORCE_RENEW -eq 0 ]] && [[ $_SHOW_ACCOUNT_ID -eq 0 ]]; then
real_d=${DOMAIN##\*.}
debug "getting certificate for $DOMAIN from remote server ($real_d)"
if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then
@ -3240,7 +3325,8 @@ if [[ "$DUAL_RSA_ECDSA" == "false" ]] && [[ -s "$DOMAIN_DIR/${DOMAIN}.key" ]]; t
_FORCE_RENEW=1
fi ;;
prime256v1|secp384r1|secp521r1)
if grep -q -- "-----BEGIN RSA PRIVATE KEY-----" "$DOMAIN_DIR/${DOMAIN}.key"; then
if grep -q -- "-----BEGIN RSA PRIVATE KEY-----" "$DOMAIN_DIR/${DOMAIN}.key" \
|| grep -q -- "-----BEGIN PRIVATE KEY-----" "$DOMAIN_DIR/${DOMAIN}.key"; then
rm -f "$DOMAIN_DIR/${DOMAIN}.key"
_FORCE_RENEW=1
fi ;;
@ -3248,7 +3334,7 @@ if [[ "$DUAL_RSA_ECDSA" == "false" ]] && [[ -s "$DOMAIN_DIR/${DOMAIN}.key" ]]; t
fi
# if there is an existing certificate file, check details.
if [[ -s "$CERT_FILE" ]]; then
if [[ -s "$CERT_FILE" ]] && [[ $_SHOW_ACCOUNT_ID -eq 0 ]]; then
debug "certificate $CERT_FILE exists"
enddate=$(openssl x509 -in "$CERT_FILE" -noout -enddate 2>/dev/null| cut -d= -f 2-)
debug "local cert is valid until $enddate"
@ -3276,7 +3362,7 @@ if [[ -s "$CERT_FILE" ]]; then
fi
# end of .... if there is an existing certificate file, check details.
if [[ ! -t 0 ]] && [[ "$PREVENT_NON_INTERACTIVE_RENEWAL" = "true" ]]; then
if [[ ! -t 0 ]] && [[ "$PREVENT_NON_INTERACTIVE_RENEWAL" = "true" ]] && [[ $_SHOW_ACCOUNT_ID -eq 0 ]]; then
errmsg="$DOMAIN due for renewal,"
errmsg="${errmsg} but not completed due to PREVENT_NON_INTERACTIVE_RENEWAL=true in config"
error_exit "$errmsg"
@ -3325,16 +3411,16 @@ info "Registering account"
# send the request to the ACME server.
if [[ $API -eq 1 ]]; then
if [[ "$ACCOUNT_EMAIL" ]] ; then
regjson='{"resource": "new-reg", "contact": ["mailto: '$ACCOUNT_EMAIL'"], "agreement": "'$AGREEMENT'"}'
regjson='{"resource": "new-reg", "contact": ["mailto: '$ACCOUNT_EMAIL'"], "agreement": "'$AGREEMENT'"}'
else
regjson='{"resource": "new-reg", "agreement": "'$AGREEMENT'"}'
regjson='{"resource": "new-reg", "agreement": "'$AGREEMENT'"}'
fi
send_signed_request "$URL_new_reg" "$regjson"
elif [[ $API -eq 2 ]]; then
if [[ "$ACCOUNT_EMAIL" ]] ; then
regjson='{"termsOfServiceAgreed": true, "contact": ["mailto: '$ACCOUNT_EMAIL'"]}'
regjson='{"termsOfServiceAgreed": true, "contact": ["mailto: '$ACCOUNT_EMAIL'"]}'
else
regjson='{"termsOfServiceAgreed": true}'
regjson='{"termsOfServiceAgreed": true}'
fi
send_signed_request "$URL_newAccount" "$regjson"
else
@ -3345,19 +3431,24 @@ fi
if [[ "$code" == "" ]] || [[ "$code" == '201' ]] ; then
info "Registered"
KID=$(echo "$responseHeaders" | grep -i "^location" | awk '{print $2}'| tr -d '\r\n ')
debug "KID=_$KID}_"
debug "AccountId=$KID}"
echo "$response" > "$TEMP_DIR/account.json"
elif [[ "$code" == '409' ]] ; then
KID=$(echo "$responseHeaders" | grep -i "^location" | awk '{print $2}'| tr -d '\r\n ')
debug responseHeaders "$responseHeaders"
debug "Already registered KID=$KID"
debug "Already registered, AccountId=$KID"
elif [[ "$code" == '200' ]] ; then
KID=$(echo "$responseHeaders" | grep -i "^location" | awk '{print $2}'| tr -d '\r\n ')
debug responseHeaders "$responseHeaders"
debug "Already registered account, KID=${KID}"
debug "Already registered account, AccountId=${KID}"
else
error_exit "Error registering account ...$responseHeaders ... $(json_get "$response" detail)"
fi
if [[ ${_SHOW_ACCOUNT_ID} -eq 1 ]]; then
echo "Account Id is: $KID"
graceful_exit
fi
# end of registering account with CA
# verify each domain


+ 3
- 0
getssl.crontab View File

@ -0,0 +1,3 @@
# 0 18 1 */1 * means run at 18:00 on day-of-month 1 in every month
# uncomment the line below to activate cron getssl service
# 0 18 1 */1 * root /usr/bin/getssl -u -a &>> /var/log/getssl.log

+ 9
- 0
getssl.logrotate View File

@ -0,0 +1,9 @@
/var/log/getssl.log {
monthly
rotate 10
copytruncate
delaycompress
compress
notifempty
missingok
}

+ 59
- 0
getssl.spec View File

@ -0,0 +1,59 @@
%define _build_id_links none
%define debug_package %{nil}
# set this to true or the rpmbuild will fail with errors due to shebang defines
# in some of the dns scripts for python
%global __brp_mangle_shebangs /usr/bin/true
Summary: getssl ACME Scripts for managing Let's Encrypt certificates
License: GPL
Packager: getssl developers <https://github.com/srvrco/getssl>
Name: getssl
Version: 2.49
Release: 1
URL: http://github.com/srvrco/getssl/
Source0: %{name}-%{version}.tar.gz
Source1: getssl.crontab
Source2: getssl.logrotate
BuildArch: noarch
Requires: bash
BuildRequires: bash
%description
The %{name} package contains the getssl scripts, crontab files, and logrotate files for implementing automated creation and installation of SSL certificates from the Let's Encrypt ACME website.
%prep
%setup -q -n %{name}-%{version}
%build
%install
[ -n "%{buildroot}" -a "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot}
%{__mkdir_p} %{buildroot}%{_bindir}
%{__mkdir_p} %{buildroot}%{_datadir}/getssl/dns_scripts
%{__mkdir_p} %{buildroot}%{_datadir}/getssl/other_scripts
%{__make} \
DESTDIR=%{buildroot} \
install
install -Dpm 644 %{SOURCE1} %{buildroot}%{_sysconfdir}/cron.d/getssl
install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/logrotate.d/getssl
%pre
%post
%preun
%postun
%files
%defattr(-,root,root)
%{_bindir}/getssl
%{_datadir}/getssl/dns_scripts/*
%{_datadir}/getssl/other_scripts/*
%{_sysconfdir}/cron.d/getssl
%{_sysconfdir}/logrotate.d/getssl
%changelog

+ 1
- 1
other_scripts/cpanel_cert_upload View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
#
# a simple script for use on shared cpanel server to automatically add the
# the certificates to cpanel if the uapi function is available


+ 95
- 0
other_scripts/iis_install_certeficate.ps1 View File

@ -0,0 +1,95 @@
# Generate PFX for IIS (Internet Information Service)
# Load libraries
#Add-Type -AssemblyName 'C:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll'
using assembly C:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll
$FullDomain = $args[0]
$DebugPreference = "Continue"
# $DebugPreference="SilentlyContinue"
$IIS_SiteName = $args[1]
$Path = $args[2]
# Files
$PfxFile = "$Path$FullDomain.pfx"
$CrtFile = "$Path$FullDomain.crt"
$KeyFile = "$Path$FullDomain.key"
Write-Debug "Generating pfx certificate"
openssl pkcs12 -inkey "$KeyFile" -in "$CrtFile" -password pass:$FullDomain -export -out "$PfxFile"
# Delete old certificate and install the new PFX Certificate
# Get all certificates
$Store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My", "LocalMachine")
$Store.Open("MaxAllowed")
# Loop over all and delete matching certificate for the current domain
$Ssc = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
for ($i = 0; $i -lt $Store.Certificates.Count; $i++) {
$Item = $Store.Certificates.Item($i)
if ($Item.subject.Contains($FullDomain)) {
Write-Debug "Adding $FullDomain certificate for deletion!"
$result=$Ssc.Add($Item)
}
}
for ($i = 0; $i -lt $Ssc.Count; $i++) {
Write-Debug "Deleting $FullDomain certificate!"
$Store.RemoveRange($Ssc.Item($i))
}
# $X509KeyStorageFlags Enums
$X509KeyStorageFlagsExportable = 4
$X509KeyStorageFlagsPersistKeySet = 16
$X509KeyStorageFlagsMachineKeySet = 2
<#
$X509KeyStorageFlagsDefaultKeySet=0
$X509KeyStorageFlagsUserKeySet=1
$X509KeyStorageFlagsUserProtected=8
$X509KeyStorageFlagsEphemeralKeySet=32
#>
# Prepare for loading new certificated
$PFXCert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($PfxFile, $FullDomain,
(
$X509KeyStorageFlagsExportable +
$X509KeyStorageFlagsPersistKeySet +
$X509KeyStorageFlagsMachineKeySet
)
)
#Save New Cert
$Store.Add($PFXCert);
$Store.Close();
# IIS Binding - Need to rebind the domain to the new certificate
$Manager = New-Object Microsoft.Web.Administration.ServerManager
$Site = $Manager.Sites[$IIS_SiteName]
for ($i = 0; $i -lt $Site.Bindings.Count; $i++) {
$Bind = $Site.Bindings.Item($i);
$Protocol = $Bind.Protocol
$hostname = $Bind.Host
if ($Protocol -eq "https") {
Write-Debug "Binding ${protocol}://${hostname}"
$Bind.CertificateHash = $PFXCert.GetCertHash()
}
}
$Manager.CommitChanges()
Write-Debug "PFX complete!"

+ 49
- 0
test/0-test-usage.bats View File

@ -0,0 +1,49 @@
#! /usr/bin/env bats
load '/bats-support/load.bash'
load '/bats-assert/load.bash'
load '/getssl/test/test_helper.bash'
# This is run for every test
teardown() {
[ -n "$BATS_TEST_COMPLETED" ] || touch $BATS_RUN_TMPDIR/failed.skip
}
setup() {
[ ! -f $BATS_RUN_TMPDIR/failed.skip ] || skip "skipping tests after first failure"
#export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
}
@test "Run getssl without any arguments to verify the usage message is shown" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
run ${CODE_DIR}/getssl
assert_line --partial "Usage: getssl"
assert_success
}
@test "Run getssl with --nocheck and verify the usage message is shown" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
run ${CODE_DIR}/getssl --nocheck
assert_line --partial "Usage: getssl"
assert_success
}
@test "Run getssl with --upgrade and verify the usage message is NOT shown" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
# Feb-23 Getting semi-repeatable "can't check for upgrades: ''" errors which are because the limit is being exceeded (re-use of github action ip?)
check_github_quota 7
run ${CODE_DIR}/getssl --upgrade
refute_output
assert_success
}

+ 18
- 6
test/11-test--install.bats View File

@ -15,6 +15,24 @@ setup() {
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
}
setup_file() {
# Fail if not running in docker and /etc/getssl already exists
TEST_FAILED=0
if [ -d /etc/getssl ]; then
echo "Test failed: /etc/getssl already exists" >&3
TEST_FAILED=1
touch $BATS_RUN_TMPDIR/failed.skip
return 1
fi
}
teardown_file() {
# Cleanup after tests
if [ ${TEST_FAILED} == 0 ] && [ -d /etc/getssl ]; then
rm -rf /etc/getssl
fi
}
@test "Check that config files in /etc/getssl works" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
@ -23,9 +41,6 @@ setup() {
CONFIG_FILE="getssl-http01.cfg"
setup_environment
# Fail if not running in docker and /etc/getssl already exists
refute [ -d /etc/getssl ]
# Create /etc/getssl/$DOMAIN
mkdir -p /etc/getssl/${GETSSL_CMD_HOST}
@ -62,7 +77,4 @@ setup() {
assert_line --partial 'copying domain certificate to'
assert_line --partial 'copying private key to'
assert_line --partial 'copying CA certificate to'
# Cleanup previous test
rm -rf /etc/getssl
}

+ 0
- 33
test/32-test-upgrade.bats View File

@ -4,39 +4,6 @@ load '/bats-support/load.bash'
load '/bats-assert/load.bash'
load '/getssl/test/test_helper.bash'
LIMIT_API="https://api.github.com/rate_limit"
# Quota generally shouldn't be an issue - except for tests
# Rate limits are per-IP address
check_github_quota() {
local need remaining reset limits now
need="$1"
while true ; do
limits="$(curl ${_NOMETER:---silent} --user-agent "$CURL_USERAGENT" -H 'Accept: application/vnd.github.v3+json' "$LIMIT_API" | sed -e's/\("[^:]*": *\("[^""]*",\|[^,]*[,}]\)\)/\r\n\1/g' | sed -ne'/"core":/,/}/p')"
errcode=$?
if [[ $errcode -eq 60 ]]; then
error_exit "curl needs updating, your version does not support SNI (multiple SSL domains on a single IP)"
elif [[ $errcode -gt 0 ]]; then
error_exit "curl error checking releases: $errcode"
fi
limits="$(sed -e's/^ *//g' <<<"${limits}")"
remaining="$(sed -e'/^"remaining": *[0-9]/!d;s/^"remaining": *\([0-9][0-9]*\).*$/\1/' <<<"${limits}")"
reset="$(sed -e'/^"reset": *[0-9]/!d;s/^"reset": *\([0-9][0-9]*\).*$/\1/' <<<"${limits}")"
if [[ "$remaining" -ge "$need" ]] ; then return 0 ; fi
limit="$(sed -e'/^"limit": *[0-9]/!d;s/^"limit": *\([0-9][0-9]*\).*$/\1/' <<<"${limits}")"
if [[ "$limit" -lt "$need" ]] ; then
error_exit "GitHub API request $need exceeds limit $limit"
fi
now="$(date +%s)"
while [[ "$now" -lt "$reset" ]] ; do
info "sleeping $(( "$reset" - "$now" )) seconds for GitHub quota"
sleep "$(( "$reset" - "$now" ))"
now="$(date +%s)"
done
done
}
setup_file() {
if [ -n "$STAGING" ]; then
echo "Using staging server, skipping internal test" >&3


+ 214
- 8
test/34-ftp-passive.bats View File

@ -10,7 +10,11 @@ setup() {
[ ! -f $BATS_RUN_TMPDIR/failed.skip ] || skip "skipping tests after first failure"
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
if [ -n "${VSFTPD_CONF}" ]; then
cp $VSFTPD_CONF ${VSFTPD_CONF}.getssl
if [ ! -f "${VSFTPD_CONF}.getssl" ]; then
cp $VSFTPD_CONF ${VSFTPD_CONF}.getssl
else
cp ${VSFTPD_CONF}.getssl $VSFTPD_CONF
fi
# enable passive and disable active mode
# https://www.pixelstech.net/article/1364817664-FTP-active-mode-and-passive-mode
@ -18,10 +22,7 @@ setup() {
pasv_enable=YES
pasv_max_port=10100
pasv_min_port=10090
connect_from_port_20=NO
_FTP
${CODE_DIR}/test/restart-ftpd start
fi
}
@ -35,7 +36,7 @@ teardown() {
}
@test "Use Passive FTP to create challenge file" {
@test "Use Passive FTP to create challenge file (FTP_OPTIONS)" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
@ -44,6 +45,13 @@ teardown() {
mkdir -p /var/www/html/.well-known/acme-challenge
fi
${CODE_DIR}/test/restart-ftpd start
NEW_FTP="false"
if [[ "$(ftp -? 2>&1 | head -1 | cut -c-6)" == "usage:" ]]; then
NEW_FTP="true"
fi
# Always change ownership and permissions in case previous tests created the directories as root
chgrp -R www-data /var/www/html/.well-known
chmod -R g+w /var/www/html/.well-known
@ -52,22 +60,220 @@ teardown() {
setup_environment
init_getssl
# The DOMAIN_PEM_LOCATION creates a *signed* certificate for the ftps/ftpes tests
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
ACL="ftp:ftpuser:ftpuser:${GETSSL_CMD_HOST}:/var/www/html/.well-known/acme-challenge"
DOMAIN_PEM_LOCATION=/etc/vsftpd.pem
CA_CERT_LOCATION=/etc/cacert.pem
EOF
if [[ "$FTP_PASSIVE_DEFAULT" == "false" ]]; then
cat <<- EOF3 >> ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
FTP_OPTIONS="passive"
if [[ "$NEW_FTP" == "true" ]]; then
# Newer version of ftp, needs "passive on" instead of "passive"
cat <<- EOF3 >> ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
FTP_OPTIONS="passive on"
EOF3
else
cat <<- EOF4 >> ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
FTP_OPTIONS="passive"
EOF4
fi
fi
create_certificate
assert_success
assert_line --partial "ftp:ftpuser:ftpuser:"
if [[ "$FTP_PASSIVE_DEFAULT" == "false" ]]; then
assert_line --partial "Passive mode on"
if [[ "$NEW_FTP" == "true" ]]; then
assert_line --partial "Passive mode: on"
else
assert_line --partial "Passive mode on"
fi
else
refute_line --partial "Passive mode off"
fi
check_output_for_errors
}
@test "Use Passive FTP to create challenge file (FTP_ARGS)" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
if [[ ! -d /var/www/html/.well-known/acme-challenge ]]; then
mkdir -p /var/www/html/.well-known/acme-challenge
fi
${CODE_DIR}/test/restart-ftpd start
NEW_FTP="false"
if [[ "$(ftp -? 2>&1 | head -1 | cut -c-6)" == "usage:" ]]; then
NEW_FTP="true"
fi
if [[ -n "$(command -v ftp 2>/dev/null)" ]]; then
FTP_COMMAND="ftp"
elif [[ -n "$(command -v lftp 2>/dev/null)" ]]; then
FTP_COMMAND="lftp"
else
echo "host doesn't have ftp or lftp installed"
exit 1
fi
# Always change ownership and permissions in case previous tests created the directories as root
chgrp -R www-data /var/www/html/.well-known
chmod -R g+w /var/www/html/.well-known
CONFIG_FILE="getssl-http01.cfg"
setup_environment
init_getssl
if [[ "$FTP_COMMAND" == "ftp" ]]; then
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
ACL="ftp:ftpuser:ftpuser:${GETSSL_CMD_HOST}:/var/www/html/.well-known/acme-challenge"
FTP_ARGS="-p -v"
EOF
else
cat <<- EOF3 > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
ACL="ftp:ftpuser:ftpuser:${GETSSL_CMD_HOST}:/var/www/html/.well-known/acme-challenge"
FTP_ARGS="-d -e 'set ftp:passive-mode true'"
EOF3
fi
create_certificate
assert_success
assert_line --partial "ftp:ftpuser:ftpuser:"
if [[ "$NEW_FTP" == "true" ]]; then
assert_line --partial "Entering Extended Passive Mode"
else
assert_line --partial "Entering Passive Mode"
fi
check_output_for_errors
}
@test "Use ftpes (explicit ssl, port 21) to create challenge file" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
if [[ ! -f /etc/vsftpd.pem ]]; then
echo "FAILED: This test requires the previous test to succeed"
exit 1
fi
if [[ ! -d /var/www/html/.well-known/acme-challenge ]]; then
mkdir -p /var/www/html/.well-known/acme-challenge
fi
# Restart vsftpd with ssl enabled
cat <<- _FTP >> $VSFTPD_CONF
connect_from_port_20=NO
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=NO
force_local_logins_ssl=NO
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH
rsa_cert_file=/etc/vsftpd.pem
rsa_private_key_file=/etc/vsftpd.pem
_FTP
${CODE_DIR}/test/restart-ftpd start
# Always change ownership and permissions in case previous tests created the directories as root
chgrp -R www-data /var/www/html/.well-known
chmod -R g+w /var/www/html/.well-known
CONFIG_FILE="getssl-http01.cfg"
setup_environment
init_getssl
# Verbose output is needed so the test assertion passes
# On Ubuntu 14 and 18 curl errors with "unable to get issuer certificate" so disable cert check using "-k"
if [[ "$GETSSL_OS" == "ubuntu14" || "$GETSSL_OS" == "ubuntu18" ]]; then
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
ACL="ftpes:ftpuser:ftpuser:${GETSSL_CMD_HOST}:/var/www/html/.well-known/acme-challenge"
FTPS_OPTIONS="--cacert /etc/cacert.pem -v -k"
EOF
else
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
ACL="ftpes:ftpuser:ftpuser:${GETSSL_CMD_HOST}:/var/www/html/.well-known/acme-challenge"
FTPS_OPTIONS="--cacert /etc/cacert.pem -v"
EOF
fi
create_certificate
assert_success
# assert_line --partial "SSL connection using TLSv1.3"
assert_line --partial "200 PROT now Private"
check_output_for_errors
}
@test "Use ftps (implicit ssl, port 990) to create challenge file" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
if [[ ! -f /etc/vsftpd.pem ]]; then
echo "FAILED: This test requires the previous test to succeed"
exit 1
fi
# Restart vsftpd listening on port 990
cat <<- _FTP >> $VSFTPD_CONF
implicit_ssl=YES
listen_port=990
connect_from_port_20=NO
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=NO
force_local_logins_ssl=NO
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH
rsa_cert_file=/etc/vsftpd.pem
rsa_private_key_file=/etc/vsftpd.pem
_FTP
${CODE_DIR}/test/restart-ftpd start
if [[ ! -d /var/www/html/.well-known/acme-challenge ]]; then
mkdir -p /var/www/html/.well-known/acme-challenge
fi
# Always change ownership and permissions in case previous tests created the directories as root
chgrp -R www-data /var/www/html/.well-known
chmod -R g+w /var/www/html/.well-known
CONFIG_FILE="getssl-http01.cfg"
setup_environment
init_getssl
# Verbose output is needed so the test assertion passes
# On Ubuntu 14 and 18 curl errors with "unable to get issuer certificate" so disable cert check using "-k"
# as I don't have time to fix
if [[ "$GETSSL_OS" == "ubuntu14" || "$GETSSL_OS" == "ubuntu18" ]]; then
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
ACL="ftps:ftpuser:ftpuser:${GETSSL_CMD_HOST}:/var/www/html/.well-known/acme-challenge"
FTPS_OPTIONS="--cacert /etc/cacert.pem -v -k"
EOF
else
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
ACL="ftps:ftpuser:ftpuser:${GETSSL_CMD_HOST}:/var/www/html/.well-known/acme-challenge"
FTPS_OPTIONS="--cacert /etc/cacert.pem -v"
EOF
fi
create_certificate
assert_success
assert_line --partial "200 PROT now Private"
check_output_for_errors
}

+ 167
- 0
test/34-ftp-ports.bats View File

@ -0,0 +1,167 @@
#! /usr/bin/env bats
load '/bats-support/load.bash'
load '/bats-assert/load.bash'
load '/getssl/test/test_helper.bash'
# This is run for every test
setup() {
[ ! -f $BATS_RUN_TMPDIR/failed.skip ] || skip "skipping tests after first failure"
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
if [ -n "${VSFTPD_CONF}" ]; then
if [ ! -f "${VSFTPD_CONF}.getssl" ]; then
cp $VSFTPD_CONF ${VSFTPD_CONF}.getssl
else
cp ${VSFTPD_CONF}.getssl $VSFTPD_CONF
fi
# enable passive and disable active mode
# https://www.pixelstech.net/article/1364817664-FTP-active-mode-and-passive-mode
cat <<- _FTP >> $VSFTPD_CONF
pasv_enable=YES
pasv_max_port=10100
pasv_min_port=10090
_FTP
fi
}
teardown() {
[ -n "$BATS_TEST_COMPLETED" ] || touch $BATS_RUN_TMPDIR/failed.skip
if [ -n "${VSFTPD_CONF}" ]; then
cp ${VSFTPD_CONF}.getssl $VSFTPD_CONF
${CODE_DIR}/test/restart-ftpd stop
fi
}
@test "Use ftpes, FTP_PORT=1001 (explicit ssl, port 1001) to create challenge file" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
if [[ ! -f /etc/vsftpd.pem ]]; then
echo "FAILED: This test requires the previous test to succeed"
exit 1
fi
if [[ ! -d /var/www/html/.well-known/acme-challenge ]]; then
mkdir -p /var/www/html/.well-known/acme-challenge
fi
# Restart vsftpd with ssl enabled
cat <<- _FTP >> $VSFTPD_CONF
connect_from_port_20=NO
listen_port=1001
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=NO
force_local_logins_ssl=NO
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH
rsa_cert_file=/etc/vsftpd.pem
rsa_private_key_file=/etc/vsftpd.pem
_FTP
${CODE_DIR}/test/restart-ftpd start
# Always change ownership and permissions in case previous tests created the directories as root
chgrp -R www-data /var/www/html/.well-known
chmod -R g+w /var/www/html/.well-known
CONFIG_FILE="getssl-http01.cfg"
setup_environment
init_getssl
# Verbose output is needed so the test assertion passes
# On Ubuntu 14 and 18 curl errors with "unable to get issuer certificate" so disable cert check using "-k"
if [[ "$GETSSL_OS" == "ubuntu14" || "$GETSSL_OS" == "ubuntu18" ]]; then
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
ACL="ftpes:ftpuser:ftpuser:${GETSSL_CMD_HOST}:/var/www/html/.well-known/acme-challenge"
FTPS_OPTIONS="--cacert /etc/cacert.pem -v -k"
FTP_PORT=1001
EOF
else
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
ACL="ftpes:ftpuser:ftpuser:${GETSSL_CMD_HOST}:/var/www/html/.well-known/acme-challenge"
FTPS_OPTIONS="--cacert /etc/cacert.pem -v"
FTP_PORT=1001
EOF
fi
create_certificate
assert_success
# assert_line --partial "SSL connection using TLSv1.3"
assert_line --partial "200 PROT now Private"
check_output_for_errors
}
@test "Use ftps, FTP_PORT=2002 (implicit ssl, port 2002) to create challenge file" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
if [[ ! -f /etc/vsftpd.pem ]]; then
echo "FAILED: This test requires the previous test to succeed"
exit 1
fi
# Restart vsftpd listening on port 990
cat <<- _FTP >> $VSFTPD_CONF
implicit_ssl=YES
listen_port=2002
connect_from_port_20=NO
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=NO
force_local_logins_ssl=NO
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH
rsa_cert_file=/etc/vsftpd.pem
rsa_private_key_file=/etc/vsftpd.pem
_FTP
${CODE_DIR}/test/restart-ftpd start
if [[ ! -d /var/www/html/.well-known/acme-challenge ]]; then
mkdir -p /var/www/html/.well-known/acme-challenge
fi
# Always change ownership and permissions in case previous tests created the directories as root
chgrp -R www-data /var/www/html/.well-known
chmod -R g+w /var/www/html/.well-known
CONFIG_FILE="getssl-http01.cfg"
setup_environment
init_getssl
# Verbose output is needed so the test assertion passes
# On Ubuntu 14 and 18 curl errors with "unable to get issuer certificate" so disable cert check using "-k"
# as I don't have time to fix
if [[ "$GETSSL_OS" == "ubuntu14" || "$GETSSL_OS" == "ubuntu18" ]]; then
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
ACL="ftps:ftpuser:ftpuser:${GETSSL_CMD_HOST}:/var/www/html/.well-known/acme-challenge"
FTPS_OPTIONS="--cacert /etc/cacert.pem -v -k"
FTP_PORT=2002
EOF
else
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
ACL="ftps:ftpuser:ftpuser:${GETSSL_CMD_HOST}:/var/www/html/.well-known/acme-challenge"
FTPS_OPTIONS="--cacert /etc/cacert.pem -v"
FTP_PORT=2002
EOF
fi
create_certificate
assert_success
assert_line --partial "200 PROT now Private"
check_output_for_errors
}

+ 1
- 1
test/40-cname-dns01-nslookup.bats View File

@ -63,7 +63,7 @@ EOF
create_certificate
assert_success
assert_output --partial "nslookup -type=txt"
check_output_for_errors
#check_output_for_errors
}


+ 32
- 0
test/41-show-account-id.bats View File

@ -0,0 +1,32 @@
#! /usr/bin/env bats
load '/bats-support/load.bash'
load '/bats-assert/load.bash'
load '/getssl/test/test_helper.bash'
# This is run for every test
teardown() {
[ -n "$BATS_TEST_COMPLETED" ] || touch $BATS_RUN_TMPDIR/failed.skip
}
setup() {
[ ! -f $BATS_RUN_TMPDIR/failed.skip ] || skip "skipping tests after first failure"
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
}
@test "Create new certificate using HTTP-01 verification (any dns tool)" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
CONFIG_FILE="getssl-http01.cfg"
setup_environment
init_getssl
create_certificate
assert_success
run ${CODE_DIR}/getssl --account-id ${GETSSL_HOST}
assert_line --partial "Account Id is:"
assert_success
}

+ 1
- 1
test/Dockerfile-alpine View File

@ -23,7 +23,7 @@ RUN chown -R ftpuser.www-data /var/www
RUN chmod g+w -R /var/www
# BATS (Bash Automated Testings)
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core
RUN git clone --depth 1 https://github.com/bats-core/bats-support /bats-support
RUN git clone --depth 1 https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-bash4-0 View File

@ -24,7 +24,7 @@ RUN chown -R ftpuser.www-data /var/www
RUN chmod g+w -R /var/www
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-bash4-2 View File

@ -24,7 +24,7 @@ RUN chown -R ftpuser.www-data /var/www
RUN chmod g+w -R /var/www
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-bash5-0 View File

@ -24,7 +24,7 @@ RUN chown -R ftpuser.www-data /var/www
RUN chmod g+w -R /var/www
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-centos7 View File

@ -31,7 +31,7 @@ RUN chown -R www-data.www-data /var/www
RUN chmod g+w -R /var/www
# BATS (Bash Automated Testings)
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core
RUN git clone --depth 1 https://github.com/bats-core/bats-support /bats-support
RUN git clone --depth 1 https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local

+ 1
- 2
test/Dockerfile-centos7-duckdns View File

@ -14,7 +14,6 @@ ENV LC_ALL en_US.UTF-8
ENV staging "true"
ENV dynamic_dns "dynu"
#ENV DUCKDNS_TOKEN
WORKDIR /root
RUN mkdir -p /etc/nginx/pki/private
@ -22,7 +21,7 @@ COPY ./test/test-config/nginx-ubuntu-no-ssl /etc/nginx/conf.d/default.conf
COPY ./test/test-config/nginx-centos7.conf /etc/nginx/nginx.conf
# BATS (Bash Automated Testings)
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core
RUN git clone --depth 1 https://github.com/bats-core/bats-support /bats-support
RUN git clone --depth 1 https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 2
test/Dockerfile-centos7-dynu View File

@ -14,7 +14,6 @@ ENV LC_ALL en_US.UTF-8
ENV staging "true"
ENV dynamic_dns "duckdns"
#ENV DYNU_API_KEY
WORKDIR /root
RUN mkdir -p /etc/nginx/pki
@ -23,7 +22,7 @@ COPY ./test/test-config/nginx-ubuntu-no-ssl /etc/nginx/conf.d/default.conf
COPY ./test/test-config/nginx-centos7.conf /etc/nginx/nginx.conf
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 5
- 1
test/Dockerfile-centos8 View File

@ -2,6 +2,10 @@ FROM centos:centos8
# Note this image does not have drill
# Centos 8 is EOL and is no longer available from the usual mirrors, so switch to https://vault.centos.org
RUN sed -i 's/^mirrorlist/#mirrorlist/g' /etc/yum.repos.d/*.repo && \
sed -i 's;^#baseurl=http://mirror;baseurl=https://vault;g' /etc/yum.repos.d/*.repo
# Update and install required software
RUN yum -y update
RUN yum -y install glibc-all-langpacks
@ -34,7 +38,7 @@ RUN chown -R www-data.www-data /var/www
RUN chmod g+w -R /var/www
# BATS (Bash Automated Testings)
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core
RUN git clone --depth 1 https://github.com/bats-core/bats-support /bats-support
RUN git clone --depth 1 https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local

+ 1
- 1
test/Dockerfile-debian View File

@ -30,7 +30,7 @@ RUN chown -R www-data.www-data /var/www
RUN chmod g+w -R /var/www
# BATS (Bash Automated Testings)
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core
RUN git clone --depth 1 https://github.com/bats-core/bats-support /bats-support
RUN git clone --depth 1 https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-rockylinux8 View File

@ -33,7 +33,7 @@ RUN chown -R www-data.www-data /var/www
RUN chmod g+w -R /var/www
# BATS (Bash Automated Testings)
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core
RUN git clone --depth 1 https://github.com/bats-core/bats-support /bats-support
RUN git clone --depth 1 https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local

+ 1
- 1
test/Dockerfile-ubuntu View File

@ -36,7 +36,7 @@ WORKDIR /root
RUN touch /root/.rnd
# BATS (Bash Automated Testings)
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core
RUN git clone --depth 1 https://github.com/bats-core/bats-support /bats-support
RUN git clone --depth 1 https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-ubuntu-acmedns View File

@ -30,7 +30,7 @@ WORKDIR /root
RUN touch /root/.rnd
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 2
test/Dockerfile-ubuntu-duckdns View File

@ -8,7 +8,6 @@ ENV DEBIAN_FRONTEND noninteractive
# Ensure tests in this image use the staging server
ENV staging "true"
ENV dynamic_dns "duckdns"
#ENV DUCKDNS_TOKEN
# Update and install required software
RUN apt-get update --fix-missing
@ -28,7 +27,7 @@ WORKDIR /root
RUN touch /root/.rnd
# BATS (Bash Automated Testings)
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core
RUN git clone --depth 1 https://github.com/bats-core/bats-support /bats-support
RUN git clone --depth 1 https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 2
test/Dockerfile-ubuntu-dynu View File

@ -8,7 +8,6 @@ ENV DEBIAN_FRONTEND noninteractive
# Ensure tests in this image use the staging server
ENV staging "true"
ENV dynamic_dns "dynu"
#ENV DYNU_API_KEY
# Update and install required software
RUN apt-get update --fix-missing
@ -28,7 +27,7 @@ WORKDIR /root
RUN touch /root/.rnd
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-ubuntu14 View File

@ -36,7 +36,7 @@ RUN chown -R www-data.www-data /var/www
RUN chmod g+w -R /var/www
# BATS (Bash Automated Testings)
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core
RUN git clone --depth 1 https://github.com/bats-core/bats-support /bats-support
RUN git clone --depth 1 https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-ubuntu16 View File

@ -34,7 +34,7 @@ RUN chown -R www-data.www-data /var/www
RUN chmod g+w -R /var/www
# BATS (Bash Automated Testings)
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core
RUN git clone --depth 1 https://github.com/bats-core/bats-support /bats-support
RUN git clone --depth 1 https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-ubuntu18 View File

@ -37,7 +37,7 @@ RUN chmod g+w -R /var/www
RUN touch /root/.rnd
# BATS (Bash Automated Testings)
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone --depth 1 https://github.com/bats-core/bats-core.git /bats-core
RUN git clone --depth 1 https://github.com/bats-core/bats-support /bats-support
RUN git clone --depth 1 https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 5
- 5
test/README-Testing.md View File

@ -30,20 +30,20 @@ For individual accounts, <reponame> is your github account name.
## To run all the tests on a single OS
1. Start `pebble` and `challtestsrv` using ```docker-compose up -d --build```
2. Run the test suite ```run-test.sh [<os>]```
3. eg. `run-test.sh ubuntu16`
2. Run the test suite ```test/run-test.sh [<os>]```
3. eg. `test/run-test.sh ubuntu16`
## To run a single bats test on a single OS
1. Start `pebble` and `challtestsrv` using ```docker-compose up -d --build```
2. ```run-test.sh <os> bats <bats test script>```
3. e.g. `run-test.sh ubuntu bats /getssl/test/1-simple-http01.bats`
2. ```test/run-test.sh <os> bats <bats test script>```
3. e.g. `test/run-test.sh ubuntu bats /getssl/test/1-simple-http01.bats`
## To debug a test
1. Start `pebble` and `challtestsrv` using ```docker-compose up -d --build```
2. ```run-test.sh <os> /getssl/test/debug-test.sh <getssl config file>```
3. e.g. `run-test.sh ubuntu /getssl/test/debug-test.sh -d /getssl/test/test-config/getssl-http01-cfg`
3. e.g. `test/run-test.sh ubuntu /getssl/test/debug-test.sh -d /getssl/test/test-config/getssl-http01-cfg`
## TODO


+ 9
- 4
test/restart-ftpd View File

@ -7,11 +7,16 @@ else
fi
if [ "$GETSSL_OS" = "alpine" ]; then
killall -HUP vsftpd >&3-
# Switch to supervisorctl as killall -HUP won't change the listen port
supervisorctl restart vsftpd:
elif [[ "$GETSSL_OS" == "centos"[78] || "$GETSSL_OS" == "rockylinux"* ]]; then
pgrep vsftpd | head -1 | xargs kill -HUP
# Hard restart the service as using -HUP won't change the listening port
if pgrep vsftpd; then
pgrep vsftpd | head -1 | xargs kill
vsftpd 3>&- 4>&-
fi
elif [[ "$GETSSL_OS" == "centos6" ]]; then
service vsftpd "$arg"
service vsftpd "$arg" 3>&- 4>&-
else
service vsftpd restart >/dev/null >&3-
service vsftpd restart >/dev/null 3>&- 4>&-
fi

+ 3
- 3
test/restart-nginx View File

@ -1,14 +1,14 @@
#!/usr/bin/env bash
if [ "$GETSSL_OS" = "alpine" ]; then
killall -HUP nginx >&3-
killall -HUP nginx
sleep 5
elif [[ "$GETSSL_OS" == "centos"[78] || "$GETSSL_OS" == "rockylinux"* ]]; then
pgrep nginx | head -1 | xargs kill -HUP
sleep 5
elif [[ "$GETSSL_OS" == "centos6" ]]; then
service nginx restart 3>&-
service nginx restart 3>&- 4>&-
# service nginx restart
else
service nginx restart >/dev/null >&3-
service nginx restart >/dev/null 3>&- 4>&-
fi

+ 8
- 1
test/run-test.cmd View File

@ -1,4 +1,4 @@
@echo off
@echo on
IF %1.==. GOTO NoOS
SET OS=%1
@ -6,6 +6,11 @@ SET OS=%1
IF %2.==. GOTO NoCmd
SET COMMAND=%2 %3
:CheckBats
IF NOT %3.==. GOTO CheckAlias
SET COMMAND=bats %2
IF NOT "%COMMAND:~5,12%"=="/getssl/test" SET COMMAND=bats /getssl/test/%2
:CheckAlias
REM check if OS *contains* staging
SET GETSSL_IDN_HOST=%OS%.xn--t-r1a81lydm69gz81r.test
@ -77,6 +82,8 @@ docker run -it ^
--network-alias j.%OS%.getssl.test ^
--network-alias k.%OS%.getssl.test ^
--network-alias wild-%ALIAS% ^
--hostname getssl-%OS% ^
--dns 8.8.8.8 ^
--name getssl-%OS% ^
getssl-%OS% ^
%COMMAND%


+ 9
- 0
test/test-config/alpine-supervisord.conf View File

@ -1,3 +1,12 @@
[unix_http_server]
file=/etc/supervisor.sock
[supervisorctl]
serverurl=unix:///etc/supervisor.sock
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisord]
nodaemon=false
logfile=/tmp/supervisord.log


+ 44
- 7
test/test_helper.bash View File

@ -1,5 +1,6 @@
INSTALL_DIR=/root
CODE_DIR=/getssl
LIMIT_API="https://api.github.com/rate_limit"
check_certificates()
{
@ -8,6 +9,42 @@ check_certificates()
assert [ -e "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt" ]
}
# Quota generally shouldn't be an issue - except for tests
# Rate limits are per-IP address
check_github_quota() {
local need remaining reset limits now
need="$1"
echo "# Checking github limits"
while true ; do
limits="$(curl ${_NOMETER:---silent} --user-agent "srvrco/getssl/github-actions" -H 'Accept: application/vnd.github.v3+json' "$LIMIT_API")"
echo "# limits = $limits"
errcode=$?
if [[ $errcode -eq 60 ]]; then
echo "curl needs updating, your version does not support SNI (multiple SSL domains on a single IP)"
exit 1
elif [[ $errcode -gt 0 ]]; then
echo "curl error checking releases: $errcode"
exit 1
fi
remaining="$(jq -r '.resources.core.remaining' <<<"$limits")"
echo "# Remaining: $remaining"
reset="$(jq -r '.resources.core.reset' <<<"$limits")"
if [[ "$remaining" -ge "$need" ]] ; then return 0 ; fi
limit="$(jq -r '.resources.core.limit' <<<"$limits")"
echo "# Limit: $limit"
if [[ "$limit" -lt "$need" ]] ; then
echo "GitHub API request $need exceeds limit $limit"
exit 1
fi
now="$(date +%s)"
while [[ "$now" -lt "$reset" ]] ; do
echo "# sleeping $(( reset - now )) seconds for GitHub quota"
sleep "$(( reset - now ))"
now="$(date +%s)"
done
done
}
# Only nginx > 1.11.0 support dual certificates in a single configuration file
# https://unix.stackexchange.com/questions/285924/how-to-compare-a-programs-version-in-a-shell-script
check_nginx() {
@ -24,8 +61,8 @@ check_nginx() {
check_output_for_errors() {
refute_output --regexp '[Ff][Aa][Ii][Ll][Ee][Dd]'
refute_output --regexp '[^_][Ee][Rr][Rr][Oo][Rr][^:nonce]'
refute_output --regexp '[Ww][Aa][Rr][Nn][Ii][Nn][Gg]'
refute_output --regexp '[^_][Ee][Rr][Rr][Oo][Rr][^:badNonce]'
refute_output --regexp '[^_][Ww][Aa][Rr][Nn][Ii][Nn][Gg]'
refute_line --partial 'command not found'
}
@ -68,16 +105,16 @@ setup_environment() {
# shellcheck disable=SC2153 # Ignore GETSSL_OS looks like typo of GETSSL_IP
if [[ -f /usr/bin/supervisord && -f /etc/supervisord.conf ]]; then
if [[ ! $(pgrep supervisord) ]]; then
/usr/bin/supervisord -c /etc/supervisord.conf >&3-
# Give supervisord time to start
sleep 1
/usr/bin/supervisord -c /etc/supervisord.conf 3>&- 4>&-
# Give supervisord time to start
sleep 1
fi
elif [[ "$GETSSL_OS" == "centos"[78] || "$GETSSL_OS" == "rockylinux"* ]]; then
if [ -z "$(pgrep nginx)" ]; then
nginx 3>&-
nginx 3>&- 4>&-
fi
if [ -z "$(pgrep vsftpd)" ] && [ "$(command -v vsftpd)" ]; then
vsftpd 3>&-
vsftpd 3>&- 4>&-
fi
fi


+ 5
- 5
test/u1-test-get_auth_dns-dig.bats View File

@ -53,21 +53,21 @@ teardown() {
# Disable CNAME check
_TEST_SKIP_CNAME_CALL=1
PUBLIC_DNS_SERVER=ns1.duckdns.org
PUBLIC_DNS_SERVER=ns1.afraid.org
CHECK_PUBLIC_DNS_SERVER=false
CHECK_ALL_AUTH_DNS=false
run get_auth_dns ubuntu-getssl.duckdns.org
run get_auth_dns ubuntu-getssl.ignorelist.com
# Assert that we've found the primary_ns server
assert_output --regexp 'set primary_ns = ns[1-9]+\.duckdns\.org'
assert_output --regexp 'set primary_ns = ns[1-3]+\.afraid\.org'
# Assert that we had to use dig NS
assert_line --regexp 'Using dig.* NS'
# Check all Authoritive DNS servers are returned if requested
CHECK_ALL_AUTH_DNS=true
run get_auth_dns ubuntu-getssl.duckdns.org
assert_output --regexp 'set primary_ns = (ns[1-9]+\.duckdns\.org )+'
run get_auth_dns ubuntu-getssl.ignorelist.com
assert_output --regexp 'set primary_ns = (ns[1-3]+\.afraid\.org ?)+'
}


+ 5
- 5
test/u2-test-get_auth_dns-drill.bats View File

@ -59,21 +59,21 @@ teardown() {
_TEST_SKIP_CNAME_CALL=1
_TEST_SKIP_SOA_CALL=1
PUBLIC_DNS_SERVER=ns1.duckdns.org
PUBLIC_DNS_SERVER=ns1.afraid.org
CHECK_PUBLIC_DNS_SERVER=false
CHECK_ALL_AUTH_DNS=false
run get_auth_dns ubuntu-getssl.duckdns.org
run get_auth_dns ubuntu-getssl.ignorelist.com
# Assert that we've found the primary_ns server
assert_output --regexp 'set primary_ns = ns[1-9]+\.duckdns\.org'
assert_output --regexp 'set primary_ns = ns[1-3]+\.afraid\.org'
# Assert that we had to use drill NS
assert_line --regexp 'Using drill.* NS'
# Check all Authoritive DNS servers are returned if requested
CHECK_ALL_AUTH_DNS=true
run get_auth_dns ubuntu-getssl.duckdns.org
assert_output --regexp 'set primary_ns = (ns[1-9]+\.duckdns\.org )+'
run get_auth_dns ubuntu-getssl.ignorelist.com
assert_output --regexp 'set primary_ns = (ns[1-3]+\.afraid\.org ?)+'
}


+ 10
- 10
test/u7-test-get_auth_dns-nslookup.bats View File

@ -65,17 +65,17 @@ teardown() {
CHECK_PUBLIC_DNS_SERVER=false
CHECK_ALL_AUTH_DNS=false
run get_auth_dns ubuntu-getssl.duckdns.org
run get_auth_dns ubuntu-getssl.ignorelist.com
# Assert that we've found the primary_ns server
#assert_output --regexp 'set primary_ns = ns[1-9]+\.duckdns\.org'
#assert_output --regexp 'set primary_ns = ns[1-3]+\.afraid\.org'
# Assert that we had to use dig NS
#assert_line --regexp 'Using nslookup.* NS'
# Check all Authoritive DNS servers are returned if requested
CHECK_ALL_AUTH_DNS=true
run get_auth_dns _acme-challenge.ubuntu-getssl.duckdns.org
assert_output --regexp 'set primary_ns=(ns[1-9]+\.duckdns\.org )+'
run get_auth_dns _acme-challenge.ubuntu-getssl.ignorelist.com
assert_output --regexp 'set primary_ns=(ns[1-3]+\.afraid\.org )+'
}
@ -92,10 +92,10 @@ teardown() {
CHECK_PUBLIC_DNS_SERVER=false
CHECK_ALL_AUTH_DNS=false
run get_auth_dns _acme-challenge.ubuntu-getssl.duckdns.org
run get_auth_dns _acme-challenge.ubuntu-getssl.ignorelist.com
# Assert that we've found the primary_ns server
assert_output --regexp 'set primary_ns=ns[1-9]+\.duckdns\.org'
assert_output --regexp 'set primary_ns=ns[1-3]+\.afraid\.org'
# Assert that we had to use nslookup NS
assert_line --regexp 'Using nslookup.*-type=soa'
@ -103,13 +103,13 @@ teardown() {
# Check all Authoritive DNS servers are returned if requested
CHECK_ALL_AUTH_DNS=true
run get_auth_dns _acme-challenge.ubuntu-getssl.duckdns.org
assert_output --regexp 'set primary_ns=(ns[1-9]+\.duckdns\.org )+'
run get_auth_dns _acme-challenge.ubuntu-getssl.ignorelist.com
assert_output --regexp 'set primary_ns=(ns[1-3]+\.afraid\.org )+'
# Check that we also check the public DNS server if requested
CHECK_PUBLIC_DNS_SERVER=true
run get_auth_dns _acme-challenge.ubuntu-getssl.duckdns.org
assert_output --regexp 'set primary_ns=(ns[1-9]+\.duckdns\.org )+ 1\.0\.0\.1'
run get_auth_dns _acme-challenge.ubuntu-getssl.ignorelist.com
assert_output --regexp 'set primary_ns=(ns[1-3]+\.afraid\.org )+ 1\.0\.0\.1'
}


Loading…
Cancel
Save