Merge pull request #98 from WordOps/updating-configuration

Updating configuration
This commit is contained in:
VirtuBox
2019-07-20 01:41:23 +02:00
committed by GitHub
20 changed files with 1577 additions and 1217 deletions

View File

@@ -30,9 +30,9 @@ script:
- unset LANG
- sudo bash -c 'echo -e "[user]\n\tname = abc\n\temail = root@localhost.com" > /home/travis/.gitconfig'
- sudo echo "Travis Banch = $TRAVIS_BRANCH"
- sudo apt-get install -y --force-yes git python3-setuptools python3-dev python3-apt ccze tree
- sudo apt-get install -qq --force-yes git python3-setuptools python3-dev python3-apt ccze tree
- sudo bash install -b $TRAVIS_BRANCH --travis
- sudo wo --help && sudo wo stack install
- sudo wo --help && sudo wo stack install && sudo wo stack install --proftpd
- sudo wo stack upgrade --netdata --no-prompt
- sudo wo site create html.net --html && sudo wo site create php.com --php && sudo wo site create mysql.com --mysql && sudo wo site create proxy.com --proxy=127.0.0.1:3000
- sudo wo site create wp1.com --wp && sudo wo site create wpsc1.net --wpsc && sudo wo site create wpfc1.com --wpfc
@@ -48,5 +48,6 @@ script:
- sudo wp --allow-root --info
- sudo wo info
- sudo tree -L 2 /etc/nginx
- sudo cat /var/www/wp1.com/wp-config.php
- sudo wo update --travis
- sudo wo stack status

View File

@@ -8,7 +8,27 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### v3.9.x - [Unreleased]
---
### v3.9.6 - 2019-07-20
#### Added
- New Nginx package on Ubuntu with Cloudflare HTTP/2 HPACK and Dynamic TLS records
- phpMyAdmin upgrade with `wo stack upgrade --phpmyadmin`
- Wildcard SSL Certificates support with DNS validation
- Let's Encrypt DNS API support (Cloudflare, DigitalOcean, etc ..) on domain, subdomain, and wildcard
- Flag `--letsencrypt=clean` to purge a previous SSL configuration
- Support for Debian 10 buster (testing - not ready for production)
- Fail2ban with custom jails to secure WordPress & SSH
- Variable `keylength` in /etc/wo/wo.conf to define letsencrypt certificate keylenght
- ProFTPd stack with UFW & Fail2ban configurationz
- Beta branch and command `wo update --beta` for beta releases
- Extra directives in wp-config.php (limit posts revisions, set max_memory, enable auto-update for minor-releases)
#### Fixed
- Nginx was not reloaded after enabling HSTS
- Netdata, Composer & Fail2Ban stack remove and purge
- WordPress not installed by `wo site update` with basic php73 sites
### v3.9.5.4 - 2019-07-13
@@ -20,14 +40,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
#### Changed
- phpRedisAdmin is now installed with the stack "--admin"
- phpRedisAdmin is now installed with the stack `--admin`
- Remove memcached - not required anymore
#### Fixed
- phpRedisAdmin installation
- Duplicated locations /robots.txt after upgrade to v3.9.5.3
- Let's Encrypt stack "wo site update --letsencrypt/--letsencrypt=off"
- Let's Encrypt stack `wo site update --letsencrypt/--letsencrypt=off`
- pt-query-advisor dead link
- Netdata persistant configuration
@@ -76,7 +96,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Install script handle migration from EEv3
- load-balancing on unix socket for php-fpm
- stub_status vhost for metrics
- "--letsencrypt=subdomain" option
- `--letsencrypt=subdomain` option
- opcache optimization for php-fpm
- EasyEngine configuration backup before migration
- EasyEngine configuration cleanup after migration

View File

@@ -42,11 +42,12 @@
- **Easy to install** : One step automated installer with migration from EasyEngine v3 support
- **Fast deployment** : Fast and automated WordPress, Nginx, PHP, MySQL & Redis installation
- **Up-to-date** : Nginx 1.16.0 with TLS v1.3 & Brotli support, PHP 7.2 & 7.3, MariaDB 10.3 & Redis 5.0
- **Custom Nginx build** : Nginx 1.16.0 - TLS v1.3 Cloudflare HTTP/2 HPACK & Brotli support
- **Up-to-date** : PHP 7.2 & 7.3, MariaDB 10.3 & Redis 5.0
- **Secured** : Hardened WordPress security with strict Nginx location directives
- **Powerful** : Optimized Nginx configurations with multiple cache backends support
- **SSL** : Let's Encrypt SSL certificates handled by acme.sh
- **Modern** : Secured SSL/TLS encryption with strong ciphers_suite, modern TLS protocols and HSTS support
- **SSL** : Domain, Subdomain & Wildcard Let's Encrypt SSL certificates handled by acme.sh
- **Modern** : Strong ciphers_suite, modern TLS protocols and HSTS support (Grade A+ on ssllabs)
- **Monitoring** : Live Nginx vhost traffic with ngx_vts_module and server monitoring with Netdata
## Requirements
@@ -58,6 +59,7 @@
- Ubuntu 19.04 (Disco)
- Debian 8 (Jessie)
- Debian 9 (Stretch)
- Debian 10 (Buster) - Not ready for production
- Raspbian 9 (Stretch)
### Ports requirements
@@ -76,20 +78,7 @@ sudo wo site create example.com --wp # Install required packages & setup Wor
## Must read
WordOps made some fundamental changes:
- We've deprecated the mail stack. As an alternative, you can take a look at [Mail-in-a-Box](https://github.com/mail-in-a-box/mailinabox), [iRedMail](https://www.iredmail.org/) or [Caesonia](https://github.com/vedetta-com/caesonia). As Roundcube alternative, there is [Rainloop](https://www.rainloop.net/) or [Afterlogic WebMail](https://github.com/afterlogic/webmail-lite-8)
- Support for w3tc is dropped as a security precaution.
- PHP 5.6 has been replaced by PHP 7.2 and PHP 7.0 has been replaced by PHP 7.3.
- Nginx-ee package has been replaced by Nginx-wo (based on Nginx stable v1.16.0 with Brotli support)
- HHVM stack has been removed
- Let's Encrypt stack isn't based on letsencrypt-auto anymore, we use acme.sh to handle SSL certificates
If you are going to migrate from EasyEngine v3, here some important informations :
- Previous php upstreams in Nginx will not be overwritted
- php5.6 and php7.0 will not be removed or uninstalled
- previous Nginx common configurations will not be overwritted
[From EasyEngine to WordOps](https://docs.wordops.net/about/from-easyengine-to-wordops/)
## Usage
@@ -133,9 +122,10 @@ wo site create example.com --proxy=127.0.0.1:3000 # create example.com with ngi
### Sites secured with Let's Encrypt
```bash
wo site create example.com --wp --letsencrypt # install wordpress & secure site with letsencrypt
wo site create sub.example.com --wp --letsencrypt=subdomain # install wordpress and secure subdomain with letsencrypt
wo site create example.com --wp --letsencrypt # wordpress secured with letsencrypt
wo site create sub.example.com --wp --letsencrypt=subdomain # wordpress + letsencrypt subdomain
wo site create site.tld --wp --letsencrypt --hsts # install wordpress & secure site with letsencrypt with HSTS
wo site create site.tld --wp --letsencrypt=wildcard --dns=dns_cf # install wordpress & issue a wildcard SSL certificate with Cloudflare DNS API
```
## Update WordOps
@@ -167,12 +157,11 @@ Apps & Tools shipped with WordOps :
- [Composer](https://github.com/composer/composer)
- [Adminer](https://www.adminer.org/)
- [phpRedisAdmin](https://github.com/erikdubbelboer/phpRedisAdmin)
- [PHPMemcachedAdmin](https://github.com/elijaa/phpmemcachedadmin)
- [opcacheGUI](https://github.com/amnuts/opcache-gui)
- [eXtplorer](https://github.com/soerennb/extplorer)
- [MySQLTuner](https://github.com/major/MySQLTuner-perl/)
- [Webgrind](https://github.com/jokkedk/webgrind)
- [MySQLTuner](https://github.com/major/MySQLTuner-perl)
## License

View File

@@ -22,7 +22,7 @@ _wo_complete()
# HANDLE EVERYTHING AFTER THE SECOND LEVEL NAMESPACE
"clean")
COMPREPLY=( $(compgen \
-W "--memcache --opcache --fastcgi --redis --all" \
-W "--opcache --fastcgi --redis --all" \
-- $cur) )
;;
@@ -74,17 +74,17 @@ _wo_complete()
# HANDLE EVERYTHING AFTER THE THIRD LEVEL NAMESPACE
"install" | "purge" | "remove" )
COMPREPLY=( $(compgen \
-W "--web --admin --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --all --redis --phpredisadmin --composer --netdata --fail2ban --dashboard" \
-W "--web --admin --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --all --redis --phpredisadmin --composer --netdata --fail2ban --dashboard --proftpd" \
-- $cur) )
;;
"upgrade" )
COMPREPLY=( $(compgen \
-W "--web --nginx --php --php73 --mysql --all --php56 --no-prompt --wpcli" \
-W "--web --nginx --php --php73 --mysql --all --netdata --composer --phpmyadmin --no-prompt --wpcli" \
-- $cur) )
;;
"start" | "stop" | "reload" | "restart" | "status")
COMPREPLY=( $(compgen \
-W "--nginx --php --php73 --mysql --memcache --redis --fail2ban --netdata" \
-W "--nginx --php --php73 --mysql --redis --fail2ban --netdata -proftpd" \
-- $cur) )
;;
"migrate")
@@ -159,13 +159,13 @@ _wo_complete()
"create")
COMPREPLY=( $(compgen \
-W "--user --pass --email --html --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --proxy= --wpredis --letsencrypt --letsencrypt=subdomain -le" \
-W "--user --pass --email --html --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --proxy= --wpredis --letsencrypt --letsencrypt=subdomain --letsencrypt=wildcard -le -le=subdomain -le=wildcard --dns --dns=dns_cf --dns=dns_do" \
-- $cur) )
;;
"update")
COMPREPLY=( $(compgen \
-W "--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --letsencrypt --letsencrypt=subdomain --letsencrypt=off --letsencrypt=renew" \
-W "--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --letsencrypt --letsencrypt=subdomain --letsencrypt=off --letsencrypt=renew -le -le=subdomain -le=wildcard --dns --dns=dns_cf --dns=dns_do" \
-- $cur) )
;;
"delete")
@@ -211,9 +211,9 @@ _wo_complete()
"--wp")
if [ ${COMP_WORDS[1]} != "debug" ]; then
if [ ${COMP_WORDS[2]} == "create" ]; then
retlist="--wp --wpsc --wpfc --user --email --pass --wpredis --letsencrypt --php73"
retlist="--wp --wpsc --wpfc --user --email --pass --wpredis --letsencrypt -le --letsencrypt=subdomain --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_do --php73"
elif [ ${COMP_WORDS[2]} == "update" ]; then
retlist="--wp --wpfc --wpsc --php73 --php73=off --wpredis --letsencrypt --letsencrypt=subdomain --letsencrypt=off --letsencrypt=renew --le --le=subdomain --le=off "
retlist="--wp --wpfc --wpsc --php73 --php73=off --wpredis --letsencrypt --letsencrypt=subdomain --letsencrypt=wildcard --letsencrypt=off --letsencrypt=renew -le -le=off -le=wildcard --dns --dns=dns_cf --dns=dns_do"
else
retlist=""
fi
@@ -230,9 +230,9 @@ _wo_complete()
"--wpsubdir" | "--wpsubdomain")
if [ ${COMP_WORDS[1]} != "debug" ]; then
if [ ${COMP_WORDS[2]} == "create" ]; then
retlist="--wpsc --wpfc --user --email --pass --wpredis --letsencrypt --letsencrypt=subdomain --php73"
retlist="--wpsc --wpfc --user --email --pass --wpredis --letsencrypt --letsencrypt=subdomain --letsencrypt=wildcard -le --php73 --dns --dns=dns_cf --dns=dns_do"
elif [ ${COMP_WORDS[2]} == "update" ]; then
retlist="--wpfc --wpsc --php73 --php73=off --wpredis --letsencrypt --letsencrypt=subdomain --letsencrypt=off --letsencrypt=renew"
retlist="--wpfc --wpsc --php73 --php73=off --wpredis --letsencrypt --letsencrypt=subdomain --letsencrypt=wildcard --letsencrypt=off --letsencrypt=renew -le --dns --dns=dns_cf --dns=dns_do"
else
retlist=""
fi
@@ -248,7 +248,7 @@ _wo_complete()
"--wpredis" | "--wpfc" | "--wpsc" | "--wpsubdir" | "--wpsubdomain" | "--user" | "--pass" | "--email" | "--wp")
if [ ${COMP_WORDS[2]} == "create" ]; then
retlist="--user --pass --email --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --php73 --letsencrypt --letsencrypt=subdomain"
retlist="--user --pass --email --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --php73 --letsencrypt --letsencrypt=subdomain --letsencrypt=wildcard -le --dns --dns=dns_cf --dns=dns_do"
else
retlist=""
fi
@@ -261,7 +261,7 @@ _wo_complete()
"--wpredis" | "--wpfc")
if [ ${COMP_WORDS[2]} == "update" ]; then
retlist="--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --letsencrypt --letsencrypt=subdomain --letsencrypt=off --letsencrypt=renew"
retlist="--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --letsencrypt --letsencrypt=subdomain --letsencrypt=off --letsencrypt=renew -le --dns --dns=dns_cf --dns=dns_do"
else
retlist=""
fi
@@ -272,11 +272,11 @@ _wo_complete()
-- $cur) )
;;
"--web" | "--admin" | "--nginx" | "--php" | "--php73" | "--mysql" | "--wpcli" | "--phpmyadmin" | "--adminer" | "--utils" | "--memcached" | "--redis | --phpredisadmin")
"--web" | "--admin" | "--nginx" | "--php" | "--php73" | "--mysql" | "--wpcli" | "--phpmyadmin" | "--adminer" | "--utils" | "--fail2ban" | "--redis | --phpredisadmin | --netdata")
if [[ ${COMP_WORDS[2]} == "install" || ${COMP_WORDS[2]} == "purge" || ${COMP_WORDS[2]} == "remove" ]]; then
retlist="--web --admin --nginx --php --php73 --mysql--wpcli --phpmyadmin --adminer --utils --memcache --redis --phpredisadmin"
retlist="--web --admin --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --redis --fail2ban --phpredisadmin --netdata"
elif [[ ${COMP_WORDS[2]} == "start" || ${COMP_WORDS[2]} == "reload" || ${COMP_WORDS[2]} == "restart" || ${COMP_WORDS[2]} == "stop" ]]; then
retlist="--nginx --php --php73 --mysql --memcache --redis"
retlist="--nginx --php --php73 --mysql --redis --netdata"
elif [[ ${COMP_WORDS[1]} == "debug" ]]; then
retlist="--start --nginx --php --php73 --fpm --fpm7 --mysql -i --interactive -stop --import-slow-log --import-slow-log-interval= -"
if [[ $prev == '--mysql' ]]; then
@@ -310,7 +310,7 @@ _wo_complete()
"--all")
if [ ${COMP_WORDS[1]} == "clean" ]; then
retlist="--memcache --opcache --fastcgi --redis"
retlist="--opcache --fastcgi --redis"
elif [ ${COMP_WORDS[2]} == "delete" ]; then
retlist="--db --files --force"
elif [ ${COMP_WORDS[2]} == "update" ]; then
@@ -324,8 +324,8 @@ _wo_complete()
-- $cur) )
;;
"--memcached" | "--opcache" | "--fastcgi" | "--all" | "--redis")
retlist="--memcached --opcache --fastcgi --redis --all"
"--opcache" | "--fastcgi" | "--all" | "--redis")
retlist="--opcache --fastcgi --redis --all"
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
@@ -363,7 +363,7 @@ _wo_complete()
case "$mprev" in
"--user" | "--email" | "--pass")
if [ ${COMP_WORDS[2]} == "create" ]; then
retlist="--user --pass --email --html --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --letsencrypt --letsencrypt=subdomain"
retlist="--user --pass --email --html --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --letsencrypt --letsencrypt=subdomain --letsencrypt=wildcard -le --dns --dns=dns_cf --dns=dns_do"
fi
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \

View File

@@ -68,6 +68,10 @@ password =
### EMail for WordPress sites
email =
[letsencrypt]
keylength = "ec-384"
[update]
### If enabled, load a plugin named `update` either from the Python module

View File

@@ -3,17 +3,17 @@
.B WordOps (wo)
\- Manage Nginx Based Websites.
.SH SYNOPSIS
wo [ --version | --help | info | stack | site | debug | update | clean | import_slow_log | log | secure | sync | maintenance]
wo [ --version | --help | info | stack | site | debug | update | clean | import_slow_log | log | secure | sync | maintenance ]
.TP
wo stack [ install | remove | purge | migrate | upgrade] [ --web | --all | --nginx | --php | --php73 | --mysql | --admin | --adminer | --redis | --phpmyadmin | --phpredisadmin | --wpcli | --utils | --dashboard | --netdata ]
.TP
wo stack [ status | start | stop | reload | restart ] [--all | --nginx | --php | --php73 |--mysql | --web | --memcached | --redis]
wo stack [ status | start | stop | reload | restart ] [--all | --nginx | --php | --php73 |--mysql | --web | --redis]
.TP
wo site [ list | info | show | enable | disable | edit | cd | show ] [ example.com ]
.TP
wo site create example.com [ --html | --php | --php73 | --mysql] [[--wp | --wpsubdir | --wpsubdomain ] [--wpsc | --wpfc | --wpredis | --letsencrypt/-le/--letsencrypt=subdomain]]
wo site create example.com [ --html | --php | --php73 | --mysql] [[--wp | --wpsubdir | --wpsubdomain ] [--wpsc | --wpfc | --wpredis | --letsencrypt/-le/--letsencrypt=subdomain/wildcard][--dns=dns_cf/dns_do]]
.TP
wo site update example.com [ --php | --php73 |--mysql] [[--wp | --wpsubdir | --wpsubdomain ] [--wpsc | --wpfc | --wpredis ] [--password] [--letsencrypt=on/off/subdomain/renew]]
wo site update example.com [ --php | --php73 |--mysql] [[--wp | --wpsubdir | --wpsubdomain ] [--wpsc | --wpfc | --wpredis ] [--password] [-le/--letsencrypt=on/off/subdomain/renew/wildcard] [--dns=dns_cf/dns_do]]
.TP
wo site delete example.com [--db | --files | --all | --no-prompt | --force/-f ]
.TP
@@ -46,19 +46,19 @@ Display WordOps (wo) help.
.TP
.B stack
.TP
.B install [ --all | --web | --nginx | --php | --php73 |--mysql | --redis | --adminer | --phpmyadmin | --phpredismyadmin | --wpcli | --utils ]
.B install [ --all | --web | --nginx | --php | --php73 |--mysql | --redis | --adminer | --phpmyadmin | --phpredismyadmin | --wpcli | --utils | --netdata | --dashboard ]
.br
Install Nginx PHP5 MySQL Postfix stack Packages if not used with
.br
any options.Installs specific package if used with option.
.TP
.B remove [ --all | --web | --nginx | --php | --php73 |--mysql | --redis | --adminer | --phpmyadmin | --phpredismyadmin | --wpcli | --utils ]
.B remove [ --all | --web | --nginx | --php | --php73 |--mysql | --redis | --adminer | --phpmyadmin | --phpredismyadmin | --wpcli | --utils | --netdata | --dashboard ]
.br
Remove Nginx PHP5 MySQL Postfix stack Packages if not used with
.br
any options. Remove specific package if used with option.
.TP
.B purge [ --all | --web | --nginx | --php | --php73 |--mysql | --redis | --adminer | --phpmyadmin | --phpredismyadmin | --wpcli | --utils ]
.B purge [ --all | --web | --nginx | --php | --php73 |--mysql | --redis | --adminer | --phpmyadmin | --phpredismyadmin | --wpcli | --utils | --netdata | --dashboard ]
.br
Purge Nginx PHP5 MySQL Postfix stack Packages if not used with any
.br
@@ -163,7 +163,7 @@ if used with --all=off argument.
.br
Update security settings.
.TP
.B clean [ --fastcgi | --opcache | --memcached | --redis | --all ]
.B clean [ --fastcgi | --opcache | --redis | --all ]
.br
Clean NGINX fastCGI cache, Opcache, memcached, Redis cache.
.br

52
install
View File

@@ -7,10 +7,10 @@
# Copyright (c) 2019 - WordOps
# This script is licensed under M.I.T
# -------------------------------------------------------------------------
# Version 3.9.5.4 - 2019-07-09
# Version 3.9.6 - 2019-07-20
# -------------------------------------------------------------------------
readonly wo_version_old="2.2.3"
readonly wo_version_new="3.9.5.4"
readonly wo_version_new="3.9.6"
# CONTENTS
# ---
# 1. VARIABLES AND DECLARATIONS
@@ -144,9 +144,9 @@ if [ -z "$wo_force_install" ]; then
wo_lib_echo_fail "other Linux distributions and perhaps even Unix deratives."
exit 100
else
check_wo_linux_distro=$(lsb_release -sc | grep -E "trusty|xenial|bionic|disco|jessie|stretch")
check_wo_linux_distro=$(lsb_release -sc | grep -E "trusty|xenial|bionic|disco|jessie|stretch|buster")
if [ -z "$check_wo_linux_distro" ]; then
wo_lib_echo_fail "WordOps (wo) only supports Ubuntu 14.04/16.04/18.04/19.04 LTS, Debian 8.x, Debian 9.x and Raspbian 9.x"
wo_lib_echo_fail "WordOps (wo) only supports Ubuntu 14.04/16.04/18.04/19.04 LTS, Debian 8.x/9.x/10.x and Raspbian 9.x"
exit 100
fi
fi
@@ -185,9 +185,9 @@ wo_install_dep() {
wget https://download.opensuse.org/repositories/home:virtubox:WordOps/Debian_9.0/Release.key -O Release.key
apt-key add - < Release.key
rm -f Release.key
[ -d /etc/apt/trusted.gpg.d ] && { wget -qO /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg; }
# install dependencies
DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confold" -y install build-essential curl gzip dirmngr sudo python3 python3-apt python3-setuptools python3-dev ca-certificates sqlite3 git tar software-properties-common pigz apt-transport-https gnupg2 cron ccze rsync tree haveged ufw > /dev/null 2>&1
[ -d /etc/apt/trusted.gpg.d ] && { wget -qO /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg; }
fi
locale-gen en
@@ -250,8 +250,8 @@ wo_sync_db() {
wo_site_current_type=$(grep "common/" /etc/nginx/sites-available/$site | awk -F "/" '{print $2}')
if [ -n "$(echo $wo_site_current_type | grep php)" ]; then
if [ "$(echo $wo_site_current_type | grep php7)" ]; then
if echo "$wo_site_current_type" | grep -q "php"; then
if echo "$wo_site_current_type" | grep -q "php7"; then
wo_php_version="7.0"
else
wo_php_version="5.6"
@@ -260,31 +260,31 @@ wo_sync_db() {
wo_php_version=""
fi
if [ "$(echo $wo_site_current_type | grep redis)" ]; then
if echo "$wo_site_current_type" | grep -q "redis"; then
wo_site_current_cache="wpredis"
elif [ -z "$(echo $wo_site_current_type | grep wpsc)" ]; then
elif echo "$wo_site_current_type" | grep -q wpsc; then
wo_site_current_cache="wpsc"
elif [ -z "$(echo $wo_site_current_type | grep wpfc)" ]; then
elif echo "$wo_site_current_type" | grep -q wpfc; then
wo_site_current_cache="wpfc"
else
wo_site_current_cache="basic"
fi
if [ "$(echo $wo_site_current_type | grep wp)" ]; then
if [ -z "$(echo $wo_site_current_type | grep wpsubdir)" ]; then
if echo "$wo_site_current_type" | grep -q wp; then
if echo "$wo_site_current_type" | grep -q wpsubdir; then
wo_site_current="wpsubdir"
elif [ -z "$(echo $wo_site_current_type | grep wpsudomain)" ]; then
elif echo "$wo_site_current_type" | grep -q wpsudomain; then
wo_site_current="wpsubdomain"
else
wo_site_current="wp"
fi
else
if [ -z "$(echo $wo_site_current_type | grep location)" ]; then
if echo "$wo_site_current_type" | grep -q location; then
wo_site_current="proxy"
elif [ -z "$(echo $wo_site_current_type | grep php)" ]; then
elif echo "$wo_site_current_type" | grep -q php; then
wo_site_current="html"
else
if [ -f /var/www/${site}/ee-config.php ] || [ -f /var/www/${site}/wo-config.php ]; then
if [ -f "/var/www/${site}/ee-config.php" ] || [ -f "/var/www/${site}/wo-config.php" ]; then
wo_site_current="mysql"
else
wo_site_current="php"
@@ -401,17 +401,19 @@ wo_install_acme_sh() {
# Clone Github repository if it doesn't exist
wo_install() {
{
rm -f /etc/bash_completion.d/wo_auto.rc
rm -rf /tmp/WordOps
git clone https://github.com/WordOps/WordOps.git /tmp/WordOps -b "$wo_branch"
cd /tmp/WordOps || exit 1
} >> "$wo_install_log" 2>&1
} \
>> "$wo_install_log" 2>&1
if [ -f $HOME/.gitconfig ]; then
if [ -f "$HOME/.gitconfig" ]; then
python3 setup.py install >> $wo_install_log 2>&1
else
if [ "$wo_force_install" = "y" ]; then
[ ! -f $HOME/.gitconfig ] && { bash -c 'echo -e "[user]\n\tname = $USER\n\temail = root@$HOSTNAME" > $HOME/.gitconfig'; }
[ ! -f "$HOME/.gitconfig" ] && { bash -c 'echo -e "[user]\n\tname = $USER\n\temail = root@$HOSTNAME" > $HOME/.gitconfig'; }
fi
python3 setup.py install
fi
@@ -548,8 +550,8 @@ wo_update_latest() {
mkdir -p /etc/mysql/conf.d
chmod 755 /etc/mysql/conf.d
}
if [ -f $HOME/.my.cnf ]; then
cp -f $HOME/.my.cnf /etc/mysql/conf.d/my.cnf
if [ -f "$HOME/.my.cnf" ]; then
cp -f "$HOME/.my.cnf" /etc/mysql/conf.d/my.cnf
chmod 600 /etc/mysql/conf.d/my.cnf
elif [ -f /root/.my.cnf ]; then
@@ -633,7 +635,7 @@ wo_tweak_kernel() {
if [ "$WO_ARCH" = "x86_64" ]; then
rm -f /etc/sysctl.d/60-ubuntu-nginx-web-server.conf
wget -qO /etc/sysctl.d/60-wo-tweaks.conf https://raw.githubusercontent.com/WordOps/WordOps/updating-configuration/wo/cli/templates/sysctl.mustache
if [ "$wo_distro_version" = "bionic" ] || [ "$wo_distro_version" = "disco" ]; then
if [ "$wo_distro_version" = "bionic" ] || [ "$wo_distro_version" = "disco" ] || [ "$wo_distro_version" = "buster" ]; then
modprobe tcp_bbr && echo 'tcp_bbr' >> /etc/modules-load.d/bbr.conf
echo -e '\nnet.ipv4.tcp_congestion_control = bbr\nnet.ipv4.tcp_notsent_lowat = 16384' >> /etc/sysctl.d/60-wo-tweaks.conf
else
@@ -679,8 +681,10 @@ if [ -x /usr/local/bin/wo ]; then
fi
if [ -z "$wo_preserve_config" ]; then
if [ -n "$(command -v nginx)" ]; then
wo_lib_echo "Upgrading Nginx" | tee -ai $wo_install_log
wo_upgrade_nginx | tee -ai $wo_install_log
if ! grep -q "v3.9.5." /etc/nginx/common/release; then
wo_lib_echo "Upgrading Nginx" | tee -ai $wo_install_log
wo_upgrade_nginx | tee -ai $wo_install_log
fi
fi
fi
wo_update_latest | tee -ai $wo_install_log

View File

@@ -57,7 +57,7 @@ if not os.path.isfile('/root/.gitconfig'):
shutil.copy2(os.path.expanduser("~")+'/.gitconfig', '/root/.gitconfig')
setup(name='wo',
version='3.9.5.4',
version='3.9.6',
description=long_description,
long_description=long_description,
classifiers=[],

View File

@@ -10,7 +10,6 @@ from wo.core.services import WOService
from wo.core.shellexec import WOShellExec
def wo_maintenance_hook(app):
pass

View File

@@ -319,7 +319,8 @@ class WOSiteCreateController(CementBaseController):
dict(help="create WordPress multisite with subdomain setup",
action='store_true')),
(['--wpfc'],
dict(help="create WordPress single/multi site with wpfc cache",
dict(help="create WordPress single/multi site with "
"Nginx fastcgi_cache",
action='store_true')),
(['--wpsc'],
dict(help="create WordPress single/multi site with wpsc cache",
@@ -333,6 +334,10 @@ class WOSiteCreateController(CementBaseController):
action='store' or 'store_const',
choices=('on', 'subdomain', 'wildcard'),
const='on', nargs='?')),
(['--dns'],
dict(help="choose dns provider api for letsencrypt",
action='store' or 'store_const',
const='dns_cf', nargs='?')),
(['--hsts'],
dict(help="enable HSTS for site secured with letsencrypt",
action='store_true')),
@@ -355,6 +360,7 @@ class WOSiteCreateController(CementBaseController):
@expose(hide=True)
def default(self):
pargs = self.app.pargs
# self.app.render((data), 'default.mustache')
# Check domain name validation
data = dict()
@@ -726,42 +732,30 @@ class WOSiteCreateController(CementBaseController):
Log.error(self, "Check the log for details: "
"`tail /var/log/wo/wordops.log` and please try again")
if self.app.pargs.letsencrypt == "on":
if self.app.pargs.letsencrypt:
data['letsencrypt'] = True
letsencrypt = True
if self.app.pargs.dns:
wo_acme_dns = pargs.dns
if data['letsencrypt'] is True:
setupLetsEncrypt(self, wo_domain)
httpsRedirect(self, wo_domain)
if self.app.pargs.hsts:
setupHsts(self, wo_domain)
if not WOService.reload_service(self, 'nginx'):
Log.error(self, "service nginx reload failed. "
"check issues with `nginx -t` command")
Log.info(self, "Congratulations! Successfully Configured "
"SSl for Site "
" https://{0}".format(wo_domain))
# Add nginx conf folder into GIT
WOGit.add(self, ["{0}/conf/nginx".format(wo_site_webroot)],
msg="Adding letsencrypts config of site: {0}"
.format(wo_domain))
updateSiteInfo(self, wo_domain, ssl=letsencrypt)
elif data['letsencrypt'] is False:
Log.info(self, "Not using Let\'s encrypt for Site "
" http://{0}".format(wo_domain))
if self.app.pargs.letsencrypt == "subdomain":
data['letsencrypt'] = True
letsencrypt = True
if data['letsencrypt'] is True:
setupLetsEncryptSubdomain(self, wo_domain)
httpsRedirect(self, wo_domain)
if self.app.pargs.letsencrypt == "subdomain":
if self.app.pargs.dns:
setupLetsEncrypt(self, wo_domain, True, False,
True, wo_acme_dns)
else:
setupLetsEncrypt(self, wo_domain, True)
httpsRedirect(self, wo_domain)
elif self.app.pargs.letsencrypt == "wildcard":
setupLetsEncrypt(self, wo_domain, False, True,
True, wo_acme_dns)
httpsRedirect(self, wo_domain, True, True)
else:
if self.app.pargs.dns:
setupLetsEncrypt(self, wo_domain, False,
False, True, wo_acme_dns)
else:
setupLetsEncrypt(self, wo_domain)
httpsRedirect(self, wo_domain)
if self.app.pargs.hsts:
setupHsts(self, wo_domain)
@@ -825,8 +819,13 @@ class WOSiteUpdateController(CementBaseController):
(['-le', '--letsencrypt'],
dict(help="configure letsencrypt ssl for the site",
action='store' or 'store_const',
choices=('on', 'off', 'renew', 'subdomain', 'wildcard'),
choices=('on', 'off', 'renew', 'subdomain',
'wildcard', 'clean'),
const='on', nargs='?')),
(['--dns'],
dict(help="choose dns provider api for letsencrypt",
action='store' or 'store_const',
const='dns_cf', nargs='?')),
(['--hsts'],
dict(help="configure hsts for the site",
action='store' or 'store_const',
@@ -834,9 +833,6 @@ class WOSiteUpdateController(CementBaseController):
const='on', nargs='?')),
(['--proxy'],
dict(help="update to proxy site", nargs='+')),
(['--experimental'],
dict(help="Enable Experimenal packages without prompt",
action='store_true')),
(['--all'],
dict(help="update all sites", action='store_true')),
(['--force'],
@@ -858,7 +854,8 @@ class WOSiteUpdateController(CementBaseController):
if not (pargs.php or pargs.php73 or
pargs.mysql or pargs.wp or pargs.wpsubdir or
pargs.wpsubdomain or pargs.wpfc or pargs.wpsc or
pargs.wpredis or pargs.letsencrypt or pargs.hsts):
pargs.wpredis or pargs.letsencrypt or pargs.hsts or
pargs.dns or pargs.force):
Log.error(self, "Please provide options to update sites.")
if pargs.all:
@@ -954,6 +951,11 @@ class WOSiteUpdateController(CementBaseController):
except SiteError as e:
Log.debug(self, str(e))
Log.info(self, "\nFail to enable HSTS")
if not WOService.reload_service(self, 'nginx'):
Log.error(self, "service nginx reload failed. "
"check issues with `nginx -t` command")
Log.info(self, "HSTS is enabled for "
"https://{0}".format(wo_domain))
return 0
if ((stype == 'php' and
@@ -965,7 +967,7 @@ class WOSiteUpdateController(CementBaseController):
(stype == 'wpsubdir' and oldsitetype in ['wpsubdomain']) or
(stype == 'wpsubdomain' and oldsitetype in ['wpsubdir']) or
(stype == oldsitetype and cache == oldcachetype) and not
(pargs.php73 or pargs.hsts or pargs.letsencrypt)):
pargs.php73):
Log.info(self, Log.FAIL + "can not update {0} {1} to {2} {3}".
format(oldsitetype, oldcachetype, stype, cache))
return 1
@@ -1181,6 +1183,9 @@ class WOSiteUpdateController(CementBaseController):
elif pargs.letsencrypt == 'off':
data['letsencrypt'] = False
letsencrypt = False
elif pargs.letsencrypt == 'clean':
data['letsencrypt'] = False
letsencrypt = False
if letsencrypt is check_ssl:
if letsencrypt is False:
@@ -1203,12 +1208,15 @@ class WOSiteUpdateController(CementBaseController):
if pargs.php73 == "on":
data['php73'] = True
php73 = True
else:
data['php73'] = False
php73 = False
if pargs.letsencrypt == "on":
if oldsitetype in ['wpsubdomain']:
data['letsencrypt'] = True
letsencrypt = True
wildcard = True
pargs.letsencrypt == 'wildcard'
else:
data['letsencrypt'] = True
letsencrypt = True
@@ -1273,22 +1281,36 @@ class WOSiteUpdateController(CementBaseController):
" http://{0}".format(wo_domain))
return 0
if pargs.letsencrypt:
if self.app.pargs.letsencrypt:
if self.app.pargs.dns:
wo_acme_dns = pargs.dns
if data['letsencrypt'] is True:
if not os.path.isfile("{0}/conf/nginx/ssl.conf.disabled"
.format(wo_site_webroot)):
if not pargs.letsencrypt == "subdomain":
setupLetsEncrypt(self, wo_domain)
else:
setupLetsEncryptSubdomain(self, wo_domain)
if self.app.pargs.letsencrypt == "on":
if self.app.pargs.dns:
setupLetsEncrypt(self, wo_domain, False,
False, True, wo_acme_dns)
else:
setupLetsEncrypt(self, wo_domain)
httpsRedirect(self, wo_domain)
elif self.app.pargs.letsencrypt == "subdomain":
if self.app.pargs.dns:
setupLetsEncrypt(self, wo_domain, True, False,
True, wo_acme_dns)
else:
setupLetsEncrypt(self, wo_domain, True)
httpsRedirect(self, wo_domain)
elif self.app.pargs.letsencrypt == "wildcard":
setupLetsEncrypt(self, wo_domain, False, True,
True, wo_acme_dns)
httpsRedirect(self, wo_domain, True, True)
else:
WOFileUtils.mvfile(self, "{0}/conf/nginx/ssl.conf.disabled"
.format(wo_site_webroot),
'{0}/conf/nginx/ssl.conf'
.format(wo_site_webroot))
httpsRedirect(self, wo_domain)
if not WOService.reload_service(self, 'nginx'):
Log.error(self, "service nginx reload failed. "
"check issues with `nginx -t` command")
@@ -1307,23 +1329,35 @@ class WOSiteUpdateController(CementBaseController):
".PLEASE renew soon . ")
elif data['letsencrypt'] is False:
if os.path.isfile("{0}/conf/nginx/ssl.conf"
.format(wo_site_webroot)):
Log.info(self, 'Setting Nginx configuration')
WOFileUtils.mvfile(self, "{0}/conf/nginx/ssl.conf"
.format(wo_site_webroot),
'{0}/conf/nginx/ssl.conf.disabled'
.format(wo_site_webroot))
httpsRedirect(self, wo_domain, False)
if os.path.isfile("{0}/conf/nginx/hsts.conf"
if self.app.pargs.letsencrypt == "off":
if os.path.isfile("{0}/conf/nginx/ssl.conf"
.format(wo_site_webroot)):
WOFileUtils.mvfile(self, "{0}/conf/nginx/hsts.conf"
Log.info(self, 'Setting Nginx configuration')
WOFileUtils.mvfile(self, "{0}/conf/nginx/ssl.conf"
.format(wo_site_webroot),
'{0}/conf/nginx/hsts.conf.disabled'
'{0}/conf/nginx/ssl.conf.disabled'
.format(wo_site_webroot))
if not WOService.reload_service(self, 'nginx'):
Log.error(self, "service nginx reload failed. "
"check issues with `nginx -t` command")
httpsRedirect(self, wo_domain, False)
if os.path.isfile("{0}/conf/nginx/hsts.conf"
.format(wo_site_webroot)):
WOFileUtils.mvfile(self, "{0}/conf/nginx/hsts.conf"
.format(wo_site_webroot),
'{0}/conf/nginx/'
'hsts.conf.disabled'
.format(wo_site_webroot))
if self.app.pargs.letsencrypt == "clean":
if os.path.isfile("{0}/conf/nginx/ssl.conf"
.format(wo_site_webroot)):
WOFileUtils.remove(self, "{0}/conf/nginx/ssl.conf"
.format(wo_site_webroot))
WOFileUtils.remove(self, "/etc/letsencrypt/live"
"/{0}".format(wo_domain))
WOFileUtils.remove(self, "/etc/nginx/conf.d/"
"force-ssl-{0}.conf"
.format(wo_domain_name))
if not WOService.reload_service(self, 'nginx'):
Log.error(self, "service nginx reload failed. "
"check issues with `nginx -t` command")
# Log.info(self,"Removing Cron Job set for cert
# auto-renewal") WOCron.remove_cron(self,'wo site
# update {0} --le=renew --min_expiry_limit 30
@@ -1415,7 +1449,8 @@ class WOSiteUpdateController(CementBaseController):
return 1
# Setup WordPress if old sites are html/php/mysql sites
if data['wp'] and oldsitetype in ['html', 'proxy', 'php', 'mysql']:
if data['wp'] and oldsitetype in ['html', 'proxy', 'php',
'mysql', 'php73']:
try:
wo_wp_creds = setupwordpress(self, data)
except SiteError as e:

View File

@@ -327,11 +327,44 @@ def setupwordpress(self, data):
raise SiteError("generate wp-config failed for wp single site")
except CommandExecutionError as e:
raise SiteError("generate wp-config failed for wp single site")
try:
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set WP_CACHE_KEY_SALT "
"\'{0}:\'\"".format(wo_domain_name))
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set WP_CACHE_KEY_SALT "
"\'{0}:\'\"".format(wo_domain_name))
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set WP_MEMORY_LIMIT "
"\'128M\'\"")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set WP_MAX_MEMORY_LIMIT "
"\'256M\'\"")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set CONCATENATE_SCRIPTS "
"false\"")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set WP_POST_REVISIONS "
"\'10\'\"")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set MEDIA_TRASH "
"true\"")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set EMPTY_TRASH_DAYS "
"\'15\'\"")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set WP_AUTO_UPDATE_CORE "
"minor\"")
except CommandExecutionError as e:
Log.error(self, "Unable to define extra variable in wp-config.php")
else:
Log.debug(self, "Generating wp-config for WordPress multisite")
@@ -339,7 +372,8 @@ def setupwordpress(self, data):
.format(WOVariables.wo_wpcli_path) +
"config create " +
"--dbname=\'{0}\' --dbprefix=\'{1}\' --dbhost=\'{2}\' "
.format(data['wo_db_name'], wo_wp_prefix, data['wo_db_host']) +
.format(data['wo_db_name'],
wo_wp_prefix, data['wo_db_host']) +
"--dbuser=\'{0}\' --dbpass=\'{1}\' "
"--extra-php<<PHP \n {2} {3} {4} \nPHP\""
.format(data['wo_db_user'], data['wo_db_pass'],
@@ -372,10 +406,44 @@ def setupwordpress(self, data):
except CommandExecutionError as e:
raise SiteError("generate wp-config failed for wp multi site")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set WP_CACHE_KEY_SALT "
"\'{0}:\'\"".format(wo_domain_name))
try:
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set WP_CACHE_KEY_SALT "
"\'{0}:\'\"".format(wo_domain_name))
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set WP_MEMORY_LIMIT "
"\'128M\'\"")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set WP_MAX_MEMORY_LIMIT "
"\'256M\'\"")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set CONCATENATE_SCRIPTS "
"false\"")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set WP_POST_REVISIONS "
"\'10\'\"")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set MEDIA_TRASH "
"true\"")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set EMPTY_TRASH_DAYS "
"\'15\'\"")
WOShellExec.cmd_exec(self, "bash -c \"php {0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"config set WP_AUTO_UPDATE_CORE "
"minor\"")
except CommandExecutionError as e:
Log.error(self, "Unable to define extra variable in wp-config.php")
# WOFileUtils.mvfile(self, os.getcwd()+'/wp-config.php',
# os.path.abspath(os.path.join(os.getcwd(), os.pardir)))
@@ -856,7 +924,7 @@ def site_package_check(self, stype):
apt_packages = apt_packages + WOVariables.wo_php73
if (os.path.isdir("/etc/nginx/common") and
not os.path.isfile("/etc/nginx/common/php73.conf")):
not os.path.isfile("/etc/nginx/common/locations-wo.conf")):
data = dict()
Log.debug(self, 'Writting the nginx configuration to '
'file /etc/nginx/common/locations-wo.conf')
@@ -1231,9 +1299,18 @@ def removeAcmeConf(self, domain):
if os.path.isdir('/etc/letsencrypt/renewal/{0}_ecc'
.format(domain)):
Log.debug(self, "Removing Acme configuration")
WOFileUtils.rm(self, '/etc/letsencrypt/renewal/{0}_ecc'
try:
WOShellExec.cmd_exec(self, "/etc/letsencrypt/acme.sh "
"--config-home "
"'/etc/letsencrypt/config' "
"--remove "
"-d {0} --ecc"
.format(domain))
except CommandExecutionError as e:
Log.error(self, "Cert removal failed")
WOFileUtils.remove(self, '/etc/letsencrypt/renewal/{0}_ecc'
.format(domain))
WOFileUtils.rm(self, '/etc/letsencrypt/live/{0}'
WOFileUtils.remove(self, '/etc/letsencrypt/live/{0}'
.format(domain))
WOGit.add(self, ["/etc/letsencrypt"],
msg="Deleted {0} "
@@ -1265,40 +1342,57 @@ def doCleanupAction(self, domain='', webroot='', dbname='', dbuser='',
raise SiteError("dbhost not provided")
deleteDB(self, dbname, dbuser, dbhost)
# setup letsencrypt for domain + www.domain
def setupLetsEncrypt(self, wo_domain_name):
if os.path.isfile("/etc/letsencrypt/renewal/{0}_ecc/{0}.conf"
.format(wo_domain_name)):
if os.path.isfile("/etc/letsencrypt/"
"renewal/{0}_ecc/"
"fullchain.cer".format(wo_domain_name)):
Log.debug(self, "Let's Encrypt certificate "
"found for the domain: {0}"
.format(wo_domain_name))
ssl = archivedCertificateHandle(self, wo_domain_name)
def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False,
wo_dns=False, wo_acme_dns='dns_cf'):
if os.path.isfile("/etc/letsencrypt/"
"renewal/{0}_ecc/"
"fullchain.cer".format(wo_domain_name)):
Log.debug(self, "Let's Encrypt certificate "
"found for the domain: {0}"
.format(wo_domain_name))
ssl = archivedCertificateHandle(self, wo_domain_name)
else:
keylenght = "{0}".format(self.app.config.get('letsencrypt',
'keylength'))
if wo_dns:
acme_mode = "--dns {0}".format(wo_acme_dns)
else:
Log.info(self, "Issuing SSL cert with acme.sh")
acme_mode = "-w /var/www/html"
Log.info(self, "Issuing SSL cert with acme.sh")
if subdomain:
ssl = WOShellExec.cmd_exec(self, "/etc/letsencrypt/acme.sh "
"--config-home "
"'/etc/letsencrypt/config' "
"--issue "
"-d {0} -d www.{0} -w /var/www/html "
"-k ec-384 -f"
.format(wo_domain_name))
else:
Log.info(self, "Issuing SSL cert with acme.sh")
ssl = WOShellExec.cmd_exec(self, "/etc/letsencrypt/acme.sh "
"--config-home "
"'/etc/letsencrypt/config' "
"--issue "
"-d {0} -d www.{0} -w /var/www/html "
"-k ec-384 -f"
.format(wo_domain_name))
"-d {0} {1}"
"-k {3} -f"
.format(wo_domain_name,
acme_mode,
keylenght))
elif wildcard:
ssl = WOShellExec.cmd_exec(self, "/etc/letsencrypt/acme.sh "
"--config-home "
"'/etc/letsencrypt/config' "
"--issue "
"-d {0} -d *.{0} --dns {1} "
"-k {2} -f"
.format(wo_domain_name,
wo_acme_dns,
keylenght))
else:
ssl = WOShellExec.cmd_exec(self, "/etc/letsencrypt/acme.sh "
"--config-home "
"'/etc/letsencrypt/config' "
"--issue "
"-d {0} -d www.{0} {1} "
"-k {2} -f"
.format(wo_domain_name,
acme_mode, keylenght))
if ssl:
try:
Log.info(self, "Deploying SSL cert with acme.sh")
Log.debug(self, "Cert deployment for domain: {0}"
@@ -1349,90 +1443,6 @@ def setupLetsEncrypt(self, wo_domain_name):
"you are running Let\'s Encrypt Client "
"\n to allow it to verify the site automatically.")
# setup letsencrypt for a subdomain
def setupLetsEncryptSubdomain(self, wo_domain_name):
if os.path.isfile("/etc/letsencrypt/renewal/{0}_ecc/{0}.conf"
.format(wo_domain_name)):
if os.path.isfile("/etc/letsencrypt/"
"renewal/{0}_ecc/"
"fullchain.cer".format(wo_domain_name)):
Log.debug(self, "Let's Encrypt certificate "
"found for the domain: {0}"
.format(wo_domain_name))
ssl = archivedCertificateHandle(self, wo_domain_name)
else:
Log.info(self, "Issuing SSL cert with acme.sh")
ssl = WOShellExec.cmd_exec(self, "/etc/letsencrypt/acme.sh "
"--config-home "
"'/etc/letsencrypt/config' "
"--issue "
"-d {0} -w /var/www/html "
"-k ec-384 -f"
.format(wo_domain_name))
else:
Log.info(self, "Issuing SSL cert with acme.sh")
ssl = WOShellExec.cmd_exec(self, "/etc/letsencrypt/acme.sh "
"--config-home "
"'/etc/letsencrypt/config' "
"--issue "
"-d {0} -w /var/www/html "
"-k ec-384 -f"
.format(wo_domain_name))
if ssl:
try:
Log.info(self, "Deploying SSL cert with acme.sh")
Log.debug(self, "Deploying cert for domain: {0}"
.format(wo_domain_name))
sslsetup = WOShellExec.cmd_exec(self, "mkdir -p {0}/{1} && "
"/etc/letsencrypt/acme.sh "
"--config-home "
"'/etc/letsencrypt/config' "
"--install-cert -d {1} --ecc "
"--cert-file {0}/{1}/cert.pem "
"--key-file {0}/{1}/key.pem "
"--fullchain-file "
"{0}/{1}/fullchain.pem "
"--ca-file {0}/{1}/ca.pem "
"--reloadcmd "
"\"nginx -t && service nginx restart\" "
.format(WOVariables.wo_ssl_live,
wo_domain_name))
Log.info(
self, "Adding /var/www/{0}/conf/nginx/ssl.conf"
.format(wo_domain_name))
sslconf = open("/var/www/{0}/conf/nginx/ssl.conf"
.format(wo_domain_name),
encoding='utf-8', mode='w')
sslconf.write("listen 443 ssl http2;\n"
"listen [::]:443 ssl http2;\n"
"ssl_certificate {0}/{1}/fullchain.pem;\n"
"ssl_certificate_key {0}/{1}/key.pem;\n"
"ssl_trusted_certificate {0}/{1}/ca.pem;\n"
"ssl_stapling_verify on;\n"
.format(WOVariables.wo_ssl_live, wo_domain_name))
sslconf.close()
updateSiteInfo(self, wo_domain_name, ssl=True)
WOGit.add(self, ["/etc/letsencrypt"],
msg="Adding letsencrypt folder")
except IOError as e:
Log.debug(self, str(e))
Log.debug(self, "Error occured while generating "
"ssl.conf")
else:
Log.error(self, "Unable to create ssl.conf", False)
Log.error(self, "Please make sure that your site is pointed to \n"
"same server on which "
"you are running Let\'s Encrypt Client "
"\n to allow it to verify the site automatically.")
# letsencrypt cert renewal
@@ -1500,7 +1510,7 @@ def setupHsts(self, wo_domain_name):
return 0
def httpsRedirect(self, wo_domain_name, redirect=True):
def httpsRedirect(self, wo_domain_name, redirect=True, wildcard=False):
if redirect:
if os.path.isfile("/etc/nginx/conf.d/force-ssl-{0}.conf.disabled"
.format(wo_domain_name)):
@@ -1510,31 +1520,54 @@ def httpsRedirect(self, wo_domain_name, redirect=True):
"/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
else:
try:
Log.info(
self, "Adding /etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
if wildcard:
try:
Log.info(
self, "Adding /etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
sslconf = open("/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name),
encoding='utf-8', mode='w')
sslconf.write("server {\n"
"\tlisten 80;\n" +
"\tlisten [::]:80;\n" +
"\tserver_name *.{0} {0};\n"
.format(wo_domain_name) +
"\treturn 301 https://$host"
"$request_uri;\n}")
sslconf.close()
except IOError as e:
Log.debug(self, str(e))
Log.debug(self, "Error occured while generating "
"/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
else:
try:
Log.info(
self, "Adding /etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
sslconf = open("/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name),
encoding='utf-8', mode='w')
sslconf.write("server {\n"
"\tlisten 80;\n" +
"\tlisten [::]:80;\n" +
"\tserver_name www.{0} {0};\n"
.format(wo_domain_name) +
"\treturn 301 https://{0}"
.format(wo_domain_name)+"$request_uri;\n}")
sslconf.close()
# Nginx Configation into GIT
except IOError as e:
Log.debug(self, str(e))
Log.debug(self, "Error occured while generating "
"/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
sslconf = open("/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name),
encoding='utf-8', mode='w')
sslconf.write("server {\n"
"\tlisten 80;\n" +
"\tlisten [::]:80;\n" +
"\tserver_name www.{0} {0};\n"
.format(wo_domain_name) +
"\treturn 301 https://{0}"
.format(wo_domain_name)+"$request_uri;\n}")
sslconf.close()
except IOError as e:
Log.debug(self, str(e))
Log.debug(self, "Error occured while generating "
"/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
Log.info(self, "Added HTTPS Force Redirection for Site "
" http://{0}".format(wo_domain_name))
# Nginx Configation into GIT
WOGit.add(self,
["/etc/nginx"], msg="Adding /etc/nginx/conf.d/"
"force-ssl-{0}.conf".format(wo_domain_name))

View File

@@ -50,6 +50,8 @@ class WOStackController(CementBaseController):
dict(help='Install web stack', action='store_true')),
(['--admin'],
dict(help='Install admin tools stack', action='store_true')),
(['--security'],
dict(help='Install security tools stack', action='store_true')),
(['--nginx'],
dict(help='Install Nginx stack', action='store_true')),
(['--php'],
@@ -79,6 +81,8 @@ class WOStackController(CementBaseController):
dict(help='Install Redis', action='store_true')),
(['--phpredisadmin'],
dict(help='Install phpRedisAdmin', action='store_true')),
(['--proftpd'],
dict(help='Install ProFTPd', action='store_true')),
]
usage = "wo stack (command) [options]"
@@ -93,8 +97,7 @@ class WOStackController(CementBaseController):
if set(WOVariables.wo_mysql).issubset(set(apt_packages)):
# add mariadb repository excepted on raspbian and ubuntu 19.04
if ((not WOVariables.wo_platform_codename == 'disco') and
(not WOVariables.wo_platform_distro == 'raspbian')):
if (not WOVariables.wo_platform_distro == 'raspbian'):
Log.info(self, "Adding repository for MySQL, please wait...")
mysql_pref = ("Package: *\nPin: origin "
"sfo1.mirrors.digitalocean.com"
@@ -194,6 +197,7 @@ class WOStackController(CementBaseController):
WORepo.add(self, ppa=WOVariables.wo_nginx_repo)
Log.debug(self, 'Adding ppa for Nginx')
else:
Log.info(self, "Adding repository for NGINX, please wait...")
WORepo.add(self, repo_url=WOVariables.wo_nginx_repo)
Log.debug(self, 'Adding repository for Nginx')
WORepo.add_key(self, WOVariables.wo_nginx_key)
@@ -208,6 +212,13 @@ class WOStackController(CementBaseController):
else:
Log.info(self, "Adding repository for PHP, please wait...")
# Add repository for php
if (WOVariables.wo_platform_codename == 'buster'):
php_pref = ("Package: *\nPin: origin "
"packages.sury.org"
"\nPin-Priority: 1000\n")
with open('/etc/apt/preferences.d/'
'PHP.pref', 'w') as php_pref_file:
php_pref_file.write(php_pref)
Log.debug(self, 'Adding repo_url of php for debian')
WORepo.add(self, repo_url=WOVariables.wo_php_repo)
Log.debug(self, 'Adding deb.sury GPG key')
@@ -370,7 +381,7 @@ class WOStackController(CementBaseController):
# php73 conf
if not os.path.isfile("/etc/nginx/common/php73.conf"):
# data = dict()
# data = dict()
Log.debug(self, 'Writting the nginx configuration to '
'file /etc/nginx/common/php73.conf')
wo_nginx = open('/etc/nginx/common/php73.conf',
@@ -1075,21 +1086,69 @@ class WOStackController(CementBaseController):
# create fail2ban configuration files
if set(WOVariables.wo_fail2ban).issubset(set(apt_packages)):
if not os.path.isfile("/etc/fail2ban/jail.d/custom.conf"):
data = dict()
Log.debug(self, "Setting up fail2ban jails configuration")
wo_fail2ban = open('/etc/fail2ban/jail.d/custom.conf',
encoding='utf-8', mode='w')
fail2ban_config = open('/etc/fail2ban/jail.d/custom.conf',
encoding='utf-8', mode='w')
self.app.render((data), 'fail2ban.mustache',
out=wo_fail2ban)
wo_fail2ban.close()
out=fail2ban_config)
fail2ban_config.close()
Log.debug(self, "Setting up fail2ban wp filter")
wo_fail2ban = open('/etc/fail2ban/filter.d/'
'wo-wordpress.conf',
encoding='utf-8', mode='w')
fail2ban_config = open('/etc/fail2ban/filter.d/'
'wo-wordpress.conf',
encoding='utf-8', mode='w')
self.app.render((data), 'fail2ban-wp.mustache',
out=wo_fail2ban)
wo_fail2ban.close()
out=fail2ban_config)
fail2ban_config.close()
Log.debug(self, "Setting up fail2ban wp filter")
fail2ban_config = open('/etc/fail2ban/filter.d/'
'nginx-forbidden.conf',
encoding='utf-8', mode='w')
self.app.render((data), 'fail2ban-forbidden.mustache',
out=fail2ban_config)
fail2ban_config.close()
WOGit.add(self, ["/etc/fail2ban"],
msg="Adding Fail2ban into Git")
WOService.reload_service(self, 'fail2ban')
# Proftpd configuration
if set(["proftpd-basic"]).issubset(set(apt_packages)):
if os.path.isfile("/etc/proftpd/proftpd.conf"):
Log.debug(self, "Setting up Proftpd configuration")
WOFileUtils.searchreplace(self, "/etc/proftpd/"
"proftpd.conf",
"# DefaultRoot",
"DefaultRoot")
WOFileUtils.searchreplace(self, "/etc/proftpd/"
"proftpd.conf",
"# RequireValidShell",
"RequireValidShell")
WOFileUtils.searchreplace(self, "/etc/proftpd/"
"proftpd.conf",
"# PassivePorts "
" "
"49152 65534",
"PassivePorts "
" "
" 49000 50000")
# add rule for proftpd with UFW
if WOAptGet.is_installed(self, 'ufw'):
try:
WOShellExec.cmd_exec(self, "ufw allow "
"49000:50000/tcp")
except CommandExecutionError as e:
Log.error(self, "Unable to add UFW rule")
if os.path.isfile("/etc/fail2ban/jail.d/custom.conf"):
with open("/etc/fail2ban/jail.d/custom.conf",
encoding='utf-8', mode='a') as f2bproftpd:
f2bproftpd.write("\n\n[proftpd]\nenabled = true\n")
WOService.reload_service(self, 'fail2ban')
WOGit.add(self, ["/etc/proftpd"],
msg="Adding ProFTPd into Git")
WOService.reload_service(self, 'proftpd')
if (packages):
if any('/usr/local/bin/wp' == x[1] for x in packages):
@@ -1407,17 +1466,22 @@ class WOStackController(CementBaseController):
(not self.app.pargs.composer) and
(not self.app.pargs.netdata) and
(not self.app.pargs.dashboard) and
(not self.app.pargs.fail2ban) and
(not self.app.pargs.security) and
(not self.app.pargs.adminer) and (not self.app.pargs.utils) and
(not self.app.pargs.redis) and
(not self.app.pargs.redis) and (not self.app.pargs.proftpd) and
(not self.app.pargs.phpredisadmin) and
(not self.app.pargs.php73)):
self.app.pargs.web = True
self.app.pargs.admin = True
self.app.pargs.security = True
if self.app.pargs.all:
self.app.pargs.web = True
self.app.pargs.admin = True
self.app.pargs.php73 = True
self.app.pargs.redis = True
self.app.pargs.proftpd = True
if self.app.pargs.web:
self.app.pargs.nginx = True
@@ -1437,6 +1501,9 @@ class WOStackController(CementBaseController):
self.app.pargs.dashboard = True
self.app.pargs.phpredisadmin = True
if self.app.pargs.security:
self.app.pargs.fail2ban = True
# Redis
if self.app.pargs.redis:
if not WOAptGet.is_installed(self, 'redis-server'):
@@ -1505,7 +1572,6 @@ class WOStackController(CementBaseController):
"/master/mysqltuner.pl",
"/usr/bin/mysqltuner",
"MySQLTuner"]]
else:
Log.debug(self, "MySQL connection is already alive")
Log.info(self, "MySQL connection is already alive")
@@ -1533,37 +1599,64 @@ class WOStackController(CementBaseController):
Log.debug(self, "Fail2ban already installed")
Log.info(self, "Fail2ban already installed")
# proftpd
if self.app.pargs.proftpd:
Log.debug(self, "Setting apt_packages variable for ProFTPd")
if not WOAptGet.is_installed(self, 'proftpd-basic'):
apt_packages = apt_packages + ["proftpd-basic"]
else:
Log.debug(self, "ProFTPd already installed")
Log.info(self, "ProFTPd already installed")
# PHPMYADMIN
if self.app.pargs.phpmyadmin:
Log.debug(self, "Setting packages variable for phpMyAdmin ")
self.app.pargs.composer = True
packages = packages + [["https://github.com/phpmyadmin/"
"phpmyadmin/archive/STABLE.tar.gz",
"/var/lib/wo/tmp/pma.tar.gz",
"phpMyAdmin"]]
if not os.path.isdir('/var/www/22222/htdocs/db/pma'):
Log.debug(self, "Setting packages variable "
"for phpMyAdmin ")
self.app.pargs.composer = True
packages = packages + [["https://github.com/phpmyadmin/"
"phpmyadmin/archive/STABLE.tar.gz",
"/var/lib/wo/tmp/pma.tar.gz",
"phpMyAdmin"]]
else:
Log.debug(self, "phpMyAdmin already installed")
Log.info(self, "phpMyAdmin already installed")
# Composer
if self.app.pargs.composer:
Log.debug(self, "Setting packages variable for Composer ")
packages = packages + [["https://getcomposer.org/installer",
"/var/lib/wo/tmp/composer-install",
"Composer"]]
if not os.path.isfile('/usr/local/bin/composer'):
Log.debug(self, "Setting packages variable for Composer ")
packages = packages + [["https://getcomposer.org/"
"installer",
"/var/lib/wo/tmp/composer-install",
"Composer"]]
else:
Log.debug(self, "Composer already installed")
Log.info(self, "Composer already installed")
# PHPREDISADMIN
if self.app.pargs.phpredisadmin:
Log.debug(self, "Setting packages variable for phpRedisAdmin")
self.app.pargs.composer = True
packages = packages + [["https://github.com/erikdubbelboer/"
"phpRedisAdmin/archive/v1.11.3.tar.gz",
"/var/lib/wo/tmp/pra.tar.gz",
"phpRedisAdmin"],
["https://github.com/nrk/predis/"
"archive/v1.1.1.tar.gz",
"/var/lib/wo/tmp/predis.tar.gz",
"Predis"]]
if not os.path.isdir('/var/www/22222/htdocs/cache/redis'):
Log.debug(
self, "Setting packages variable for phpRedisAdmin")
self.app.pargs.composer = True
packages = packages + [["https://github.com/"
"erikdubbelboer/"
"phpRedisAdmin/archive"
"/v1.11.3.tar.gz",
"/var/lib/wo/tmp/pra.tar.gz",
"phpRedisAdmin"]]
else:
Log.debug(self, "phpRedisAdmin already installed")
Log.info(self, "phpRedisAdmin already installed")
# ADMINER
if self.app.pargs.adminer:
Log.debug(self, "Setting packages variable for Adminer ")
packages = packages + [["https://github.com/vrana/adminer/"
"releases/download/v{0}"
if not os.path.isdir('{0}22222/htdocs/db/adminer'
.format(WOVariables.wo_webroot)):
Log.debug(self, "Setting packages variable for Adminer ")
packages = packages + [["https://github.com/vrana/adminer/"
"releases/download/v{0}"
"/adminer-{0}.php"
.format(WOVariables.wo_adminer),
"{0}22222/"
@@ -1574,9 +1667,12 @@ class WOStackController(CementBaseController):
"/vrana/adminer/master/designs/"
"pepa-linha/adminer.css",
"{0}22222/"
"htdocs/db/adminer/adminer.css"
.format(WOVariables.wo_webroot),
"Adminer theme"]]
"htdocs/db/adminer/adminer.css"
.format(WOVariables.wo_webroot),
"Adminer theme"]]
else:
Log.debug(self, "Adminer already installed")
Log.info(self, "Adminer already installed")
# Netdata
if self.app.pargs.netdata:
@@ -1586,20 +1682,28 @@ class WOStackController(CementBaseController):
'kickstart-static64.sh',
'/var/lib/wo/tmp/kickstart.sh',
'Netdata']]
else:
Log.debug(self, "Netdata already installed")
Log.info(self, "Netdata already installed")
# WordOps Dashboard
if self.app.pargs.dashboard:
Log.debug(self, "Setting packages variable for WO-Dashboard")
packages = packages + \
[["https://github.com/WordOps/"
"wordops-dashboard/releases/"
"download/v1.0/wo-dashboard.tar.gz",
"/var/lib/wo/tmp/wo-dashboard.tar.gz",
"WordOps Dashboard"],
["https://github.com/soerennb/"
"extplorer/archive/v2.1.11.tar.gz",
"/var/lib/wo/tmp/extplorer.tar.gz",
"eXtplorer"]]
if not os.path.isfile('/var/www/22222/htdocs/index.php'):
Log.debug(
self, "Setting packages variable for WO-Dashboard")
packages = packages + \
[["https://github.com/WordOps/"
"wordops-dashboard/releases/"
"download/v1.0/wo-dashboard.tar.gz",
"/var/lib/wo/tmp/wo-dashboard.tar.gz",
"WordOps Dashboard"],
["https://github.com/soerennb/"
"extplorer/archive/v2.1.11.tar.gz",
"/var/lib/wo/tmp/extplorer.tar.gz",
"eXtplorer"]]
else:
Log.debug(self, "WordOps dashboard already installed")
Log.info(self, "WordOps dashboard already installed")
# UTILS
if self.app.pargs.utils:
@@ -1723,10 +1827,13 @@ class WOStackController(CementBaseController):
(not self.app.pargs.wpcli) and (not self.app.pargs.phpmyadmin) and
(not self.app.pargs.adminer) and (not self.app.pargs.utils) and
(not self.app.pargs.composer) and (not self.app.pargs.netdata) and
(not self.app.pargs.fail2ban) and (not self.app.pargs.proftpd) and
(not self.app.pargs.security) and
(not self.app.pargs.all) and (not self.app.pargs.redis) and
(not self.app.pargs.phpredisadmin)):
self.app.pargs.web = True
self.app.pargs.admin = True
self.app.pargs.security = True
if self.app.pargs.all:
self.app.pargs.web = True
@@ -1748,6 +1855,9 @@ class WOStackController(CementBaseController):
self.app.pargs.dashboard = True
self.app.pargs.phpredisadmin = True
if self.app.pargs.security:
self.app.pargs.fail2ban = True
# NGINX
if self.app.pargs.nginx:
if WOAptGet.is_installed(self, 'nginx-custom'):
@@ -1790,6 +1900,23 @@ class WOStackController(CementBaseController):
Log.debug(self, "Removing apt_packages variable of MySQL")
apt_packages = apt_packages + WOVariables.wo_mysql
packages = packages + ['/usr/bin/mysqltuner']
# fail2ban
if self.app.pargs.fail2ban:
if WOAptGet.is_installed(self, 'fail2ban'):
Log.debug(self, "Remove apt_packages variable of Fail2ban")
apt_packages = apt_packages + WOVariables.wo_fail2ban
else:
Log.error(self, "Fail2ban not found")
# proftpd
if self.app.pargs.proftpd:
if WOAptGet.is_installed(self, 'proftpd-basic'):
Log.debug(self, "Remove apt_packages variable for ProFTPd")
apt_packages = apt_packages + ["proftpd-basic"]
else:
Log.error(self, "ProFTPd not found")
# WPCLI
if self.app.pargs.wpcli:
Log.debug(self, "Removing package variable of WPCLI ")
@@ -1894,10 +2021,13 @@ class WOStackController(CementBaseController):
(not self.app.pargs.wpcli) and (not self.app.pargs.phpmyadmin) and
(not self.app.pargs.adminer) and (not self.app.pargs.utils) and
(not self.app.pargs.composer) and (not self.app.pargs.netdata) and
(not self.app.pargs.fail2ban) and (not self.app.pargs.proftpd) and
(not self.app.pargs.security) and
(not self.app.pargs.all) and (not self.app.pargs.redis) and
(not self.app.pargs.phpredisadmin)):
self.app.pargs.web = True
self.app.pargs.admin = True
self.app.pargs.security = True
if self.app.pargs.all:
self.app.pargs.web = True
@@ -1919,6 +2049,8 @@ class WOStackController(CementBaseController):
self.app.pargs.dashboard = True
self.app.pargs.phpredisadmin = True
if self.app.pargs.security:
self.app.pargs.fail2ban = True
# NGINX
if self.app.pargs.nginx:
if WOAptGet.is_installed(self, 'nginx-custom'):
@@ -1952,6 +2084,22 @@ class WOStackController(CementBaseController):
else:
Log.error(self, "Cannot Purge PHP 7.3. not found.")
# fail2ban
if self.app.pargs.fail2ban:
if WOAptGet.is_installed(self, 'fail2ban'):
Log.debug(self, "Purge apt_packages variable of Fail2ban")
apt_packages = apt_packages + WOVariables.wo_fail2ban
else:
Log.error(self, "Fail2ban not found")
# proftpd
if self.app.pargs.proftpd:
if WOAptGet.is_installed(self, 'proftpd-basic'):
Log.debug(self, "Purge apt_packages variable for ProFTPd")
apt_packages = apt_packages + ["proftpd-basic"]
else:
Log.error(self, "ProFTPd not found")
# WP-CLI
if self.app.pargs.wpcli:
Log.debug(self, "Purge package variable WPCLI")
@@ -2034,6 +2182,9 @@ class WOStackController(CementBaseController):
"libexec/netdata-"
"uninstaller.sh -y -f")
if (set(["fail2ban"]).issubset(set(apt_packages))):
WOService.stop_service(self, 'fail2ban')
if (apt_packages):
Log.info(self, "Purging packages, please wait...")
WOAptGet.remove(self, apt_packages, purge=True)

View File

@@ -4,6 +4,7 @@ from wo.core.services import WOService
from wo.core.logging import Log
from wo.core.variables import WOVariables
from wo.core.aptget import WOAptGet
import os
class WOStackStatusController(CementBaseController):
@@ -12,11 +13,6 @@ class WOStackStatusController(CementBaseController):
stacked_on = 'stack'
stacked_type = 'embedded'
description = 'Check the stack status'
arguments = [
(['--memcached'],
dict(help='start/stop/restart memcached',
action='store_true')),
]
@expose(help="Start stack services")
def start(self):
@@ -25,9 +21,9 @@ class WOStackStatusController(CementBaseController):
if not (self.app.pargs.nginx or self.app.pargs.php or
self.app.pargs.php73 or
self.app.pargs.mysql or
self.app.pargs.memcached or
self.app.pargs.redis or
self.app.pargs.fail2ban or
self.app.pargs.proftpd or
self.app.pargs.netdata):
self.app.pargs.nginx = True
self.app.pargs.php = True
@@ -68,12 +64,6 @@ class WOStackStatusController(CementBaseController):
Log.warn(self, "Remote MySQL found, "
"Unable to check MySQL service status")
if self.app.pargs.memcached:
if WOAptGet.is_installed(self, 'memcached'):
services = services + ['memcached']
else:
Log.info(self, "Memcached is not installed")
if self.app.pargs.redis:
if WOAptGet.is_installed(self, 'redis-server'):
services = services + ['redis-server']
@@ -82,10 +72,24 @@ class WOStackStatusController(CementBaseController):
if self.app.pargs.fail2ban:
if WOAptGet.is_installed(self, 'fail2ban'):
services = services + ['fail2ban-client']
services = services + ['fail2ban']
else:
Log.info(self, "fail2ban is not installed")
# proftpd
if self.app.pargs.proftpd:
if WOAptGet.is_installed(self, 'proftpd-basic'):
services = services + ['proftpd']
else:
Log.info(self, "ProFTPd is not installed")
# netdata
if self.app.pargs.netdata:
if os.path.isdir("/opt/netdata"):
services = services + ['netdata']
else:
Log.info(self, "Netdata is not installed")
for service in services:
Log.debug(self, "Starting service: {0}".format(service))
WOService.start_service(self, service)
@@ -97,18 +101,22 @@ class WOStackStatusController(CementBaseController):
if not (self.app.pargs.nginx or self.app.pargs.php or
self.app.pargs.php73 or
self.app.pargs.mysql or
self.app.pargs.memcached or
self.app.pargs.fail2ban or
self.app.pargs.netdata or
self.app.pargs.proftpd or
self.app.pargs.redis):
self.app.pargs.nginx = True
self.app.pargs.php = True
self.app.pargs.mysql = True
# nginx
if self.app.pargs.nginx:
if (WOAptGet.is_installed(self, 'nginx-custom')):
services = services + ['nginx']
else:
Log.info(self, "Nginx is not installed")
# php7.2
if self.app.pargs.php:
if WOAptGet.is_installed(self, 'php7.2-fpm'):
services = services + ['php7.2-fpm']
@@ -120,12 +128,14 @@ class WOStackStatusController(CementBaseController):
else:
Log.info(self, "PHP7.3-FPM is not installed")
# php7.3
if self.app.pargs.php73:
if WOAptGet.is_installed(self, 'php7.3-fpm'):
services = services + ['php7.3-fpm']
else:
Log.info(self, "PHP7.3-FPM is not installed")
# mysql
if self.app.pargs.mysql:
if ((WOVariables.wo_mysql_host is "localhost") or
(WOVariables.wo_mysql_host is "127.0.0.1")):
@@ -139,24 +149,34 @@ class WOStackStatusController(CementBaseController):
Log.warn(self, "Remote MySQL found, "
"Unable to check MySQL service status")
if self.app.pargs.memcached:
if WOAptGet.is_installed(self, 'memcached'):
services = services + ['memcached']
else:
Log.info(self, "Memcached is not installed")
# redis
if self.app.pargs.redis:
if WOAptGet.is_installed(self, 'redis-server'):
services = services + ['redis-server']
else:
Log.info(self, "Redis server is not installed")
# fail2ban
if self.app.pargs.fail2ban:
if WOAptGet.is_installed(self, 'fail2ban'):
services = services + ['fail2ban-client']
services = services + ['fail2ban']
else:
Log.info(self, "fail2ban is not installed")
# proftpd
if self.app.pargs.proftpd:
if WOAptGet.is_installed(self, 'proftpd-basic'):
services = services + ['proftpd']
else:
Log.info(self, "ProFTPd is not installed")
# netdata
if self.app.pargs.netdata:
if os.path.isdir("/opt/netdata"):
services = services + ['netdata']
else:
Log.info(self, "Netdata is not installed")
for service in services:
Log.debug(self, "Stopping service: {0}".format(service))
WOService.stop_service(self, service)
@@ -168,7 +188,8 @@ class WOStackStatusController(CementBaseController):
if not (self.app.pargs.nginx or self.app.pargs.php or
self.app.pargs.php73 or
self.app.pargs.mysql or
self.app.pargs.memcached or
self.app.pargs.netdata or
self.app.pargs.proftpd or
self.app.pargs.redis or
self.app.pargs.fail2ban):
self.app.pargs.nginx = True
@@ -212,12 +233,6 @@ class WOStackStatusController(CementBaseController):
Log.warn(self, "Remote MySQL found, "
"Unable to check MySQL service status")
if self.app.pargs.memcached:
if WOAptGet.is_installed(self, 'memcached'):
services = services + ['memcached']
else:
Log.info(self, "Memcached is not installed")
if self.app.pargs.redis:
if WOAptGet.is_installed(self, 'redis-server'):
services = services + ['redis-server']
@@ -226,10 +241,24 @@ class WOStackStatusController(CementBaseController):
if self.app.pargs.fail2ban:
if WOAptGet.is_installed(self, 'fail2ban'):
services = services + ['fail2ban-client']
services = services + ['fail2ban']
else:
Log.info(self, "fail2ban is not installed")
# proftpd
if self.app.pargs.proftpd:
if WOAptGet.is_installed(self, 'proftpd-basic'):
services = services + ['proftpd']
else:
Log.info(self, "ProFTPd is not installed")
# netdata
if self.app.pargs.netdata:
if os.path.isdir("/opt/netdata"):
services = services + ['netdata']
else:
Log.info(self, "Netdata is not installed")
for service in services:
Log.debug(self, "Restarting service: {0}".format(service))
WOService.restart_service(self, service)
@@ -241,7 +270,8 @@ class WOStackStatusController(CementBaseController):
if not (self.app.pargs.nginx or self.app.pargs.php or
self.app.pargs.php73 or
self.app.pargs.mysql or
self.app.pargs.memcached or
self.app.pargs.netdata or
self.app.pargs.proftpd or
self.app.pargs.redis or
self.app.pargs.fail2ban):
self.app.pargs.nginx = True
@@ -284,12 +314,6 @@ class WOStackStatusController(CementBaseController):
Log.warn(self, "Remote MySQL found, "
"Unable to check MySQL service status")
if self.app.pargs.memcached:
if WOAptGet.is_installed(self, 'memcached'):
services = services + ['memcached']
else:
Log.info(self, "Memcached is not installed")
if self.app.pargs.redis:
if WOAptGet.is_installed(self, 'redis-server'):
services = services + ['redis-server']
@@ -298,10 +322,24 @@ class WOStackStatusController(CementBaseController):
if self.app.pargs.fail2ban:
if WOAptGet.is_installed(self, 'fail2ban'):
services = services + ['fail2ban-client']
services = services + ['fail2ban']
else:
Log.info(self, "fail2ban is not installed")
# proftpd
if self.app.pargs.proftpd:
if WOAptGet.is_installed(self, 'proftpd-basic'):
services = services + ['proftpd']
else:
Log.info(self, "ProFTPd is not installed")
# netdata
if self.app.pargs.netdata:
if os.path.isdir("/opt/netdata"):
services = services + ['netdata']
else:
Log.info(self, "Netdata is not installed")
for service in services:
if WOService.get_service_status(self, service):
Log.info(self, "{0:10}: {1}".format(service, "Running"))
@@ -313,7 +351,8 @@ class WOStackStatusController(CementBaseController):
if not (self.app.pargs.nginx or self.app.pargs.php or
self.app.pargs.php73 or
self.app.pargs.mysql or
self.app.pargs.memcached or
self.app.pargs.netdata or
self.app.pargs.proftpd or
self.app.pargs.redis or
self.app.pargs.fail2ban):
self.app.pargs.nginx = True
@@ -357,12 +396,6 @@ class WOStackStatusController(CementBaseController):
Log.warn(self, "Remote MySQL found, "
"Unable to check MySQL service status")
if self.app.pargs.memcached:
if WOAptGet.is_installed(self, 'memcached'):
services = services + ['memcached']
else:
Log.info(self, "Memcached is not installed")
if self.app.pargs.redis:
if WOAptGet.is_installed(self, 'redis-server'):
services = services + ['redis-server']
@@ -371,10 +404,24 @@ class WOStackStatusController(CementBaseController):
if self.app.pargs.fail2ban:
if WOAptGet.is_installed(self, 'fail2ban'):
services = services + ['fail2ban-client']
services = services + ['fail2ban']
else:
Log.info(self, "fail2ban is not installed")
# proftpd
if self.app.pargs.proftpd:
if WOAptGet.is_installed(self, 'proftpd-basic'):
services = services + ['proftpd']
else:
Log.info(self, "ProFTPd is not installed")
# netdata
if self.app.pargs.netdata:
if os.path.isdir("/opt/netdata"):
services = services + ['netdata']
else:
Log.info(self, "Netdata is not installed")
for service in services:
Log.debug(self, "Reloading service: {0}".format(service))
WOService.reload_service(self, service)

View File

@@ -38,6 +38,10 @@ class WOStackUpgradeController(CementBaseController):
dict(help='Upgrade Redis', action='store_true')),
(['--netdata'],
dict(help='Upgrade Netdata', action='store_true')),
(['--composer'],
dict(help='Upgrade Composer', action='store_true')),
(['--phpmyadmin'],
dict(help='Upgrade phpMyAdmin', action='store_true')),
(['--no-prompt'],
dict(help="Upgrade Packages without any prompt",
action='store_true')),
@@ -83,7 +87,9 @@ class WOStackUpgradeController(CementBaseController):
if ((not self.app.pargs.web) and (not self.app.pargs.nginx) and
(not self.app.pargs.php) and (not self.app.pargs.mysql) and
(not self.app.pargs.all) and (not self.app.pargs.wpcli) and
(not self.app.pargs.netdata) and (not self.app.pargs.redis)):
(not self.app.pargs.netdata) and (not self.app.pargs.composer) and
(not self.app.pargs.phpmyadmin) and
(not self.app.pargs.redis)):
self.app.pargs.web = True
if self.app.pargs.all:
@@ -144,6 +150,26 @@ class WOStackUpgradeController(CementBaseController):
'kickstart-static64.sh',
'/var/lib/wo/tmp/kickstart.sh',
'Netdata']]
if self.app.pargs.phpmyadmin:
if os.path.isdir('/var/www/22222/htdocs/db/pma'):
packages = packages + \
[["https://files.phpmyadmin.net"
"/phpMyAdmin/{0}/"
"phpMyAdmin-{0}-"
"all-languages"
".zip".format(WOVariables.wo_phpmyadmin),
"/var/lib/wo/tmp/pma.tar.gz",
"PHPMyAdmin"]]
else:
Log.error(self, "phpMyAdmin isn't installed")
if self.app.pargs.composer:
if os.path.isfile('/usr/local/bin/composer'):
packages = packages + [["https://getcomposer.org/installer",
"/var/lib/wo/tmp/composer-install",
"Composer"]]
else:
Log.error(self, "Composer isn't installed")
if len(packages) or len(apt_packages):
@@ -191,6 +217,34 @@ class WOStackUpgradeController(CementBaseController):
"kickstart.sh "
"--dont-wait")
if self.app.pargs.composer:
Log.info(self, "Upgrading Composer, please wait...")
WOShellExec.cmd_exec(self, "php -q /var/lib/wo"
"/tmp/composer-install "
"--install-dir=/var/lib/wo/tmp/")
shutil.copyfile('/var/lib/wo/tmp/composer.phar',
'/usr/local/bin/composer')
WOFileUtils.chmod(self, "/usr/local/bin/composer", 0o775)
if self.app.pargs.phpmyadmin:
Log.info(self, "Upgrading phpMyAdmin, please wait...")
WOExtract.extract(
self, '/var/lib/wo/tmp/pma.tar.gz', '/var/lib/wo/tmp/')
shutil.copyfile('{0}22222/htdocs/db/pma'
'/config.inc.php'
.format(WOVariables.wo_webroot),
'/var/lib/wo/tmp/phpMyAdmin-{0}'
'-all-languages/config.inc.php'
.format(WOVariables.wo_phpmyadmin)
)
WOFileUtils.remove(self, '{0}22222/htdocs/db/pma'
.format(WOVariables.wo_webroot))
shutil.move('/var/lib/wo/tmp/phpMyAdmin-{0}'
'-all-languages/'
.format(WOVariables.wo_phpmyadmin),
'{0}22222/htdocs/db/pma/'
.format(WOVariables.wo_webroot))
Log.info(self, "Successfully updated packages")
else:
self.app.args.print_help()

View File

@@ -25,6 +25,9 @@ class WOUpdateController(CementBaseController):
(['--preserve'],
dict(help='Preserve current Nginx configuration',
action='store_true')),
(['--beta'],
dict(help='Update WordOps to latest beta release',
action='store_true')),
(['--travis'],
dict(help='Argument used only for WordOps development',
action='store_true')),
@@ -36,51 +39,33 @@ class WOUpdateController(CementBaseController):
filename = "woupdate" + time.strftime("%Y%m%d-%H%M%S")
if self.app.pargs.travis:
WODownload.download(self, [["https://raw.githubusercontent.com/"
"WordOps/WordOps/updating-configuration/install",
"/tmp/{0}".format(filename),
"update script"]])
try:
Log.info(self, "updating WordOps, please wait...")
os.system("bash /tmp/{0} --travis --force".format(filename))
except OSError as e:
Log.debug(self, str(e))
Log.error(self, "WordOps update failed !")
wo_branch = "updating-configuration"
install_args = "--travis --force "
elif self.app.pargs.beta:
wo_branch = "beta"
install_args = ""
else:
WODownload.download(self, [["https://raw.githubusercontent.com/"
"WordOps/WordOps/master/install",
"/tmp/{0}".format(filename),
"update script"]])
if self.app.pargs.force:
try:
Log.info(self, "updating WordOps, please wait...")
os.system("bash /tmp/{0} --force".format(filename))
except OSError as e:
Log.debug(self, str(e))
Log.error(self, "WordOps update failed !")
except Exception as e:
Log.debug(self, str(e))
Log.error(self, "WordOps update failed !")
elif self.app.pargs.preserve:
try:
Log.info(self, "updating WordOps, please wait...")
os.system("bash /tmp/{0} --preserve".format(filename))
except OSError as e:
Log.debug(self, str(e))
Log.error(self, "WordOps update failed !")
except Exception as e:
Log.debug(self, str(e))
Log.error(self, "WordOps update failed !")
else:
try:
Log.info(self, "updating WordOps, please wait...")
os.system("bash /tmp/{0}".format(filename))
except OSError as e:
Log.debug(self, str(e))
Log.error(self, "WordOps update failed !")
except Exception as e:
Log.debug(self, str(e))
Log.error(self, "WordOps update failed !")
wo_branch = "master "
install_args = ""
if self.app.pargs.force:
install_args = install_args + "--force "
if self.app.pargs.preserve:
install_args = install_args + "--preserve "
WODownload.download(self, [["https://raw.githubusercontent.com/"
"WordOps/WordOps/{0}/install"
.format(wo_branch),
"/var/lib/wo/tmp/{0}".format(filename),
"update script"]])
try:
Log.info(self, "updating WordOps, please wait...")
os.system("/bin/bash /var/lib/wo/tmp/{0} "
"-b {1} {2}".format(filename,
wo_branch, install_args))
except OSError as e:
Log.debug(self, str(e))
Log.error(self, "WordOps update failed !")
def load(app):

View File

@@ -17,7 +17,7 @@ maxretry = 5
[nginx-forbidden]
enabled = true
filter = nginx-forbidden
port = http,https
action = iptables-multiport[name="wo-wordpress", port="http,https"]
logpath = /var/log/nginx/*error*.log
findtime = 60
bantime = 6000

View File

@@ -40,6 +40,22 @@ location /wp-content/uploads {
deny all;
}
}
# webp rewrite rules for EWWW testing image
location /wp-content/plugins/ewww-image-optimizer/images {
location ~ \.(png|jpe?g)$ {
add_header Vary "Accept-Encoding";
add_header "Access-Control-Allow-Origin" "*";
add_header Cache-Control "public, no-transform";
access_log off;
log_not_found off;
expires max;
try_files $uri$webp_suffix $uri =404;
}
location ~ \.php$ {
#Prevent Direct Access Of PHP Files From Web Browsers
deny all;
}
}
# Deny access to any files with a .php extension in the uploads directory
# Works in sub-directory installs and also in multisite network
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)

View File

@@ -21,7 +21,7 @@ location = /robots.txt {
}
# fallback for robots.txt with default wordpress rules
location @robots {
return 200 "User-agent: *\nDisallow: /wp-admin/\nAllow: /wp-admin/admin-ajax.php\n";
return 200 "User-agent: *\nDisallow: /wp-admin/\nAllow: /wp-admin/admin-ajax.php\n";
}
# webp rewrite rules for jpg and png images
# try to load alternative image.png.webp before image.png
@@ -36,7 +36,23 @@ location /wp-content/uploads {
try_files $uri$webp_suffix $uri =404;
}
location ~ \.php$ {
#Prevent Direct Access Of PHP Files From Web Browsers
#Prevent Direct Access Of PHP Files From Web Browsers
deny all;
}
}
# webp rewrite rules for EWWW testing image
location /wp-content/plugins/ewww-image-optimizer/images {
location ~ \.(png|jpe?g)$ {
add_header Vary "Accept-Encoding";
add_header "Access-Control-Allow-Origin" "*";
add_header Cache-Control "public, no-transform";
access_log off;
log_not_found off;
expires max;
try_files $uri$webp_suffix $uri =404;
}
location ~ \.php$ {
#Prevent Direct Access Of PHP Files From Web Browsers
deny all;
}
}

View File

@@ -11,10 +11,11 @@ class WOVariables():
"""Intialization of core variables"""
# WordOps version
wo_version = "3.9.5.4"
wo_version = "3.9.6"
# WordOps packages versions
wo_wp_cli = "2.2.0"
wo_adminer = "4.7.1"
wo_phpmyadmin = "4.9.0.1"
# Get WPCLI path
wo_wpcli_path = os.popen('command -v wp | tr "\n" " "').read()
@@ -107,6 +108,10 @@ class WOVariables():
wo_nginx_repo = ("deb http://download.opensuse.org"
"/repositories/home:"
"/virtubox:/WordOps/Debian_9.0/ /")
elif wo_platform_codename == 'buster':
wo_nginx_repo = ("deb http://download.opensuse.org"
"/repositories/home:"
"/virtubox:/WordOps/Debian_10/ /")
else:
wo_nginx_repo = ("deb http://download.opensuse.org/repositories/home:"
"/virtubox:/WordOps/Raspbian_9.0/ /")
@@ -145,7 +150,8 @@ class WOVariables():
"php7.3-bcmath", "php7.3-mysql", "php7.3-opcache",
"php7.3-zip", "php7.3-xml", "php7.3-soap"]
wo_php_extra = ["php-memcached", "php-imagick",
"graphviz", "php-xdebug", "php-msgpack", "php-redis"]
"graphviz", "php-xdebug", "php-msgpack",
"php-redis", "php-mysql"]
wo_php_key = 'AC0E47584A7A714D'
@@ -162,7 +168,7 @@ class WOVariables():
.format(codename=wo_platform_codename))
wo_mysql = ["mariadb-server", "percona-toolkit", "python3-mysqldb"]
wo_fail2ban = "fail2ban"
wo_fail2ban = ["fail2ban", "python3-pyinotify"]
# Redis repo details
if wo_platform_distro == 'ubuntu':