diff --git a/config/plugins.d/secure.conf b/config/plugins.d/secure.conf new file mode 100644 index 00000000..b70f167b --- /dev/null +++ b/config/plugins.d/secure.conf @@ -0,0 +1,8 @@ +### Example Plugin Configuration for EasyEngine + +[secure] + +### If enabled, load a plugin named `example` either from the Python module +### `ee.cli.plugins.example` or from the file path +### `/var/lib/ee/plugins/example.py` +enable_plugin = true diff --git a/ee/cli/plugins/clean.py b/ee/cli/plugins/clean.py index 1cf8575c..21138e3b 100644 --- a/ee/cli/plugins/clean.py +++ b/ee/cli/plugins/clean.py @@ -4,6 +4,7 @@ from ee.core.services import EEService from cement.core.controller import CementBaseController, expose from cement.core import handler, hook import os +import urllib.request def clean_plugin_hook(app): @@ -48,31 +49,30 @@ class EECleanController(CementBaseController): @expose(hide=True) def clean_memcache(self): - print("in memcache..") if(EEAptGet.is_installed("memcached")): - print("memcache is installed...") + self.app.log.info("memcache is installed") EEService.restart_service(self, "memcached") - print("Cleaning memcache..") + self.app.log.info("Cleaning memcache..") else: - print("memcache is not installed..") + self.app.log.info("memcache is not installed") @expose(hide=True) def clean_fastcgi(self): if(os.path.isdir("/var/run/nginx-cache")): - print("Cleaning fastcgi...") + self.app.log.info("Cleaning fastcgi...") EEShellExec.cmd_exec(self, "rm -rf /var/run/nginx-cache/*") else: - print("Error occur while Cleaning fastcgi..") + self.app.log.info("Error occur while Cleaning fastcgi..") @expose(hide=True) def clean_opcache(self): try: - print("Cleaning opcache.... ") - EEShellExec.cmd_exec(self, "wget --no-check-certificate --spider" - " -q https://127.0.0.1:22222/cache/opcache" - "/opgui.php?page=reset") - except OSError: - print("Unable to clean opache..") + self.app.log.info("Cleaning opcache.... ") + wp = urllib.request.urlopen(" https://127.0.0.1:22222/cache" + "/opcache/opgui.php?page=reset").read() + except Exception as e: + self.app.log.info("Unable to clean opacache\n {0}{1}" + .format(e.errno, e.strerror)) def load(app): diff --git a/ee/cli/plugins/debug.py b/ee/cli/plugins/debug.py index 63397c3e..b181dc29 100644 --- a/ee/cli/plugins/debug.py +++ b/ee/cli/plugins/debug.py @@ -57,7 +57,8 @@ class EEDebugController(CementBaseController): for ip_addr in debug_address: if not ("debug_connection "+ip_addr in open('/etc/nginx/' 'nginx.conf').read()): - print("Setting up NGINX debug connection for "+ip_addr) + self.app.log.info("Setting up NGINX debug connection" + " for "+ip_addr) EEShellExec.cmd_exec(self, "sed -i \"/events {{/a\\ \\ \\ " "\\ $(echo debug_connection " "{ip}\;)\" /etc/nginx/" @@ -65,19 +66,19 @@ class EEDebugController(CementBaseController): self.trigger_nginx = True if not self.trigger_nginx: - print("NGINX debug connection already enabled") + self.app.log.info("NGINX debug connection already enabled") self.msg = self.msg + [" /var/log/nginx/*.error.log"] # stop global debug elif not self.start and not self.app.pargs.site_name: if "debug_connection " in open('/etc/nginx/nginx.conf').read(): - print("Disabling Nginx debug connections") + self.app.log.info("Disabling Nginx debug connections") EEShellExec.cmd_exec(self, "sed -i \"/debug_connection.*/d\"" " /etc/nginx/nginx.conf") self.trigger_nginx = True else: - print("Nginx debug connection already disbaled") + self.app.log.info("Nginx debug connection already disbaled") # start site specific debug elif self.start and self.app.pargs.site_name: @@ -86,20 +87,22 @@ class EEDebugController(CementBaseController): if os.path.isfile(config_path): if not EEShellExec.cmd_exec("grep \"error.log debug\" {0}" .format(config_path)): - print("Starting NGINX debug connection for {0}" - .format(self.app.pargs.site_name)) + self.app.log.info("Starting NGINX debug connection for " + "{0}" + .format(self.app.pargs.site_name)) EEShellExec.cmd_exec("sed -i \"s/error.log;/error.log " "debug;/\" {0}".format(config_path)) self.trigger_nginx = True else: - print("Debug for site allready enabled") + self.app.log.info("Debug for site allready enabled") self.msg = self.msg + ['/var/www//logs/error.log' .format(self.app.pargs.site_name)] else: - print("{0} domain not valid".format(self.app.pargs.site_name)) + self.app.log.info("{0} domain not valid" + .format(self.app.pargs.site_name)) # stop site specific debug elif not self.start and self.app.pargs.site_name: @@ -108,18 +111,19 @@ class EEDebugController(CementBaseController): if os.path.isfile(config_path): if EEShellExec.cmd_exec("grep \"error.log debug\" {0}" .format(config_path)): - print("Stoping NGINX debug connection for {0}" - .format(self.app.pargs.site_name)) + self.app.log.info("Stoping NGINX debug connection for {0}" + .format(self.app.pargs.site_name)) EEShellExec.cmd_exec("sed -i \"s/error.log debug;/" "error.log;/\" {0}" .format(config_path)) self.trigger_nginx = True else: - print("Debug for site allready disbaled") + self.app.log.info("Debug for site allready disbaled") else: - print("{0} domain not valid".format(self.app.pargs.site_name)) + self.app.log.info("{0} domain not valid" + .format(self.app.pargs.site_name)) @expose(hide=True) def debug_php(self): @@ -129,16 +133,16 @@ class EEDebugController(CementBaseController): "{/,/}/p \" /etc/nginx/" "conf.d/upstream.conf " "| grep 9001")): - print("Enabling PHP debug") + self.app.log.info("Enabling PHP debug") data = dict(php="9001", debug="9001") - self.app.log.debug('writting the nginx configration to file' - '/etc/nginx/conf.d/upstream.conf ') + self.app.log.info('writting the nginx configration to file' + '/etc/nginx/conf.d/upstream.conf ') ee_nginx = open('/etc/nginx/conf.d/upstream.conf', 'w') self.app.render((data), 'upstream.mustache', out=ee_nginx) ee_nginx.close() self.trigger_php = True else: - print("PHP debug is allready enabled") + self.app.log.info("PHP debug is allready enabled") self.msg = self.msg + ['/var/log/php5/slow.log'] @@ -147,16 +151,16 @@ class EEDebugController(CementBaseController): if EEShellExec.cmd_exec(self, "sed -n \"/upstream php {/,/}/p\" " "/etc/nginx/conf.d/upstream.conf " "| grep 9001"): - print("Disabling PHP debug") + self.app.log.info("Disabling PHP debug") data = dict(php="9000", debug="9001") - self.app.log.debug('writting the nginx configration to file' - '/etc/nginx/conf.d/upstream.conf ') + self.app.log.info('writting the nginx configration to file' + '/etc/nginx/conf.d/upstream.conf ') ee_nginx = open('/etc/nginx/conf.d/upstream.conf', 'w') self.app.render((data), 'upstream.mustache', out=ee_nginx) ee_nginx.close() self.trigger_php = True else: - print("PHP debug is allready disbaled") + self.app.log.info("PHP debug is allready disbaled") @expose(hide=True) def debug_fpm(self): @@ -164,26 +168,27 @@ class EEDebugController(CementBaseController): if self.start: if not EEShellExec.cmd_exec(self, "grep \"log_level = debug\" " "/etc/php5/fpm/php-fpm.conf"): - print("Setting up PHP5-FPM log_level = debug") + self.app.log.info("Setting up PHP5-FPM log_level = debug") EEShellExec.cmd_exec(self, "sed -i \"s\';log_level.*\'log_" "level = debug\'\" /etc/php5/fpm" "/php-fpm.conf") self.trigger_php = True else: - print("PHP5-FPM log_level = debug already setup") + self.app.log.info("PHP5-FPM log_level = debug already setup") self.msg = self.msg + ['/var/log/php5/fpm.log'] # PHP5-FPM stop global debug else: if EEShellExec.cmd_exec(self, "grep \"log_level = debug\" " "/etc/php5/fpm/php-fpm.conf"): - print("Disabling PHP5-FPM log_level = debug") + self.app.log.info("Disabling PHP5-FPM log_level = debug") EEShellExec.cmd_exec(self, "sed -i \"s\'log_level.*\';log_" "level = notice\'\" /etc/php5/fpm" "/php-fpm.conf") self.trigger_php = True else: - print("PHP5-FPM log_level = debug already disabled") + self.app.log.info("PHP5-FPM log_level = debug " + " already disabled") @expose(hide=True) def debug_mysql(self): @@ -213,7 +218,7 @@ class EEDebugController(CementBaseController): "n#EasyEngine end MySQL slow log\\\";" " }} | crontab -\"".format(cron_time)) else: - print("MySQL slow log is allready enabled") + self.app.log.info("MySQL slow log is allready enabled") self.msg = self.msg + ['/var/log/mysql/mysql-slow.log'] @@ -231,7 +236,7 @@ class EEDebugController(CementBaseController): EEShellExec.cmd_exec(self, "crontab -l | sed \'/#EasyEngine " "start/,/#EasyEngine end/d\' | crontab -") else: - print("MySQL slow log already disabled") + self.app.log.info("MySQL slow log already disabled") @expose(hide=True) def debug_wp(self): @@ -242,7 +247,7 @@ class EEDebugController(CementBaseController): if os.path.isfile(wp_config): if not EEShellExec.cmd_exec(self, "grep \"\'WP_DEBUG\'\" {0} |" " grep true".format(wp_config)): - print("Starting WordPress debug") + self.app.log.info("Starting WordPress debug") open("{0}/htdocs/wp-content/debug.log".format(webroot), 'a').close() EEShellExec.cmd_exec(self, "chown www-data: {0}/htdocs/wp-" @@ -260,9 +265,10 @@ class EEDebugController(CementBaseController): "wp-content/plugins" .format(webroot)) else: - print("WordPress debug log already enabled") + self.app.log.info("WordPress debug log already enabled") else: - print("{0} domain not valid".format(self.app.pargs.site_name)) + self.app.log.info("{0} domain not valid" + .format(self.app.pargs.site_name)) elif not self.start and self.app.pargs.site_name: wp_config = ("/var/www/{0}/wp-config.php" @@ -271,7 +277,7 @@ class EEDebugController(CementBaseController): if os.path.isfile(wp_config): if EEShellExec.cmd_exec(self, "grep \"\'WP_DEBUG\'\" {0} | " "grep true".format(wp_config)): - print("Disabling WordPress debug") + self.app.log.info("Disabling WordPress debug") EEShellExec.cmd_exec(self, "sed -i \"s/define(\'WP_DEBUG\'" ", true);/define(\'WP_DEBUG\', " "false);/\" {0}".format(wp_config)) @@ -287,9 +293,10 @@ class EEDebugController(CementBaseController): else: print("WordPress debug all already disbaled") else: - print("{0} domain not valid".format(self.app.pargs.site_name)) + self.app.log.info("{0} domain not valid" + .format(self.app.pargs.site_name)) else: - print("Missing argument site_name") + self.app.log.info("Missing argument site_name") @expose(hide=True) def debug_rewrite(self): @@ -297,12 +304,12 @@ class EEDebugController(CementBaseController): if self.start and not self.app.pargs.site_name: if not EEShellExec.cmd_exec(self, "grep \"rewrite_log on;\" " "/etc/nginx/nginx.conf"): - print("Setting up Nginx rewrite logs") + self.app.log.info("Setting up Nginx rewrite logs") EEShellExec.cmd_exec(self, "sed -i \'/http {/a \\\\t" "rewrite_log on;\' /etc/nginx/nginx.conf") self.trigger_nginx = True else: - print("NGINX rewrite logs already enabled") + self.app.log.info("NGINX rewrite logs already enabled") if '/var/log/nginx/*.error.log' not in self.msg: self.msg = self.msg + ['/var/log/nginx/*.error.log'] @@ -311,27 +318,27 @@ class EEDebugController(CementBaseController): elif not self.start and not self.app.pargs.site_name: if EEShellExec.cmd_exec(self, "grep \"rewrite_log on;\" " "/etc/nginx/nginx.conf"): - print("Disabling Nginx rewrite logs") + self.app.log.info("Disabling Nginx rewrite logs") EEShellExec.cmd_exec(self, "sed -i \"/rewrite_log.*/d\"" " /etc/nginx/nginx.conf") self.trigger_nginx = True else: - print("NGINX rewrite logs already disbaled") + self.app.log.info("NGINX rewrite logs already disbaled") # Start Nginx rewrite for site elif self.start and self.app.pargs.site_name: config_path = ("/etc/nginx/sites-available/{0}.conf" .format(self.app.pargs.site_name)) if not EEShellExec.cmd_exec(self, "grep \"rewrite_log on;\" {0}" .format(config_path)): - print("Setting up NGINX rewrite logs for {0}" - .format(self.app.pargs.site_name)) + self.app.log.info("Setting up NGINX rewrite logs for {0}" + .format(self.app.pargs.site_name)) EEShellExec.cmd_exec(self, "sed -i \"/access_log/i \\\\\\t" "rewrite_log on;\" {0}" .format(config_path)) self.trigger_nginx = True else: - print("Nginx rewrite logs for {0} allready setup" - .format(self.app.pargs.site_name)) + self.app.log.info("Nginx rewrite logs for {0} allready setup" + .format(self.app.pargs.site_name)) if ('/var/www/{0}/logs/error.log'.format(self.app.pargs.site_name) not in self.msg): @@ -344,14 +351,15 @@ class EEDebugController(CementBaseController): .format(self.app.pargs.site_name)) if EEShellExec.cmd_exec(self, "grep \"rewrite_log on;\" {0}" .format(config_path)): - print("Disabling NGINX rewrite logs for {0}" - .format(self.app.pargs.site_name)) + self.app.log.info("Disabling NGINX rewrite logs for {0}" + .format(self.app.pargs.site_name)) EEShellExec.cmd_exec(self, "sed -i \"/rewrite_log.*/d\" {0}" .format(config_path)) self.trigger_nginx = True else: - print("Nginx rewrite logs for {0} allready disbaled" - .format(self.app.pargs.site_name)) + self.app.log.info("Nginx rewrite logs for {0} allready " + " disbaled" + .format(self.app.pargs.site_name)) @expose(hide=True) def default(self): @@ -398,8 +406,8 @@ class EEDebugController(CementBaseController): EEService.reload_service(self, ['php5-fpm']) if len(self.msg) > 0: - print("Use following command to check debug logs:\n{0}" - .format(self.msg.join())) + self.app.log.info("Use following command to check debug logs:" + "\n{0}".format(self.msg.join())) def load(app): diff --git a/ee/cli/plugins/secure.py b/ee/cli/plugins/secure.py new file mode 100644 index 00000000..79bcc4cf --- /dev/null +++ b/ee/cli/plugins/secure.py @@ -0,0 +1,113 @@ +from cement.core.controller import CementBaseController, expose +from cement.core import handler, hook +from ee.core.shellexec import EEShellExec +from ee.core.variables import EEVariables +import string +import random +import sys +import hashlib +import getpass + + +def secure_plugin_hook(app): + # do something with the ``app`` object here. + pass + + +class EEsecureController(CementBaseController): + class Meta: + label = 'secure' + stacked_on = 'base' + stacked_type = 'nested' + description = 'clean command cleans different cache with following \ + options' + arguments = [ + (['--auth'], + dict(help='secure auth', action='store_true')), + (['--port'], + dict(help='secure port', action='store_true')), + (['--ip'], + dict(help='secure ip', action='store_true')) + ] + + @expose(hide=True) + def default(self): + if self.app.pargs.auth: + self.secure_auth() + if self.app.pargs.port: + self.secure_port() + if self.app.pargs.ip: + self.secure_ip() + + @expose(hide=True) + def secure_auth(self): + passwd = ''.join([random.choice + (string.ascii_letters + string.digits) + for n in range(6)]) + username = input("Provide HTTP authentication user " + "name [{0}] :".format(EEVariables.ee_user)) + password = input("Provide HTTP authentication " + "password [{0}]".format(passwd)) + if username == "": + username = EEVariables.ee_user + self.app.log.info("HTTP authentication username:{username}" + .format(username=username)) + if password == "": + password = passwd + self.app.log.info("HTTP authentication password:{password}" + .format(password=password)) + EEShellExec.cmd_exec(self, "printf \"{username}:" + "$(openssl passwd -crypt " + "{password} 2> /dev/null)\n\"" + "> /etc/nginx/htpasswd-ee 2>/dev/null" + .format(username=username, + password=password)) + + @expose(hide=True) + def secure_port(self): + port = input("EasyEngine admin port [22222]:") + if port == "": + port = 22222 + if EEVariables.ee_platform_distro == 'Ubuntu': + EEShellExec.cmd_exec(self, "sed -i \"s/listen.*/listen " + "{port} default_server ssl spdy;/\" " + "/etc/nginx/sites-available/22222" + .format(port=port)) + elif EEVariables.ee_platform_distro == 'Debian': + EEShellExec.cmd_exec(self, "sed -i \"s/listen.*/listen " + "{port} default_server ssl;/\" " + "/etc/nginx/sites-available/22222" + .format(port=port)) + + @expose(hide=True) + def secure_ip(self): + #TODO:remaining with ee.conf updation in file + newlist = [] + ip = input("Enter the comma separated IP addresses " + "to white list [127.0.0.1]:") + try: + user_list_ip = ip.split(',') + except Exception as e: + ip = ['127.0.0.1'] + self.app.config.set('mysql', 'grant-host', "hello") + exist_ip_list = self.app.config.get('stack', 'ip-address').split() + print(exist_ip_list) + for check_ip in user_list_ip: + if check_ip not in exist_ip_list: + newlist.extend(exist_ip_list) + # changes in acl.conf file + if len(newlist) != 0: + EEShellExec.cmd_exec(self, "sed -i \"/allow.*/d\" /etc/nginx" + "/common/acl.conf") + for whitelist_adre in newlist: + EEShellExec.cmd_exec(self, "sed -i \"/deny/i " + "echo allow {whitelist_adre}\\;\" " + "/etc/nginx/common/acl.conf" + .format(whitelist_adre=whitelist_adre)) + + +def load(app): + # register the plugin class.. this only happens if the plugin is enabled + handler.register(EEsecureController) + # register a hook (function) to run after arguments are parsed. + hook.register('post_argument_parsing', secure_plugin_hook) diff --git a/ee/cli/plugins/site_functions.py b/ee/cli/plugins/site_functions.py index ba1c42f6..9377e712 100644 --- a/ee/cli/plugins/site_functions.py +++ b/ee/cli/plugins/site_functions.py @@ -6,6 +6,7 @@ import getpass from ee.core.fileutils import EEFileUtils from ee.core.mysql import EEMysql from ee.core.shellexec import EEShellExec +from ee.core.variables import EEVariables def setup_domain(self, data): @@ -64,8 +65,10 @@ def setup_database(self, data): prompt_dbuser = self.app.config.get('mysql', 'db-user') ee_mysql_host = self.app.config.get('mysql', 'grant-host') ee_db_name = '' + ee_db_username = '' + ee_db_password = '' - if prompt_dbname == 'True': + if prompt_dbname == 'True' or prompt_dbname == 'true': try: ee_db_name = input('Enter the MySQL database name [{0}]:' .format(ee_replace_dot)) @@ -76,7 +79,7 @@ def setup_database(self, data): if not ee_db_name: ee_db_name = ee_replace_dot - if prompt_dbuser: + if prompt_dbuser == 'True' or prompt_dbuser == 'true': try: ee_db_username = input('Enter the MySQL database user name [{0}]: ' .format(ee_replace_dot)) @@ -98,17 +101,19 @@ def setup_database(self, data): ee_db_name = (ee_db_name[0:6] + ee_random10) # create MySQL database - EEMysql.execute(self, "create database \'{0}\'" + EEMysql.execute(self, "create database {0}" .format(ee_db_name)) + print("create user {0}@{1} identified by '{2}'" + .format(ee_db_username, ee_mysql_host, ee_db_password)) # Create MySQL User EEMysql.execute(self, - "create user \'{0}\'@\'{1}\' identified by \'{2}\'" + "create user {0}@{1} identified by '{2}'" .format(ee_db_username, ee_mysql_host, ee_db_password)) # Grant permission EEMysql.execute(self, - "grant all privileges on \'{0}\'.* to \'{1}\'@\'{2}\'" + "grant all privileges on {0}.* to {1}@{2}" .format(ee_db_name, ee_db_username, ee_db_password)) data['ee_db_name'] = ee_db_name data['ee_db_user'] = ee_db_username @@ -126,59 +131,55 @@ def setup_wordpress(self, data): # Random characters ee_random = (''.join(random.sample(string.ascii_uppercase + string.ascii_lowercase + string.digits, 15))) + ee_wp_prefix = '' + ee_wp_user = '' + ee_wp_pass = '' + print("Downloading Wordpress, please wait...") EEFileUtils.chdir(self, '{0}/htdocs/'.format(ee_site_webroot)) EEShellExec.cmd_exec(self, "wp --allow-root core download") - setup_database(self, data) - if prompt_wpprefix == 'True': - ee_wp_prefix = input('Enter the WordPress table prefix [wp_]: ' - .format(ee_replace_dot)) - while re.match('^[A-Za-z0-9_]*$', ee_wp_prefix): - print("Warning: table prefix can only contain numbers, letters," - "and underscores") - ee_wp_prefix = input('Enter the WordPress table prefix [wp_]: ') + data = setup_database(self, data) + if prompt_wpprefix == 'True' or prompt_wpprefix == 'true': + try: + ee_wp_prefix = input('Enter the WordPress table prefix [wp_]: ' + .format(ee_replace_dot)) + while re.match('^[A-Za-z0-9_]*$', ee_wp_prefix): + print("Warning: table prefix can only contain numbers, " + "letters, and underscores") + ee_wp_prefix = input('Enter the WordPress table prefix [wp_]: ' + ) + except EOFError as e: + print("{0} {1}".format(e.errorno, e.strerror)) + sys.exit(1) + if not ee_wp_prefix: ee_wp_prefix = 'wp_' # Modify wp-config.php & move outside the webroot - '''EEFileUtils.copyfile(self, - '{0}/htdocs/wp-config-sample.php' - .format(ee_site_webroot), - '{0}/wp-config.php'.format(ee_site_webroot)) - EEFileUtils.searchreplace('{0}/wp-config.php'.format(ee_site_webroot), - 'database_name_here', '') - EEFileUtils.searchreplace('{0}/wp-config.php'.format(ee_site_webroot), - 'database_name_here', '') - EEFileUtils.searchreplace('{0}/wp-config.php'.format(ee_site_webroot), - 'username_here', '') - EEFileUtils.searchreplace('{0}/wp-config.php'.format(ee_site_webroot), - 'password_here', '') - EEFileUtils.searchreplace('{0}/wp-config.php'.format(ee_site_webroot), - 'localhost', '') - EEFileUtils.searchreplace('{0}/wp-config.php'.format(ee_site_webroot), - 'wp_', '')''' EEFileUtils.chdir(self, '{0}/htdocs/'.format(ee_site_webroot)) if not data['multisite']: - EEShellExec.cmd_exec(self, "wp --allow-root core config" - "--dbname={0} --dbprefix={1} --dbuser={2}" - .format(ee_db_name, ee_wp_prefix, ee_db_user) - + "--dbpass={0}".format(ee_db_password)) + print("Generating wp-config") + + EEShellExec.cmd_exec(self, "wp --allow-root core config " + + "--dbname={0} --dbprefix={1} --dbuser={2} " + .format(data['ee_db_name'], ee_wp_prefix, + data['ee_db_user']) + + "--dbpass={0}".format(data['ee_db_pass'])) else: - EEShellExec.cmd_exec(self, "wp --allow-root core config" - "--dbname={0} --dbprefix={1}" - .format(ee_db_name, ee_wp_prefix) + EEShellExec.cmd_exec(self, "php /usr/bin/wp --allow-root core config " + + "--dbname={0} --dbprefix={1} " + .format(data['ee_db_name'], ee_wp_prefix) + "--dbuser={0} --dbpass={1} --extra-php<