@@ -42,10 +42,110 @@ class letsencrypt {
4242 public function __construct (){
4343
4444 }
45+
46+ public function get_acme_script () {
47+ $ acme = excplode ("\n" , shell_exec ('which /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh ' ));
48+ $ acme = reset ($ acme );
49+ if (is_executable ($ acme )) {
50+ return $ acme ;
51+ } else {
52+ return false ;
53+ }
54+ }
55+
56+ public function get_acme_command ($ domains , $ key_file , $ bundle_file , $ cert_file ) {
57+
58+ $ letsencrypt = $ this ->get_acme_script ();
59+
60+ $ cmd = '' ;
61+ // generate cli format
62+ foreach ($ domains as $ domain ) {
63+ $ cmd .= (string ) " -d " . $ domain ;
64+ }
65+
66+ $ cmd = $ letsencrypt . " --issue $ cmd -w /usr/local/ispconfig/interface/acme && " . $ letsencrypt . " --install-cert " . $ cmd . " --key-file " . escapeshellarg ($ key_file ) . " --fullchain-file " . escapeshellarg ($ bundle_file ) . " --cert-file " . escapeshellarg ($ cert_file ) . " --reloadcmd " . escapeshellarg ($ this ->get_reload_command ());
67+
68+ return $ cmd ;
69+ }
70+
71+ public function get_certbot_script () {
72+ $ letsencrypt = explode ("\n" , shell_exec ('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot ' ));
73+ $ letsencrypt = reset ($ letsencrypt );
74+ if (is_executable ($ letsencrypt )) {
75+ return $ letsencrypt ;
76+ } else {
77+ return false ;
78+ }
79+ }
4580
81+ private function install_acme () {
82+ $ install_cmd = 'wget -O - https://get.acme.sh | sh ' ;
83+ $ ret = null ;
84+ $ val = 0 ;
85+ exec ($ install_cmd . ' 2>&1 ' , $ ret , $ val );
86+
87+ return ($ val == 0 ? true : false );
88+ }
89+
90+ private function get_reload_command () {
91+ global $ app , $ conf ;
92+
93+ $ web_config = $ app ->getconf ->get_server_config ($ conf ['server_id ' ], 'web ' );
94+
95+ $ daemon = '' ;
96+ switch ($ web_config ['server_type ' ]) {
97+ case 'nginx ' :
98+ $ daemon = $ web_config ['server_type ' ];
99+ break ;
100+ default :
101+ if (is_file ($ conf ['init_scripts ' ] . '/ ' . 'httpd24-httpd ' ) || is_dir ('/opt/rh/httpd24/root/etc/httpd ' )) {
102+ $ daemon = 'httpd24-httpd ' ;
103+ } elseif (is_file ($ conf ['init_scripts ' ] . '/ ' . 'httpd ' ) || is_dir ('/etc/httpd ' )) {
104+ $ daemon = 'httpd ' ;
105+ } else {
106+ $ daemon = 'apache2 ' ;
107+ }
108+ }
109+
110+ $ cmd = $ app ->system ->getinitcommand ($ daemon , 'force-reload ' );
111+ return $ cmd ;
112+ }
113+
114+ public function get_certbot_command ($ domains ) {
115+
116+ $ letsencrypt = $ this ->get_certbot_script ();
117+
118+ $ cmd = '' ;
119+ // generate cli format
120+ foreach ($ domains as $ domain ) {
121+ $ cmd .= (string ) " --domains " . $ domain ;
122+ }
123+
124+ $ matches = array ();
125+ $ ret = null ;
126+ $ val = 0 ;
127+ $ letsencrypt_version = exec ($ letsencrypt . ' --version 2>&1 ' , $ ret , $ val );
128+ if (preg_match ('/^(\S+|\w+)\s+(\d+(\.\d+)+)$/ ' , $ letsencrypt_version , $ matches )) {
129+ $ letsencrypt_version = $ matches [2 ];
130+ }
131+ if (version_compare ($ letsencrypt_version , '0.22 ' , '>= ' )) {
132+ $ acme_version = 'https://acme-v02.api.letsencrypt.org/directory ' ;
133+ } else {
134+ $ acme_version = 'https://acme-v01.api.letsencrypt.org/directory ' ;
135+ }
136+
137+ $ cmd = $ letsencrypt . " certonly -n --text --agree-tos --expand --authenticator webroot --server $ acme_version --rsa-key-size 4096 --email postmaster@ $ domain $ cmd --webroot-path /usr/local/ispconfig/interface/acme " ;
138+
139+ return $ cmd ;
140+ }
141+
46142 public function get_letsencrypt_certificate_paths ($ domains = array ()) {
47143 global $ app ;
48144
145+ if ($ this ->get_acme_script ()) {
146+ return false ;
147+ }
148+
49149 if (empty ($ domains )) return false ;
50150 if (!is_dir ($ this ->renew_config_path )) return false ;
51151
@@ -183,11 +283,17 @@ public function request_certificates($data, $server_type = 'apache') {
183283 $ web_config = $ app ->getconf ->get_server_config ($ conf ['server_id ' ], 'web ' );
184284 $ server_config = $ app ->getconf ->get_server_config ($ conf ['server_id ' ], 'server ' );
185285
286+ $ use_acme = false ;
287+ if ($ this ->get_acme_script ()) {
288+ $ use_acme = true ;
289+ } elseif (!$ this ->get_certbot_script ()) {
290+ // acme and le missing
291+ $ this ->install_acme ();
292+ }
293+
186294 $ tmp = $ app ->letsencrypt ->get_website_certificate_paths ($ data );
187295 $ domain = $ tmp ['domain ' ];
188296 $ key_file = $ tmp ['key ' ];
189- $ key_file2 = $ tmp ['key2 ' ];
190- $ csr_file = $ tmp ['csr ' ];
191297 $ crt_file = $ tmp ['crt ' ];
192298 $ bundle_file = $ tmp ['bundle ' ];
193299
@@ -256,43 +362,40 @@ public function request_certificates($data, $server_type = 'apache') {
256362 $ app ->log ("There were " . $ le_domain_count . " domains in the domain list. LE only supports 100, so we strip the rest. " , LOGLEVEL_WARN );
257363 }
258364
259- // generate cli format
260- foreach ($ temp_domains as $ temp_domain ) {
261- $ cli_domain_arg .= (string ) " --domains " . $ temp_domain ;
262- }
263-
264365 // unset useless data
265366 unset($ subdomains );
266367 unset($ aliasdomains );
267368
268369 $ letsencrypt_cmd = '' ;
370+ if ($ use_acme ) {
371+ $ letsencrypt_cmd = $ this ->get_acme_command ($ temp_domains , $ key_file , $ bundle_file , $ crt_file );
372+ } else {
373+ $ letsencrypt_cmd = $ this ->get_certbot_command ($ temp_domains );
374+ }
375+
269376 $ success = false ;
270377 if (!empty ($ cli_domain_arg )) {
271378 if (!isset ($ server_config ['migration_mode ' ]) || $ server_config ['migration_mode ' ] != 'y ' ) {
272379 $ app ->log ("Create Let's Encrypt SSL Cert for: $ domain " , LOGLEVEL_DEBUG );
273380 $ app ->log ("Let's Encrypt SSL Cert domains: $ cli_domain_arg " , LOGLEVEL_DEBUG );
274381
275- $ letsencrypt = explode ("\n" , shell_exec ('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot ' ));
276- $ letsencrypt = reset ($ letsencrypt );
277- if (is_executable ($ letsencrypt )) {
278- $ letsencrypt_version = exec ($ letsencrypt . ' --version 2>&1 ' , $ ret , $ val );
279- if (preg_match ('/^(\S+|\w+)\s+(\d+(\.\d+)+)$/ ' , $ letsencrypt_version , $ matches )) {
280- $ letsencrypt_version = $ matches [2 ];
281- }
282- if ($ letsencrypt_version >=0.22 ) {
283- $ acme_version = 'https://acme-v02.api.letsencrypt.org/directory ' ;
284- } else {
285- $ acme_version = 'https://acme-v01.api.letsencrypt.org/directory ' ;
286- }
287- $ letsencrypt_cmd = $ letsencrypt . " certonly -n --text --agree-tos --expand --authenticator webroot --server $ acme_version --rsa-key-size 4096 --email postmaster@ $ domain $ cli_domain_arg --webroot-path /usr/local/ispconfig/interface/acme " ;
288- $ success = $ app ->system ->_exec ($ letsencrypt_cmd );
289- }
382+ $ success = $ app ->system ->_exec ($ letsencrypt_cmd );
290383 } else {
291384 $ app ->log ("Migration mode active, skipping Let's Encrypt SSL Cert creation for: $ domain " , LOGLEVEL_DEBUG );
292385 $ success = true ;
293386 }
294387 }
295388
389+ if ($ use_acme === true ) {
390+ if (!$ success ) {
391+ $ app ->log ('Let \'s Encrypt SSL Cert for: ' . $ domain . ' could not be issued. ' , LOGLEVEL_WARN );
392+ $ app ->log ($ letsencrypt_cmd , LOGLEVEL_WARN );
393+ return false ;
394+ } else {
395+ return true ;
396+ }
397+ }
398+
296399 $ le_files = $ this ->get_letsencrypt_certificate_paths ($ temp_domains );
297400 unset($ temp_domains );
298401
0 commit comments