Newer
Older
//if(is_file($conf['init_scripts'].'/'.'openbsd-inetd')) exec($conf['init_scripts'].'/'.'openbsd-inetd restart');
}
if(!is_file('/etc/pure-ftpd/conf/DontResolve')) exec('echo "yes" > /etc/pure-ftpd/conf/DontResolve');
}
public function configure_mydns() {
global $conf;
// configure pam for SMTP authentication agains the ispconfig database
$configfile = 'mydns.conf';
if(is_file($conf['mydns']['config_dir'].'/'.$configfile)) copy($conf['mydns']['config_dir'].'/'.$configfile, $conf['mydns']['config_dir'].'/'.$configfile.'~');
if(is_file($conf['mydns']['config_dir'].'/'.$configfile.'~')) chmod($conf['mydns']['config_dir'].'/'.$configfile.'~', 0400);
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
$content = str_replace('{mysql_server_host}', $conf['mysql']['host'], $content);
Michel Käser
committed
$content = str_replace('{mysql_server_port}', $conf['mysql']['port'], $content);
$content = str_replace('{server_id}', $conf['server_id'], $content);
wf($conf['mydns']['config_dir'].'/'.$configfile, $content);
chmod($conf['mydns']['config_dir'].'/'.$configfile, 0600);
chown($conf['mydns']['config_dir'].'/'.$configfile, 'root');
chgrp($conf['mydns']['config_dir'].'/'.$configfile, 'root');
}
public function configure_powerdns() {
global $conf;
//* Create the database
if(!$this->db->query('CREATE DATABASE IF NOT EXISTS ?? DEFAULT CHARACTER SET ?', $conf['powerdns']['database'], $conf['mysql']['charset'])) {
$this->error('Unable to create MySQL database: '.$conf['powerdns']['database'].'.');
}
//* Create the ISPConfig database user in the local database
$query = "GRANT ALL ON ?? TO ?@'localhost'";
if(!$this->db->query($query, $conf['powerdns']['database'] . '.*', $conf['mysql']['ispconfig_user'])) {
$this->error('Unable to create user for powerdns database Error: '.$this->db->errorMessage);
}
//* load the powerdns databse dump
if($conf['mysql']['admin_password'] == '') {
caselog("mysql --default-character-set=".$conf['mysql']['charset']." -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' '".$conf['powerdns']['database']."' < '".ISPC_INSTALL_ROOT."/install/sql/powerdns.sql' &> /dev/null",
__FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in powerdns.sql');
} else {
caselog("mysql --default-character-set=".$conf['mysql']['charset']." -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' -p'".$conf['mysql']['admin_password']."' '".$conf['powerdns']['database']."' < '".ISPC_INSTALL_ROOT."/install/sql/powerdns.sql' &> /dev/null",
__FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in powerdns.sql');
}
//* Create the powerdns config file
$configfile = 'pdns.local';
if(is_file($conf['powerdns']['config_dir'].'/'.$configfile)) copy($conf['powerdns']['config_dir'].'/'.$configfile, $conf['powerdns']['config_dir'].'/'.$configfile.'~');
if(is_file($conf['powerdns']['config_dir'].'/'.$configfile.'~')) chmod($conf['powerdns']['config_dir'].'/'.$configfile.'~', 0400);
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
$content = str_replace('{powerdns_database}', $conf['powerdns']['database'], $content);
$content = str_replace('{mysql_server_host}', $conf['mysql']['host'], $content);
Michel Käser
committed
$content = str_replace('{mysql_server_port}', $conf['mysql']['port'], $content);
wf($conf['powerdns']['config_dir'].'/'.$configfile, $content);
chmod($conf['powerdns']['config_dir'].'/'.$configfile, 0600);
chown($conf['powerdns']['config_dir'].'/'.$configfile, 'root');
chgrp($conf['powerdns']['config_dir'].'/'.$configfile, 'root');
}
//** writes bind configuration files
public function process_bind_file($configfile, $target='/', $absolute=false) {
global $conf;
if ($absolute) $full_file_name = $target.$configfile;
else $full_file_name = $conf['ispconfig_install_dir'].$target.$configfile;
//* Backup exiting file
if(is_file($full_file_name)) {
copy($full_file_name, $config_dir.$configfile.'~');
}
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
$content = str_replace('{mysql_server_ispconfig_database}', $conf['mysql']['database'], $content);
$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
$content = str_replace('{ispconfig_install_dir}', $conf['ispconfig_install_dir'], $content);
$content = str_replace('{dnssec_conffile}', $conf['ispconfig_install_dir'].'/server/scripts/dnssec-config.sh', $content);
wf($full_file_name, $content);
}
public function configure_bind() {
global $conf;
//* Check if the zonefile directory has a slash at the end
$content=$conf['bind']['bind_zonefiles_dir'];
if(substr($content, -1, 1) != '/') {
$content .= '/';
Florian Schaal
committed
if(!@is_dir($content)) mkdir($content, 02770, true);
//* Chown the slave subdirectory to $conf['bind']['bind_user']
chown($content, $conf['bind']['bind_user']);
chgrp($content, $conf['bind']['bind_group']);
Florian Schaal
committed
chmod($content, 02770);
//* Install scripts for dnssec implementation
$this->process_bind_file('named.conf.options', '/etc/bind/', true); //TODO replace hardcoded path
public function configure_xmpp($options = '') {
global $conf;
if($conf['xmpp']['installed'] == false) return;
//* Create the logging directory for xmpp server
if(!@is_dir('/var/log/metronome')) mkdir('/var/log/metronome', 0755, true);
chown('/var/log/metronome', 'metronome');
if(!@is_dir('/var/run/metronome')) mkdir('/var/run/metronome', 0755, true);
chown('/var/run/metronome', 'metronome');
if(!@is_dir('/var/lib/metronome')) mkdir('/var/lib/metronome', 0755, true);
chown('/var/lib/metronome', 'metronome');
if(!@is_dir('/etc/metronome/hosts')) mkdir('/etc/metronome/hosts', 0755, true);
if(!@is_dir('/etc/metronome/status')) mkdir('/etc/metronome/status', 0755, true);
unlink('/etc/metronome/metronome.cfg.lua');
$row = $this->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ?", $conf["server_id"]);
$server_name = $row["server_name"];
$tpl = new tpl('metronome_conf_main.master');
wf('/etc/metronome/metronome.cfg.lua', $tpl->grab());
unset($tpl);
$tpl = new tpl('metronome_conf_global.master');
$tpl->setVar('xmpp_admins','');
wf('/etc/metronome/global.cfg.lua', $tpl->grab());
unset($tpl);
// Copy isp libs
if(!@is_dir('/usr/lib/metronome/isp-modules')) mkdir('/usr/lib/metronome/isp-modules', 0755, true);
caselog('cp -rf apps/metronome_libs/* /usr/lib/metronome/isp-modules/', __FILE__, __LINE__);
caselog('chmod 755 /usr/lib/metronome/isp-modules/mod_auth_external/authenticate_isp.sh', __FILE__, __LINE__);
// Process db config
$full_file_name = '/usr/lib/metronome/isp-modules/mod_auth_external/db_conf.inc.php';
$content = rf($full_file_name);
$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
$content = str_replace('{server_id}', $conf['server_id'], $content);
wf($full_file_name, $content);
if(!stristr($options, 'dont-create-certs')){
// Create SSL Certificate for localhost
// Ensure no line is left blank
echo "writing new private key to 'localhost.key'\n-----\n";
$ssl_country = $this->free_query('Country Name (2 letter code)', 'AU','ssl_cert_country');
$ssl_locality = $this->free_query('Locality Name (eg, city)', 'City Name','ssl_cert_locality');
$ssl_organisation = $this->free_query('Organization Name (eg, company)', 'Internet Widgits Pty Ltd','ssl_cert_organisation');
$ssl_organisation_unit = $this->free_query('Organizational Unit Name (eg, section)', 'Infrastructure','ssl_cert_organisation_unit');
$ssl_domain = $this->free_query('Common Name (e.g. server FQDN or YOUR name)', $conf['hostname'],'ssl_cert_common_name');
$ssl_email = $this->free_query('Email Address', 'hostmaster@'.$conf['hostname'],'ssl_cert_email');
$tpl = new tpl('metronome_conf_ssl.master');
$tpl->setVar('ssl_country',$ssl_country);
$tpl->setVar('ssl_locality',$ssl_locality);
$tpl->setVar('ssl_organisation',$ssl_organisation);
$tpl->setVar('ssl_organisation_unit',$ssl_organisation_unit);
$tpl->setVar('domain',$ssl_domain);
$tpl->setVar('ssl_email',$ssl_email);
wf('/etc/metronome/certs/localhost.cnf', $tpl->grab());
unset($tpl);
// Generate new key, csr and cert
exec("(cd /etc/metronome/certs && make localhost.key)");
exec("(cd /etc/metronome/certs && make localhost.csr)");
exec("(cd /etc/metronome/certs && make localhost.cert)");
exec('chmod 0400 /etc/metronome/certs/localhost.key');
exec('chown metronome /etc/metronome/certs/localhost.key');
echo "IMPORTANT:\n";
echo "Localhost Key, Csr and a self-signed Cert have been saved to /etc/metronome/certs\n";
echo "In order to work with all clients, the server must have a trusted certificate, so use the Csr\n";
echo "to get a trusted certificate from your CA or replace Key and Cert with already signed files for\n";
echo "your domain. Clients like Pidgin dont allow to use untrusted self-signed certificates.\n";
echo "\n";
/*
echo "-----\n";
echo "Metronome XMPP SSL server certificate is not renewed. Run the following command manual as root to recreate it:\n";
echo "# (cd /etc/metronome/certs && make localhost.key && make localhost.csr && make localhost.cert && chmod 0400 localhost.key && chown metronome localhost.key)\n";
echo "-----\n";
// Copy init script
caselog('cp -f apps/metronome-init /etc/init.d/metronome', __FILE__, __LINE__);
caselog('chmod u+x /etc/init.d/metronome', __FILE__, __LINE__);
caselog('update-rc.d metronome defaults', __FILE__, __LINE__);
exec($this->getinitcommand($conf['xmpp']['init_script'], 'restart'));
}
public function configure_apache() {
global $conf;
if($conf['apache']['installed'] == false) return;
//* Create the logging directory for the vhost logfiles
if(!@is_dir($conf['ispconfig_log_dir'].'/httpd')) mkdir($conf['ispconfig_log_dir'].'/httpd', 0755, true);
if(is_file('/etc/suphp/suphp.conf')) {
replaceLine('/etc/suphp/suphp.conf', 'php="php:/usr/bin', 'x-httpd-suphp="php:/usr/bin/php-cgi"', 0);
//replaceLine('/etc/suphp/suphp.conf','docroot=','docroot=/var/clients',0);
replaceLine('/etc/suphp/suphp.conf', 'umask=00', 'umask=0022', 0);
}
if(is_file('/etc/apache2/sites-enabled/000-default')) {
replaceLine('/etc/apache2/sites-available/000-default', 'NameVirtualHost *', 'NameVirtualHost *:80', 1, 0);
replaceLine('/etc/apache2/sites-available/000-default', '<VirtualHost *>', '<VirtualHost *:80>', 1, 0);
}
if(is_file('/etc/apache2/ports.conf')) {
// add a line "Listen 443" to ports conf if line does not exist
replaceLine('/etc/apache2/ports.conf', 'Listen 443', 'Listen 443', 1);
Till Brehm
committed
// Comment out the namevirtualhost lines, as they were added by ispconfig in ispconfig.conf file again
replaceLine('/etc/apache2/ports.conf', 'NameVirtualHost *:80', '# NameVirtualHost *:80', 1);
replaceLine('/etc/apache2/ports.conf', 'NameVirtualHost *:443', '# NameVirtualHost *:443', 1);
if(is_file('/etc/apache2/mods-available/fcgid.conf')) {
// add or modify the parameters for fcgid.conf
replaceLine('/etc/apache2/mods-available/fcgid.conf','MaxRequestLen','MaxRequestLen 15728640',1);
}
if(is_file('/etc/apache2/apache.conf')) {
if(hasLine('/etc/apache2/apache.conf', 'Include sites-enabled/', 1) == false) {
if(hasLine('/etc/apache2/apache.conf', 'IncludeOptional sites-enabled/*.conf', 1) == false && hasLine('/etc/apache2/apache.conf', 'IncludeOptional sites-enabled/', 1) == false) {
replaceLine('/etc/apache2/apache.conf', 'Include sites-enabled/', 'Include sites-enabled/', 1, 1);
} elseif(hasLine('/etc/apache2/apache.conf', 'IncludeOptional sites-enabled/*.vhost', 1) == false) {
replaceLine('/etc/apache2/apache.conf', 'IncludeOptional sites-enabled/*.vhost', 'IncludeOptional sites-enabled/', 1, 1);
}
}
}
if(is_file('/etc/apache2/apache2.conf')) {
if(hasLine('/etc/apache2/apache2.conf', 'Include sites-enabled/', 1) == false && hasLine('/etc/apache2/apache2.conf', 'IncludeOptional sites-enabled/', 1) == false) {
if(hasLine('/etc/apache2/apache2.conf', 'Include sites-enabled/*.conf', 1) == true) {
replaceLine('/etc/apache2/apache2.conf', 'Include sites-enabled/*.conf', 'Include sites-enabled/', 1, 1);
} elseif(hasLine('/etc/apache2/apache2.conf', 'IncludeOptional sites-enabled/*.conf', 1) == true) {
replaceLine('/etc/apache2/apache2.conf', 'IncludeOptional sites-enabled/*.conf', 'IncludeOptional sites-enabled/', 1, 1);
//* Copy the ISPConfig configuration include
$vhost_conf_dir = $conf['apache']['vhost_conf_dir'];
$vhost_conf_enabled_dir = $conf['apache']['vhost_conf_enabled_dir'];
$tpl = new tpl('apache_ispconfig.conf.master');
$tpl->setVar('apache_version',getapacheversion());
if($this->is_update == true) {
$tpl->setVar('logging',get_logging_state());
} else {
$tpl->setVar('logging','yes');
}
$records = $this->db->queryAllRecords("SELECT * FROM ?? WHERE server_id = ? AND virtualhost = 'y'", $conf['mysql']['master_database'] . '.server_ip', $conf['server_id']);
if(is_array($records) && count($records) > 0) {
foreach($records as $rec) {
if($rec['ip_type'] == 'IPv6') {
$ip_address = '['.$rec['ip_address'].']';
} else {
$ip_address = $rec['ip_address'];
}
$ports = explode(',', $rec['virtualhost_port']);
if(is_array($ports)) {
foreach($ports as $port) {
$port = intval($port);
if($port > 0 && $port < 65536 && $ip_address != '') {
$ip_addresses[] = array('ip_address' => $ip_address, 'port' => $port);
}
}
}
if(count($ip_addresses) > 0) $tpl->setLoop('ip_adresses',$ip_addresses);
wf($vhost_conf_dir.'/ispconfig.conf', $tpl->grab());
unset($tpl);
if(!@is_link($vhost_conf_enabled_dir.'/000-ispconfig.conf')) {
symlink($vhost_conf_dir.'/ispconfig.conf', $vhost_conf_enabled_dir.'/000-ispconfig.conf');
}
//* make sure that webalizer finds its config file when it is directly in /etc
if(@is_file('/etc/webalizer.conf') && !@is_dir('/etc/webalizer')) {
mkdir('/etc/webalizer');
symlink('/etc/webalizer.conf', '/etc/webalizer/webalizer.conf');
}
if(is_file('/etc/webalizer/webalizer.conf')) {
// Change webalizer mode to incremental
replaceLine('/etc/webalizer/webalizer.conf', '#IncrementalName', 'IncrementalName webalizer.current', 0, 0);
replaceLine('/etc/webalizer/webalizer.conf', '#Incremental', 'Incremental yes', 0, 0);
replaceLine('/etc/webalizer/webalizer.conf', '#HistoryName', 'HistoryName webalizer.hist', 0, 0);
// Check the awsatst script
if(!is_dir('/usr/share/awstats/tools')) exec('mkdir -p /usr/share/awstats/tools');
if(!file_exists('/usr/share/awstats/tools/awstats_buildstaticpages.pl') && file_exists('/usr/share/doc/awstats/examples/awstats_buildstaticpages.pl')) symlink('/usr/share/doc/awstats/examples/awstats_buildstaticpages.pl', '/usr/share/awstats/tools/awstats_buildstaticpages.pl');
if(file_exists('/etc/awstats/awstats.conf.local')) replaceLine('/etc/awstats/awstats.conf.local', 'LogFormat=4', 'LogFormat=1', 0, 1);
//* add a sshusers group
$command = 'groupadd sshusers';
if(!is_group('sshusers')) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
}
public function configure_nginx(){
if($conf['nginx']['installed'] == false) return;
//* Create the logging directory for the vhost logfiles
if(!@is_dir($conf['ispconfig_log_dir'].'/httpd')) mkdir($conf['ispconfig_log_dir'].'/httpd', 0755, true);
//* make sure that webalizer finds its config file when it is directly in /etc
if(@is_file('/etc/webalizer.conf') && !@is_dir('/etc/webalizer')) {
mkdir('/etc/webalizer');
symlink('/etc/webalizer.conf', '/etc/webalizer/webalizer.conf');
}
if(is_file('/etc/webalizer/webalizer.conf')) {
// Change webalizer mode to incremental
replaceLine('/etc/webalizer/webalizer.conf', '#IncrementalName', 'IncrementalName webalizer.current', 0, 0);
replaceLine('/etc/webalizer/webalizer.conf', '#Incremental', 'Incremental yes', 0, 0);
replaceLine('/etc/webalizer/webalizer.conf', '#HistoryName', 'HistoryName webalizer.hist', 0, 0);
// Check the awsatst script
if(!is_dir('/usr/share/awstats/tools')) exec('mkdir -p /usr/share/awstats/tools');
if(!file_exists('/usr/share/awstats/tools/awstats_buildstaticpages.pl') && file_exists('/usr/share/doc/awstats/examples/awstats_buildstaticpages.pl')) symlink('/usr/share/doc/awstats/examples/awstats_buildstaticpages.pl', '/usr/share/awstats/tools/awstats_buildstaticpages.pl');
if(file_exists('/etc/awstats/awstats.conf.local')) replaceLine('/etc/awstats/awstats.conf.local', 'LogFormat=4', 'LogFormat=1', 0, 1);
//* add a sshusers group
$command = 'groupadd sshusers';
if(!is_group('sshusers')) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
// add anonymized log option to nginxx.conf file
$nginx_conf_file = $conf['nginx']['config_dir'].'/nginx.conf';
if(is_file($nginx_conf_file)) {
$tmp = file_get_contents($nginx_conf_file);
if(!stristr($tmp, 'log_format anonymized')) {
copy($nginx_conf_file,$nginx_conf_file.'~');
replaceLine($nginx_conf_file, 'http {', "http {\n\n".file_get_contents('tpl/nginx_anonlog.master'), 0, 0);
}
}
Falko Timme
committed
public function configure_fail2ban() {
public function configure_squid()
{
global $conf;
$row = $this->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ?", $conf["server_id"]);
$ip_address = gethostbyname($row["server_name"]);
$server_name = $row["server_name"];
if(is_file($conf["squid"]["config_dir"].'/'.$configfile)) copy($conf["squid"]["config_dir"].'/'.$configfile, $conf["squid"]["config_dir"].'/'.$configfile.'~');
if(is_file($conf["squid"]["config_dir"].'/'.$configfile.'~')) exec('chmod 400 '.$conf["squid"]["config_dir"].'/'.$configfile.'~');
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', "tpl/".$configfile.".master");
$content = str_replace('{server_name}', $server_name, $content);
$content = str_replace('{ip_address}', $ip_address, $content);
$content = str_replace('{config_dir}', $conf['squid']['config_dir'], $content);
wf($conf["squid"]["config_dir"].'/'.$configfile, $content);
exec('chmod 600 '.$conf["squid"]["config_dir"].'/'.$configfile);
exec('chown root:root '.$conf["squid"]["config_dir"].'/'.$configfile);
}
public function configure_ufw_firewall()
{
if($this->is_update == false) {
$configfile = 'ufw.conf';
if(is_file('/etc/ufw/ufw.conf')) copy('/etc/ufw/ufw.conf', '/etc/ufw/ufw.conf~');
$content = rf("tpl/".$configfile.".master");
wf('/etc/ufw/ufw.conf', $content);
exec('chmod 600 /etc/ufw/ufw.conf');
exec('chown root:root /etc/ufw/ufw.conf');
}
public function configure_bastille_firewall() {
global $conf;
$dist_init_scripts = $conf['init_scripts'];
if(is_dir('/etc/Bastille.backup')) caselog('rm -rf /etc/Bastille.backup', __FILE__, __LINE__);
if(is_dir('/etc/Bastille')) caselog('mv -f /etc/Bastille /etc/Bastille.backup', __FILE__, __LINE__);
@mkdir('/etc/Bastille', 0700);
if(is_dir('/etc/Bastille.backup/firewall.d')) caselog('cp -pfr /etc/Bastille.backup/firewall.d /etc/Bastille/', __FILE__, __LINE__);
if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/bastille-firewall.cfg.master')) {
caselog('cp -f ' . $conf['ispconfig_install_dir'].'/server/conf-custom/install/bastille-firewall.cfg.master /etc/Bastille/bastille-firewall.cfg', __FILE__, __LINE__);
} else {
caselog('cp -f tpl/bastille-firewall.cfg.master /etc/Bastille/bastille-firewall.cfg', __FILE__, __LINE__);
}
caselog('chmod 644 /etc/Bastille/bastille-firewall.cfg', __FILE__, __LINE__);
$content = rf('/etc/Bastille/bastille-firewall.cfg');
$content = str_replace('{DNS_SERVERS}', '', $content);
$tcp_public_services = '';
$udp_public_services = '';
$row = $this->db->queryOneRecord('SELECT * FROM ?? WHERE server_id = ?', $conf["mysql"]["database"] . '.firewall', $conf['server_id']);
if(trim($row['tcp_port']) != '' || trim($row['udp_port']) != '') {
$tcp_public_services = trim(str_replace(',', ' ', $row['tcp_port']));
$udp_public_services = trim(str_replace(',', ' ', $row['udp_port']));
} else {
$tcp_public_services = '21 22 25 53 80 110 143 443 3306 8080 10000';
$udp_public_services = '53';
}
if(!stristr($tcp_public_services, $conf['apache']['vhost_port'])) {
$tcp_public_services .= ' '.intval($conf['apache']['vhost_port']);
if($row['tcp_port'] != '') $this->db->query("UPDATE firewall SET tcp_port = tcp_port + ? WHERE server_id = ?", ',' . intval($conf['apache']['vhost_port']), $conf['server_id']);
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
}
$content = str_replace('{TCP_PUBLIC_SERVICES}', $tcp_public_services, $content);
$content = str_replace('{UDP_PUBLIC_SERVICES}', $udp_public_services, $content);
wf('/etc/Bastille/bastille-firewall.cfg', $content);
if(is_file($dist_init_scripts.'/bastille-firewall')) caselog('mv -f '.$dist_init_scripts.'/bastille-firewall '.$dist_init_scripts.'/bastille-firewall.backup', __FILE__, __LINE__);
caselog('cp -f apps/bastille-firewall '.$dist_init_scripts, __FILE__, __LINE__);
caselog('chmod 700 '.$dist_init_scripts.'/bastille-firewall', __FILE__, __LINE__);
if(is_file('/sbin/bastille-ipchains')) caselog('mv -f /sbin/bastille-ipchains /sbin/bastille-ipchains.backup', __FILE__, __LINE__);
caselog('cp -f apps/bastille-ipchains /sbin', __FILE__, __LINE__);
caselog('chmod 700 /sbin/bastille-ipchains', __FILE__, __LINE__);
if(is_file('/sbin/bastille-netfilter')) caselog('mv -f /sbin/bastille-netfilter /sbin/bastille-netfilter.backup', __FILE__, __LINE__);
caselog('cp -f apps/bastille-netfilter /sbin', __FILE__, __LINE__);
caselog('chmod 700 /sbin/bastille-netfilter', __FILE__, __LINE__);
if(!@is_dir('/var/lock/subsys')) caselog('mkdir /var/lock/subsys', __FILE__, __LINE__);
exec('which ipchains &> /dev/null', $ipchains_location, $ret_val);
if(!is_file('/sbin/ipchains') && !is_link('/sbin/ipchains') && $ret_val == 0) phpcaselog(@symlink(shell_exec('which ipchains'), '/sbin/ipchains'), 'create symlink', __FILE__, __LINE__);
unset($ipchains_location);
exec('which iptables &> /dev/null', $iptables_location, $ret_val);
if(!is_file('/sbin/iptables') && !is_link('/sbin/iptables') && $ret_val == 0) phpcaselog(@symlink(trim(shell_exec('which iptables')), '/sbin/iptables'), 'create symlink', __FILE__, __LINE__);
unset($iptables_location);
}
public function configure_vlogger() {
global $conf;
//** Configure vlogger to use traffic logging to mysql (master) db
$configfile = 'vlogger-dbi.conf';
if(is_file($conf['vlogger']['config_dir'].'/'.$configfile)) copy($conf['vlogger']['config_dir'].'/'.$configfile, $conf['vlogger']['config_dir'].'/'.$configfile.'~');
if(is_file($conf['vlogger']['config_dir'].'/'.$configfile.'~')) chmod($conf['vlogger']['config_dir'].'/'.$configfile.'~', 0400);
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
if($conf['mysql']['master_slave_setup'] == 'y') {
$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['master_ispconfig_user'], $content);
$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['master_ispconfig_password'], $content);
$content = str_replace('{mysql_server_database}', $conf['mysql']['master_database'], $content);
$content = str_replace('{mysql_server_ip}', $conf['mysql']['master_host'], $content);
$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
wf($conf['vlogger']['config_dir'].'/'.$configfile, $content);
chmod($conf['vlogger']['config_dir'].'/'.$configfile, 0600);
chown($conf['vlogger']['config_dir'].'/'.$configfile, 'root');
chgrp($conf['vlogger']['config_dir'].'/'.$configfile, 'root');
}
public function configure_apps_vhost() {
global $conf;
//* Create the ispconfig apps vhost user and group
if($conf['apache']['installed'] == true){
$apps_vhost_user = escapeshellcmd($conf['web']['apps_vhost_user']);
$apps_vhost_group = escapeshellcmd($conf['web']['apps_vhost_group']);
$install_dir = escapeshellcmd($conf['web']['website_basedir'].'/apps');
$command = 'groupadd '.$apps_vhost_user;
if(!is_group($apps_vhost_group)) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
$command = 'useradd -g '.$apps_vhost_group.' -d '.$install_dir.' '.$apps_vhost_group;
if(!is_user($apps_vhost_user)) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
//$command = 'adduser '.$conf['apache']['user'].' '.$apps_vhost_group;
$command = 'usermod -a -G '.$apps_vhost_group.' '.$conf['apache']['user'];
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
Falko Timme
committed
if(!@is_dir($install_dir)){
mkdir($install_dir, 0755, true);
} else {
chmod($install_dir, 0755);
}
chown($install_dir, $apps_vhost_user);
chgrp($install_dir, $apps_vhost_group);
//* Copy the apps vhost file
$vhost_conf_dir = $conf['apache']['vhost_conf_dir'];
$vhost_conf_enabled_dir = $conf['apache']['vhost_conf_enabled_dir'];
$apps_vhost_servername = ($conf['web']['apps_vhost_servername'] == '')?'':'ServerName '.$conf['web']['apps_vhost_servername'];
//* Get the apps vhost port
if($this->is_update == true) {
$conf['web']['apps_vhost_port'] = get_apps_vhost_port_number();
}
// Dont just copy over the virtualhost template but add some custom settings
$tpl = new tpl('apache_apps.vhost.master');
$tpl->setVar('apps_vhost_ip',$conf['web']['apps_vhost_ip']);
$tpl->setVar('apps_vhost_port',$conf['web']['apps_vhost_port']);
$tpl->setVar('apps_vhost_dir',$conf['web']['website_basedir'].'/apps');
$tpl->setVar('apps_vhost_basedir',$conf['web']['website_basedir']);
$tpl->setVar('apps_vhost_servername',$apps_vhost_servername);
if(is_file($install_dir.'/interface/ssl/ispserver.crt') && is_file($install_dir.'/interface/ssl/ispserver.key')) {
$tpl->setVar('ssl_comment','');
} else {
$tpl->setVar('ssl_comment','#');
}
if(is_file($install_dir.'/interface/ssl/ispserver.crt') && is_file($install_dir.'/interface/ssl/ispserver.key') && is_file($install_dir.'/interface/ssl/ispserver.bundle')) {
$tpl->setVar('ssl_bundle_comment','');
} else {
$tpl->setVar('ssl_bundle_comment','#');
}
$tpl->setVar('apache_version',getapacheversion());
if($this->is_update == true) {
$tpl->setVar('logging',get_logging_state());
} else {
$tpl->setVar('logging','yes');
}
if($conf['rspamd']['installed'] == true) {
$tpl->setVar('use_rspamd', 'yes');
}
// comment out the listen directive if port is 80 or 443
if($conf['web']['apps_vhost_port'] == 80 or $conf['web']['apps_vhost_port'] == 443) {
$tpl->setVar('vhost_port_listen','#');
$tpl->setVar('vhost_port_listen','');
wf($vhost_conf_dir.'/apps.vhost', $tpl->grab());
unset($tpl);
//copy('tpl/apache_ispconfig.vhost.master', "$vhost_conf_dir/ispconfig.vhost");
//* and create the symlink
if(@is_link($vhost_conf_enabled_dir.'/apps.vhost')) unlink($vhost_conf_enabled_dir.'/apps.vhost');
if(!@is_link($vhost_conf_enabled_dir.'/000-apps.vhost') && @is_file($vhost_conf_dir.'/apps.vhost')) {
@symlink($vhost_conf_dir.'/apps.vhost', $vhost_conf_enabled_dir.'/000-apps.vhost');
if(!is_file($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter')) {
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/apache_apps_fcgi_starter.master', 'tpl/apache_apps_fcgi_starter.master');
$content = str_replace('{fastcgi_bin}', $conf['fastcgi']['fastcgi_bin'], $content);
$content = str_replace('{fastcgi_phpini_path}', $conf['fastcgi']['fastcgi_phpini_path'], $content);
mkdir($conf['web']['website_basedir'].'/php-fcgi-scripts/apps', 0755, true);
$this->set_immutable($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter', false);
//copy('tpl/apache_apps_fcgi_starter.master',$conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter');
wf($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter', $content);
exec('chmod +x '.$conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter');
exec('chown -R ispapps:ispapps '.$conf['web']['website_basedir'].'/php-fcgi-scripts/apps');
$this->set_immutable($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter', true);
if($conf['nginx']['installed'] == true){
$apps_vhost_user = escapeshellcmd($conf['web']['apps_vhost_user']);
$apps_vhost_group = escapeshellcmd($conf['web']['apps_vhost_group']);
$install_dir = escapeshellcmd($conf['web']['website_basedir'].'/apps');
$command = 'groupadd '.$apps_vhost_user;
if(!is_group($apps_vhost_group)) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
$command = 'useradd -g '.$apps_vhost_group.' -d '.$install_dir.' '.$apps_vhost_group;
if(!is_user($apps_vhost_user)) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
//$command = 'adduser '.$conf['nginx']['user'].' '.$apps_vhost_group;
$command = 'usermod -a -G '.$apps_vhost_group.' '.$conf['nginx']['user'];
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
if(!@is_dir($install_dir)){
mkdir($install_dir, 0755, true);
} else {
chmod($install_dir, 0755);
}
chown($install_dir, $apps_vhost_user);
chgrp($install_dir, $apps_vhost_group);
//* Copy the apps vhost file
$vhost_conf_dir = $conf['nginx']['vhost_conf_dir'];
$vhost_conf_enabled_dir = $conf['nginx']['vhost_conf_enabled_dir'];
$apps_vhost_servername = ($conf['web']['apps_vhost_servername'] == '')?'_':$conf['web']['apps_vhost_servername'];
// Dont just copy over the virtualhost template but add some custom settings
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/nginx_apps.vhost.master', 'tpl/nginx_apps.vhost.master');
if($conf['web']['apps_vhost_ip'] == '_default_'){
$apps_vhost_ip = '';
} else {
$apps_vhost_ip = $conf['web']['apps_vhost_ip'].':';
}
if($conf['rspamd']['installed'] == true) {
$content = str_replace('{use_rspamd}', '', $content);
} else {
$content = str_replace('{use_rspamd}', '# ', $content);
}
Falko Timme
committed
$socket_dir = escapeshellcmd($conf['nginx']['php_fpm_socket_dir']);
if(substr($socket_dir, -1) != '/') $socket_dir .= '/';
Falko Timme
committed
if(!is_dir($socket_dir)) exec('mkdir -p '.$socket_dir);
$fpm_socket = $socket_dir.'apps.sock';
$cgi_socket = escapeshellcmd($conf['nginx']['cgi_socket']);
$content = str_replace('{apps_vhost_ip}', $apps_vhost_ip, $content);
$content = str_replace('{apps_vhost_port}', $conf['web']['apps_vhost_port'], $content);
$content = str_replace('{apps_vhost_dir}', $conf['web']['website_basedir'].'/apps', $content);
$content = str_replace('{apps_vhost_servername}', $apps_vhost_servername, $content);
Falko Timme
committed
//$content = str_replace('{fpm_port}', ($conf['nginx']['php_fpm_start_port']+1), $content);
$content = str_replace('{fpm_socket}', $fpm_socket, $content);
$content = str_replace('{cgi_socket}', $cgi_socket, $content);
if( file_exists('/var/run/php5-fpm.sock')
|| file_exists('/var/run/php/php7.0-fpm.sock')
|| file_exists('/var/run/php/php7.1-fpm.sock')
|| file_exists('/var/run/php/php7.2-fpm.sock')
|| file_exists('/var/run/php/php7.3-fpm.sock')
|| file_exists('/var/run/php/php7.4-fpm.sock')
){
Falko Timme
committed
$use_tcp = '#';
$use_socket = '';
} else {
$use_tcp = '';
$use_socket = '#';
}
$content = str_replace('{use_tcp}', $use_tcp, $content);
$content = str_replace('{use_socket}', $use_socket, $content);
// SSL in apps vhost is off by default. Might change later.
$content = str_replace('{ssl_on}', '', $content);
$content = str_replace('{ssl_comment}', '#', $content);
// Fix socket path on PHP 7 systems
if(file_exists('/var/run/php/php7.0-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.0-fpm.sock', $content);
if(file_exists('/var/run/php/php7.1-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.1-fpm.sock', $content);
if(file_exists('/var/run/php/php7.2-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.2-fpm.sock', $content);
if(file_exists('/var/run/php/php7.3-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.3-fpm.sock', $content);
if(file_exists('/var/run/php/php7.4-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.4-fpm.sock', $content);
wf($vhost_conf_dir.'/apps.vhost', $content);
// PHP-FPM
// Dont just copy over the php-fpm pool template but add some custom settings
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/apps_php_fpm_pool.conf.master', 'tpl/apps_php_fpm_pool.conf.master');
$content = str_replace('{fpm_pool}', 'apps', $content);
Falko Timme
committed
//$content = str_replace('{fpm_port}', ($conf['nginx']['php_fpm_start_port']+1), $content);
$content = str_replace('{fpm_socket}', $fpm_socket, $content);
$content = str_replace('{fpm_user}', $apps_vhost_user, $content);
$content = str_replace('{fpm_group}', $apps_vhost_group, $content);
wf($conf['nginx']['php_fpm_pool_dir'].'/apps.conf', $content);
//copy('tpl/nginx_ispconfig.vhost.master', "$vhost_conf_dir/ispconfig.vhost");
//* and create the symlink
if(@is_link($vhost_conf_enabled_dir.'/apps.vhost')) unlink($vhost_conf_enabled_dir.'/apps.vhost');
if(!@is_link($vhost_conf_enabled_dir.'/000-apps.vhost')) {
symlink($vhost_conf_dir.'/apps.vhost', $vhost_conf_enabled_dir.'/000-apps.vhost');
Hj Ahmad Rasyid Hj Ismail
committed
}
}
Hj Ahmad Rasyid Hj Ismail
committed
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
private function curl_request($url, $use_ipv6 = false) {
$set_headers = [
'Connection: Close',
'User-Agent: ISPConfig/3',
'Accept: */*'
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_HTTPHEADER, $set_headers);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
if($use_ipv6) {
if(defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V6')) {
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
}
} else {
if(defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V4')) {
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
}
Hj Ahmad Rasyid Hj Ismail
committed
$response = curl_exec($ch);
curl_close($ch);
return $response;
public function make_acme_vhost($server = 'apache') {
if($conf['hostname'] !== 'localhost' && $conf['hostname'] !== '') {
$server_name = $conf['hostname'];
} else {
$server_name = exec('hostname -f');
}
$use_template = 'apache_acme.conf.master';
$use_symlink = '999-acme.conf';
$use_name = 'acme.conf';
if($server === 'nginx') {
$use_template = 'nginx_acme.vhost.master';
$use_symlink = '999-acme.vhost';
$use_name = 'acme.vhost';
}
$vhost_conf_dir = $conf[$server]['vhost_conf_dir'];
$vhost_conf_enabled_dir = $conf[$server]['vhost_conf_enabled_dir'];
$tpl = new tpl($use_template);
$tpl->setVar('domain', $server_name);
if($server !== 'nginx') {
$tpl->setVar('apache_version',getapacheversion());
}
$acme_dir = $conf['ispconfig_install_dir'] . '/interface/acme';
//* Create the ISPConfig installation directory
if(!@is_dir($acme_dir)) {
$command = "mkdir -p $acme_dir";
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
}
wf($vhost_conf_dir.'/' . $use_name, $tpl->grab());
if(@is_link($vhost_conf_enabled_dir.'/' . $use_symlink)) {
unlink($vhost_conf_enabled_dir.'/' . $use_symlink);
if(!@is_link($vhost_conf_enabled_dir.'' . $use_symlink)) {
symlink($vhost_conf_dir.'/' . $use_name, $vhost_conf_enabled_dir.'/' . $use_symlink);
Hj Ahmad Rasyid Hj Ismail
committed
global $conf, $autoinstall;
Hj Ahmad Rasyid Hj Ismail
committed
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
//* Get hostname from user entry or shell command */
if($conf['hostname'] !== 'localhost' && $conf['hostname'] !== '') {
$hostname = $conf['hostname'];
} else {
$hostname = exec('hostname -f');
}
// Check dns a record exist and its ip equal to server public ip
$svr_ip4 = $this->curl_request('https://ispconfig.org/remoteip.php', false);
$svr_ip6 = $this->curl_request('https://ispconfig.org/remoteip.php', true);
if(function_exists('idn_to_ascii')) {
if(defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46') && constant('IDNA_NONTRANSITIONAL_TO_ASCII')) {
$hostname = idn_to_ascii($hostname, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
} else {
$hostname = idn_to_ascii($hostname);
}
}
$dns_ips = array();
if (checkdnsrr($hostname, 'A')) {
$dnsa=dns_get_record($hostname, DNS_A);
if($dnsa) {
foreach ($dnsa as $rec) {
$dns_ips[] = $rec['ip'];
}
}
}
if (checkdnsrr($hostname, 'AAAA')) {
$dnsaaaa=dns_get_record($hostname, DNS_AAAA);
if($dnsaaaa) {
foreach ($dnsaaaa as $rec) {
$dns_ips[] = $rec['ip'];
}
}
}
//* Define and check ISPConfig SSL folder */
$ssl_dir = $conf['ispconfig_install_dir'].'/interface/ssl';
if(!@is_dir($ssl_dir)) {
mkdir($ssl_dir, 0755, true);
}
$ssl_crt_file = $ssl_dir.'/ispserver.crt';
$ssl_csr_file = $ssl_dir.'/ispserver.csr';
$ssl_key_file = $ssl_dir.'/ispserver.key';
$ssl_pem_file = $ssl_dir.'/ispserver.pem';
$date = new DateTime();
Hj Ahmad Rasyid Hj Ismail
committed
// Request for certs if no LE SSL folder for server fqdn exist
swriteln('Checking / creating certificate for ' . $hostname);
$acme_cert_dir = '/usr/local/ispconfig/server/scripts/' . $hostname;
$check_acme_file = $acme_cert_dir . '/' . $hostname . '.cer';
if(!@is_dir($acme_cert_dir)) {
$acme_cert_dir = '/root/.acme.sh/' . $hostname;
$check_acme_file = $acme_cert_dir . '/' . $hostname . '.cer';
if(!@is_dir($acme_cert_dir)) {
$acme_cert_dir = '/etc/letsencrypt/live/' . $hostname;
$check_acme_file = $acme_cert_dir . '/cert.pem';
}
}
swriteln('Using certificate path ' . $acme_cert_dir);
$ip_address_match = false;
if(!(($svr_ip4 && in_array($svr_ip4, $dns_ips)) || ($svr_ip6 && in_array($svr_ip6, $dns_ips)))) {
swriteln('Server\'s public ip(s) (' . $svr_ip4 . ($svr_ip6 ? ', ' . $svr_ip6 : '') . ') not found in A/AAAA records for ' . $hostname . ': ' . implode(', ', $dns_ips));
if(strtolower($this->simple_query('Ignore DNS check and continue to request certificate?', array('y', 'n') , 'n','ignore_hostname_dns')) == 'y') {
$ip_address_match = true;
}
} else {
$ip_address_match = true;
}
if ((!@is_dir($acme_cert_dir) || !@file_exists($check_acme_file) || !@file_exists($ssl_crt_file) || md5_file($check_acme_file) != md5_file($ssl_crt_file)) && $ip_address_match == true) {
Hj Ahmad Rasyid Hj Ismail
committed
// This script is needed earlier to check and open http port 80 or standalone might fail
// Make executable and temporary symlink latest letsencrypt pre, post and renew hook script before install
if(file_exists(ISPC_INSTALL_ROOT . '/server/scripts/letsencrypt_pre_hook.sh') && !file_exists('/usr/local/bin/letsencrypt_pre_hook.sh')) {
symlink(ISPC_INSTALL_ROOT . '/server/scripts/letsencrypt_pre_hook.sh', '/usr/local/bin/letsencrypt_pre_hook.sh');
chown('/usr/local/bin/letsencrypt_pre_hook.sh', 'root');
chmod('/usr/local/bin/letsencrypt_pre_hook.sh', 0700);
Hj Ahmad Rasyid Hj Ismail
committed
}
if(file_exists(ISPC_INSTALL_ROOT . '/server/scripts/letsencrypt_post_hook.sh') && !file_exists('/usr/local/bin/letsencrypt_post_hook.sh')) {
symlink(ISPC_INSTALL_ROOT . '/server/scripts/letsencrypt_post_hook.sh', '/usr/local/bin/letsencrypt_post_hook.sh');
chown('/usr/local/bin/letsencrypt_post_hook.sh', 'root');
chmod('/usr/local/bin/letsencrypt_post_hook.sh', 0700);
Hj Ahmad Rasyid Hj Ismail
committed
}
if(file_exists(ISPC_INSTALL_ROOT . '/server/scripts/letsencrypt_renew_hook.sh') && !file_exists('/usr/local/bin/letsencrypt_renew_hook.sh')) {
symlink(ISPC_INSTALL_ROOT . '/server/scripts/letsencrypt_renew_hook.sh', '/usr/local/bin/letsencrypt_renew_hook.sh');
chown('/usr/local/bin/letsencrypt_renew_hook.sh', 'root');
chmod('/usr/local/bin/letsencrypt_renew_hook.sh', 0700);
Hj Ahmad Rasyid Hj Ismail
committed
}
Hj Ahmad Rasyid Hj Ismail
committed
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
// Check http port 80 status as it cannot be determined at post hook stage
$port80_status=exec('true &>/dev/null </dev/tcp/127.0.0.1/80 && echo open || echo close');
// Set pre-, post- and renew hook
$pre_hook = "--pre-hook \"letsencrypt_pre_hook.sh\"";
$renew_hook = " --renew-hook \"letsencrypt_renew_hook.sh\"";
if($port80_status == 'close') {
$post_hook = " --post-hook \"letsencrypt_post_hook.sh\"";
$hook = $pre_hook . $post_hook . $renew_hook;
} else {
$hook = $pre_hook . $renew_hook;
}
// Get the default LE client name and version
$le_client = explode("\n", shell_exec('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot'));
$le_client = reset($le_client);
// Check for Neilpang acme.sh as well
$acme = explode("\n", shell_exec('which /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh'));
$acme = reset($acme);
$restore_conf_symlink = false;
// we only need this for apache, so use fixed conf index
$vhost_conf_dir = $conf['apache']['vhost_conf_dir'];
$vhost_conf_enabled_dir = $conf['apache']['vhost_conf_enabled_dir'];
// first of all create the acme vhosts if not existing
if($conf['nginx']['installed'] == true) {
swriteln('Using nginx for certificate validation');
} elseif($conf['apache']['installed'] == true) {
swriteln('Using apache for certificate validation');
if($this->is_update == false && @is_link($vhost_conf_enabled_dir.'/000-ispconfig.conf')) {
$restore_conf_symlink = true;
unlink($vhost_conf_enabled_dir.'/000-ispconfig.conf');
}
if($conf[$server]['installed'] == true && $conf[$server]['init_script'] != '') {
if($this->is_update) {
system($this->getinitcommand($conf[$server]['init_script'], 'force-reload').' &> /dev/null || ' . $this->getinitcommand($conf[$server]['init_script'], 'restart').' &> /dev/null');
} else {
system($this->getinitcommand($conf[$server]['init_script'], 'restart').' &> /dev/null');
}
$issued_successfully = false;
Hj Ahmad Rasyid Hj Ismail
committed
// Attempt to use Neilpang acme.sh first, as it is now the preferred LE client
if (is_executable($acme)) {
$out = null;
$ret = null;
if($conf['nginx']['installed'] == true || $conf['apache']['installed'] == true) {
exec("$acme --issue -w /usr/local/ispconfig/interface/acme -d " . escapeshellarg($hostname) . " $renew_hook", $out, $ret);
Hj Ahmad Rasyid Hj Ismail
committed
}
// Else, it is not webserver, so we use standalone
else {
exec("$acme --issue --standalone -d " . escapeshellarg($hostname) . " $hook", $out, $ret);
Hj Ahmad Rasyid Hj Ismail
committed
}
if($ret == 0 || ($ret == 2 && file_exists($check_acme_file))) {
// acme.sh returns with 2 on issue for already existing certificate
// Backup existing ispserver ssl files
if(file_exists($ssl_crt_file) || is_link($ssl_crt_file)) {
rename($ssl_crt_file, $ssl_crt_file . '-' . $date->format('YmdHis') . '.bak');
}
if(file_exists($ssl_key_file) || is_link($ssl_key_file)) {
rename($ssl_key_file, $ssl_key_file . '-' . $date->format('YmdHis') . '.bak');
}
if(file_exists($ssl_pem_file) || is_link($ssl_pem_file)) {
rename($ssl_pem_file, $ssl_pem_file . '-' . $date->format('YmdHis') . '.bak');
}
Hj Ahmad Rasyid Hj Ismail
committed
$check_acme_file = $ssl_crt_file;
// Define LE certs name and path, then install them
//$acme_cert = "--cert-file $acme_cert_dir/cert.pem";
$acme_key = "--key-file " . escapeshellarg($ssl_key_file);
$acme_chain = "--fullchain-file " . escapeshellarg($ssl_crt_file);
exec("$acme --install-cert -d " . escapeshellarg($hostname) . " $acme_key $acme_chain");
$issued_successfully = true;
} else {
swriteln('Issuing certificate via acme.sh failed. Please check that your hostname can be verified by letsencrypt');
Hj Ahmad Rasyid Hj Ismail
committed
// Else, we attempt to use the official LE certbot client certbot
} else {
// But only if it is otherwise available
if(is_executable($le_client)) {
$out = null;
$ret = null;
Hj Ahmad Rasyid Hj Ismail
committed
// Get its version info due to be used for webroot arguement issues
$le_info = exec($le_client . ' --version 2>&1', $ret, $val);
if(preg_match('/^(\S+|\w+)\s+(\d+(\.\d+)+)$/', $le_info, $matches)) {
$le_version = $matches[2];
}
// Define certbot commands
$acme_version = '--server https://acme-v0' . (($le_version >=0.22) ? '2' : '1') . '.api.letsencrypt.org/directory';
$certonly = 'certonly --agree-tos --non-interactive --expand --rsa-key-size 4096';
// If this is a webserver
if($conf['nginx']['installed'] == true || $conf['apache']['installed'] == true) {
exec("$le_client $certonly $acme_version --authenticator webroot --webroot-path /usr/local/ispconfig/interface/acme --email " . escapeshellarg('postmaster@' . $hostname) . " -d " . escapeshellarg($hostname) . " $renew_hook", $out, $ret);
Hj Ahmad Rasyid Hj Ismail
committed
// Else, it is not webserver, so we use standalone
else {
exec("$le_client $certonly $acme_version --standalone --email " . escapeshellarg('postmaster@' . $hostname) . " -d " . escapeshellarg($hostname) . " $hook", $out, $ret);
}
if($ret == 0) {
// certbot returns with 0 on issue for already existing certificate
// Backup existing ispserver ssl files
if(file_exists($ssl_crt_file) || is_link($ssl_crt_file)) {
rename($ssl_crt_file, $ssl_crt_file . '-' . $date->format('YmdHis') . '.bak');
}
if(file_exists($ssl_key_file) || is_link($ssl_key_file)) {
rename($ssl_key_file, $ssl_key_file . '-' . $date->format('YmdHis') . '.bak');
}
if(file_exists($ssl_pem_file) || is_link($ssl_pem_file)) {
rename($ssl_pem_file, $ssl_pem_file . '-' . $date->format('YmdHis') . '.bak');
}