App-Acmeman
view release on metacpan or search on metacpan
lib/App/Acmeman/Source/Apache.pm view on Meta::CPAN
package App::Acmeman::Source::Apache;
use strict;
use warnings;
use Carp;
use feature 'state';
use File::Path qw(make_path);
use File::Spec;
use App::Acmeman::Apache::Layout;
use App::Acmeman::Log qw(:all);
use parent 'App::Acmeman::Source';
use Getopt::Long qw(GetOptionsFromArray :config gnu_getopt no_ignore_case);
use Apache::Defaults;
use Apache::Config::Preproc;
use Text::ParseWords;
sub new {
my $class = shift;
my $server_root;
GetOptionsFromArray(\@_,
'server-root=s' => \$server_root);
my $layout = detect App::Acmeman::Apache::Layout(@_);
my $self = bless { _layout => $layout }, $class;
$self->server_root($server_root) if $server_root;
return $self;
}
sub layout { shift->{_layout} }
sub scan {
my ($self) = @_;
debug(2, 'assuming Apache layout "'.$self->layout->name.'"');
$self->set(qw(core postrenew), $self->layout->restart_command)
unless $self->is_set(qw(core postrenew));
return $self->examine_http_config($self->layout->config_file);
}
sub dequote {
my ($self, $arg) = @_;
if (defined($arg) && $arg =~ s{^"(.*?)"$}{$1}) {
$arg =~ s{\\([\\"])}{$1}g;
}
return $arg;
}
sub examine_http_config {
my ($self, $file) = @_;
my $app = new Apache::Config::Preproc(
$file,
-expand => [ 'compact',
{ 'include' => [ server_root => $self->server_root ] },
{ 'macro' => [
'keep' => [ qw(LetsEncryptChallenge
LetsEncryptReference
LetsEncryptSSL)
]
]
}
])
or do {
error($Apache::Admin::Config::ERROR);
return 0;
};
foreach my $sect ($app->section(-name => "macro")) {
if ($sect->value =~ m{^(?ix)letsencryptssl
\s+
(.+)}
&& ! $self->is_set(qw(files apache))) {
$self->set(qw(files apache argument), $1);
map {
if ($_->name =~ m{^(?ix)
SSLCertificate((?:Key)|(?:Chain))?File}) {
my %t = (
'' => 'certificate-file',
key => 'key-file',
chain => 'ca-file'
);
$self->set(qw(files apache), $t{lc($1||'')},
$self->dequote($_->value));
}
} $sect->directive();
} elsif ($sect->value =~ m{^(?ix)letsencryptchallenge$}) {
foreach my $alias ($sect->directive('alias')) {
if ($alias->value =~ m{^/.well-known/acme-challenge\s+(.+)}) {
my $dir = $self->dequote($1);
$dir =~ s{/.well-known/acme-challenge$}{};
$self->set(qw(core rootdir), $dir);
debug(3, "ACME challenge root dir: $dir");
}
}
}
}
foreach my $sect ($app->section(-name => "virtualhost")) {
my ($server_name) = (map {
(my $s = $self->dequote($_->value)) =~ s{^https?://}{};
$s
} $sect->directive('servername'));
my @server_aliases = map { quotewords('\s+', 0,
$self->dequote($_->value)) }
$sect->directive('serveralias');
my @d = map {
if ($_->value =~ m{^(?ix)
(?:letsencrypt(challenge|ssl|reference))
(?:\s+(.+))?}) {
[lc($1),$self->dequote($2)]
} else {
()
}
lib/App/Acmeman/Source/Apache.pm view on Meta::CPAN
print $fd <<EOT;
<Macro LetsEncryptChallenge>
Alias /.well-known/acme-challenge $challenge_dir
<Directory $challenge_dir>
Options None
Require all granted
</Directory>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule /.well-known/acme-challenge - [L]
</IfModule>
</Macro>
<Macro LetsEncryptReference \$domain>
Use LetsEncryptChallenge
Alias /.dummy/\$domain /dev/null
</Macro>
<Macro LetsEncryptSSL \$domain>
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:E...
SSLCertificateFile $acme_dir/\$domain/cert.pem
SSLCertificateKeyFile $acme_dir/\$domain/privkey.pem
SSLCACertificateFile $acme_dir/$App::Acmeman::letsencrypt_root_cert_basename
</Macro>
<Macro LetsEncryptServer \$domain>
ServerName \$domain
Use LetsEncryptSSL \$domain
</Macro>
EOT
;
close $fd;
error("created file \"$filename\"", prefix => 'note');
$self->layout->post_setup($filename);
}
my $pfx = "please,";
unless ($self->is_letsencryptssl_defined) {
error("please, make sure your Apache configuration includes this file",
prefix => 'note');
$pfx = "and";
}
unless ($self->layout->apache_modules('macro')) {
error("$pfx enable mod_macro",
prefix => 'note');
}
return 1;
}
# Check if LetsEncryptSSL macro is defined
sub is_letsencryptssl_defined {
my ($self) = @_;
my $app = new Apache::Config::Preproc(
$self->layout->config_file,
-expand => [ 'compact',
{ 'include' => [ server_root => $self->server_root ] },
{ 'macro' => [
'keep' => [ qw(LetsEncryptChallenge
LetsEncryptReference
LetsEncryptSSL)
]
]
}
]);
if ($app) {
return grep { $_->value =~ m{^(?i)letsencryptssl\s+} }
$app->section(-name => "macro");
} else {
debug(1, $Apache::Admin::Config::ERROR);
return undef
}
}
1;
( run in 0.575 second using v1.01-cache-2.11-cpan-97f6503c9c8 )