]> git.proxmox.com Git - proxmox-acme.git/blob - src/PVE/ACME/DNSChallenge.pm
Add DNSChallenge Plugin
[proxmox-acme.git] / src / PVE / ACME / DNSChallenge.pm
1 package PVE::ACME::DNSChallenge;
2
3 use strict;
4 use warnings;
5
6 use Digest::SHA qw(sha256);
7 use PVE::Tools;
8
9 use base qw(PVE::ACME::Challenge);
10
11 my $ACME_PATH = '/usr/share/proxmox-acme/proxmox-acme';
12
13 sub supported_challenge_types {
14 return { 'dns-01' => 1 };
15 }
16
17 sub type {
18 return 'dns';
19 }
20
21 my $api_name_list = [
22 'acmedns',
23 'acmeproxy',
24 'active24',
25 'ad',
26 'ali',
27 'autodns',
28 'aws',
29 'azure',
30 'cf',
31 'clouddns',
32 'cloudns',
33 'cn',
34 'conoha',
35 'constellix',
36 'cx',
37 'cyon',
38 'da',
39 'ddnss',
40 'desec',
41 'dgon',
42 'dnsimple',
43 'do',
44 'doapi',
45 'domeneshop',
46 'dp',
47 'dpi',
48 'dreamhost',
49 'duckdns',
50 'durabledns',
51 'dyn',
52 'dynu',
53 'dynv6',
54 'easydns',
55 'euserv',
56 'exoscale',
57 'freedns',
58 'gandi_livedns',
59 'gcloud',
60 'gd',
61 'gdnsdk',
62 'he',
63 'hexonet',
64 'hostingde',
65 'infoblox',
66 'internetbs',
67 'inwx',
68 'ispconfig',
69 'jd',
70 'kas',
71 'kinghost',
72 'knot',
73 'leaseweb',
74 'lexicon',
75 'linode',
76 'linode_v4',
77 'loopia',
78 'lua',
79 'maradns',
80 'me',
81 'miab',
82 'misaka',
83 'myapi',
84 'mydevil',
85 'mydnsjp',
86 'namecheap',
87 'namecom',
88 'namesilo',
89 'nederhost',
90 'neodigit',
91 'netcup',
92 'nic',
93 'nsd',
94 'nsone',
95 'nsupdate',
96 'nw',
97 'one',
98 'online',
99 'openprovider',
100 'opnsense',
101 'ovh',
102 'pdns',
103 'pleskxml',
104 'pointhq',
105 'rackspace',
106 'rcode0',
107 'regru',
108 'schlundtech',
109 'selectel',
110 'servercow',
111 'tele3',
112 'ultra',
113 'unoeuro',
114 'variomedia',
115 'vscale',
116 'vultr',
117 'yandex',
118 'zilore',
119 'zone',
120 'zonomi',
121 ];
122
123 sub properties {
124 return {
125 api => {
126 description => "API plugin name",
127 type => 'string',
128 enum => $api_name_list,
129 },
130 data => {
131 type => 'string',
132 description => 'DNS plugin data.',
133 },
134 };
135 }
136
137 sub options {
138 return {
139 api => {},
140 data => {},
141 nodes => { optional => 1 },
142 disable => { optional => 1 },
143 };
144 }
145
146 my $outfunc = sub {
147 my $line = shift;
148 print "$line\n";
149 };
150
151 sub extract_challenge {
152 my ($self, $challenge) = @_;
153
154 return PVE::ACME::Challenge->extract_challenge($challenge, 'dns-01');
155 }
156
157 # The order of the parameters passed to proxmox-acme is important
158 # proxmox-acme setup $plugin [$domain|$alias] $txtvalue $plugin_conf_string
159 sub setup {
160 my ($self, $data) = @_;
161
162 die "No plugin data for DNSChallenge\n" if !defined($data->{plugin});
163 my $domain = $data->{plugin}->{alias} ? $data->{plugin}->{alias} : $data->{domain};
164 my $txtvalue = PVE::ACME::encode(sha256($data->{key_authorization}));
165 my $dnsplugin = $data->{plugin}->{api};
166 my $plugin_conf_string = $data->{plugin}->{data};
167
168 # for security reasons, we execute the command as nobody
169 # we can't verify that the code of the DNSPlugins are harmless.
170 my $cmd = ["setpriv", "--reuid", "nobody", "--regid", "nogroup", "--clear-groups", "--"];
171 push @$cmd, "/usr/bin/bash", $ACME_PATH, "setup", $dnsplugin, $domain;
172 push @$cmd, $txtvalue, $plugin_conf_string;
173
174 PVE::Tools::run_command($cmd, outfunc => $outfunc);
175 print "Add TXT record: _acme-challenge.$domain\n";
176 }
177
178 # The order of the parameters passed to proxmox-acme is important
179 # proxmox-acme teardown $plugin [$domain|$alias] $txtvalue $plugin_conf_string
180 sub teardown {
181 my ($self, $data) = @_;
182
183 die "No plugin data for DNSChallenge\n" if !defined($data->{plugin});
184 my $domain = $data->{plugin}->{alias} ? $data->{plugin}->{alias} : $data->{domain};
185 my $txtvalue = PVE::ACME::encode(sha256($data->{key_authorization}));
186 my $dnsplugin = $data->{plugin}->{api};
187 my $plugin_conf_string = $data->{plugin}->{data};
188
189 # for security reasons, we execute the command as nobody
190 # we can't verify that the code of the DNSPlugins are harmless.
191 my $cmd = ["setpriv", "--reuid", "nobody", "--regid", "nogroup", "--clear-groups", "--"];
192 push @$cmd, "/usr/bin/bash", "$ACME_PATH", "teardown", $dnsplugin, $domain ;
193 push @$cmd, $txtvalue, $plugin_conf_string;
194 PVE::Tools::run_command($cmd, outfunc => $outfunc);
195 print "Remove TXT record: _acme-challenge.$domain\n";
196 }
197
198 1;