]> git.proxmox.com Git - proxmox-acme.git/blob - src/PVE/ACME/DNSChallenge.pm
Implement function to resolve all subplugins
[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 sub get_subplugins {
158 return $api_name_list;
159 }
160
161 # The order of the parameters passed to proxmox-acme is important
162 # proxmox-acme setup $plugin [$domain|$alias] $txtvalue $plugin_conf_string
163 sub setup {
164 my ($self, $data) = @_;
165
166 die "No plugin data for DNSChallenge\n" if !defined($data->{plugin});
167 my $domain = $data->{plugin}->{alias} ? $data->{plugin}->{alias} : $data->{domain};
168 my $txtvalue = PVE::ACME::encode(sha256($data->{key_authorization}));
169 my $dnsplugin = $data->{plugin}->{api};
170 my $plugin_conf_string = $data->{plugin}->{data};
171
172 # for security reasons, we execute the command as nobody
173 # we can't verify that the code of the DNSPlugins are harmless.
174 my $cmd = ["setpriv", "--reuid", "nobody", "--regid", "nogroup", "--clear-groups", "--"];
175 push @$cmd, "/usr/bin/bash", $ACME_PATH, "setup", $dnsplugin, $domain;
176 push @$cmd, $txtvalue, $plugin_conf_string;
177
178 PVE::Tools::run_command($cmd, outfunc => $outfunc);
179 print "Add TXT record: _acme-challenge.$domain\n";
180 }
181
182 # The order of the parameters passed to proxmox-acme is important
183 # proxmox-acme teardown $plugin [$domain|$alias] $txtvalue $plugin_conf_string
184 sub teardown {
185 my ($self, $data) = @_;
186
187 die "No plugin data for DNSChallenge\n" if !defined($data->{plugin});
188 my $domain = $data->{plugin}->{alias} ? $data->{plugin}->{alias} : $data->{domain};
189 my $txtvalue = PVE::ACME::encode(sha256($data->{key_authorization}));
190 my $dnsplugin = $data->{plugin}->{api};
191 my $plugin_conf_string = $data->{plugin}->{data};
192
193 # for security reasons, we execute the command as nobody
194 # we can't verify that the code of the DNSPlugins are harmless.
195 my $cmd = ["setpriv", "--reuid", "nobody", "--regid", "nogroup", "--clear-groups", "--"];
196 push @$cmd, "/usr/bin/bash", "$ACME_PATH", "teardown", $dnsplugin, $domain ;
197 push @$cmd, $txtvalue, $plugin_conf_string;
198 PVE::Tools::run_command($cmd, outfunc => $outfunc);
199 print "Remove TXT record: _acme-challenge.$domain\n";
200 }
201
202 1;