diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-02-09 09:05:59 +0100 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-02-09 09:05:59 +0100 |
commit | 28d06bca0b9f2a64a92e54aeafcae1140c69a09c (patch) | |
tree | 8debdc976ecf25f2d4be9e3993e60df6d428527f | |
parent | b147b39e5cfbba272e0f172dc84c2f7570318fcc (diff) | |
download | acmeman-28d06bca0b9f2a64a92e54aeafcae1140c69a09c.tar.gz acmeman-28d06bca0b9f2a64a92e54aeafcae1140c69a09c.tar.bz2 |
Improve debugging, use 4096 bit keys; fix adding alternative names
-rw-r--r-- | Changes | 2 | ||||
-rwxr-xr-x | acmeman | 77 |
2 files changed, 61 insertions, 18 deletions
@@ -1,3 +1,3 @@ -0.90 2017-02-05 +1.00 2017-02-09 * Initial version (Git) @@ -1,4 +1,18 @@ #! /usr/bin/perl +# Copyright (C) 2017 Sergey Poznyakoff <gray@gnu.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. use strict; use feature 'state'; use Protocol::ACME; @@ -17,7 +31,7 @@ use Getopt::Long qw(:config gnu_getopt no_ignore_case); use POSIX qw(strftime time floor); use Data::Dumper; -our $VERSION = '0.90'; +our $VERSION = '1.00'; =head1 NAME @@ -175,7 +189,26 @@ exists. =item B<-d>, B<--debug> -Increase debugging level. Multiple options accumulate. +Increase debugging level. Multiple options accumulate. Three debugging +levels are implemented: + +=over 8 + +=item B<-d> + +List certificates being renewed. + +=item B<-dd> + +List files being created. Show basic information about ACME transactions for +each certificate. + +=item B<-ddd> + +Verbosely report parsing of Apache configuration files. Show detailed +debugging information about ACME transactions for each certificate. + +=back =item B<-f>, B<--config-file=>I<FILE> @@ -190,7 +223,7 @@ B<slackware>, B<debian>, and B<rh> (for Red Hat). With B<--setup>, don't actually write anything, just print what would have been done. Otherwise, use LetsEncrypt staging server, instead of -production. +production. Implies B<--debug>. =item B<-s>, B<--setup> @@ -296,10 +329,10 @@ sub debug_to_loglevel { sub make_csr { my $cn = shift; - my $req = Crypt::OpenSSL::PKCS10->new(2048); + my $req = Crypt::OpenSSL::PKCS10->new(4096); $req->set_subject("/CN=$cn"); $req->add_ext(Crypt::OpenSSL::PKCS10::NID_subject_alt_name, - join(',', map { "DNS:$_" } @_)); + join(',', map { "DNS:$_" } @_)) if @_; $req->add_ext_final(); $req->sign(); if (exists($filename_pattern{key})) { @@ -356,7 +389,6 @@ sub domain_cert_expires { } debug(1, "$crt expires on $expiry, $in"); if ($now + $time_delta < $ts) { - debug(1, "$crt expires on $expiry, $in"); return 0; } else { debug(1, "will renew $crt (expires on $expiry, $in)"); @@ -370,8 +402,16 @@ sub domain_cert_expires { sub register_domain_certificate { my $domain = shift; - debug(1, "CN=$domain, alternatives=@_"); + if ($debug) { + my $crt = make_filename('cert', $domain); + if (-f $crt) { + debug(1, "renewing $crt: CN=$domain, alternatives=@_"); + } else { + debug(1, "issuing $crt: CN=$domain, alternatives=@_"); + } + } + my $acme = Protocol::ACME->new( host => $acme_host, account_key => { @@ -408,10 +448,13 @@ sub register_domain_certificate { error("$domain: $@->{error}{status} $@->{error}{detail}"); } else { error("$domain: $@->{detail} $@->{type}"); - } + } + } elsif (ref($@) == '') { + chomp $@; + error("$domain: failed to renew certificate: $@"); } else { error("$domain: failed to renew certificate"); - print STDERR Dumper([$@]) if $debug; + print STDERR Dumper([$@]); } } } @@ -447,7 +490,7 @@ sub examine_http_config { state $state = STATE_INITIAL; - debug(2, "reading apache configuration file \"$file\""); + debug(3, "reading apache configuration file \"$file\""); if (open(my $fd, '<', $file)) { my $server_name; my @server_aliases; @@ -459,7 +502,7 @@ sub examine_http_config { s/^\s+//; next if /^(#.*)?$/; if (/^include(optional)?\s+(.+?)\s*$/i) { - debug(2, "$file:$line: state $state: Include$1 $2"); + debug(3, "$file:$line: state $state: Include$1 $2"); http_include(dequote($2), $1 ne ''); next; } @@ -487,14 +530,14 @@ sub examine_http_config { && @server_aliases && (!%select || exists($select{$server_name}))) { my @names = uniq(@server_aliases); - debug(1, "$file:$line: will handle @names"); + debug(3, "$file:$line: will handle @names"); push @virthost, \@names; } $state = STATE_INITIAL; } elsif (/^(?:(?i)Use)\s+LetsEncryptChallenge/) { $state = STATE_USE_CHALLENGE; # } elsif (/^Use\s+LetsEncryptSSL\s+(\S+)/i) { - # debug(1, "$file: $1"); + # debug(3, "$file: $1"); # push @virthost, [ $1 ]; } elsif (/^(?:(?i)ServerName)\s+(\S+)/) { $server_name = dequote($1); @@ -509,7 +552,7 @@ sub examine_http_config { my $dir = dequote($1); $dir =~ s{/.well-known/acme-challenge$}{}; $www_root = $dir; - debug(1, "ACME challenge root dir: $www_root"); + debug(3, "ACME challenge root dir: $www_root"); } } elsif ($state == STATE_MACRO_SERVER) { if (m{^</macro}i) { @@ -595,7 +638,7 @@ sub initial_setup { error("the file \"$filename\" already exists"); abend(EX_NOPERM, "use --force to continue") unless $force; } - debug(1, "writing $filename"); + debug(2, "writing $filename"); unless ($dry_run) { prep_dir($filename); open(my $fd, '>', $filename) @@ -700,7 +743,7 @@ if ($dry_run) { unless (defined($apache_layout)) { while (my ($name, $layout) = each %apache_layout_tab) { if (-f $layout->{config}) { - debug(1, "assuming Apache layout \"$name\""); + debug(2, "assuming Apache layout \"$name\""); $apache_layout = $layout; last; } @@ -732,7 +775,7 @@ if (defined($www_root)) { abend(EX_CONFIG, "filename patterns not defined") unless (defined($filename_arg) && defined($filename_pattern{cert})); -$account_key = Crypt::OpenSSL::RSA->generate_key(2048); +$account_key = Crypt::OpenSSL::RSA->generate_key(4096); $challenge = Protocol::ACME::Challenge::LocalFile->new({www_root => $www_root}); foreach my $vhost (@virthost) { |