diff --git a/README.md b/README.md index 1b8cbe4..8b059ec 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -

- WordOps +

Wordops +
-

+

An essential toolset that eases WordPress site and server administration

diff --git a/install b/install index 05113d3..732770b 100644 --- a/install +++ b/install @@ -7,10 +7,10 @@ # Copyright (c) 2019 - WordOps # This script is licensed under M.I.T # ------------------------------------------------------------------------- -# Version 3.9.5 - 2019-04-03 +# Version 3.9.5 - 2019-04-05 # ------------------------------------------------------------------------- readonly wo_version_old="2.2.3" -readonly wo_version_new="3.9.4.3" +readonly wo_version_new="3.9.4.4" # CONTENTS # --- # 1. VARIABLES AND DECLARATIONS @@ -81,7 +81,11 @@ fi ### # 1 - Define variables for later use ### -wo_branch="$1" +if [ -n "$1" ]; then + wo_branch="$1" +else + wo_branch="master" +fi readonly wo_log_dir=/var/log/wo/ readonly wo_backup_dir=/var/lib/wo-backup/ readonly wo_install_log=/var/log/wo/install.log @@ -381,10 +385,6 @@ wo_install() { rm -rf /tmp/easyengine rm -rf /tmp/wordops - [ -z "$wo_branch" ] && { - wo_branch=master - } - git clone -b "$wo_branch" https://github.com/WordOps/WordOps.git /tmp/wordops --quiet cd /tmp/wordops || exit 1 diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..2fe842e Binary files /dev/null and b/logo.png differ diff --git a/wo/cli/plugins/site.py b/wo/cli/plugins/site.py index 439bd1a..1c85972 100644 --- a/wo/cli/plugins/site.py +++ b/wo/cli/plugins/site.py @@ -753,6 +753,11 @@ class WOSiteUpdateController(CementBaseController): action='store' or 'store_const', choices=('on', 'off', 'renew', 'subdomain', 'wildcard'), const='on', nargs='?')), + (['--hsts'], + dict(help="configure hsts on site secured with letsencrypt", + action='store' or 'store_const', + choices=('on', 'off'), + const='on', nargs='?')), (['--proxy'], dict(help="update to proxy site", nargs='+')), (['--experimental'], @@ -1073,6 +1078,16 @@ class WOSiteUpdateController(CementBaseController): elif pargs.letsencrypt == 'off': data['letsencrypt'] = False letsencrypt = False + data['hsts'] = False + hsts = False + + if pargs.hsts: + if pargs.hsts == 'on': + data['hsts'] = True + hsts = True + elif pargs.hsts == 'off': + data['hsts'] = False + hsts = False if letsencrypt is check_ssl: if letsencrypt is False: @@ -1170,12 +1185,23 @@ class WOSiteUpdateController(CementBaseController): .format(wo_site_webroot)) httpsRedirect(self, wo_domain) + if data['hsts'] is True: + if not os.path.isfile(("{0}/conf/nginx/hsts.conf.disabled") + .format(wo_site_webroot)): + setupHsts(self, wo_domain) + else: + WOFileUtils.mvfile(self, "{0}/conf/nginx/" + "hsts.conf.disabled" + .format(wo_site_webroot), + '{0}/conf/nginx/hsts.conf' + .format(wo_site_webroot)) 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 " + Log.info(self, "Congratulations! Successfully " + "Configured SSl for Site " " https://{0}".format(wo_domain)) if (SSL.getExpirationDays(self, wo_domain) > 0): @@ -1194,6 +1220,12 @@ class WOSiteUpdateController(CementBaseController): '{0}/conf/nginx/ssl.conf.disabled' .format(wo_site_webroot)) 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 not WOService.reload_service(self, 'nginx'): Log.error(self, "service nginx reload failed. " "check issues with `nginx -t` command") @@ -1217,6 +1249,16 @@ class WOSiteUpdateController(CementBaseController): .format(wo_site_webroot)) httpsRedirect(self, wo_domain) + if data['hsts'] is True: + if not os.path.isfile(("{0}/conf/nginx/hsts.conf.disabled") + .format(wo_site_webroot)): + setupHsts(self, wo_domain) + else: + WOFileUtils.mvfile(self, "{0}/conf/nginx/" + "hsts.conf.disabled" + .format(wo_site_webroot), + '{0}/conf/nginx/hsts.conf' + .format(wo_site_webroot)) if not WOService.reload_service(self, 'nginx'): Log.error(self, "service nginx reload failed. " @@ -1243,6 +1285,14 @@ class WOSiteUpdateController(CementBaseController): '{0}/conf/nginx/ssl.conf.disabled' .format(wo_site_webroot)) 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 not WOService.reload_service(self, 'nginx'): Log.error(self, "service nginx reload failed. " "check issues with `nginx -t` command") @@ -1269,7 +1319,8 @@ class WOSiteUpdateController(CementBaseController): "check issues with `nginx -t` command") updateSiteInfo(self, wo_domain, stype=stype, cache=cache, - ssl=True if check_site.is_ssl else False, php_version=check_php_version) + ssl=True if check_site.is_ssl else False, + php_version=check_php_version) Log.info(self, "Successfully updated site" " http://{0}".format(wo_domain)) @@ -1327,44 +1378,94 @@ class WOSiteUpdateController(CementBaseController): Log.debug(self, str(e)) Log.info(self, Log.FAIL + "Update site failed. " "Check the log for details:" - " `tail /var/log/wo/wordops.log` and please try again") + " `tail /var/log/wo/wordops.log` " + "and please try again") return 1 if ((oldcachetype in ['wpsc', 'basic', 'wpredis'] and (data['wpfc'])) or (oldsitetype == 'wp' and data['multisite'] and data['wpfc'])): try: - plugin_data = '{"log_level":"INFO","log_filesize":5,"enable_purge":1,"enable_map":0,"enable_log":0,"enable_stamp":0,"purge_homepage_on_new":1,"purge_homepage_on_edit":1,"purge_homepage_on_del":1,"purge_archive_on_new":1,"purge_archive_on_edit":0,"purge_archive_on_del":0,"purge_archive_on_new_comment":0,"purge_archive_on_deleted_comment":0,"purge_page_on_mod":1,"purge_page_on_new_comment":1,"purge_page_on_deleted_comment":1,"cache_method":"enable_fastcgi","purge_method":"get_request","redis_hostname":"127.0.0.1","redis_port":"6379","redis_prefix":"nginx-cache:"}' + plugin_data = '{"log_level":"INFO","log_filesize":5,' + '"enable_purge":1,"enable_map":0,"enable_log":0,' + '"enable_stamp":0,"purge_homepage_on_new":1,' + '"purge_homepage_on_edit":1,"purge_homepage_on_del":1,' + '"purge_archive_on_new":1,"purge_archive_on_edit":0,' + '"purge_archive_on_del":0,"purge_archive_on_new_comment":0,' + '"purge_archive_on_deleted_comment":0,"purge_page_on_mod":1,' + '"purge_page_on_new_comment":1,' + '"purge_page_on_deleted_comment":1,' + '"cache_method":"enable_fastcgi",' + '"purge_method":"get_request",' + '"redis_hostname":"127.0.0.1","redis_port":"6379",' + '"redis_prefix":"nginx-cache:"}' setupwp_plugin( - self, 'nginx-helper', 'rt_wp_nginx_helper_options', plugin_data, data) + self, 'nginx-helper', + 'rt_wp_nginx_helper_options', plugin_data, data) except SiteError as e: Log.debug(self, str(e)) - Log.info(self, Log.FAIL + "Update nginx-helper settings failed. " + Log.info(self, Log.FAIL + "Update nginx-helper " + "settings failed. " "Check the log for details:" - " `tail /var/log/wo/wordops.log` and please try again") + " `tail /var/log/wo/wordops.log` " + "and please try again") return 1 elif ((oldcachetype in ['wpsc', 'basic', 'wpfc'] and - (data['wpredis'])) or (oldsitetype == 'wp' and data['multisite'] and data['wpredis'])): + (data['wpredis'])) or (oldsitetype == 'wp' and + data['multisite'] and data['wpredis'])): try: - plugin_data = '{"log_level":"INFO","log_filesize":5,"enable_purge":1,"enable_map":0,"enable_log":0,"enable_stamp":0,"purge_homepage_on_new":1,"purge_homepage_on_edit":1,"purge_homepage_on_del":1,"purge_archive_on_new":1,"purge_archive_on_edit":0,"purge_archive_on_del":0,"purge_archive_on_new_comment":0,"purge_archive_on_deleted_comment":0,"purge_page_on_mod":1,"purge_page_on_new_comment":1,"purge_page_on_deleted_comment":1,"cache_method":"enable_redis","purge_method":"get_request","redis_hostname":"127.0.0.1","redis_port":"6379","redis_prefix":"nginx-cache:"}' + plugin_data = '{"log_level":"INFO","log_filesize":5,' + '"enable_purge":1,"enable_map":0,"enable_log":0,' + '"enable_stamp":0,"purge_homepage_on_new":1,' + '"purge_homepage_on_edit":1,"purge_homepage_on_del":1,' + '"purge_archive_on_new":1,"purge_archive_on_edit":0,' + '"purge_archive_on_del":0,' + '"purge_archive_on_new_comment":0,' + '"purge_archive_on_deleted_comment":0,' + '"purge_page_on_mod":1,' + '"purge_page_on_new_comment":1,' + '"purge_page_on_deleted_comment":1,' + '"cache_method":"enable_redis",' + '"purge_method":"get_request",' + '"redis_hostname":"127.0.0.1","redis_port":"6379",' + '"redis_prefix":"nginx-cache:"}' setupwp_plugin( - self, 'nginx-helper', 'rt_wp_nginx_helper_options', plugin_data, data) + self, 'nginx-helper', + 'rt_wp_nginx_helper_options', plugin_data, data) except SiteError as e: Log.debug(self, str(e)) - Log.info(self, Log.FAIL + "Update nginx-helper settings failed. " + Log.info(self, Log.FAIL + "Update nginx-helper " + "settings failed. " "Check the log for details:" - " `tail /var/log/wo/wordops.log` and please try again") + " `tail /var/log/wo/wordops.log` " + "and please try again") return 1 else: try: - plugin_data = '{"log_level":"INFO","log_filesize":5,"enable_purge":0,"enable_map":0,"enable_log":0,"enable_stamp":0,"purge_homepage_on_new":1,"purge_homepage_on_edit":1,"purge_homepage_on_del":1,"purge_archive_on_new":1,"purge_archive_on_edit":0,"purge_archive_on_del":0,"purge_archive_on_new_comment":0,"purge_archive_on_deleted_comment":0,"purge_page_on_mod":1,"purge_page_on_new_comment":1,"purge_page_on_deleted_comment":1,"cache_method":"enable_redis","purge_method":"get_request","redis_hostname":"127.0.0.1","redis_port":"6379","redis_prefix":"nginx-cache:"}' + plugin_data = '{"log_level":"INFO","log_filesize":5,' + '"enable_purge":0,"enable_map":0,"enable_log":0,' + '"enable_stamp":0,"purge_homepage_on_new":1,' + '"purge_homepage_on_edit":1,"purge_homepage_on_del":1,' + '"purge_archive_on_new":1,"purge_archive_on_edit":0,' + '"purge_archive_on_del":0,' + '"purge_archive_on_new_comment":0,' + '"purge_archive_on_deleted_comment":0,' + '"purge_page_on_mod":1,"purge_page_on_new_comment":1,' + '"purge_page_on_deleted_comment":1,' + '"cache_method":"enable_redis",' + '"purge_method":"get_request",' + '"redis_hostname":"127.0.0.1",' + '"redis_port":"6379","redis_prefix":"nginx-cache:"}' setupwp_plugin( - self, 'nginx-helper', 'rt_wp_nginx_helper_options', plugin_data, data) + self, 'nginx-helper', + 'rt_wp_nginx_helper_options', plugin_data, data) except SiteError as e: Log.debug(self, str(e)) - Log.info(self, Log.FAIL + "Update nginx-helper settings failed. " + Log.info(self, Log.FAIL + "Update nginx-helper " + "settings failed. " "Check the log for details:" - " `tail /var/log/wo/wordops.log` and please try again") + " `tail /var/log/wo/wordops.log` " + "and please try again") return 1 if oldcachetype == 'wpsc' and not data['wpsc']: @@ -1374,7 +1475,8 @@ class WOSiteUpdateController(CementBaseController): Log.debug(self, str(e)) Log.info(self, Log.FAIL + "Update site failed." "Check the log for details:" - " `tail /var/log/wo/wordops.log` and please try again") + " `tail /var/log/wo/wordops.log` " + "and please try again") return 1 if oldcachetype == 'wpredis' and not data['wpredis']: @@ -1384,7 +1486,8 @@ class WOSiteUpdateController(CementBaseController): Log.debug(self, str(e)) Log.info(self, Log.FAIL + "Update site failed." "Check the log for details:" - " `tail /var/log/wo/wordops.log` and please try again") + " `tail /var/log/wo/wordops.log` " + "and please try again") return 1 if oldcachetype != 'wpsc' and data['wpsc']: @@ -1401,10 +1504,12 @@ class WOSiteUpdateController(CementBaseController): try: if installwp_plugin(self, 'redis-cache', data): # search for wp-config.php - if WOFileUtils.isexist(self, "{0}/wp-config.php".format(wo_site_webroot)): + if WOFileUtils.isexist(self, "{0}/wp-config.php" + .format(wo_site_webroot)): config_path = '{0}/wp-config.php'.format( wo_site_webroot) - elif WOFileUtils.isexist(self, "{0}/htdocs/wp-config.php".format(wo_site_webroot)): + elif WOFileUtils.isexist(self, "{0}/htdocs/wp-config.php" + .format(wo_site_webroot)): config_path = '{0}/htdocs/wp-config.php'.format( wo_site_webroot) else: diff --git a/wo/cli/plugins/site_functions.py b/wo/cli/plugins/site_functions.py index fb779aa..8b49670 100644 --- a/wo/cli/plugins/site_functions.py +++ b/wo/cli/plugins/site_functions.py @@ -96,8 +96,8 @@ def setupdomain(self, data): Log.info(self, "[" + Log.ENDC + "Done" + Log.OKBLUE + "]") except CalledProcessError as e: Log.debug(self, "{0}".format(str(e))) - Log.info(self, "[" + Log.ENDC + Log.FAIL + "Fail" - + Log.OKBLUE + "]") + Log.info(self, "[" + Log.ENDC + Log.FAIL + "Fail" + + Log.OKBLUE + "]") raise SiteError("created nginx configuration failed for site." " check with `nginx -t`") @@ -312,8 +312,8 @@ def setupwordpress(self, data): "--dbuser=\'{2}\' --dbhost=\'{3}\' " .format(data['wo_db_name'], wo_wp_prefix, data['wo_db_user'], data['wo_db_host'] - ) - + "--dbpass=\'{0}\' " + ) + + "--dbpass=\'{0}\' " "--extra-php<.* "POST .*/wp-login.php([/\?#\\].*)? HTTP/.*" 200 +ignoreregex = diff --git a/wo/cli/templates/fail2ban.mustache b/wo/cli/templates/fail2ban.mustache new file mode 100644 index 0000000..10937f6 --- /dev/null +++ b/wo/cli/templates/fail2ban.mustache @@ -0,0 +1,24 @@ +[recidive] +enabled = true + +[nginx-http-auth] +enabled = true + +[nginx-botsearch] +enabled = true + +[wo-wordpress] +enabled = true +filter = wo-wordpress +action = iptables-multiport[name="wo-wordpress", port="http,https"] +logpath = /var/log/nginx/*access.log +maxretry = 5 + +[nginx-forbidden] +enabled = true +filter = nginx-forbidden +port = http,https +logpath = /var/log/nginx/*error*.log +findtime = 60 +bantime = 6000 +maxretry = 3 \ No newline at end of file diff --git a/wo/core/variables.py b/wo/core/variables.py index ab2eb2b..2aa6237 100644 --- a/wo/core/variables.py +++ b/wo/core/variables.py @@ -152,6 +152,8 @@ class WOVariables(): wo_mysql = ["mariadb-server", "percona-toolkit"] + wo_fail2ban = "fail2ban" + # Redis repo details if wo_platform_distro == 'ubuntu': wo_redis_repo = ("ppa:chris-lea/redis-server")