Skip to content

Commit 301dfb7

Browse files
committed
Update installer_base.lib.php for ISPConfig to use certbot webroot for webservers and certbot standalone for other servers. Also extend the certs for postfix, dovecot and pure-ftpd-mysql.
1 parent 9c5fbe7 commit 301dfb7

File tree

1 file changed

+89
-63
lines changed

1 file changed

+89
-63
lines changed

install/lib/installer_base.lib.php

Lines changed: 89 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22

33
/*
4-
Copyright (c) 2007-2010, Till Brehm, projektfarm Gmbh
4+
Copyright (c) 2007-2018, Till Brehm, projektfarm Gmbh, Hj Ahmad Rasyid Hj Ismail
55
All rights reserved.
66
77
Redistribution and use in source and binary forms, with or without modification,
@@ -2400,41 +2400,68 @@ public function configure_apps_vhost() {
24002400
public function make_ispconfig_ssl_cert() {
24012401
global $conf, $autoinstall;
24022402

2403-
// Get hostname from user entry or shell command
2403+
//* Get hostname from user entry or shell command */
24042404
if($conf['hostname'] !== ('localhost' || '')) $hostname = $conf['hostname'];
24052405
else $hostname = exec('hostname -f');
2406-
2406+
24072407
// Check dns a record exist and its ip equal to server public ip
24082408
$svr_ip = file_get_contents('http://dynamicdns.park-your-domain.com/getip');
24092409
if (checkdnsrr(idn_to_ascii($hostname, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46), 'A')) {
24102410
$dnsa=dns_get_record($hostname, DNS_A);
24112411
$dns_ips = array();
24122412
foreach ($dnsa as $rec) {
2413-
$dns_ips[] = $rec['ip'];
2413+
$dns_ips[] = $rec['ip'];
24142414
}
24152415
}
24162416

2417-
// Check if LE SSL folder for the hostname existed
2418-
// Then create standalone LE SSL certs for this server
2419-
$le_live_dir = '/etc/letsencrypt/live/' . $hostname;
2417+
// Request for certs if no LE SSL folder for server fqdn exist
2418+
$le_live_dir = '/etc/letsencrypt/live/' . $hostname;
24202419
if (!@is_dir($le_live_dir) && in_array($svr_ip, $dns_ips)) {
24212420

2422-
// If it is nginx webserver
2423-
if($conf['nginx']['installed'] == true)
2424-
exec("certbot certonly --authenticator standalone -d $hostname --pre-hook 'service nginx stop' --post-hook 'service nginx start'");
2425-
2426-
// If it is apache2 webserver
2427-
elseif($conf['apache']['installed'] == true)
2428-
exec("certbot certonly --authenticator standalone -d $hostname --pre-hook 'service apache2 stop' --post-hook 'service apache2 start'");
2429-
2430-
// If it is not webserver
2431-
else
2432-
exec("certbot certonly --authenticator standalone -d $hostname");
2421+
// Try to support for multi domain, if it is defined in letsencrypt_domains.master
2422+
$domain_file = '/usr/local/ispconfig/server/conf-custom/letsencrypt_domains.master';
2423+
$cli_domain_arg = '';
2424+
2425+
// If file exist, get the unique domains but not more then 99
2426+
if (file_exists($domain_file)) {
2427+
$extra_domains = file($domain_file, FILE_IGNORE_NEW_LINES);
2428+
$extra_domains = array_unique($extra_domains);
2429+
$le_domain_count = count($extra_domains);
2430+
if($le_domain_count > 99) {
2431+
$extra_domains = array_slice($extra_domains, 0, 99);
2432+
echo "\nExtra domains exceed limits. Only the first 99 will be expanded into the hostname FQDN cert.\n";
2433+
}
2434+
foreach($extra_domains as $le_domain) $cli_domain_arg .= (string) ' -d ' . $le_domain;
2435+
}
2436+
2437+
// Get the default LE client name and version
2438+
$le_client = explode("\n", shell_exec('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot'));
2439+
$le_client = reset($le_client);
2440+
$le_info = exec($le_client . ' --version 2>&1', $ret, $val);
2441+
if(preg_match('/^(\S+|\w+)\s+(\d+(\.\d+)+)$/', $le_info, $matches)) { $le_name = $matches[1]; $le_version = $matches[2]; }
2442+
$acme_version = '--server https://acme-v0' . (($le_version >=0.22) ? '2' : '1') . '.api.letsencrypt.org/directory';
2443+
$certonly = 'certonly --agree-tos --non-interactive --expand --rsa-key-size 4096';
2444+
$webroot = '--authenticator webroot --webroot-path /var/www/html';
2445+
$standalone = '--authenticator standalone';
2446+
2447+
// Only certbot is supported to prevent unknown failures
2448+
if($le_name == 'certbot' && is_executable($le_client)) {
2449+
// If this is a webserver, we use webroot
2450+
if(($conf['nginx']['installed'] || $conf['apache']['installed']) == true) {
2451+
$well_known = '/var/www/html/.well-known';
2452+
$challenge = "$well_known/acme_challenge";
2453+
$acme_challenge = '/usr/local/ispconfig/interface/acme/.well-known/acme-challenge';
2454+
if (!is_dir($well_known)) mkdir($well_known, 0755, true);
2455+
if (!is_dir($challenge)) exec("ln -sf $acme_challenge $challenge");
2456+
exec("$le_client $certonly $acme_version $webroot --email postmaster@$hostname -d $hostname $cli_domain_arg");
2457+
}
2458+
// Else, it is not webserver, so we use standalone
2459+
else
2460+
exec("$le_client $certonly $acme_version $standalone --email postmaster@$hostname -d $hostname $cli_domain_arg");
2461+
}
24332462
}
2434-
// TODO: To implement webroot instead of standalone via
2435-
// probably ispconfig vhost to provide for port 80 && 443
24362463

2437-
// Define and check ISPConfig SSL folder
2464+
//* Define and check ISPConfig SSL folder */
24382465
$install_dir = $conf['ispconfig_install_dir'];
24392466

24402467
$ssl_crt_file = $install_dir.'/interface/ssl/ispserver.crt';
@@ -2443,63 +2470,62 @@ public function make_ispconfig_ssl_cert() {
24432470
$ssl_pem_file = $install_dir.'/interface/ssl/ispserver.pem';
24442471

24452472
if(!@is_dir($install_dir.'/interface/ssl')) mkdir($install_dir.'/interface/ssl', 0755, true);
2446-
2473+
2474+
$date = new DateTime();
2475+
24472476
// If the LE SSL certs for this hostname exists
24482477
if (is_dir($le_live_dir) && in_array($svr_ip, $dns_ips)) {
2449-
2478+
24502479
// Backup existing ispserver ssl files
2451-
$date = new DateTime();
24522480
if (file_exists($ssl_crt_file)) rename($ssl_crt_file, $ssl_crt_file . '-' .$date->format('YmdHis') . '.bak');
24532481
if (file_exists($ssl_crt_file)) rename($ssl_key_file, $ssl_key_file . '-' .$date->format('YmdHis') . '.bak');
24542482
if (file_exists($ssl_crt_file)) rename($ssl_pem_file, $ssl_pem_file . '-' .$date->format('YmdHis') . '.bak');
2455-
2483+
24562484
// Create symlink to LE fullchain and key for ISPConfig
24572485
symlink($le_live_dir.'/fullchain.pem', $ssl_crt_file);
24582486
symlink($le_live_dir.'/privkey.pem', $ssl_key_file);
24592487

24602488
// Build ispserver.pem file and chmod it
24612489
exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file; chmod 600 $ssl_pem_file");
2462-
2463-
2464-
2490+
24652491
// Extend LE SSL certs to postfix
2466-
if ($conf['postfix']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig LE SSL certs to postfix?', array('y', 'n'), 'y')) == 'y')) {
2467-
2468-
// Define folder, file(s)
2469-
$cf = $conf['postfix'];
2470-
$postfix_dir = $cf['config_dir'];
2471-
if(!is_dir($postfix_dir)) $this->error("The postfix configuration directory '$postfix_dir' does not exist.");
2472-
$smtpd_crt = $postfix_dir.'/smtpd.cert';
2473-
$smtpd_key = $postfix_dir.'/smtpd.key';
2474-
2475-
// Backup existing postfix ssl files
2476-
if (file_exists($smtpd_crt)) rename($smtpd_crt, $smtpd_crt . '-' .$date->format('YmdHis') . '.bak');
2477-
if (file_exists($smtpd_key)) rename($smtpd_key, $smtpd_key . '-' .$date->format('YmdHis') . '.bak');
2478-
2479-
// Create symlink to ISPConfig SSL files
2480-
symlink($ssl_crt_file, $smtpd_crt);
2481-
symlink($ssl_key_file, $smtpd_key);
2482-
}
2483-
2492+
if ($conf['postfix']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig LE SSL certs to postfix?', array('y', 'n'), 'y')) == 'y') {
2493+
2494+
// Define folder, file(s)
2495+
$cf = $conf['postfix'];
2496+
$postfix_dir = $cf['config_dir'];
2497+
if(!is_dir($postfix_dir)) $this->error("The postfix configuration directory '$postfix_dir' does not exist.");
2498+
$smtpd_crt = $postfix_dir.'/smtpd.cert';
2499+
$smtpd_key = $postfix_dir.'/smtpd.key';
2500+
2501+
// Backup existing postfix ssl files
2502+
if (file_exists($smtpd_crt)) rename($smtpd_crt, $smtpd_crt . '-' .$date->format('YmdHis') . '.bak');
2503+
if (file_exists($smtpd_key)) rename($smtpd_key, $smtpd_key . '-' .$date->format('YmdHis') . '.bak');
2504+
2505+
// Create symlink to ISPConfig SSL files
2506+
symlink($ssl_crt_file, $smtpd_crt);
2507+
symlink($ssl_key_file, $smtpd_key);
2508+
}
2509+
24842510
// Extend LE SSL certs to pureftpd
24852511
if ($conf['pureftpd']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig LE SSL certs to pureftpd? Creating dhparam file takes some times.', array('y', 'n'), 'y')) == 'y') {
2486-
2487-
// Define folder, file(s)
2488-
$pureftpd_dir = '/etc/ssl/private';
2489-
if(!is_dir($pureftpd_dir)) mkdir($pureftpd_dir, 0755, true);
2490-
$pureftpd_pem = $pureftpd_dir.'/pure-ftpd.pem';
2491-
2492-
// Backup existing postfix ssl files
2493-
if (file_exists($pureftpd_pem)) rename($pureftpd_pem, $pureftpd_pem . '-' .$date->format('YmdHis') . '.bak');
2494-
2495-
// Create symlink to ISPConfig SSL files
2496-
symlink($ssl_pem_file, $pureftpd_pem);
2497-
if (!file_exists("$pureftpd_dir/pure-ftpd-dhparams.pem"))
2498-
exec("cd $pureftpd_dir; openssl dhparam -out dhparam4096.pem 4096; ln -sf dhparam4096.pem pure-ftpd-dhparams.pem");
2499-
}
2500-
2512+
2513+
// Define folder, file(s)
2514+
$pureftpd_dir = '/etc/ssl/private';
2515+
if(!is_dir($pureftpd_dir)) mkdir($pureftpd_dir, 0755, true);
2516+
$pureftpd_pem = $pureftpd_dir.'/pure-ftpd.pem';
2517+
2518+
// Backup existing postfix ssl files
2519+
if (file_exists($pureftpd_pem)) rename($pureftpd_pem, $pureftpd_pem . '-' .$date->format('YmdHis') . '.bak');
2520+
2521+
// Create symlink to ISPConfig SSL files
2522+
symlink($ssl_pem_file, $pureftpd_pem);
2523+
if (!file_exists("$pureftpd_dir/pure-ftpd-dhparams.pem"))
2524+
exec("cd $pureftpd_dir; openssl dhparam -out dhparam4096.pem 4096; ln -sf dhparam4096.pem pure-ftpd-dhparams.pem");
2525+
}
2526+
25012527
} else {
2502-
2528+
25032529
// We can still use the old self-signed method
25042530
$ssl_pw = substr(md5(mt_rand()), 0, 6);
25052531
exec("openssl genrsa -des3 -passout pass:$ssl_pw -out $ssl_key_file 4096");
@@ -2513,7 +2539,7 @@ public function make_ispconfig_ssl_cert() {
25132539
rename($ssl_key_file, $ssl_key_file.'.secure');
25142540
rename($ssl_key_file.'.insecure', $ssl_key_file);
25152541
}
2516-
2542+
25172543
exec("chown -R root:root $install_dir/interface/ssl");
25182544

25192545
}

0 commit comments

Comments
 (0)