From 9ea9794d8b8babae7cb670f8d187f16fbf0ed848 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 9 Nov 2015 02:13:08 +0100 Subject: first working version --- README.md | 65 +++++++ _todo | 5 + apache.letsencrypt.conf | 5 + cli.ini | 29 +++ cli.ini.patch | 11 ++ install.php | 165 +++++++++++++++++ ispconfig.patch | 466 ++++++++++++++++++++++++++++++++++++++++++++++++ nginx.conf.patch | 15 ++ 8 files changed, 761 insertions(+) create mode 100644 README.md create mode 100644 _todo create mode 100644 apache.letsencrypt.conf create mode 100644 cli.ini create mode 100644 cli.ini.patch create mode 100644 install.php create mode 100644 ispconfig.patch create mode 100644 nginx.conf.patch diff --git a/README.md b/README.md new file mode 100644 index 0000000..4ca41ef --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +ISPConfig Let's Encrypt +========================= + + +# REQUIRREMENTS + +Let's Encrypt installed + +ISPConfig 3.0.5.4p8 or newer + +Apache or Nginx + + +# INSTALLATION (as root) + +``` +git clone https://github.com/alexalouit/ISPConfig-letsencrypt.git +cd ISPConfig-letsencrypt +php -q install.php +``` + +After install, a new checkbox will be available in editing website, just check it. + + +## MANUAL INSTALLATION + +- patch or create Let's Encrypt configuration +``` +cp ./cli.ini /etc/letsencrypt/cli.ini + or +patch /etc/letsencrypt/cli.ini < ./cli.ini.patch +``` + +- patch ISPConfig +``` +cp ispconfig.patch /usr/local/ispconfig/ispconfig.patch +cd /usr/local/ispconfig +patch -p3 < ./ispconfig.patch +rm ./ispconfig.patch +``` + +- prepare apache +``` +cp ./apache.letsencrypt.conf /etc/apache2/conf-available/letsencrypt.conf +a2enmod headers +a2enconf letsencrypt +service apache2 reload +``` + +- prepare nginx +``` +patch /etc/nginx/nginx.conf < ./nginx.conf.patch +service nginx reload +``` + +- create a cron for automatic renewal: +``` +crontab -e +30 02 * * * /root/.local/share/letsencrypt/bin/letsencrypt-renewer >> /var/log/ispconfig/cron.log; done +``` + +- sql queries: +``` +ALTER TABLE `web_domain` ADD `ssl_letsencrypt` enum('n','y') NOT NULL DEFAULT 'n'; +``` \ No newline at end of file diff --git a/_todo b/_todo new file mode 100644 index 0000000..cf2c6a5 --- /dev/null +++ b/_todo @@ -0,0 +1,5 @@ +check dns entry is correct before request to Let's Encrypt (apache and nginx plugin) +check dns MX entry is correct before request to Let's Encrypt (apache and nginx plugin) +check if we already have a symlink and if he's valid (apache and nginx plugin) +force ssl field to on when use Let's Encrypt (api access) +disable ssl tab when use Let's Encrypt (webgui) \ No newline at end of file diff --git a/apache.letsencrypt.conf b/apache.letsencrypt.conf new file mode 100644 index 0000000..43ab897 --- /dev/null +++ b/apache.letsencrypt.conf @@ -0,0 +1,5 @@ + + + Header set Content-Type "application/jose+json" + + \ No newline at end of file diff --git a/cli.ini b/cli.ini new file mode 100644 index 0000000..6eab855 --- /dev/null +++ b/cli.ini @@ -0,0 +1,29 @@ +# This is an example of the kind of things you can do in a configuration file. +# All flags used by the client can be configured here. Run Let's Encrypt with +# "--help" to learn more about the available options. + +# Use a 4096 bit RSA key instead of 2048 +rsa-key-size = 4096 + +# Always use the staging/testing server +server = https://acme-staging.api.letsencrypt.org/directory + +# Uncomment and update to register with the specified e-mail address +# email = foo@example.com + +# Uncomment to use a text interface instead of ncurses +# text = True + +# Uncomment to use the standalone authenticator on port 443 +# authenticator = standalone +# standalone-supported-challenges = dvsni + +# Uncomment to use the webroot authenticator. Replace webroot-path with the +# path to the public_html / webroot folder being served by your web server. +# authenticator = webroot +# webroot-path = /usr/share/nginx/html + +text = True +agree-dev-preview = True +agree-tos = True +authenticator = webroot diff --git a/cli.ini.patch b/cli.ini.patch new file mode 100644 index 0000000..e038f5c --- /dev/null +++ b/cli.ini.patch @@ -0,0 +1,11 @@ +--- cli.ini 2015-11-06 20:21:09.332000000 +0100 ++++ cli.ini 2015-11-06 20:21:27.380000000 +0100 +@@ -22,3 +22,8 @@ + # path to the public_html / webroot folder being served by your web server. + # authenticator = webroot + # webroot-path = /usr/share/nginx/html ++ ++text = True ++agree-dev-preview = True ++agree-tos = True ++authenticator = webroot diff --git a/install.php b/install.php new file mode 100644 index 0000000..f5ef25f --- /dev/null +++ b/install.php @@ -0,0 +1,165 @@ + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +$backup_dir = "/var/backup/"; +$backup_file = date("Ymdhis")."-ISPConfig-letsencrypt.tar.gz"; +$backup_file2 = date("Ymdhis")."-cronjob.txt"; + +if(!file_exists("/usr/local/ispconfig/server/lib/config.inc.php") OR !file_exists("/usr/local/ispconfig/server/lib/mysql_clientdb.conf")) { + echo "ERROR: Unable to load the ISPConfig defaut configuration files.\n"; + exit; +} + +require_once "/usr/local/ispconfig/server/lib/config.inc.php"; +require_once "/usr/local/ispconfig/server/lib/mysql_clientdb.conf"; + +if($conf["app_version"] != "3.0.5.4p8") { + echo "ERROR: This version is unsupported.\n"; + exit; +} + +if(!file_exists($backup_dir)) { + echo "Backup directory not found.\n"; + mkdir($backup_dir, 0700); +} + +if(!file_exists($backup_dir)) { + echo "ERROR: Create it, and relaunch me!\n"; + exit; +} + +if(getcwd() != realpath(dirname(__FILE__))) { + echo "ERROR: Run me in current installer directory!\n"; + exit; +} + +echo "Create backup on " . $backup_dir . " directory\n"; + +exec("/bin/tar -czf " . $backup_dir . $backup_file . " /usr/local/ispconfig"); + +if(!file_exists($backup_dir . $backup_file )) { + echo "ERROR: There was a problem with the backup file.\n"; + exit; +} + +echo "Backup finished\n"; + +if(!is_dir("/etc/letsencrypt")) { + echo "ERROR: Let's Encrypt directory ( /etc/letsencrypt/ ) is missing, install it corecctly!\n"; + exit; +} + +if(!is_file("/root/.local/share/letsencrypt/bin/letsencrypt")) { + echo "ERROR: Let's Encrypt ( /root/.local/share/letsencrypt/bin/letsencrypt ) is missing, install it corecctly!\n"; + exit; +} + +if(!is_file("/root/.local/share/letsencrypt/bin/letsencrypt-renewer")) { + echo "ERROR: Let's Encrypt ( /root/.local/share/letsencrypt/bin/letsencrypt-renewer ) is missing, install it corecctly!\n"; + exit; +} + +if(!is_file("/etc/letsencrypt/cli.ini")) { + echo "Let's Encrypt configuration file don't exist, create it.\n"; + exec("cp ./cli.ini /etc/letsencrypt/cli.ini"); +} else { + echo "Let's Encrypt configuration file exist, patch it.\n"; + exec("patch /etc/letsencrypt/cli.ini < ./cli.ini.patch"); +} + +if(!$buffer = mysql_connect($clientdb_host, $clientdb_user, $clientdb_password)) { + echo "ERROR: There was a problem with the MySQL connection.\n"; + exit; +} + +echo "Start MySQL update..\n"; +mysql_db_query($conf['db_database'], "ALTER TABLE `web_domain` ADD `ssl_letsencrypt` enum('n','y') NOT NULL DEFAULT 'n';", $buffer); + +if(is_file("/etc/apache2/apache2.conf")) { + echo "Configure Apache and reload it.\n"; + if(is_file("/etc/apache2/conf-available/letsencrypt.conf")) { + exec("rm /etc/apache2/conf-available/letsencrypt.conf"); + } + exec("cp ./apache.letsencrypt.conf /etc/apache2/conf-available/letsencrypt.conf"); + exec("a2enmod headers"); + exec("a2enconf letsencrypt"); + exec("service apache2 reload"); +} + +if(is_file("/etc/nginx/nginx.conf")) { + echo "Patch Nginx and reload it.\n"; + exec("patch /etc/nginx/nginx.conf < ./nginx.conf.patch"); + exec("service nginx reload"); +} + +echo "Create backup cronjob on " . $backup_dir . " directory\n"; +exec("crontab -l >> " . $backup_dir . $backup_file2); +if(!file_exists($backup_dir . $backup_file2 )) { + echo "ERROR: There was a problem with the cronjob backup file.\n"; + exit; +} + +exec("crontab -l", $output); + +if(!in_array("30 02 * * * /root/.local/share/letsencrypt/bin/letsencrypt-renewer >> /var/log/ispconfig/cron.log; done", $output)) { + echo "Add a cronjob for renewal certs\n"; + + $output[] = "30 02 * * * /root/.local/share/letsencrypt/bin/letsencrypt-renewer >> /var/log/ispconfig/cron.log; done"; + + exec("touch ./crontab.tmp"); + if(!is_file("./crontab.tmp")) { + echo "ERROR: Unable to create temporary crontab file.\n"; + exit; + } + + foreach($output as $line) { + exec("echo '" . $line . "' >> ./crontab.tmp"); + } + + exec("cat ./crontab.tmp", $crontab); + + if(empty(array_diff($output, $crontab))) { + exec("crontab ./crontab.tmp"); + exec("rm ./crontab.tmp"); + } else { + echo "ERROR: There was a problem with the cronjob temporary file.\n"; + exit; + } +} else { + echo "Renewer already present in crontab.\n"; +} + +echo "And finally, patch ISPConfig.\n"; +exec("cp ispconfig.patch /usr/local/ispconfig/ispconfig.patch"); +exec("cd /usr/local/ispconfig"); +exec("patch -p3 < ./ispconfig.patch"); +exec("rm ./ispconfig.patch"); + +echo "Done my job. Enjoy!\n"; +exit; +?> diff --git a/ispconfig.patch b/ispconfig.patch new file mode 100644 index 0000000..72073f8 --- /dev/null +++ b/ispconfig.patch @@ -0,0 +1,466 @@ +diff -u -r /root/ispconfig/interface/web/sites/form/web_domain.tform.php /usr/local/ispconfig/interface/web/sites/form/web_domain.tform.php +--- /root/ispconfig/interface/web/sites/form/web_domain.tform.php 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/form/web_domain.tform.php 2015-11-05 02:28:13.272000000 +0100 +@@ -232,6 +232,12 @@ + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), ++ 'ssl_letsencrypt' => array ( ++ 'datatype' => 'VARCHAR', ++ 'formtype' => 'CHECKBOX', ++ 'default' => 'n', ++ 'value' => array(0 => 'n', 1 => 'y') ++ ), + 'php' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/ar_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/ar_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/ar_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/ar_web_domain.lng 2015-11-06 18:36:40.896000000 +0100 +@@ -28,6 +28,7 @@ + $wb['errordocs_txt'] = 'Own Error-Documents'; + $wb['subdomain_txt'] = 'Auto-Subdomain'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Client'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/bg_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/bg_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/bg_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/bg_web_domain.lng 2015-11-06 18:36:41.096000000 +0100 +@@ -26,6 +26,7 @@ + $wb['ssi_txt'] = 'SSI'; + $wb['errordocs_txt'] = 'Собствени страници за грешки'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Клиент'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/br_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/br_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/br_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/br_web_domain.lng 2015-11-06 18:36:40.896000000 +0100 +@@ -27,6 +27,7 @@ + $wb['errordocs_txt'] = 'Suas Páginas de Erro'; + $wb['subdomain_txt'] = 'Auto-Subdomínio'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Cliente'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/cz_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/cz_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/cz_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/cz_web_domain.lng 2015-11-06 18:36:40.920000000 +0100 +@@ -27,6 +27,7 @@ + $wb['ssi_txt'] = 'SSI'; + $wb['subdomain_txt'] = 'Automatická subdoména'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Klient'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/de_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/de_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/de_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/de_web_domain.lng 2015-11-06 18:36:38.772000000 +0100 +@@ -27,6 +27,7 @@ + $wb['cgi_txt'] = 'CGI'; + $wb['ssi_txt'] = 'SSI'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Kunde'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/el_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/el_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/el_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/el_web_domain.lng 2015-11-06 18:36:39.484000000 +0100 +@@ -30,6 +30,7 @@ + $wb['errordocs_txt'] = 'Προσωπικά έγγραφα σφάλματος'; + $wb['subdomain_txt'] = 'Auto-Subdomain'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Πελάτης'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/en_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/en_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/en_web_domain.lng 2015-11-07 13:37:31.740000000 +0100 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/en_web_domain.lng 2015-11-07 13:37:36.004000000 +0100 +@@ -33,6 +33,7 @@ + $wb["errordocs_txt"] = 'Own Error-Documents'; + $wb["subdomain_txt"] = 'Auto-Subdomain'; + $wb["ssl_txt"] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb["suexec_txt"] = 'SuEXEC'; + $wb["php_txt"] = 'PHP'; + $wb["client_txt"] = 'Client'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/es_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/es_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/es_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/es_web_domain.lng 2015-11-06 18:36:38.360000000 +0100 +@@ -31,6 +31,7 @@ + $wb['errordocs_txt'] = 'Documentos propios de error'; + $wb['subdomain_txt'] = 'Auto-Subdominio'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Cliente'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/fi_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/fi_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/fi_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/fi_web_domain.lng 2015-11-06 18:36:38.376000000 +0100 +@@ -25,6 +25,7 @@ + $wb['cgi_txt'] = 'CGI'; + $wb['ssi_txt'] = 'SSI'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Asiakas'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/fr_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/fr_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/fr_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/fr_web_domain.lng 2015-11-06 18:36:41.744000000 +0100 +@@ -25,6 +25,7 @@ + $wb['ssi_txt'] = 'SSI'; + $wb['errordocs_txt'] = 'Pages derreurs personnalisées'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Client'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/hr_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/hr_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/hr_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/hr_web_domain.lng 2015-11-06 18:36:38.412000000 +0100 +@@ -30,6 +30,7 @@ + $wb['errordocs_txt'] = 'Vlastite error stranice'; + $wb['subdomain_txt'] = 'Automatska poddomena'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Klijent'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/hu_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/hu_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/hu_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/hu_web_domain.lng 2015-11-06 18:36:35.844000000 +0100 +@@ -26,6 +26,7 @@ + $wb['ssi_txt'] = 'SSI'; + $wb['errordocs_txt'] = 'Saját hibaoldal'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['disabled_txt'] = 'Letiltva'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/id_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/id_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/id_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/id_web_domain.lng 2015-11-06 18:36:36.228000000 +0100 +@@ -28,6 +28,7 @@ + $wb['errordocs_txt'] = 'Dokumen-Kesalahan Pribadi'; + $wb['subdomain_txt'] = 'Subdomain Otomatis'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Klien'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/it_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/it_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/it_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/it_web_domain.lng 2015-11-06 18:36:36.892000000 +0100 +@@ -26,6 +26,7 @@ + $wb['ssi_txt'] = 'SSI'; + $wb['errordocs_txt'] = 'Errori personalizzati'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Cliente'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/ja_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/ja_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/ja_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/ja_web_domain.lng 2015-11-06 18:36:34.476000000 +0100 +@@ -27,6 +27,7 @@ + $wb['errordocs_txt'] = '独自のエラーページを使う'; + $wb['subdomain_txt'] = '自動サブドメイン'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'クライアント'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/nl_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/nl_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/nl_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/nl_web_domain.lng 2015-11-06 18:36:35.852000000 +0100 +@@ -30,6 +30,7 @@ + $wb['errordocs_txt'] = 'Own Error-documenten'; + $wb['subdomain_txt'] = 'Auto-subdomein'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Klant'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/pl_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/pl_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/pl_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/pl_web_domain.lng 2015-11-06 18:36:35.828000000 +0100 +@@ -27,6 +27,7 @@ + $wb['errordocs_txt'] = 'Własne strony błędów'; + $wb['subdomain_txt'] = 'Automatyczna subdomena'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Klient'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/pt_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/pt_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/pt_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/pt_web_domain.lng 2015-11-06 18:36:33.296000000 +0100 +@@ -27,6 +27,7 @@ + $wb['errordocs_txt'] = 'Páginas de Erro'; + $wb['subdomain_txt'] = 'Auto-Subdomínio'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Cliente'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/ro_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/ro_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/ro_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/ro_web_domain.lng 2015-11-06 18:36:33.884000000 +0100 +@@ -27,6 +27,7 @@ + $wb['errordocs_txt'] = 'Own Error-Documents'; + $wb['subdomain_txt'] = 'Auto-Subdomain'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Client'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/ru_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/ru_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/ru_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/ru_web_domain.lng 2015-11-06 18:36:54.424000000 +0100 +@@ -25,6 +25,7 @@ + $wb['cgi_txt'] = 'CGI'; + $wb['ssi_txt'] = 'SSI'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Клиент'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/se_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/se_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/se_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/se_web_domain.lng 2015-11-06 18:36:33.256000000 +0100 +@@ -26,6 +26,7 @@ + $wb['ssi_txt'] = 'SSI'; + $wb['errordocs_txt'] = 'Own Error-Documents'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Client'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/sk_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/sk_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/sk_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/sk_web_domain.lng 2015-11-06 18:36:33.096000000 +0100 +@@ -27,6 +27,7 @@ + $wb['errordocs_txt'] = 'Vlastné Error-Dokumenty'; + $wb['subdomain_txt'] = 'Auto-Subdomény'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Klient'; +diff -u -r /root/ispconfig/interface/web/sites/lib/lang/tr_web_domain.lng /usr/local/ispconfig/interface/web/sites/lib/lang/tr_web_domain.lng +--- /root/ispconfig/interface/web/sites/lib/lang/tr_web_domain.lng 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/interface/web/sites/lib/lang/tr_web_domain.lng 2015-11-06 18:39:23.560000000 +0100 +@@ -27,6 +27,7 @@ + $wb['errordocs_txt'] = 'Özelleştirilebilir Hata Sayfaları'; + $wb['subdomain_txt'] = 'Otomatik Subdomain'; + $wb['ssl_txt'] = 'SSL'; ++$wb['ssl_letsencrypt_txt'] = 'Let\'s Encrypt'; + $wb['suexec_txt'] = 'SuEXEC'; + $wb['php_txt'] = 'PHP'; + $wb['client_txt'] = 'Müşteri'; +diff -u -r /root/ispconfig/interface/web/sites/templates/web_domain_edit.htm /usr/local/ispconfig/interface/web/sites/templates/web_domain_edit.htm +--- /root/ispconfig/interface/web/sites/templates/web_domain_edit.htm 2015-11-06 20:44:44.560000000 +0100 ++++ /usr/local/ispconfig/interface/web/sites/templates/web_domain_edit.htm 2015-11-06 20:44:05.192000000 +0100 +@@ -130,6 +130,12 @@ +
+ {tmpl_var name='ssl'} +
++ ++
++

{tmpl_var name='ssl_letsencrypt_txt'}

++
++ {tmpl_var name='ssl_letsencrypt'} ++
+
+
+ +@@ -261,5 +267,11 @@ + submitForm('pageForm','sites/web_domain_edit.php'); + }); + +- +- +\ No newline at end of file ++ ++ jQuery('input#ssl_letsencrypt').bind('change', function() { ++ if(jQuery('input#ssl_letsencrypt').is(":checked")) jQuery('input#ssl').prop('checked', true); ++ }); ++ jQuery('input#ssl').bind('change', function() { ++ if(jQuery('input#ssl_letsencrypt').is(":checked")) jQuery('input#ssl_letsencrypt').prop('checked', false); ++ }); ++ +diff -u -r /root/ispconfig/server/conf/nginx_vhost.conf.master /usr/local/ispconfig/server/conf/nginx_vhost.conf.master +--- /root/ispconfig/server/conf/nginx_vhost.conf.master 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/server/conf/nginx_vhost.conf.master 2015-11-08 02:40:25.192000000 +0100 +@@ -105,12 +105,14 @@ + access_log /var/log/ispconfig/httpd//access.log combined; + + ## Disable .htaccess and other hidden files ++ + location ~ /\. { + deny all; + access_log off; + log_not_found off; + } +- ++ ++ + location = /favicon.ico { + log_not_found off; + access_log off; +@@ -229,4 +231,4 @@ + } + + } +- +\ No newline at end of file ++ +diff -u -r /root/ispconfig/server/plugins-available/apache2_plugin.inc.php /usr/local/ispconfig/server/plugins-available/apache2_plugin.inc.php +--- /root/ispconfig/server/plugins-available/apache2_plugin.inc.php 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/server/plugins-available/apache2_plugin.inc.php 2015-11-08 03:03:12.028000000 +0100 +@@ -935,7 +935,7 @@ + + // Check if a SSL cert exists + $ssl_dir = $data['new']['document_root'].'/ssl'; +- $domain = $data['new']['ssl_domain']; ++ $domain = $data['new']['domain']; + $key_file = $ssl_dir.'/'.$domain.'.key'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + $bundle_file = $ssl_dir.'/'.$domain.'.bundle'; +@@ -950,6 +950,57 @@ + } + */ + ++ //* Generate Let's Encrypt SSL certificat ++ if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y') { ++//* TODO: check dns entry is correct ++ $crt_tmp_file = "/etc/letsencrypt/live/".$domain."/cert.pem"; ++ $key_tmp_file = "/etc/letsencrypt/live/".$domain."/privkey.pem"; ++ $webroot = $data['new']['document_root']."/web"; ++ ++ //* check if we have already a Let's Encrypt cert ++ if(!file_exists($crt_tmp_file) && !file_exists($key_tmp_file)) { ++ exec("/root/.local/share/letsencrypt/bin/letsencrypt auth -a webroot --email postmaster@$domain --domains $domain --webroot-path $webroot --text --agree-tos"); ++ $app->log("Creating Let's Encrypt SSL Cert for: $domain", LOGLEVEL_DEBUG); ++ }; ++ ++ //* check is been correctly created ++ if(file_exists($crt_tmp_file) OR file_exists($key_tmp_file)) { ++ $date = date("YmdHis"); ++//* TODO: check if is a symlink, if target same keep it, either remove it ++ if(is_file($key_file)) { ++ $app->system->copy($key_file, $key_file.'.old'.$date); ++ $app->system->chmod($key_file.'.old.'.$date, 0400); ++ $app->system->unlink($key_file); ++ } ++ ++ if ($web_config["website_symlinks_rel"] == 'y') { ++ $this->create_relative_link(escapeshellcmd($key_tmp_file), escapeshellcmd($key_file)); ++ } else { ++ exec("ln -s ".escapeshellcmd($key_tmp_file)." ".escapeshellcmd($key_file)); ++ } ++ ++ if(is_file($crt_file)) { ++ $app->system->copy($crt_file, $crt_file.'.old.'.$date); ++ $app->system->chmod($crt_file.'.old.'.$date, 0400); ++ $app->system->unlink($crt_file); ++ } ++ ++ if($web_config["website_symlinks_rel"] == 'y') { ++ $this->create_relative_link(escapeshellcmd($crt_tmp_file), escapeshellcmd($crt_file)); ++ } else { ++ exec("ln -s ".escapeshellcmd($crt_tmp_file)." ".escapeshellcmd($crt_file)); ++ } ++ ++ /* we don't need to store it. ++ /* Update the DB of the (local) Server */ ++ $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key' WHERE domain = '".$data['new']['domain']."'"); ++ $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); ++ /* Update also the master-DB of the Server-Farm */ ++ $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key' WHERE domain = '".$data['new']['domain']."'"); ++ $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); ++ } ++ }; ++ + if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1; + + //$vhost_data['document_root'] = $data['new']['document_root'].'/' . $web_folder; +diff -u -r /root/ispconfig/server/plugins-available/nginx_plugin.inc.php /usr/local/ispconfig/server/plugins-available/nginx_plugin.inc.php +--- /root/ispconfig/server/plugins-available/nginx_plugin.inc.php 2015-06-05 10:06:30.000000000 +0200 ++++ /usr/local/ispconfig/server/plugins-available/nginx_plugin.inc.php 2015-11-08 03:13:36.524000000 +0100 +@@ -1102,10 +1102,66 @@ + + // Check if a SSL cert exists + $ssl_dir = $data['new']['document_root'].'/ssl'; ++ if(!isset($data['new']['ssl_domain']) OR empty($data['new']['ssl_domain'])) { $data['new']['ssl_domain'] = $data['new']['domain']; } + $domain = $data['new']['ssl_domain']; ++ $tpl->setVar('ssl_domain', $domain); + $key_file = $ssl_dir.'/'.$domain.'.key'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + ++ ++ $tpl->setVar('ssl_letsencrypt', "n"); ++ //* Generate Let's Encrypt SSL certificat ++ if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y') { ++ $tpl->setVar('ssl_letsencrypt', "y"); ++ //* TODO: check dns entry is correct ++ $crt_tmp_file = "/etc/letsencrypt/live/".$domain."/fullchain.pem"; ++ $key_tmp_file = "/etc/letsencrypt/live/".$domain."/privkey.pem"; ++ $webroot = $data['new']['document_root']."/web"; ++ ++ //* check if we have already a Let's Encrypt cert ++ if(!file_exists($crt_tmp_file) && !file_exists($key_tmp_file)) { ++ exec("/root/.local/share/letsencrypt/bin/letsencrypt auth -a webroot --email postmaster@$domain --domains $domain --webroot-path $webroot --text --agree-tos"); ++ $app->log("Creating Let's Encrypt SSL Cert for: $domain", LOGLEVEL_DEBUG); ++ }; ++ ++ //* check is been correctly created ++ if(file_exists($crt_tmp_file) OR file_exists($key_tmp_file)) { ++ $date = date("YmdHis"); ++//* TODO: check if is a symlink, if target same keep it, either remove it ++ if(is_file($key_file)) { ++ $app->system->copy($key_file, $key_file.'.old'.$date); ++ $app->system->chmod($key_file.'.old.'.$date, 0400); ++ $app->system->unlink($key_file); ++ } ++ ++ if ($web_config["website_symlinks_rel"] == 'y') { ++ $this->create_relative_link(escapeshellcmd($key_tmp_file), escapeshellcmd($key_file)); ++ } else { ++ exec("ln -s ".escapeshellcmd($key_tmp_file)." ".escapeshellcmd($key_file)); ++ } ++ ++ if(is_file($crt_file)) { ++ $app->system->copy($crt_file, $crt_file.'.old.'.$date); ++ $app->system->chmod($crt_file.'.old.'.$date, 0400); ++ $app->system->unlink($crt_file); ++ } ++ ++ if($web_config["website_symlinks_rel"] == 'y') { ++ $this->create_relative_link(escapeshellcmd($crt_tmp_file), escapeshellcmd($crt_file)); ++ } else { ++ exec("ln -s ".escapeshellcmd($crt_tmp_file)." ".escapeshellcmd($crt_file)); ++ } ++ ++ /* we don't need to store it. ++ /* Update the DB of the (local) Server */ ++ $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = '".$data['new']['domain']."'"); ++ $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); ++ /* Update also the master-DB of the Server-Farm */ ++ $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = '".$data['new']['domain']."'"); ++ $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); ++ } ++ }; ++ + if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { + $vhost_data['ssl_enabled'] = 1; + $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG); \ No newline at end of file diff --git a/nginx.conf.patch b/nginx.conf.patch new file mode 100644 index 0000000..b49364b --- /dev/null +++ b/nginx.conf.patch @@ -0,0 +1,15 @@ +--- /etc/nginx/nginx.conf.orig 2015-11-08 01:44:42.558552834 +0100 ++++ /etc/nginx/nginx.conf 2015-11-08 02:10:51.275908452 +0100 +@@ -9,6 +9,12 @@ + + http { + ++ server { ++ location ~ /.well-known/acme-challenge/(.*) { ++ default_type application/jose+json; ++ } ++ } ++ + ## + # Basic Settings + ## -- cgit v1.2.3