mirror of
https://git.proxmox.com/git/proxmox-acme
synced 2025-04-29 03:21:39 +00:00
Add DNSChallenge Plugin
This plugin calls the custom script acme.sh and uses the implementation of the DNS API. Signed-off-by: Wolfgang Link <w.link@proxmox.com>
This commit is contained in:
parent
d18383f0d3
commit
98b96d9ee7
3
debian/control
vendored
3
debian/control
vendored
@ -13,5 +13,6 @@ Description: easy and small shell script to automatically issue
|
||||
and renew the free certificates from Let's Encrypt.
|
||||
Depends: curl (>= 7.64.0-1),
|
||||
coreutils (>= 8.30-1),
|
||||
sed (>= 4.7-1)
|
||||
sed (>= 4.7-1),
|
||||
libpve-common-perl,
|
||||
Recommends: idn
|
||||
|
@ -107,6 +107,7 @@ LIB_SOURCES = \
|
||||
ACME.pm \
|
||||
ACME/Challenge.pm \
|
||||
ACME/StandAlone.pm \
|
||||
ACME/DNSChallenge.pm \
|
||||
|
||||
all:
|
||||
|
||||
|
@ -23,6 +23,8 @@ file_set_contents
|
||||
file_get_contents
|
||||
);
|
||||
|
||||
use PVE::ACME::DNSChallenge;
|
||||
|
||||
Crypt::OpenSSL::RSA->import_random_seed();
|
||||
|
||||
my $LETSENCRYPT_STAGING = 'https://acme-staging-v02.api.letsencrypt.org/directory';
|
||||
|
198
src/PVE/ACME/DNSChallenge.pm
Normal file
198
src/PVE/ACME/DNSChallenge.pm
Normal file
@ -0,0 +1,198 @@
|
||||
package PVE::ACME::DNSChallenge;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Digest::SHA qw(sha256);
|
||||
use PVE::Tools;
|
||||
|
||||
use base qw(PVE::ACME::Challenge);
|
||||
|
||||
my $ACME_PATH = '/usr/share/proxmox-acme/proxmox-acme';
|
||||
|
||||
sub supported_challenge_types {
|
||||
return { 'dns-01' => 1 };
|
||||
}
|
||||
|
||||
sub type {
|
||||
return 'dns';
|
||||
}
|
||||
|
||||
my $api_name_list = [
|
||||
'acmedns',
|
||||
'acmeproxy',
|
||||
'active24',
|
||||
'ad',
|
||||
'ali',
|
||||
'autodns',
|
||||
'aws',
|
||||
'azure',
|
||||
'cf',
|
||||
'clouddns',
|
||||
'cloudns',
|
||||
'cn',
|
||||
'conoha',
|
||||
'constellix',
|
||||
'cx',
|
||||
'cyon',
|
||||
'da',
|
||||
'ddnss',
|
||||
'desec',
|
||||
'dgon',
|
||||
'dnsimple',
|
||||
'do',
|
||||
'doapi',
|
||||
'domeneshop',
|
||||
'dp',
|
||||
'dpi',
|
||||
'dreamhost',
|
||||
'duckdns',
|
||||
'durabledns',
|
||||
'dyn',
|
||||
'dynu',
|
||||
'dynv6',
|
||||
'easydns',
|
||||
'euserv',
|
||||
'exoscale',
|
||||
'freedns',
|
||||
'gandi_livedns',
|
||||
'gcloud',
|
||||
'gd',
|
||||
'gdnsdk',
|
||||
'he',
|
||||
'hexonet',
|
||||
'hostingde',
|
||||
'infoblox',
|
||||
'internetbs',
|
||||
'inwx',
|
||||
'ispconfig',
|
||||
'jd',
|
||||
'kas',
|
||||
'kinghost',
|
||||
'knot',
|
||||
'leaseweb',
|
||||
'lexicon',
|
||||
'linode',
|
||||
'linode_v4',
|
||||
'loopia',
|
||||
'lua',
|
||||
'maradns',
|
||||
'me',
|
||||
'miab',
|
||||
'misaka',
|
||||
'myapi',
|
||||
'mydevil',
|
||||
'mydnsjp',
|
||||
'namecheap',
|
||||
'namecom',
|
||||
'namesilo',
|
||||
'nederhost',
|
||||
'neodigit',
|
||||
'netcup',
|
||||
'nic',
|
||||
'nsd',
|
||||
'nsone',
|
||||
'nsupdate',
|
||||
'nw',
|
||||
'one',
|
||||
'online',
|
||||
'openprovider',
|
||||
'opnsense',
|
||||
'ovh',
|
||||
'pdns',
|
||||
'pleskxml',
|
||||
'pointhq',
|
||||
'rackspace',
|
||||
'rcode0',
|
||||
'regru',
|
||||
'schlundtech',
|
||||
'selectel',
|
||||
'servercow',
|
||||
'tele3',
|
||||
'ultra',
|
||||
'unoeuro',
|
||||
'variomedia',
|
||||
'vscale',
|
||||
'vultr',
|
||||
'yandex',
|
||||
'zilore',
|
||||
'zone',
|
||||
'zonomi',
|
||||
];
|
||||
|
||||
sub properties {
|
||||
return {
|
||||
api => {
|
||||
description => "API plugin name",
|
||||
type => 'string',
|
||||
enum => $api_name_list,
|
||||
},
|
||||
data => {
|
||||
type => 'string',
|
||||
description => 'DNS plugin data.',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
sub options {
|
||||
return {
|
||||
api => {},
|
||||
data => {},
|
||||
nodes => { optional => 1 },
|
||||
disable => { optional => 1 },
|
||||
};
|
||||
}
|
||||
|
||||
my $outfunc = sub {
|
||||
my $line = shift;
|
||||
print "$line\n";
|
||||
};
|
||||
|
||||
sub extract_challenge {
|
||||
my ($self, $challenge) = @_;
|
||||
|
||||
return PVE::ACME::Challenge->extract_challenge($challenge, 'dns-01');
|
||||
}
|
||||
|
||||
# The order of the parameters passed to proxmox-acme is important
|
||||
# proxmox-acme setup $plugin [$domain|$alias] $txtvalue $plugin_conf_string
|
||||
sub setup {
|
||||
my ($self, $data) = @_;
|
||||
|
||||
die "No plugin data for DNSChallenge\n" if !defined($data->{plugin});
|
||||
my $domain = $data->{plugin}->{alias} ? $data->{plugin}->{alias} : $data->{domain};
|
||||
my $txtvalue = PVE::ACME::encode(sha256($data->{key_authorization}));
|
||||
my $dnsplugin = $data->{plugin}->{api};
|
||||
my $plugin_conf_string = $data->{plugin}->{data};
|
||||
|
||||
# for security reasons, we execute the command as nobody
|
||||
# we can't verify that the code of the DNSPlugins are harmless.
|
||||
my $cmd = ["setpriv", "--reuid", "nobody", "--regid", "nogroup", "--clear-groups", "--"];
|
||||
push @$cmd, "/usr/bin/bash", $ACME_PATH, "setup", $dnsplugin, $domain;
|
||||
push @$cmd, $txtvalue, $plugin_conf_string;
|
||||
|
||||
PVE::Tools::run_command($cmd, outfunc => $outfunc);
|
||||
print "Add TXT record: _acme-challenge.$domain\n";
|
||||
}
|
||||
|
||||
# The order of the parameters passed to proxmox-acme is important
|
||||
# proxmox-acme teardown $plugin [$domain|$alias] $txtvalue $plugin_conf_string
|
||||
sub teardown {
|
||||
my ($self, $data) = @_;
|
||||
|
||||
die "No plugin data for DNSChallenge\n" if !defined($data->{plugin});
|
||||
my $domain = $data->{plugin}->{alias} ? $data->{plugin}->{alias} : $data->{domain};
|
||||
my $txtvalue = PVE::ACME::encode(sha256($data->{key_authorization}));
|
||||
my $dnsplugin = $data->{plugin}->{api};
|
||||
my $plugin_conf_string = $data->{plugin}->{data};
|
||||
|
||||
# for security reasons, we execute the command as nobody
|
||||
# we can't verify that the code of the DNSPlugins are harmless.
|
||||
my $cmd = ["setpriv", "--reuid", "nobody", "--regid", "nogroup", "--clear-groups", "--"];
|
||||
push @$cmd, "/usr/bin/bash", "$ACME_PATH", "teardown", $dnsplugin, $domain ;
|
||||
push @$cmd, $txtvalue, $plugin_conf_string;
|
||||
PVE::Tools::run_command($cmd, outfunc => $outfunc);
|
||||
print "Remove TXT record: _acme-challenge.$domain\n";
|
||||
}
|
||||
|
||||
1;
|
Loading…
Reference in New Issue
Block a user