Merge pull request #144 from WordOps/updating-configuration

Updating configuration
This commit is contained in:
VirtuBox
2019-09-06 17:07:40 +02:00
committed by GitHub
18 changed files with 508 additions and 299 deletions

View File

@@ -8,6 +8,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### v3.9.x - [Unreleased] ### v3.9.x - [Unreleased]
### v3.9.8.11 - 2019-09-06
#### Changed
- Improved general logs display
- UFW configuration is only applied during initial installation if UFW is disabled
#### Fixed
- Redis-server configuration and start
- Nginx upgrade with `wo stack upgrade`
### v3.9.8.10 - 2019-09-04 ### v3.9.8.10 - 2019-09-04
#### Changed #### Changed

112
install
View File

@@ -390,7 +390,7 @@ wo_update_wp_cli() {
wo_install_acme_sh() { wo_install_acme_sh() {
# check if acme.sh is already installed # check if acme.sh is already installed
if [ ! -x /etc/letsencrypt/acme.sh ]; then if [ ! -x /etc/letsencrypt/acme.sh ] && [ ! -d /etc/letsencrypt/archive ]; then
{ {
# clone the git repository # clone the git repository
if [ -d /opt/acme.sh/.git ]; then if [ -d /opt/acme.sh/.git ]; then
@@ -539,6 +539,8 @@ wo_upgrade_nginx() {
sed -i "s/locations-php71.conf/locations-wo.conf/" /etc/nginx/sites-available/* sed -i "s/locations-php71.conf/locations-wo.conf/" /etc/nginx/sites-available/*
sed -i "s/locations-php72.conf/locations-wo.conf/" /etc/nginx/sites-available/* sed -i "s/locations-php72.conf/locations-wo.conf/" /etc/nginx/sites-available/*
sed -i "s/locations-php73.conf/locations-wo.conf/" /etc/nginx/sites-available/* sed -i "s/locations-php73.conf/locations-wo.conf/" /etc/nginx/sites-available/*
sed -i "s/php.conf/php72.conf/" /etc/nginx/sites-available/*
sed -i "s/php7.conf/php72.conf/" /etc/nginx/sites-available/*
sed -i 's/ssl on;/#ssl on;/' /var/www/*/conf/nginx/ssl.conf sed -i 's/ssl on;/#ssl on;/' /var/www/*/conf/nginx/ssl.conf
# update redis.conf headers # update redis.conf headers
@@ -731,75 +733,71 @@ wo_uninstall() {
} }
wo_ufw_setup() { wo_ufw_setup() {
if ! grep -q "ENABLED=yes" /etc/ufw/ufw.conf; then
# get custom ssh port # get custom ssh port
if [ -f /etc/ssh/sshd_config ]; then if [ -f /etc/ssh/sshd_config ]; then
CURRENT_SSH_PORT=$(grep "Port" /etc/ssh/sshd_config | awk -F " " '{print $2}') CURRENT_SSH_PORT=$(grep "Port" /etc/ssh/sshd_config | awk -F " " '{print $2}')
fi fi
# define firewall rules # define firewall rules
if ! grep -q "LOGLEVEL=low" /etc/ufw/ufw.conf; then if ! grep -q "LOGLEVEL=low" /etc/ufw/ufw.conf; then
ufw logging low ufw logging low
fi fi
if ! grep -q 'DEFAULT_OUTPUT_POLICY="ACCEPT"' /etc/default/ufw; then if ! grep -q 'DEFAULT_OUTPUT_POLICY="ACCEPT"' /etc/default/ufw; then
ufw default allow outgoing ufw default allow outgoing
fi fi
if ! grep -q 'DEFAULT_INPUT_POLICY="DROP"' /etc/default/ufw; then if ! grep -q 'DEFAULT_INPUT_POLICY="DROP"' /etc/default/ufw; then
ufw default deny incoming ufw default deny incoming
fi fi
if ! grep -q "\-\-dport 22 -j" /etc/ufw/user.rules; then if ! grep -q "\-\-dport 22 -j" /etc/ufw/user.rules; then
# default ssh port # default ssh port
ufw limit 22 ufw limit 22
fi
# custom ssh port
if [ "$CURRENT_SSH_PORT" != "22" ]; then
if ! grep -q "\-\-dport $CURRENT_SSH_PORT -j" /etc/ufw/user.rules; then
ufw limit "$CURRENT_SSH_PORT"
fi fi
fi
# nginx # custom ssh port
if ! grep -q "\-\-dport 80 -j" /etc/ufw/user.rules; then if [ "$CURRENT_SSH_PORT" != "22" ]; then
# http if ! grep -q "\-\-dport $CURRENT_SSH_PORT -j" /etc/ufw/user.rules; then
ufw allow http ufw limit "$CURRENT_SSH_PORT"
fi fi
if ! grep -q "\-\-dport 443 -j" /etc/ufw/user.rules; then fi
# https
ufw allow https
fi
# ntp # nginx
if ! grep -q "\-\-dport 123 -j" /etc/ufw/user.rules; then if ! grep -q "\-\-dport 80 -j" /etc/ufw/user.rules; then
ufw allow 123 # http
fi ufw allow http
fi
if ! grep -q "\-\-dport 443 -j" /etc/ufw/user.rules; then
# https
ufw allow https
fi
if ! grep -q "\-\-dport 22222 -j" /etc/ufw/user.rules; then # ntp
# wordops backend if ! grep -q "\-\-dport 123 -j" /etc/ufw/user.rules; then
ufw limit 22222 ufw allow 123
fi fi
# enable ufw
if [ -n "$CURRENT_SSH_PORT" ]; then if ! grep -q "\-\-dport 22222 -j" /etc/ufw/user.rules; then
if ! grep -q "ENABLED=yes" /etc/ufw/ufw.conf; then # wordops backend
ufw limit 22222
fi
# enable ufw
if [ -n "$CURRENT_SSH_PORT" ]; then
ufw --force enable ufw --force enable
else fi
ufw reload
# remove ufw from syslog
if [ -f /etc/rsyslog.d/20-ufw.conf ]; then
sed -i 's/\#\& stop/\& stop/' /etc/rsyslog.d/20-ufw.conf
service rsyslog restart
fi fi
fi fi
# remove ufw from syslog
if [ -f /etc/rsyslog.d/20-ufw.conf ]; then
sed -i 's/\#\& stop/\& stop/' /etc/rsyslog.d/20-ufw.conf
service rsyslog restart
fi
} \ } \
>> $wo_install_log >> $wo_install_log
wo_cheat_install() { wo_cheat_install() {
curl -sL https://cht.sh/:cht.sh > /usr/local/bin/cht.sh curl -sL https://cht.sh/:cht.sh > /usr/local/bin/cht.sh
chmod +x /usr/local/bin/cht.sh chmod +x /usr/local/bin/cht.sh
[ ! -h /usr/local/bin/cheat ] && { [ ! -h /usr/local/bin/cheat ] && {
ln -s /usr/local/bin/cht.sh /usr/local/bin/cheat ln -s /usr/local/bin/cht.sh /usr/local/bin/cheat
} }
curl -sL https://cheat.sh/:bash_completion > /etc/bash_completion.d/cht.sh curl -sL https://cheat.sh/:bash_completion > /etc/bash_completion.d/cht.sh
} }

View File

@@ -10,7 +10,7 @@ CGREEN="${CSI}1;32m"
CEND="${CSI}0m" CEND="${CSI}0m"
exit_script() { exit_script() {
curl --progress-bar --upload-file /var/log/wo/wordops.log https://transfer.vtbox.net/"$(basename wordops.log)" && echo "" | sudo tee -a $HOME/.transfer.log && echo "" curl --progress-bar --upload-file /var/log/wo/wordops.log https://transfer.vtbox.net/"$(basename wordops.log)" && echo ""
exit 1 exit 1
} }

View File

@@ -1,12 +1,14 @@
"""WordOps main application entry point.""" """WordOps main application entry point."""
import sys
import os import os
import sys
from cement.core import foundation from cement.core import foundation
from cement.utils.misc import init_defaults from cement.core.exc import CaughtSignal, FrameworkError
from cement.core.exc import FrameworkError, CaughtSignal
from cement.ext.ext_argparse import ArgParseArgumentHandler from cement.ext.ext_argparse import ArgParseArgumentHandler
from wo.core import exc from cement.utils.misc import init_defaults
from wo.cli.ext.wo_outputhandler import WOOutputHandler from wo.cli.ext.wo_outputhandler import WOOutputHandler
from wo.core import exc
# this has to happen after you import sys, but before you import anything # this has to happen after you import sys, but before you import anything
# from Cement "source: https://github.com/datafolklabs/cement/issues/290" # from Cement "source: https://github.com/datafolklabs/cement/issues/290"

View File

@@ -86,12 +86,12 @@ class WOSecureController(CementBaseController):
while not pargs.user_input.isdigit(): while not pargs.user_input.isdigit():
Log.info(self, "Please enter a valid port number ") Log.info(self, "Please enter a valid port number ")
pargs.user_input = input("WordOps " pargs.user_input = input("WordOps "
"admin port [22222]:") "admin port [22222]:")
if not pargs.user_input: if not pargs.user_input:
port = input("WordOps admin port [22222]:") port = input("WordOps admin port [22222]:")
if port == "": if port == "":
pargs.user_input = 22222 pargs.user_input = 22222
while not port.isdigit() and port != "": while (not port.isdigit()) and (port != "") and (not port < 65556):
Log.info(self, "Please Enter valid port number :") Log.info(self, "Please Enter valid port number :")
port = input("WordOps admin port [22222]:") port = input("WordOps admin port [22222]:")
pargs.user_input = port pargs.user_input = port

View File

@@ -7,6 +7,7 @@ from subprocess import Popen
from cement.core import handler, hook from cement.core import handler, hook
from cement.core.controller import CementBaseController, expose from cement.core.controller import CementBaseController, expose
from wo.cli.plugins.site_functions import * from wo.cli.plugins.site_functions import *
from wo.cli.plugins.sitedb import (addNewSite, deleteSiteInfo, getAllsites, from wo.cli.plugins.sitedb import (addNewSite, deleteSiteInfo, getAllsites,
getSiteInfo, updateSiteInfo) getSiteInfo, updateSiteInfo)

View File

@@ -35,15 +35,18 @@ class SiteError(Exception):
def pre_run_checks(self): def pre_run_checks(self):
# Check nginx configuration # Check nginx configuration
Log.info(self, "Running pre-update checks, please wait...") Log.wait(self, "Running pre-update checks")
try: try:
Log.debug(self, "checking NGINX configuration ...") Log.debug(self, "checking NGINX configuration ...")
FNULL = open('/dev/null', 'w') FNULL = open('/dev/null', 'w')
subprocess.check_call(["/usr/sbin/nginx", "-t"], stdout=FNULL, subprocess.check_call(["/usr/sbin/nginx", "-t"], stdout=FNULL,
stderr=subprocess.STDOUT) stderr=subprocess.STDOUT)
except CalledProcessError as e: except CalledProcessError as e:
Log.failed(self, "Running pre-update checks")
Log.debug(self, "{0}".format(str(e))) Log.debug(self, "{0}".format(str(e)))
raise SiteError("nginx configuration check failed.") raise SiteError("nginx configuration check failed.")
else:
Log.valide(self, "Running pre-update checks")
def check_domain_exists(self, domain): def check_domain_exists(self, domain):
@@ -643,7 +646,7 @@ def setupwordpressnetwork(self, data):
def installwp_plugin(self, plugin_name, data): def installwp_plugin(self, plugin_name, data):
wo_site_webroot = data['webroot'] wo_site_webroot = data['webroot']
Log.info(self, "Installing plugin {0}, please wait..." Log.wait(self, "Installing plugin {0}"
.format(plugin_name)) .format(plugin_name))
WOFileUtils.chdir(self, '{0}/htdocs/'.format(wo_site_webroot)) WOFileUtils.chdir(self, '{0}/htdocs/'.format(wo_site_webroot))
try: try:
@@ -665,9 +668,13 @@ def installwp_plugin(self, plugin_name, data):
else '' else ''
)) ))
except CommandExecutionError as e: except CommandExecutionError as e:
Log.failed(self, "Installing plugin {0}"
.format(plugin_name))
Log.debug(self, "{0}".format(e)) Log.debug(self, "{0}".format(e))
raise SiteError("plugin activation failed") raise SiteError("plugin activation failed")
else:
Log.valide(self, "Installing plugin {0}"
.format(plugin_name))
return 1 return 1
@@ -676,7 +683,7 @@ def uninstallwp_plugin(self, plugin_name, data):
Log.debug(self, "Uninstalling plugin {0}, please wait..." Log.debug(self, "Uninstalling plugin {0}, please wait..."
.format(plugin_name)) .format(plugin_name))
WOFileUtils.chdir(self, '{0}/htdocs/'.format(wo_site_webroot)) WOFileUtils.chdir(self, '{0}/htdocs/'.format(wo_site_webroot))
Log.info(self, "Uninstalling plugin {0}, please wait..." Log.wait(self, "Uninstalling plugin {0}"
.format(plugin_name)) .format(plugin_name))
try: try:
WOShellExec.cmd_exec(self, "{0} plugin " WOShellExec.cmd_exec(self, "{0} plugin "
@@ -689,13 +696,18 @@ def uninstallwp_plugin(self, plugin_name, data):
"--allow-root uninstall " "--allow-root uninstall "
"{0}".format(plugin_name)) "{0}".format(plugin_name))
except CommandExecutionError as e: except CommandExecutionError as e:
Log.failed(self, "Uninstalling plugin {0}"
.format(plugin_name))
Log.debug(self, "{0}".format(e)) Log.debug(self, "{0}".format(e))
raise SiteError("plugin uninstall failed") raise SiteError("plugin uninstall failed")
else:
Log.valide(self, "Uninstalling plugin {0}"
.format(plugin_name))
def setupwp_plugin(self, plugin_name, plugin_option, plugin_data, data): def setupwp_plugin(self, plugin_name, plugin_option, plugin_data, data):
wo_site_webroot = data['webroot'] wo_site_webroot = data['webroot']
Log.info(self, "Setting plugin {0}, please wait..." Log.wait(self, "Setting plugin {0}"
.format(plugin_name)) .format(plugin_name))
WOFileUtils.chdir(self, '{0}/htdocs/'.format(wo_site_webroot)) WOFileUtils.chdir(self, '{0}/htdocs/'.format(wo_site_webroot))
@@ -707,8 +719,13 @@ def setupwp_plugin(self, plugin_name, plugin_option, plugin_data, data):
"{0} \'{1}\' --format=json" "{0} \'{1}\' --format=json"
.format(plugin_option, plugin_data)) .format(plugin_option, plugin_data))
except CommandExecutionError as e: except CommandExecutionError as e:
Log.failed(self, "Setting plugin {0}"
.format(plugin_name))
Log.debug(self, "{0}".format(e)) Log.debug(self, "{0}".format(e))
raise SiteError("plugin setup failed") raise SiteError("plugin setup failed")
else:
Log.valide(self, "Setting plugin {0}"
.format(plugin_name))
else: else:
try: try:
WOShellExec.cmd_exec(self, "{0} " WOShellExec.cmd_exec(self, "{0} "
@@ -718,8 +735,13 @@ def setupwp_plugin(self, plugin_name, plugin_option, plugin_data, data):
.format(plugin_option, plugin_data .format(plugin_option, plugin_data
)) ))
except CommandExecutionError as e: except CommandExecutionError as e:
Log.failed(self, "Setting plugin {0}"
.format(plugin_name))
Log.debug(self, "{0}".format(e)) Log.debug(self, "{0}".format(e))
raise SiteError("plugin setup failed") raise SiteError("plugin setup failed")
else:
Log.valide(self, "Setting plugin {0}"
.format(plugin_name))
def setwebrootpermissions(self, webroot): def setwebrootpermissions(self, webroot):
@@ -1354,7 +1376,7 @@ def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False,
if subdomain: if subdomain:
Log.info(self, "Certificate type: Subdomain") Log.info(self, "Certificate type: Subdomain")
Log.info(self, "Validation mode : {0}".format(validation_mode)) Log.info(self, "Validation mode : {0}".format(validation_mode))
Log.wait(self, "Issuing SSL certificate with acme.sh") Log.wait(self, "Issuing SSL cert with acme.sh")
ssl = WOShellExec.cmd_exec(self, "{0} ".format(wo_acme_exec) + ssl = WOShellExec.cmd_exec(self, "{0} ".format(wo_acme_exec) +
"--issue " "--issue "
"-d {0} {1} " "-d {0} {1} "
@@ -1365,7 +1387,7 @@ def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False,
elif wildcard: elif wildcard:
Log.info(self, "Certificate type: Wildcard") Log.info(self, "Certificate type: Wildcard")
Log.info(self, "Validation mode : {0}".format(validation_mode)) Log.info(self, "Validation mode : {0}".format(validation_mode))
Log.wait(self, "Issuing SSL certificate with acme.sh") Log.wait(self, "Issuing SSL cert with acme.sh")
ssl = WOShellExec.cmd_exec(self, "{0} ".format(wo_acme_exec) + ssl = WOShellExec.cmd_exec(self, "{0} ".format(wo_acme_exec) +
"--issue " "--issue "
"-d {0} -d '*.{0}' --dns {1} " "-d {0} -d '*.{0}' --dns {1} "
@@ -1376,7 +1398,7 @@ def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False,
else: else:
Log.info(self, "Certificate type: Domain + www") Log.info(self, "Certificate type: Domain + www")
Log.info(self, "Validation mode : {0}".format(validation_mode)) Log.info(self, "Validation mode : {0}".format(validation_mode))
Log.wait(self, "Issuing SSL certificate with acme.sh") Log.wait(self, "Issuing SSL cert with acme.sh")
ssl = WOShellExec.cmd_exec(self, "{0} ".format(wo_acme_exec) + ssl = WOShellExec.cmd_exec(self, "{0} ".format(wo_acme_exec) +
"--issue " "--issue "
"-d {0} -d www.{0} {1} " "-d {0} -d www.{0} {1} "
@@ -1384,8 +1406,8 @@ def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False,
.format(wo_domain_name, .format(wo_domain_name,
acme_mode, keylenght)) acme_mode, keylenght))
if ssl: if ssl:
Log.valide(self, "Issuing SSL certificate with acme.sh") Log.valide(self, "Issuing SSL cert with acme.sh")
Log.wait(self, "Deploying SSL cert with acme.sh") Log.wait(self, "Deploying SSL cert")
Log.debug(self, "Cert deployment for domain: {0}" Log.debug(self, "Cert deployment for domain: {0}"
.format(wo_domain_name)) .format(wo_domain_name))
try: try:
@@ -1405,7 +1427,7 @@ def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False,
"service nginx restart\" " "service nginx restart\" "
.format(WOVariables.wo_ssl_live, .format(WOVariables.wo_ssl_live,
wo_domain_name)) wo_domain_name))
Log.valide(self, "Deploying SSL cert with acme.sh") Log.valide(self, "Deploying SSL cert")
if os.path.isdir('/var/www/{0}/conf/nginx' if os.path.isdir('/var/www/{0}/conf/nginx'
.format(wo_domain_name)): .format(wo_domain_name)):
@@ -1553,6 +1575,7 @@ def httpsRedirect(self, wo_domain_name, redirect=True, wildcard=False):
"/etc/nginx/conf.d/force-ssl-{0}.conf" "/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name)) .format(wo_domain_name))
else: else:
Log.wait(self, "Adding HTTPS redirection")
if wildcard: if wildcard:
try: try:
sslconf = open("/etc/nginx/conf.d/force-ssl-{0}.conf" sslconf = open("/etc/nginx/conf.d/force-ssl-{0}.conf"
@@ -1582,18 +1605,18 @@ def httpsRedirect(self, wo_domain_name, redirect=True, wildcard=False):
"\tlisten [::]:80;\n" + "\tlisten [::]:80;\n" +
"\tserver_name www.{0} {0};\n" "\tserver_name www.{0} {0};\n"
.format(wo_domain_name) + .format(wo_domain_name) +
"\treturn 301 https://{0}" "\treturn 301 https://$host"
.format(wo_domain_name)+"$request_uri;\n}") "$request_uri;\n}")
sslconf.close() sslconf.close()
except IOError as e: except IOError as e:
Log.failed(self, "Adding HTTPS redirection")
Log.debug(self, str(e)) Log.debug(self, str(e))
Log.debug(self, "Error occured while generating " Log.debug(self, "Error occured while generating "
"/etc/nginx/conf.d/force-ssl-{0}.conf" "/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name)) .format(wo_domain_name))
else:
Log.info(self, "Added HTTPS Force Redirection for Site " Log.valide(self, "Adding HTTPS redirection")
" http://{0}".format(wo_domain_name))
# Nginx Configation into GIT # Nginx Configation into GIT
WOGit.add(self, WOGit.add(self,
["/etc/nginx"], msg="Adding /etc/nginx/conf.d/" ["/etc/nginx"], msg="Adding /etc/nginx/conf.d/"
@@ -1715,3 +1738,16 @@ def archivedCertificateHandle(self, domain):
.format(domain)) .format(domain))
return ssl return ssl
def setuprocketchat(self):
if ((not WOVariables.wo_platform_codename == 'bionic') and
(not WOVariables.wo_platform_codename == 'xenial')):
Log.info(self, "Rocket.chat is only available on Ubuntu 16.04 "
"& 18.04 LTS")
return False
else:
if not WOAptGet.is_installed(self, 'snapd'):
WOAptGet.install(self, ["snapd"])
if WOShellExec.cmd_exec(self, "snap install rocketchat-server"):
return True

View File

@@ -9,11 +9,12 @@ import re
import shutil import shutil
import string import string
import psutil
import requests import requests
import psutil
from cement.core import handler, hook from cement.core import handler, hook
from cement.core.controller import CementBaseController, expose from cement.core.controller import CementBaseController, expose
from wo.cli.plugins.site_functions import * from wo.cli.plugins.site_functions import *
from wo.cli.plugins.sitedb import * from wo.cli.plugins.sitedb import *
from wo.cli.plugins.stack_migrate import WOStackMigrateController from wo.cli.plugins.stack_migrate import WOStackMigrateController
@@ -189,9 +190,8 @@ class WOStackController(CementBaseController):
# Redis # Redis
if pargs.redis: if pargs.redis:
pargs.php = True
if not WOAptGet.is_installed(self, 'redis-server'): if not WOAptGet.is_installed(self, 'redis-server'):
apt_packages = apt_packages + ["redis-server"] apt_packages = apt_packages + WOVariables.wo_redis
else: else:
Log.info(self, "Redis already installed") Log.info(self, "Redis already installed")
@@ -200,11 +200,8 @@ class WOStackController(CementBaseController):
if pargs.php: if pargs.php:
Log.debug(self, "Setting apt_packages variable for PHP 7.2") Log.debug(self, "Setting apt_packages variable for PHP 7.2")
if not (WOAptGet.is_installed(self, 'php7.2-fpm')): if not (WOAptGet.is_installed(self, 'php7.2-fpm')):
if not (WOAptGet.is_installed(self, 'php7.3-fpm')): apt_packages = (apt_packages + WOVariables.wo_php +
apt_packages = (apt_packages + WOVariables.wo_php + WOVariables.wo_php_extra)
WOVariables.wo_php_extra)
else:
apt_packages = apt_packages + WOVariables.wo_php
else: else:
Log.debug(self, "PHP 7.2 already installed") Log.debug(self, "PHP 7.2 already installed")
Log.info(self, "PHP 7.2 already installed") Log.info(self, "PHP 7.2 already installed")
@@ -213,12 +210,9 @@ class WOStackController(CementBaseController):
if pargs.php73: if pargs.php73:
Log.debug(self, "Setting apt_packages variable for PHP 7.3") Log.debug(self, "Setting apt_packages variable for PHP 7.3")
if not WOAptGet.is_installed(self, 'php7.3-fpm'): if not WOAptGet.is_installed(self, 'php7.3-fpm'):
if not (WOAptGet.is_installed(self, 'php7.2-fpm')): apt_packages = (apt_packages + WOVariables.wo_php +
apt_packages = (apt_packages + WOVariables.wo_php + WOVariables.wo_php73 +
WOVariables.wo_php73 + WOVariables.wo_php_extra)
WOVariables.wo_php_extra)
else:
apt_packages = apt_packages + WOVariables.wo_php73
else: else:
Log.debug(self, "PHP 7.3 already installed") Log.debug(self, "PHP 7.3 already installed")
Log.info(self, "PHP 7.3 already installed") Log.info(self, "PHP 7.3 already installed")
@@ -228,17 +222,7 @@ class WOStackController(CementBaseController):
pargs.mysqltuner = True pargs.mysqltuner = True
Log.debug(self, "Setting apt_packages variable for MySQL") Log.debug(self, "Setting apt_packages variable for MySQL")
if not WOShellExec.cmd_exec(self, "mysqladmin ping"): if not WOShellExec.cmd_exec(self, "mysqladmin ping"):
if not WOVariables.wo_distro == 'raspbian': apt_packages = apt_packages + WOVariables.wo_mysql
if (not WOVariables.wo_platform_codename == 'jessie'):
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysqldb", "mariadb-backup"]
else:
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysql.connector"]
else:
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysqldb"]
apt_packages = apt_packages + wo_mysql
else: else:
Log.debug(self, "MySQL already installed and alive") Log.debug(self, "MySQL already installed and alive")
Log.info(self, "MySQL already installed and alive") Log.info(self, "MySQL already installed and alive")
@@ -502,13 +486,13 @@ class WOStackController(CementBaseController):
WOAptGet.install(self, apt_packages) WOAptGet.install(self, apt_packages)
Log.valide(self, "Installing APT packages ") Log.valide(self, "Installing APT packages ")
Log.wait(self, "Configuring APT packages ") Log.wait(self, "Configuring APT packages ")
post_pref(self, apt_packages, empty_packages) post_pref(self, apt_packages, [])
Log.valide(self, "Configuring APT packages ") Log.valide(self, "Configuring APT packages ")
if (packages): if (packages):
Log.debug(self, "Downloading following: {0}".format(packages)) Log.debug(self, "Downloading following: {0}".format(packages))
WODownload.download(self, packages) WODownload.download(self, packages)
Log.debug(self, "Calling post_pref") Log.debug(self, "Calling post_pref")
post_pref(self, empty_packages, packages) post_pref(self, [], packages)
if disp_msg: if disp_msg:
if (self.msg): if (self.msg):
@@ -548,6 +532,7 @@ class WOStackController(CementBaseController):
pargs.proftpd = True pargs.proftpd = True
pargs.utils = True pargs.utils = True
pargs.redis = True pargs.redis = True
pargs.security = True
packages = packages + ['/var/www/22222/htdocs'] packages = packages + ['/var/www/22222/htdocs']
if pargs.web: if pargs.web:
@@ -823,6 +808,7 @@ class WOStackController(CementBaseController):
Log.debug(self, "Removing apt_packages variable of MySQL") Log.debug(self, "Removing apt_packages variable of MySQL")
apt_packages = apt_packages + ['mariadb-server', 'mysql-common', apt_packages = apt_packages + ['mariadb-server', 'mysql-common',
'mariadb-client'] 'mariadb-client']
packages = packages + ['/etc/mysql', '/var/lib/mysql']
# mysqlclient # mysqlclient
if pargs.mysqlclient: if pargs.mysqlclient:

View File

@@ -3,6 +3,7 @@ import os
from cement.core import handler, hook from cement.core import handler, hook
from cement.core.controller import CementBaseController, expose from cement.core.controller import CementBaseController, expose
from wo.core.apt_repo import WORepo from wo.core.apt_repo import WORepo
from wo.core.aptget import WOAptGet from wo.core.aptget import WOAptGet
from wo.core.logging import Log from wo.core.logging import Log
@@ -28,6 +29,17 @@ class WOStackMigrateController(CementBaseController):
# Backup all database # Backup all database
WOMysql.backupAll(self) WOMysql.backupAll(self)
if not WOVariables.wo_distro == 'raspbian':
if (not WOVariables.wo_platform_codename == 'jessie'):
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysqldb", "mariadb-backup"]
else:
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysql.connector"]
else:
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysqldb"]
# Add MariaDB repo # Add MariaDB repo
Log.info(self, "Adding repository for MariaDB, please wait...") Log.info(self, "Adding repository for MariaDB, please wait...")
@@ -78,7 +90,7 @@ class WOStackMigrateController(CementBaseController):
log=False) log=False)
# Install MariaDB # Install MariaDB
apt_packages = ["mariadb-server"] apt_packages = wo_mysql
Log.info(self, "Updating apt-cache, hang on...") Log.info(self, "Updating apt-cache, hang on...")
WOAptGet.update(self) WOAptGet.update(self)

View File

@@ -23,14 +23,13 @@ from wo.core.services import WOService
from wo.core.shellexec import CommandExecutionError, WOShellExec from wo.core.shellexec import CommandExecutionError, WOShellExec
from wo.core.template import WOTemplate from wo.core.template import WOTemplate
from wo.core.variables import WOVariables from wo.core.variables import WOVariables
from wo.core.sslutils import SSL
def pre_pref(self, apt_packages): def pre_pref(self, apt_packages):
"""Pre settings to do before installation packages""" """Pre settings to do before installation packages"""
if (set(["mariadb-server"]).issubset(set(apt_packages)) or if ("mariadb-server" in apt_packages or "mariadb-client" in apt_packages):
set(["mariadb-client"]).issubset(set(apt_packages)) or
set(["mariadb-backup"]).issubset((set(apt_packages)))):
# add mariadb repository excepted on raspbian and ubuntu 19.04 # add mariadb repository excepted on raspbian and ubuntu 19.04
if (not WOVariables.wo_distro == 'raspbian'): if (not WOVariables.wo_distro == 'raspbian'):
Log.info(self, "Adding repository for MySQL, please wait...") Log.info(self, "Adding repository for MySQL, please wait...")
@@ -41,13 +40,11 @@ def pre_pref(self, apt_packages):
'MariaDB.pref', 'w') as mysql_pref_file: 'MariaDB.pref', 'w') as mysql_pref_file:
mysql_pref_file.write(mysql_pref) mysql_pref_file.write(mysql_pref)
WORepo.add(self, repo_url=WOVariables.wo_mysql_repo) WORepo.add(self, repo_url=WOVariables.wo_mysql_repo)
Log.debug(self, 'Adding key for {0}'
.format(WOVariables.wo_mysql_repo))
WORepo.add_key(self, '0xcbcb082a1bb943db', WORepo.add_key(self, '0xcbcb082a1bb943db',
keyserver="keyserver.ubuntu.com") keyserver='keys.gnupg.net')
WORepo.add_key(self, '0xF1656F24C74CD1D8', WORepo.add_key(self, '0xF1656F24C74CD1D8',
keyserver="keyserver.ubuntu.com") keyserver='hkp://keys.gnupg.net')
if set(["mariadb-server"]).issubset(set(apt_packages)): if "mariadb-server" in apt_packages:
# generate random 24 characters root password # generate random 24 characters root password
chars = ''.join(random.sample(string.ascii_letters, 24)) chars = ''.join(random.sample(string.ascii_letters, 24))
@@ -139,7 +136,7 @@ def pre_pref(self, apt_packages):
Log.debug(self, 'Adding deb.sury GPG key') Log.debug(self, 'Adding deb.sury GPG key')
WORepo.add_key(self, WOVariables.wo_php_key) WORepo.add_key(self, WOVariables.wo_php_key)
# add redis repository # add redis repository
if set(['redis-server']).issubset(set(apt_packages)): if set(WOVariables.wo_redis).issubset(set(apt_packages)):
Log.info(self, "Adding repository for Redis, please wait...") Log.info(self, "Adding repository for Redis, please wait...")
if WOVariables.wo_distro == 'ubuntu': if WOVariables.wo_distro == 'ubuntu':
Log.debug(self, 'Adding ppa for redis') Log.debug(self, 'Adding ppa for redis')
@@ -367,7 +364,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
WOTemplate.render( WOTemplate.render(
self, self,
'/etc/nginx/sites-available/22222', '/etc/nginx/sites-available/22222',
'22222.mustache', data, overwrite=False) '22222.mustache', data, overwrite=True)
passwd = ''.join([random.choice passwd = ''.join([random.choice
(string.ascii_letters + string.digits) (string.ascii_letters + string.digits)
for n in range(24)]) for n in range(24)])
@@ -392,98 +389,60 @@ def post_pref(self, apt_packages, packages, upgrade=False):
'/etc/nginx/' '/etc/nginx/'
'sites-enabled/' 'sites-enabled/'
'22222']) '22222'])
# Create log and cert folder and softlinks # Create log and cert folder and softlinks
if not os.path.exists('{0}22222/logs' if not os.path.exists('{0}22222/logs'
.format(ngxroot)): .format(ngxroot)):
Log.debug(self, "Creating directory " Log.debug(self, "Creating directory "
"{0}22222/logs " "{0}22222/logs "
.format(ngxroot)) .format(ngxroot))
os.makedirs('{0}22222/logs' os.makedirs('{0}22222/logs'
.format(ngxroot))
if not os.path.exists('{0}22222/cert'
.format(ngxroot)):
Log.debug(self, "Creating directory "
"{0}22222/cert"
.format(ngxroot))
os.makedirs('{0}22222/cert'
.format(ngxroot))
if not os.path.isdir('{0}22222/conf/nginx'
.format(ngxroot)):
Log.debug(self, "Creating directory "
"{0}22222/conf/nginx"
.format(ngxroot))
os.makedirs('{0}22222/conf/nginx'
.format(ngxroot))
WOFileUtils.create_symlink(
self,
['/var/log/nginx/'
'22222.access.log',
'{0}22222/'
'logs/access.log'
.format(ngxroot)]
)
WOFileUtils.create_symlink(
self,
['/var/log/nginx/'
'22222.error.log',
'{0}22222/'
'logs/error.log'
.format(ngxroot)]
)
try:
WOShellExec.cmd_exec(
self, "openssl genrsa -out "
"{0}22222/cert/22222.key 2048"
.format(ngxroot))
WOShellExec.cmd_exec(
self, "openssl req -new -batch "
"-subj /commonName=localhost/ "
"-key {0}22222/cert/22222.key "
"-out {0}22222/cert/"
"22222.csr"
.format(ngxroot)) .format(ngxroot))
WOFileUtils.mvfile( if not os.path.exists('{0}22222/cert'
self, "{0}22222/cert/22222.key" .format(ngxroot)):
.format(ngxroot), Log.debug(self, "Creating directory "
"{0}22222/cert/" "{0}22222/cert"
"22222.key.org" .format(ngxroot))
os.makedirs('{0}22222/cert'
.format(ngxroot)) .format(ngxroot))
WOShellExec.cmd_exec( if not os.path.isdir('{0}22222/conf/nginx'
self, "openssl rsa -in " .format(ngxroot)):
"{0}22222/cert/" Log.debug(self, "Creating directory "
"22222.key.org -out " "{0}22222/conf/nginx"
"{0}22222/cert/22222.key" .format(ngxroot))
os.makedirs('{0}22222/conf/nginx'
.format(ngxroot)) .format(ngxroot))
WOShellExec.cmd_exec( WOFileUtils.create_symlink(
self, "openssl x509 -req -days " self,
"3652 -in {0}22222/cert/" ['/var/log/nginx/'
"22222.csr -signkey {0}" '22222.access.log',
"22222/cert/22222.key -out " '{0}22222/'
"{0}22222/cert/22222.crt" 'logs/access.log'
.format(ngxroot)) .format(ngxroot)]
)
except CommandExecutionError as e: WOFileUtils.create_symlink(
Log.debug(self, "{0}".format(e)) self,
Log.error( ['/var/log/nginx/'
self, "Failed to generate HTTPS " '22222.error.log',
"certificate for 22222", False) '{0}22222/'
'logs/error.log'
.format(ngxroot)]
)
if (not os.path.isfile('{0}22222/cert/22222.key'
.format(ngxroot))):
SSL.selfsignedcert(self, proftpd=False, backend=True)
if not os.path.isfile('{0}22222/conf/nginx/ssl.conf' if not os.path.isfile('{0}22222/conf/nginx/ssl.conf'
.format(ngxroot)): .format(ngxroot)):
with open("/var/www/22222/conf/nginx/" with open("/var/www/22222/conf/nginx/"
"ssl.conf", "w") as php_file: "ssl.conf", "w") as php_file:
php_file.write("ssl_certificate " php_file.write("ssl_certificate "
"/var/www/22222/cert/22222.crt;\n" "/var/www/22222/cert/22222.crt;\n"
"ssl_certificate_key " "ssl_certificate_key "
"/var/www/22222/cert/22222.key;\n") "/var/www/22222/cert/22222.key;\n")
server_ip = requests.get('http://v4.wordops.eu') server_ip = requests.get('http://v4.wordops.eu')
@@ -876,7 +835,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
WOService.restart_service(self, 'php7.3-fpm') WOService.restart_service(self, 'php7.3-fpm')
# create mysql config if it doesn't exist # create mysql config if it doesn't exist
if set(["mariadb-server"]).issubset(set(apt_packages)): if "mariadb-server" in apt_packages:
if not os.path.isfile("/etc/mysql/my.cnf"): if not os.path.isfile("/etc/mysql/my.cnf"):
config = ("[mysqld]\nwait_timeout = 30\n" config = ("[mysqld]\nwait_timeout = 30\n"
"interactive_timeout=60\nperformance_schema = 0" "interactive_timeout=60\nperformance_schema = 0"
@@ -953,7 +912,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
WOService.reload_service(self, 'fail2ban') WOService.reload_service(self, 'fail2ban')
# Proftpd configuration # Proftpd configuration
if set(["proftpd-basic"]).issubset(set(apt_packages)): if "proftpd-basic" in apt_packages:
if os.path.isfile("/etc/proftpd/proftpd.conf"): if os.path.isfile("/etc/proftpd/proftpd.conf"):
Log.info(self, "Configuring ProFTPd") Log.info(self, "Configuring ProFTPd")
Log.debug(self, "Setting up Proftpd configuration") Log.debug(self, "Setting up Proftpd configuration")
@@ -976,28 +935,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
# proftpd TLS configuration # proftpd TLS configuration
if not os.path.isdir("/etc/proftpd/ssl"): if not os.path.isdir("/etc/proftpd/ssl"):
WOFileUtils.mkdir(self, "/etc/proftpd/ssl") WOFileUtils.mkdir(self, "/etc/proftpd/ssl")
SSL.selfsignedcert(self, proftpd=True, backend=False)
try:
WOShellExec.cmd_exec(self, "openssl genrsa -out "
"/etc/proftpd/ssl/proftpd.key 2048")
WOShellExec.cmd_exec(self, "openssl req -new -batch "
"-subj /commonName=localhost/ "
"-key /etc/proftpd/ssl/proftpd.key "
"-out /etc/proftpd/ssl/proftpd.csr")
WOFileUtils.mvfile(self, "/etc/proftpd/ssl/proftpd.key",
"/etc/proftpd/ssl/proftpd.key.org")
WOShellExec.cmd_exec(self, "openssl rsa -in "
"/etc/proftpd/ssl/proftpd.key.org "
"-out /etc/proftpd/ssl/proftpd.key")
WOShellExec.cmd_exec(self, "openssl x509 -req -days "
"3652 -in /etc/proftpd/ssl/proftpd.csr "
"-signkey /etc/proftpd/ssl/proftpd.key "
" -out /etc/proftpd/ssl/proftpd.crt")
except CommandExecutionError as e:
Log.debug(self, "{0}".format(e))
Log.error(
self, "Failed to generate SSL "
"certificate for Proftpd")
WOFileUtils.chmod(self, "/etc/proftpd/ssl/proftpd.key", 0o700) WOFileUtils.chmod(self, "/etc/proftpd/ssl/proftpd.key", 0o700)
WOFileUtils.chmod(self, "/etc/proftpd/ssl/proftpd.crt", 0o700) WOFileUtils.chmod(self, "/etc/proftpd/ssl/proftpd.crt", 0o700)
data = dict() data = dict()
@@ -1041,7 +979,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
WOService.reload_service(self, 'proftpd') WOService.reload_service(self, 'proftpd')
# Redis configuration # Redis configuration
if set(['redus-server']).issubset(set(apt_packages)): if "redis-server" in apt_packages:
if os.path.isfile("/etc/nginx/conf.d/upstream.conf"): if os.path.isfile("/etc/nginx/conf.d/upstream.conf"):
if not WOFileUtils.grep(self, "/etc/nginx/conf.d/" if not WOFileUtils.grep(self, "/etc/nginx/conf.d/"
"upstream.conf", "upstream.conf",
@@ -1072,7 +1010,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
if (os.path.isfile("/etc/redis/redis.conf") and if (os.path.isfile("/etc/redis/redis.conf") and
(not WOFileUtils.grep(self, "/etc/redis/redis.conf", (not WOFileUtils.grep(self, "/etc/redis/redis.conf",
"WordOps"))): "WordOps"))):
Log.info(self, "Tuning Redis configuration") Log.wait(self, "Tuning Redis configuration")
with open("/etc/redis/redis.conf", with open("/etc/redis/redis.conf",
"a") as redis_file: "a") as redis_file:
redis_file.write("\n# WordOps v3.9.8\n") redis_file.write("\n# WordOps v3.9.8\n")
@@ -1116,6 +1054,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
WOFileUtils.chown(self, '/etc/redis/redis.conf', WOFileUtils.chown(self, '/etc/redis/redis.conf',
'redis', 'redis', recursive=False) 'redis', 'redis', recursive=False)
WOService.restart_service(self, 'redis-server') WOService.restart_service(self, 'redis-server')
Log.valide(self, "Tuning Redis configuration")
# ClamAV configuration # ClamAV configuration
if set(WOVariables.wo_clamav).issubset(set(apt_packages)): if set(WOVariables.wo_clamav).issubset(set(apt_packages)):

View File

@@ -62,7 +62,6 @@ class WOStackUpgradeController(CementBaseController):
# All package update # All package update
apt_packages = [] apt_packages = []
packages = [] packages = []
nginx_packages = []
self.msg = [] self.msg = []
pargs = self.app.pargs pargs = self.app.pargs
@@ -94,7 +93,7 @@ class WOStackUpgradeController(CementBaseController):
if pargs.nginx: if pargs.nginx:
if WOAptGet.is_installed(self, 'nginx-custom'): if WOAptGet.is_installed(self, 'nginx-custom'):
nginx_packages = nginx_packages + WOVariables.wo_nginx apt_packages = apt_packages + WOVariables.wo_nginx
else: else:
Log.info(self, "Nginx Stable is not already installed") Log.info(self, "Nginx Stable is not already installed")
@@ -178,41 +177,56 @@ class WOStackUpgradeController(CementBaseController):
"Composer"]] "Composer"]]
else: else:
Log.error(self, "Composer isn't installed") Log.error(self, "Composer isn't installed")
if len(apt_packages) or len(packages):
if len(apt_packages): if ((not (apt_packages)) and (not(packages))):
Log.info(self, "Your site may be down for few seconds if " self.app.args.print_help()
"you are upgrading Nginx, PHP-FPM, MariaDB or Redis") else:
if (apt_packages):
if not (set(["php7.2-fpm"]).issubset(set(apt_packages)) and
set(["php7.3-fpm"]).issubset(set(apt_packages)) and
set(["nginx-custom",
"nginx-wo"]).issubset(set(apt_packages)) and
set(['mariadb-server']).issubset(set(apt_packages))):
pass
else:
Log.info(
self, "Your site may be down for few seconds if "
"you are upgrading Nginx, PHP-FPM, MariaDB or Redis")
# Check prompt # Check prompt
if ((not pargs.no_prompt) and (not pargs.force)): if ((not pargs.no_prompt) and (not pargs.force)):
start_upgrade = input("Do you want to continue:[y/N]") start_upgrade = input("Do you want to continue:[y/N]")
if start_upgrade != "Y" and start_upgrade != "y": if start_upgrade != "Y" and start_upgrade != "y":
Log.error(self, "Not starting package update") Log.error(self, "Not starting package update")
Log.info(self, "Updating APT packages, please wait...") Log.wait(self, "Updating APT packages")
pre_pref(self, nginx_packages)
# apt-get update # apt-get update
WOAptGet.update(self) WOAptGet.update(self)
if set(WOVariables.wo_php).issubset(set(apt_packages)): Log.valide(self, "Updating APT packages")
Log.wait(self, "Upgrading APT Packages")
# additional pre_pref
if ["nginx-custom"] in apt_packages:
pre_pref(self, WOVariables.wo_nginx)
if ["php7.2-fpm"] in apt_packages:
WOAptGet.remove(self, ['php7.2-fpm'], WOAptGet.remove(self, ['php7.2-fpm'],
auto=False, purge=True) auto=False, purge=True)
if set(WOVariables.wo_php73).issubset(set(apt_packages)): if ["php7.3-fpm"] in apt_packages:
WOAptGet.remove(self, ['php7.3-fpm'], WOAptGet.remove(self, ['php7.3-fpm'],
auto=False, purge=True) auto=False, purge=True)
# Update packages
if not os.path.isfile(
'/etc/apt/preferences.d/nginx-block'):
WOAptGet.install(self, nginx_packages)
Log.wait(self, "Upgrading APT Packages ") # check if nginx upgrade is blocked
if os.path.isfile(
'/etc/apt/preferences.d/nginx-block'):
apt_packages.remove(WOVariables.wo_nginx)
post_pref(self, WOVariables.wo_nginx, [], True)
# upgrade packages
WOAptGet.install(self, apt_packages) WOAptGet.install(self, apt_packages)
Log.valide(self, "Upgrading APT Packages ") Log.valide(self, "Upgrading APT Packages")
Log.wait(self, "Configuring APT Packages ") Log.wait(self, "Configuring APT Packages")
post_pref(self, nginx_packages, [], True)
Log.valide(self, "Configuring APT Packages ")
post_pref(self, apt_packages, [], True) post_pref(self, apt_packages, [], True)
Log.valide(self, "Configuring APT Packages")
# Post Actions after package updates # Post Actions after package updates
if len(packages): if (packages):
if pargs.wpcli: if pargs.wpcli:
WOFileUtils.rm(self, '/usr/local/bin/wp') WOFileUtils.rm(self, '/usr/local/bin/wp')
@@ -229,7 +243,7 @@ class WOStackUpgradeController(CementBaseController):
WOFileUtils.chmod(self, "/usr/local/bin/wp", 0o775) WOFileUtils.chmod(self, "/usr/local/bin/wp", 0o775)
if pargs.netdata: if pargs.netdata:
Log.wait(self, "Upgrading Netdata ") Log.wait(self, "Upgrading Netdata")
if os.path.isdir('/opt/netdata'): if os.path.isdir('/opt/netdata'):
WOShellExec.cmd_exec( WOShellExec.cmd_exec(
self, "bash /opt/netdata/usr/" self, "bash /opt/netdata/usr/"
@@ -240,7 +254,7 @@ class WOStackUpgradeController(CementBaseController):
self, "bash /usr/" self, "bash /usr/"
"libexec/netdata/netdata-" "libexec/netdata/netdata-"
"updater.sh") "updater.sh")
Log.valide(self, "Upgrading Netdata ") Log.valide(self, "Upgrading Netdata")
if pargs.dashboard: if pargs.dashboard:
Log.debug(self, "Extracting wo-dashboard.tar.gz " Log.debug(self, "Extracting wo-dashboard.tar.gz "
@@ -252,21 +266,22 @@ class WOStackUpgradeController(CementBaseController):
.format(WOVariables.wo_webroot)) .format(WOVariables.wo_webroot))
WOFileUtils.chown(self, "{0}22222/htdocs" WOFileUtils.chown(self, "{0}22222/htdocs"
.format(WOVariables.wo_webroot), .format(WOVariables.wo_webroot),
WOVariables.wo_php_user, 'www-data',
WOVariables.wo_php_user, recursive=True) 'www-data', recursive=True)
if pargs.composer: if pargs.composer:
Log.wait(self, "Upgrading Composer ") Log.wait(self, "Upgrading Composer ")
WOShellExec.cmd_exec(self, "php -q /var/lib/wo" WOShellExec.cmd_exec(
"/tmp/composer-install " self, "php -q /var/lib/wo"
"--install-dir=/var/lib/wo/tmp/") "/tmp/composer-install "
"--install-dir=/var/lib/wo/tmp/")
shutil.copyfile('/var/lib/wo/tmp/composer.phar', shutil.copyfile('/var/lib/wo/tmp/composer.phar',
'/usr/local/bin/composer') '/usr/local/bin/composer')
WOFileUtils.chmod(self, "/usr/local/bin/composer", 0o775) WOFileUtils.chmod(self, "/usr/local/bin/composer", 0o775)
Log.valide(self, "Upgrading Composer ") Log.valide(self, "Upgrading Composer ")
if pargs.phpmyadmin: if pargs.phpmyadmin:
Log.wait(self, "Upgrading phpMyAdmin ") Log.wait(self, "Upgrading phpMyAdmin ")
WOExtract.extract(self, '/var/lib/wo/tmp/pma.tar.gz', WOExtract.extract(self, '/var/lib/wo/tmp/pma.tar.gz',
'/var/lib/wo/tmp/') '/var/lib/wo/tmp/')
shutil.copyfile(('{0}22222/htdocs/db/pma' shutil.copyfile(('{0}22222/htdocs/db/pma'
@@ -285,10 +300,8 @@ class WOStackUpgradeController(CementBaseController):
.format(WOVariables.wo_webroot)) .format(WOVariables.wo_webroot))
WOFileUtils.chown(self, "{0}22222/htdocs" WOFileUtils.chown(self, "{0}22222/htdocs"
.format(WOVariables.wo_webroot), .format(WOVariables.wo_webroot),
WOVariables.wo_php_user, 'www-data',
WOVariables.wo_php_user, recursive=True) 'www-data', recursive=True)
Log.valide(self, "Upgrading phpMyAdmin ") Log.valide(self, "Upgrading phpMyAdmin ")
Log.info(self, "Successfully updated packages") Log.info(self, "Successfully updated packages")
else:
self.app.args.print_help()

View File

@@ -0,0 +1,82 @@
# WordOps nextcloud configuration
add_header X-Robots-Tag none;
add_header X-Permitted-Cross-Domain-Policies none;
add_header Referrer-Policy no-referrer;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
location / {
rewrite ^ /index.php$request_uri;
}
location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
deny all;
}
location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS on;
# Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
# Enable pretty urls
fastcgi_param front_controller_active true;
fastcgi_pass {{upstream}};
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
# Adding the cache control header for js, css and map files
# Make sure it is BELOW the PHP block
location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
# Add headers to serve security related headers (It is intended to
# have those duplicated to the ones above)
# Before enabling Strict-Transport-Security headers please read into
# this topic first.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
add_header Referrer-Policy no-referrer;
# Optional: Don't log access to assets
access_log off;
}
location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ {
try_files $uri /index.php$request_uri;
# Optional: Don't log access to other assets
access_log off;
}

View File

@@ -48,8 +48,9 @@ class WORepo():
Log.debug(self, "{0}".format(e)) Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to add repo") Log.error(self, "Unable to add repo")
if ppa is not None: if ppa is not None:
WOShellExec.cmd_exec(self, "LC_ALL=C.UTF-8 add-apt-repository -yu '{ppa_name}'" WOShellExec.cmd_exec(
.format(ppa_name=ppa)) self, "LC_ALL=C.UTF-8 add-apt-repository -yu '{ppa_name}'"
.format(ppa_name=ppa))
def remove(self, ppa=None, repo_url=None): def remove(self, ppa=None, repo_url=None):
""" """
@@ -77,13 +78,35 @@ class WORepo():
Log.debug(self, "{0}".format(e)) Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to remove repo") Log.error(self, "Unable to remove repo")
def add_key(self, keyids, keyserver=None): def add_key(self, keyid, keyserver=None):
""" """
This function adds imports repository keys from keyserver. This function adds imports repository keys from keyserver.
default keyserver is hkp://keyserver.ubuntu.com default keyserver is hkp://keyserver.ubuntu.com
user can provide other keyserver with keyserver="hkp://xyz" user can provide other keyserver with keyserver="hkp://xyz"
""" """
WOShellExec.cmd_exec(self, "apt-key adv --keyserver {serv}" try:
.format(serv=(keyserver or WOShellExec.cmd_exec(
"hkp://keyserver.ubuntu.com")) + self, "apt-key adv --keyserver {serv}"
" --recv-keys {key}".format(key=keyids)) .format(serv=(keyserver or
"hkp://keyserver.ubuntu.com")) +
" --recv-keys {key}".format(key=keyid))
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to import repo key")
def add_keys(self, keyids, keyserver=None):
"""
This function adds imports repository keys from keyserver.
default keyserver is hkp://keyserver.ubuntu.com
user can provide other keyserver with keyserver="hkp://xyz"
"""
all_keys = ' '.join(keyids)
try:
WOShellExec.cmd_exec(
self, "apt-key adv --keyserver {serv}"
.format(serv=(keyserver or
"hkp://keyserver.ubuntu.com")) +
" --recv-keys {keys}".format(keys=all_keys))
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to import repo keys")

View File

@@ -54,7 +54,7 @@ class WOAptGet():
"`tail /var/log/wo/wordops.log` " "`tail /var/log/wo/wordops.log` "
"and please try again...") "and please try again...")
except Exception as e: except Exception:
Log.error(self, "apt-get update exited with error") Log.error(self, "apt-get update exited with error")
def check_upgrade(self): def check_upgrade(self):

View File

@@ -50,9 +50,12 @@ class Log:
""" """
Logs info messages with validation step Logs info messages with validation step
""" """
space_to_add = int(31 - len(msg[0:31]))
space = " "
print( print(
Log.OKBLUE + msg + Log.OKBLUE + "{0}".format(msg[0:31]) +
" [" + Log.ENDC + ".." + Log.OKBLUE + "]" + Log.ENDC, end=end) "{0}".format(space[0:space_to_add]) +
" [" + Log.ENDC + ".." + Log.OKBLUE + "]" + Log.ENDC, end=end)
if log: if log:
self.app.log.info(Log.OKBLUE + msg + Log.ENDC) self.app.log.info(Log.OKBLUE + msg + Log.ENDC)
@@ -60,9 +63,12 @@ class Log:
""" """
Logs info messages after validation step Logs info messages after validation step
""" """
space_to_add = int(31 - len(msg[0:31]))
space = " "
print( print(
Log.OKBLUE + msg + Log.OKBLUE + "{0}".format(msg[0:31]) +
" [" + Log.ENDC + Log.OKGREEN + "OK" + "{0}".format(space[0:space_to_add]) +
" [" + Log.ENDC + Log.OKGREEN + "OK" +
Log.ENDC + Log.OKBLUE + "]" + Log.ENDC, end=end) Log.ENDC + Log.OKBLUE + "]" + Log.ENDC, end=end)
if log: if log:
self.app.log.info(Log.OKGREEN + msg + Log.ENDC) self.app.log.info(Log.OKGREEN + msg + Log.ENDC)
@@ -71,9 +77,12 @@ class Log:
""" """
Logs info messages after validation step Logs info messages after validation step
""" """
space_to_add = int(31 - len(msg[0:31]))
space = " "
print( print(
Log.OKBLUE + msg + Log.OKBLUE + "{0}".format(msg[0:31]) +
" [" + Log.ENDC + Log.FAIL + "OK" + "{0}".format(space[0:space_to_add]) +
" [" + Log.ENDC + Log.FAIL + "KO" +
Log.ENDC + Log.OKBLUE + "]" + Log.ENDC, end=end) Log.ENDC + Log.OKBLUE + "]" + Log.ENDC, end=end)
if log: if log:
self.app.log.info(Log.FAIL + msg + Log.ENDC) self.app.log.info(Log.FAIL + msg + Log.ENDC)

View File

@@ -38,7 +38,8 @@ class WOService():
Log.info(self, "Start : {0:10}" .format(service_name), end='') Log.info(self, "Start : {0:10}" .format(service_name), end='')
retcode = subprocess.getstatusoutput(service_cmd) retcode = subprocess.getstatusoutput(service_cmd)
if retcode[0] == 0: if retcode[0] == 0:
Log.info(self, "[" + Log.ENDC + "OK" + Log.OKBLUE + "]") Log.info(self, "[" + Log.ENDC + Log.OKGREEN +
"OK" + Log.ENDC + Log.OKBLUE + "]")
return True return True
else: else:
Log.debug(self, "{0}".format(retcode[1])) Log.debug(self, "{0}".format(retcode[1]))
@@ -55,11 +56,12 @@ class WOService():
Similar to `service xyz stop` Similar to `service xyz stop`
""" """
try: try:
Log.info(self, "Stop : {0:10}" .format(service_name), end='') Log.info(self, "Stop : {0:10}" .format(service_name), end='')
retcode = subprocess.getstatusoutput('service {0} stop' retcode = subprocess.getstatusoutput('service {0} stop'
.format(service_name)) .format(service_name))
if retcode[0] == 0: if retcode[0] == 0:
Log.info(self, "[" + Log.ENDC + "OK" + Log.OKBLUE + "]") Log.info(self, "[" + Log.ENDC + Log.OKGREEN + "OK" +
Log.ENDC + Log.OKBLUE + "]")
return True return True
else: else:
Log.debug(self, "{0}".format(retcode[1])) Log.debug(self, "{0}".format(retcode[1]))

View File

@@ -39,6 +39,9 @@ class SSL:
def getexpirationdate(self, domain): def getexpirationdate(self, domain):
# check if exist # check if exist
if os.path.islink('/var/www/{0}/conf/nginx/ssl.conf'):
split_domain = domain.split('.')
domain = ('.').join(split_domain[1:])
if not os.path.isfile('/etc/letsencrypt/live/{0}/cert.pem' if not os.path.isfile('/etc/letsencrypt/live/{0}/cert.pem'
.format(domain)): .format(domain)):
Log.error(self, 'File Not Found: /etc/letsencrypt/' Log.error(self, 'File Not Found: /etc/letsencrypt/'
@@ -68,22 +71,26 @@ class SSL:
"--allow-root --quiet")) "--allow-root --quiet"))
test_url = re.split(":", wo_siteurl) test_url = re.split(":", wo_siteurl)
if not (test_url[0] == 'https'): if not (test_url[0] == 'https'):
WOShellExec.cmd_exec( Log.wait(self, "Updating site url with https")
self, "{0} option update siteurl " try:
"\'https://{1}\' --allow-root".format( WOShellExec.cmd_exec(
WOVariables.wo_wpcli_path, domain)) self, "{0} option update siteurl "
WOShellExec.cmd_exec( "\'https://{1}\' --allow-root".format(
self, "{0} option update home " WOVariables.wo_wpcli_path, domain))
"\'https://{1}\' --allow-root".format( WOShellExec.cmd_exec(
WOVariables.wo_wpcli_path, domain)) self, "{0} option update home "
WOShellExec.cmd_exec( "\'https://{1}\' --allow-root".format(
self, "{0} search-replace \'http://{0}\'" WOVariables.wo_wpcli_path, domain))
"\'https://{0}\' --skip-columns=guid " WOShellExec.cmd_exec(
"--skip-tables=wp_users" self, "{0} search-replace \'http://{0}\'"
.format(domain)) "\'https://{0}\' --skip-columns=guid "
Log.info( "--skip-tables=wp_users"
self, "Site address updated " .format(domain))
"successfully to https://{0}".format(domain)) except Exception as e:
Log.debug(self, str(e))
Log.failed(self, "Updating site url with https")
else:
Log.valide(self, "Updating site url with https")
# check if a wildcard exist to secure a new subdomain # check if a wildcard exist to secure a new subdomain
@@ -111,3 +118,81 @@ class SSL:
certfile.close() certfile.close()
return iswildcard return iswildcard
def setupHsts(self, wo_domain_name):
Log.info(
self, "Adding /var/www/{0}/conf/nginx/hsts.conf"
.format(wo_domain_name))
hstsconf = open("/var/www/{0}/conf/nginx/hsts.conf"
.format(wo_domain_name),
encoding='utf-8', mode='w')
hstsconf.write("more_set_headers "
"\"Strict-Transport-Security: "
"max-age=31536000; "
"includeSubDomains; "
"preload\";")
hstsconf.close()
return 0
def selfsignedcert(self, proftpd=False, backend=False):
"""issue a self-signed certificate"""
selfs_tmp = '/var/lib/wo/tmp/selfssl'
# create self-signed tmp directory
if not os.path.isdir(selfs_tmp):
WOFileUtils.mkdir(self, selfs_tmp)
try:
WOShellExec.cmd_exec(
self, "openssl genrsa -out "
"{0}/ssl.key 2048"
.format(selfs_tmp))
WOShellExec.cmd_exec(
self, "openssl req -new -batch "
"-subj /commonName=localhost/ "
"-key {0}/ssl.key -out {0}/ssl.csr"
.format(selfs_tmp))
WOFileUtils.mvfile(
self, "{0}/ssl.key"
.format(selfs_tmp),
"{0}/ssl.key.org"
.format(selfs_tmp))
WOShellExec.cmd_exec(
self, "openssl rsa -in "
"{0}/ssl.key.org -out "
"{0}/ssl.key"
.format(selfs_tmp))
WOShellExec.cmd_exec(
self, "openssl x509 -req -days "
"3652 -in {0}/ssl.csr -signkey {0}"
"/ssl.key -out {0}/ssl.crt"
.format(selfs_tmp))
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(
self, "Failed to generate HTTPS "
"certificate for 22222", False)
if backend:
WOFileUtils.mvfile(
self, "{0}/ssl.key"
.format(selfs_tmp),
"/var/www/22222/cert/22222.key")
WOFileUtils.mvfile(
self, "{0}/ssl.crt"
.format(selfs_tmp),
"/var/www/22222/cert/22222.crt")
if proftpd:
WOFileUtils.mvfile(
self, "{0}/ssl.key"
.format(selfs_tmp),
"/etc/proftpd/ssl/proftpd.key")
WOFileUtils.mvfile(
self, "{0}/ssl.crt"
.format(selfs_tmp),
"/etc/proftpd/ssl/proftpd.crt")
# remove self-signed tmp directory
WOFileUtils.rm(self, selfs_tmp)

View File

@@ -145,13 +145,22 @@ class WOVariables():
"10.3/debian {codename} main" "10.3/debian {codename} main"
.format(codename=wo_platform_codename)) .format(codename=wo_platform_codename))
if not wo_distro == 'raspbian':
if (not wo_platform_codename == 'jessie'):
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysqldb", "mariadb-backup"]
else:
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysql.connector"]
else:
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysqldb"]
if wo_platform_codename == 'jessie': if wo_platform_codename == 'jessie':
wo_mysql_client = ["mariadb-client", "python3-mysqldb"] wo_mysql_client = ["mariadb-client", "python3-mysqldb"]
else: else:
wo_mysql_client = ["mariadb-client", "python3-mysql.connector"] wo_mysql_client = ["mariadb-client", "python3-mysql.connector"]
wo_fail2ban = ["fail2ban"] wo_fail2ban = ["fail2ban"]
wo_clamav = ["clamav", "clamav-freshclam"] wo_clamav = ["clamav", "clamav-freshclam"]