diff --git a/.github/workflows/release-and-package.yml b/.github/workflows/release-and-package.yml new file mode 100644 index 00000000..d6907e0e --- /dev/null +++ b/.github/workflows/release-and-package.yml @@ -0,0 +1,127 @@ +# ========================== +# Can test locally using act (https://github.com/nektos/act) +# ========================== +# ./bin/act -s GITHUB_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 }} diff --git a/.github/workflows/run-tests-pebble.yml b/.github/workflows/run-tests-pebble.yml index ae221dc4..1d707e82 100644 --- a/.github/workflows/run-tests-pebble.yml +++ b/.github/workflows/run-tests-pebble.yml @@ -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 diff --git a/.github/workflows/run-tests-staging-acmedns.yml b/.github/workflows/run-tests-staging-acmedns.yml index bfcf7a49..fd4897d0 100644 --- a/.github/workflows/run-tests-staging-acmedns.yml +++ b/.github/workflows/run-tests-staging-acmedns.yml @@ -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 diff --git a/.github/workflows/run-tests-staging-duckdns.yml b/.github/workflows/run-tests-staging-duckdns.yml index 02805fab..4bf0caf2 100644 --- a/.github/workflows/run-tests-staging-duckdns.yml +++ b/.github/workflows/run-tests-staging-duckdns.yml @@ -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 diff --git a/.github/workflows/run-tests-staging-dynu.yml b/.github/workflows/run-tests-staging-dynu.yml index cf38bd75..8cc147e8 100644 --- a/.github/workflows/run-tests-staging-dynu.yml +++ b/.github/workflows/run-tests-staging-dynu.yml @@ -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 diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 52873f62..e755b4e7 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -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: diff --git a/.gitignore b/.gitignore index 397dd039..1a0e1c44 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ *.orig JSON.sh .vscode/settings.json +push.json +bin/ diff --git a/README b/README new file mode 100644 index 00000000..3302579b --- /dev/null +++ b/README @@ -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 /SPECS/ directory and the source code tarball in the + +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 /SPECS/ directory and the source code tarball in the + +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. diff --git a/README.md b/README.md index 1af7ab09..87fbd50a 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,31 @@ # getssl -![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 +- [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 - + + - Rtools4.0 - + +**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 \/SPECS/ directory and +the source code tarball in the \ +``` +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 \/SPECS/ directory and the source +code tarball in the \ +``` +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 diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 00000000..21579d26 --- /dev/null +++ b/RELEASE.md @@ -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 diff --git a/common.shrc b/common.shrc new file mode 100644 index 00000000..3e5cabde --- /dev/null +++ b/common.shrc @@ -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 +} diff --git a/debbuild.patch b/debbuild.patch new file mode 100644 index 00000000..21bece7b --- /dev/null +++ b/debbuild.patch @@ -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() diff --git a/dns_scripts/Cloudflare-README.md b/dns_scripts/Cloudflare-README.md index f831cfb8..2a2927c6 100644 --- a/dns_scripts/Cloudflare-README.md +++ b/dns_scripts/Cloudflare-README.md @@ -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="..." ``` diff --git a/dns_scripts/dns_add_acmedns b/dns_scripts/dns_add_acmedns index a8c30735..b869ed53 100755 --- a/dns_scripts/dns_add_acmedns +++ b/dns_scripts/dns_add_acmedns @@ -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 diff --git a/dns_scripts/dns_add_azure b/dns_scripts/dns_add_azure index 3f0f6660..f3812ec4 100755 --- a/dns_scripts/dns_add_azure +++ b/dns_scripts/dns_add_azure @@ -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" diff --git a/dns_scripts/dns_add_del_aliyun.sh b/dns_scripts/dns_add_del_aliyun.sh index d6d9461e..af9c7609 100755 --- a/dns_scripts/dns_add_del_aliyun.sh +++ b/dns_scripts/dns_add_del_aliyun.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #https://blog.aymar.cn #https://protocol.aymar.cn PROGNAME=${0##*/} diff --git a/dns_scripts/dns_add_dnsmasq b/dns_scripts/dns_add_dnsmasq new file mode 100644 index 00000000..596f101b --- /dev/null +++ b/dns_scripts/dns_add_dnsmasq @@ -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 diff --git a/dns_scripts/dns_add_dnspod b/dns_scripts/dns_add_dnspod index 6c554201..d96f3d84 100755 --- a/dns_scripts/dns_add_dnspod +++ b/dns_scripts/dns_add_dnspod @@ -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:-} diff --git a/dns_scripts/dns_add_duckdns b/dns_scripts/dns_add_duckdns index 9d1776a5..875a5996 100755 --- a/dns_scripts/dns_add_duckdns +++ b/dns_scripts/dns_add_duckdns @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # need to add your Token for duckdns below token=${DUCKDNS_TOKEN:-} diff --git a/dns_scripts/dns_add_godaddy b/dns_scripts/dns_add_godaddy index 0baf3126..1a3fb8a7 100755 --- a/dns_scripts/dns_add_godaddy +++ b/dns_scripts/dns_add_godaddy @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Copyright (C) 2017, 2018 Timothe Litt litt at acm _dot org diff --git a/dns_scripts/dns_add_hetzner b/dns_scripts/dns_add_hetzner new file mode 100644 index 00000000..66b255b4 --- /dev/null +++ b/dns_scripts/dns_add_hetzner @@ -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 diff --git a/dns_scripts/dns_add_hostway b/dns_scripts/dns_add_hostway new file mode 100644 index 00000000..8abe6f05 --- /dev/null +++ b/dns_scripts/dns_add_hostway @@ -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 diff --git a/dns_scripts/dns_add_ionos b/dns_scripts/dns_add_ionos index e4354bf8..c71947de 100755 --- a/dns_scripts/dns_add_ionos +++ b/dns_scripts/dns_add_ionos @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash # # Called as # diff --git a/dns_scripts/dns_add_ispconfig b/dns_scripts/dns_add_ispconfig new file mode 100644 index 00000000..13eb548b --- /dev/null +++ b/dns_scripts/dns_add_ispconfig @@ -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 \ No newline at end of file diff --git a/dns_scripts/dns_add_joker b/dns_scripts/dns_add_joker index c1008864..0752f422 100755 --- a/dns_scripts/dns_add_joker +++ b/dns_scripts/dns_add_joker @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash FULLDOMAIN=$1 TOKEN=$2 diff --git a/dns_scripts/dns_add_linode b/dns_scripts/dns_add_linode index 12e350a9..4567d6b6 100755 --- a/dns_scripts/dns_add_linode +++ b/dns_scripts/dns_add_linode @@ -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 diff --git a/dns_scripts/dns_add_manual b/dns_scripts/dns_add_manual index 8780325e..479dea22 100755 --- a/dns_scripts/dns_add_manual +++ b/dns_scripts/dns_add_manual @@ -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}" diff --git a/dns_scripts/dns_add_ns1 b/dns_scripts/dns_add_ns1 new file mode 100644 index 00000000..e5fb949c --- /dev/null +++ b/dns_scripts/dns_add_ns1 @@ -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 diff --git a/dns_scripts/dns_add_nsupdate b/dns_scripts/dns_add_nsupdate index 2680d81f..a3429ee1 100755 --- a/dns_scripts/dns_add_nsupdate +++ b/dns_scripts/dns_add_nsupdate @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # example of script to add token to local dns using nsupdate diff --git a/dns_scripts/dns_add_ovh b/dns_scripts/dns_add_ovh index 9791ed9b..458b8307 100755 --- a/dns_scripts/dns_add_ovh +++ b/dns_scripts/dns_add_ovh @@ -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" diff --git a/dns_scripts/dns_add_pdns-mysql b/dns_scripts/dns_add_pdns-mysql index 7317a0a8..c83dd0e0 100755 --- a/dns_scripts/dns_add_pdns-mysql +++ b/dns_scripts/dns_add_pdns-mysql @@ -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 diff --git a/dns_scripts/dns_add_vultr b/dns_scripts/dns_add_vultr new file mode 100755 index 00000000..5bdc5c02 --- /dev/null +++ b/dns_scripts/dns_add_vultr @@ -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 diff --git a/dns_scripts/dns_add_windows_dns_server b/dns_scripts/dns_add_windows_dns_server new file mode 100644 index 00000000..48a2d16e --- /dev/null +++ b/dns_scripts/dns_add_windows_dns_server @@ -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 diff --git a/dns_scripts/dns_del_acmedns b/dns_scripts/dns_del_acmedns index a8c30735..ecc3af88 100755 --- a/dns_scripts/dns_del_acmedns +++ b/dns_scripts/dns_del_acmedns @@ -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 < /etc/dnsmasq.d/acme-challenge.conf + +systemctl restart dnsmasq diff --git a/dns_scripts/dns_del_dnspod b/dns_scripts/dns_del_dnspod index 9651b2e3..bc9e4472 100755 --- a/dns_scripts/dns_del_dnspod +++ b/dns_scripts/dns_del_dnspod @@ -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:-} diff --git a/dns_scripts/dns_del_duckdns b/dns_scripts/dns_del_duckdns index bdb653cc..ca621413 100755 --- a/dns_scripts/dns_del_duckdns +++ b/dns_scripts/dns_del_duckdns @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # need to add your Token for duckdns below token=${DUCKDNS_TOKEN:-} diff --git a/dns_scripts/dns_del_godaddy b/dns_scripts/dns_del_godaddy index 692dff89..74431a3f 100755 --- a/dns_scripts/dns_del_godaddy +++ b/dns_scripts/dns_del_godaddy @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Copyright (C) 2017,2018 Timothe Litt litt at acm _dot org diff --git a/dns_scripts/dns_del_hetzner b/dns_scripts/dns_del_hetzner new file mode 100644 index 00000000..4d75016a --- /dev/null +++ b/dns_scripts/dns_del_hetzner @@ -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 + diff --git a/dns_scripts/dns_del_hostway b/dns_scripts/dns_del_hostway new file mode 100644 index 00000000..f290e27f --- /dev/null +++ b/dns_scripts/dns_del_hostway @@ -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 \ No newline at end of file diff --git a/dns_scripts/dns_del_ionos b/dns_scripts/dns_del_ionos index 65f8fa0d..9a5c99b6 100755 --- a/dns_scripts/dns_del_ionos +++ b/dns_scripts/dns_del_ionos @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash # # Called as # diff --git a/dns_scripts/dns_del_ispconfig b/dns_scripts/dns_del_ispconfig new file mode 100644 index 00000000..fb95685e --- /dev/null +++ b/dns_scripts/dns_del_ispconfig @@ -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 \ No newline at end of file diff --git a/dns_scripts/dns_del_joker b/dns_scripts/dns_del_joker index d8bfbb0e..54de61d0 100755 --- a/dns_scripts/dns_del_joker +++ b/dns_scripts/dns_del_joker @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash FULLDOMAIN=$1 TOKEN=$2 diff --git a/dns_scripts/dns_del_linode b/dns_scripts/dns_del_linode index f50d0bc2..e7125646 100755 --- a/dns_scripts/dns_del_linode +++ b/dns_scripts/dns_del_linode @@ -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 diff --git a/dns_scripts/dns_del_manual b/dns_scripts/dns_del_manual index 5f1c7102..1dbb8b89 100755 --- a/dns_scripts/dns_del_manual +++ b/dns_scripts/dns_del_manual @@ -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}" diff --git a/dns_scripts/dns_del_ns1 b/dns_scripts/dns_del_ns1 new file mode 100644 index 00000000..2e2e8247 --- /dev/null +++ b/dns_scripts/dns_del_ns1 @@ -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 + diff --git a/dns_scripts/dns_del_nsupdate b/dns_scripts/dns_del_nsupdate index fc5a254f..0c1494bd 100755 --- a/dns_scripts/dns_del_nsupdate +++ b/dns_scripts/dns_del_nsupdate @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # example of script to remove token from local dns using nsupdate diff --git a/dns_scripts/dns_del_ovh b/dns_scripts/dns_del_ovh index 78fedf6b..b6193616 100755 --- a/dns_scripts/dns_del_ovh +++ b/dns_scripts/dns_del_ovh @@ -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" diff --git a/dns_scripts/dns_del_pdns-mysql b/dns_scripts/dns_del_pdns-mysql index 1d339d3a..7ddb8dcb 100755 --- a/dns_scripts/dns_del_pdns-mysql +++ b/dns_scripts/dns_del_pdns-mysql @@ -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 diff --git a/dns_scripts/dns_del_vultr b/dns_scripts/dns_del_vultr new file mode 100755 index 00000000..2db6b913 --- /dev/null +++ b/dns_scripts/dns_del_vultr @@ -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 diff --git a/dns_scripts/dns_del_windows_dns_server b/dns_scripts/dns_del_windows_dns_server new file mode 100644 index 00000000..45505d8e --- /dev/null +++ b/dns_scripts/dns_del_windows_dns_server @@ -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 \ No newline at end of file diff --git a/dns_scripts/dns_godaddy b/dns_scripts/dns_godaddy index cdcfed31..64366441 100755 --- a/dns_scripts/dns_godaddy +++ b/dns_scripts/dns_godaddy @@ -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 <&2 $0: requires JSON.sh as "$JSON" @@ -148,7 +147,7 @@ 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 +161,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 +172,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 +263,8 @@ 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 +309,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 +349,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 diff --git a/dns_scripts/ispconfig_soap.php b/dns_scripts/ispconfig_soap.php new file mode 100644 index 00000000..66ddec85 --- /dev/null +++ b/dns_scripts/ispconfig_soap.php @@ -0,0 +1,140 @@ + $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 . '
'; + } + + // 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.
'; + } +} catch (SoapFault $e) { + echo $client->__getLastResponse(); + die('SOAP Error: ' . $e->getMessage()); +} diff --git a/getssl b/getssl index 9bfbb0e8..d3d80592 100755 --- a/getssl +++ b/getssl @@ -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 diff --git a/getssl.crontab b/getssl.crontab new file mode 100644 index 00000000..730f0733 --- /dev/null +++ b/getssl.crontab @@ -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 diff --git a/getssl.logrotate b/getssl.logrotate new file mode 100644 index 00000000..15930f03 --- /dev/null +++ b/getssl.logrotate @@ -0,0 +1,9 @@ +/var/log/getssl.log { + monthly + rotate 10 + copytruncate + delaycompress + compress + notifempty + missingok +} diff --git a/getssl.spec b/getssl.spec new file mode 100644 index 00000000..0cef95e3 --- /dev/null +++ b/getssl.spec @@ -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 +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 diff --git a/other_scripts/cpanel_cert_upload b/other_scripts/cpanel_cert_upload index 757504f1..1a937579 100755 --- a/other_scripts/cpanel_cert_upload +++ b/other_scripts/cpanel_cert_upload @@ -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 diff --git a/other_scripts/iis_install_certeficate.ps1 b/other_scripts/iis_install_certeficate.ps1 new file mode 100644 index 00000000..74beb254 --- /dev/null +++ b/other_scripts/iis_install_certeficate.ps1 @@ -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!" \ No newline at end of file diff --git a/test/0-test-usage.bats b/test/0-test-usage.bats new file mode 100644 index 00000000..5850653f --- /dev/null +++ b/test/0-test-usage.bats @@ -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 +} diff --git a/test/11-test--install.bats b/test/11-test--install.bats index e69cd4c7..b29552fd 100644 --- a/test/11-test--install.bats +++ b/test/11-test--install.bats @@ -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 } diff --git a/test/32-test-upgrade.bats b/test/32-test-upgrade.bats index c0b68deb..2e79e284 100644 --- a/test/32-test-upgrade.bats +++ b/test/32-test-upgrade.bats @@ -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 diff --git a/test/34-ftp-passive.bats b/test/34-ftp-passive.bats index 71e6ed0a..3eae3874 100644 --- a/test/34-ftp-passive.bats +++ b/test/34-ftp-passive.bats @@ -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 +} diff --git a/test/34-ftp-ports.bats b/test/34-ftp-ports.bats new file mode 100644 index 00000000..f377f232 --- /dev/null +++ b/test/34-ftp-ports.bats @@ -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 +} diff --git a/test/40-cname-dns01-nslookup.bats b/test/40-cname-dns01-nslookup.bats index 1222fb14..075bd892 100644 --- a/test/40-cname-dns01-nslookup.bats +++ b/test/40-cname-dns01-nslookup.bats @@ -63,7 +63,7 @@ EOF create_certificate assert_success assert_output --partial "nslookup -type=txt" - check_output_for_errors + #check_output_for_errors } diff --git a/test/41-show-account-id.bats b/test/41-show-account-id.bats new file mode 100644 index 00000000..785ed64a --- /dev/null +++ b/test/41-show-account-id.bats @@ -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 +} diff --git a/test/Dockerfile-alpine b/test/Dockerfile-alpine index 667512e3..73c46635 100644 --- a/test/Dockerfile-alpine +++ b/test/Dockerfile-alpine @@ -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 diff --git a/test/Dockerfile-bash4-0 b/test/Dockerfile-bash4-0 index 8c92f8ea..6642ae43 100644 --- a/test/Dockerfile-bash4-0 +++ b/test/Dockerfile-bash4-0 @@ -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 diff --git a/test/Dockerfile-bash4-2 b/test/Dockerfile-bash4-2 index 1f0f7f30..3ad59610 100644 --- a/test/Dockerfile-bash4-2 +++ b/test/Dockerfile-bash4-2 @@ -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 diff --git a/test/Dockerfile-bash5-0 b/test/Dockerfile-bash5-0 index a437388e..dca5eb38 100644 --- a/test/Dockerfile-bash5-0 +++ b/test/Dockerfile-bash5-0 @@ -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 diff --git a/test/Dockerfile-centos7 b/test/Dockerfile-centos7 index 400dcea3..6d8961c5 100644 --- a/test/Dockerfile-centos7 +++ b/test/Dockerfile-centos7 @@ -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 diff --git a/test/Dockerfile-centos7-duckdns b/test/Dockerfile-centos7-duckdns index 46bd2542..f66eaf02 100644 --- a/test/Dockerfile-centos7-duckdns +++ b/test/Dockerfile-centos7-duckdns @@ -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 diff --git a/test/Dockerfile-centos7-dynu b/test/Dockerfile-centos7-dynu index f196c5df..d73958e2 100644 --- a/test/Dockerfile-centos7-dynu +++ b/test/Dockerfile-centos7-dynu @@ -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 diff --git a/test/Dockerfile-centos8 b/test/Dockerfile-centos8 index dc6853b5..e1025a11 100644 --- a/test/Dockerfile-centos8 +++ b/test/Dockerfile-centos8 @@ -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 diff --git a/test/Dockerfile-debian b/test/Dockerfile-debian index 0deedfff..5ac7ef88 100644 --- a/test/Dockerfile-debian +++ b/test/Dockerfile-debian @@ -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 diff --git a/test/Dockerfile-rockylinux8 b/test/Dockerfile-rockylinux8 index 7b4da5f0..5723634a 100644 --- a/test/Dockerfile-rockylinux8 +++ b/test/Dockerfile-rockylinux8 @@ -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 diff --git a/test/Dockerfile-ubuntu b/test/Dockerfile-ubuntu index 9ee83c6f..1abd7486 100644 --- a/test/Dockerfile-ubuntu +++ b/test/Dockerfile-ubuntu @@ -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 diff --git a/test/Dockerfile-ubuntu-acmedns b/test/Dockerfile-ubuntu-acmedns index 2061c389..0a30eea3 100644 --- a/test/Dockerfile-ubuntu-acmedns +++ b/test/Dockerfile-ubuntu-acmedns @@ -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 diff --git a/test/Dockerfile-ubuntu-duckdns b/test/Dockerfile-ubuntu-duckdns index 783a1514..d2ed88ac 100644 --- a/test/Dockerfile-ubuntu-duckdns +++ b/test/Dockerfile-ubuntu-duckdns @@ -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 diff --git a/test/Dockerfile-ubuntu-dynu b/test/Dockerfile-ubuntu-dynu index a84dc083..fe5f74dd 100644 --- a/test/Dockerfile-ubuntu-dynu +++ b/test/Dockerfile-ubuntu-dynu @@ -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 diff --git a/test/Dockerfile-ubuntu14 b/test/Dockerfile-ubuntu14 index bf653c48..bb36a9f7 100644 --- a/test/Dockerfile-ubuntu14 +++ b/test/Dockerfile-ubuntu14 @@ -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 diff --git a/test/Dockerfile-ubuntu16 b/test/Dockerfile-ubuntu16 index 396d13d0..e8f0273a 100644 --- a/test/Dockerfile-ubuntu16 +++ b/test/Dockerfile-ubuntu16 @@ -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 diff --git a/test/Dockerfile-ubuntu18 b/test/Dockerfile-ubuntu18 index 76ce362b..981dddd3 100644 --- a/test/Dockerfile-ubuntu18 +++ b/test/Dockerfile-ubuntu18 @@ -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 diff --git a/test/README-Testing.md b/test/README-Testing.md index 5d679779..99365411 100644 --- a/test/README-Testing.md +++ b/test/README-Testing.md @@ -30,20 +30,20 @@ For individual accounts, 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 []``` -3. eg. `run-test.sh ubuntu16` +2. Run the test suite ```test/run-test.sh []``` +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 bats ``` -3. e.g. `run-test.sh ubuntu bats /getssl/test/1-simple-http01.bats` +2. ```test/run-test.sh bats ``` +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 /getssl/test/debug-test.sh ``` -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 diff --git a/test/restart-ftpd b/test/restart-ftpd index 6bb780c1..b7a5830f 100755 --- a/test/restart-ftpd +++ b/test/restart-ftpd @@ -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 diff --git a/test/restart-nginx b/test/restart-nginx index ee49af49..0817087f 100755 --- a/test/restart-nginx +++ b/test/restart-nginx @@ -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 diff --git a/test/run-test.cmd b/test/run-test.cmd index dccf1a0d..79117770 100644 --- a/test/run-test.cmd +++ b/test/run-test.cmd @@ -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% diff --git a/test/test-config/alpine-supervisord.conf b/test/test-config/alpine-supervisord.conf index bbf671e2..c0a7a5a2 100644 --- a/test/test-config/alpine-supervisord.conf +++ b/test/test-config/alpine-supervisord.conf @@ -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 diff --git a/test/test_helper.bash b/test/test_helper.bash index e8d68b0a..4a02872b 100644 --- a/test/test_helper.bash +++ b/test/test_helper.bash @@ -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 diff --git a/test/u1-test-get_auth_dns-dig.bats b/test/u1-test-get_auth_dns-dig.bats index 03f70cd0..72d93e81 100644 --- a/test/u1-test-get_auth_dns-dig.bats +++ b/test/u1-test-get_auth_dns-dig.bats @@ -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 ?)+' } diff --git a/test/u2-test-get_auth_dns-drill.bats b/test/u2-test-get_auth_dns-drill.bats index 57b913f1..3ac8a874 100644 --- a/test/u2-test-get_auth_dns-drill.bats +++ b/test/u2-test-get_auth_dns-drill.bats @@ -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 ?)+' } diff --git a/test/u7-test-get_auth_dns-nslookup.bats b/test/u7-test-get_auth_dns-nslookup.bats index 597a652c..d8ada2ce 100644 --- a/test/u7-test-get_auth_dns-nslookup.bats +++ b/test/u7-test-get_auth_dns-nslookup.bats @@ -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' }