def edit_nginx(self, domain_name): if not os.path.isfile('/etc/temp_nginx_conf/%s_http.conf' % self.provision) \ or not os.path.isfile('/etc/temp_nginx_conf/%s_ssl.conf' % self.provision): print('No temporary nginx file exists. Please backup firstly') return False # check new nginx conf right after editing for fi in glob.glob('/etc/temp_nginx_conf/%s_*.conf' % self.provision): shutil.copy(fi, '/etc/nginx/conf.d/') nginx_check = fLib.check_nginx_valid() if nginx_check > 0: # rollback for fi in glob.glob('/etc/nginx/bk_nginx_conf/%s_*.conf' % self.provision): shutil.copy(fi, '/etc/nginx/conf.d/') print('Insert failed. Might your conf is invalid') return False else: # if editing nginx okie, apply new conf nginx_check = fLib.check_nginx_valid() if nginx_check == 0: fLib.reload_service('nginx') return True else: print( 'nginx conf check failed. Please run "nginx -t" for more details' ) return False
def delete_filterip(self, url=None, rule_id=None): self.backup_nginx_conf() if url == 'wp-login': print('can not configure wp-login url') return False else: if not self.check_existence_in_file( 'filter_%s_%s' % (self.provision, rule_id), self.path): print('Not found the rule ID as %s in nginx config' % rule_id) return False else: self.remove_conf_related_nginx('filter_%s_%s' % (self.provision, rule_id)) nginx_check = fLib.check_nginx_valid() if nginx_check == 0: os.remove('/etc/nginx/restrict_rule/filter_%s_%s' % (self.provision, rule_id)) print('Done') fLib.reload_service('nginx') return True else: print('NGINX config check failed') self.rollback_nginx_only() return False
def k_ssl(self, email=None, https=None, hsts=None): if email: self.enable_ssl(email) self.k_autorenewal('on') if hsts != "": self.k_hsts(hsts) if https != "": self.k_https(https) fLib.reload_service('httpd') if fLib.check_nginx_valid() == 0: fLib.reload_service('nginx') print('Done') return True else: print('Nginx conf check failed.') return False
def add_filterip(self, url=None, ip_address=None, rule_id=None): self.backup_nginx_conf() if self.check_existence_in_file( 'filter_%s_%s' % (self.provision, rule_id), self.path): print('the filter ID already existed') return False output_file = '/etc/nginx/restrict_rule/filter_%s_%s' % ( self.provision, rule_id) if url == 'wp-admin': pattern = ('location', '#deny all', '#allow ipas', '}') replacement = ('#location', 'deny all', 'allow %s' % ip_address, '#}') self.replace_multiple(self.filter_template_file, output_file, pattern, replacement) self.inject_rule_to_nginx('#Restric filter here', output_file) elif url == 'wp-login': print('can not add restriction rule to wp-login url') return False else: if self.check_existence_in_file(url, self.path): print(' the %s location has been added' % url) return False else: pattern = ('url', '#deny all', '#allow ipas') replacement = (url, 'deny all', 'allow %s' % ip_address) self.replace_multiple(self.filter_template_file, output_file, pattern, replacement) self.inject_rule_to_nginx('#Addnew Restrict Filter', output_file) nginx_check = fLib.check_nginx_valid() if nginx_check == 0: fLib.reload_service('nginx') print('Done') return True self.rollback_nginx_only() os.remove(output_file) return False
def remove_ssl(self): has_installed = 0 with open('/etc/nginx/conf.d/%s_ssl.conf' % self.provision, 'rt') as f: for line in f: if re.search(r'^\s*ssl_certificate\s+', line) and not re.search(r'localhost\.', line): # cert_file = line.split('ssl_certificate')[1].split(';')[0].strip() has_installed = 1 # if re.search(r'^\s*ssl_certificate_key\s+', line) and not re.search(r'localhost\.', line): # key_file = line.split('ssl_certificate_key')[1].split(';')[0].strip() break if has_installed: if not os.path.isdir('/etc/kusanagi.d/ssl/recycle_bin'): os.mkdir('/etc/kusanagi.d/ssl/recycle_bin', mode=0o755) self.k_https('noredirect') pat = (r'^(\s*ssl_certificate\s+)\S+;', r'^(\s*ssl_certificate_key\s+)\S+;') repl = (r'\1/etc/pki/tls/certs/localhost.crt;', r'\1/etc/pki/tls/private/localhost.key;') setMng.replace_multiple_in_file('/etc/nginx/conf.d/%s_ssl.conf' % self.provision, pat, repl) pat = (r'^(\s*SSLCertificateFile\s+)\S+', r'^(\s*SSLCertificateKeyFile\s+)\S+') repl = (r'\1/etc/pki/tls/certs/localhost.crt;', r'\1/etc/pki/tls/private/localhost.key;') setMng.replace_multiple_in_file('/etc/httpd/conf.d/%s_ssl.conf' % self.provision, pat, repl) if os.path.isfile('/etc/letsencrypt/renewal/%s.conf' % self.fqdn): shutil.move('/etc/letsencrypt/renewal/%s.conf' % self.fqdn, '/etc/kusanagi.d/ssl/recycle_bin/%s.conf' % self.fqdn) for root, dirs, files in os.walk('/etc/letsencrypt/renewal'): for name in files: if re.search(r'%s-\d+' % self.fqdn, os.path.join(root, name)): renewal_file = os.path.join(root, name) dest_file = '/etc/kusanagi.d/ssl/recycle_bin/%s' % name shutil.move(renewal_file, dest_file) # shutil.move(cert_file, '/etc/kusanagi.d/ssl/recycle_bin/') # shutil.move(key_file, '/etc/kusanagi.d/ssl/recycle_bin/') fLib.reload_service('httpd') if fLib.check_nginx_valid() == 0: fLib.reload_service('nginx') print('Done') return True else: print('Nginx conf check failed.') return False else: print('Not installed SSL. Nothing to do') return True
def k_cert_change(self, cert_file_path=None, key_file_path=None): ssl_dir = '/etc/kusanagi.d/ssl/%s' % self.provision if cert_file_path and key_file_path: if not os.path.isdir(ssl_dir): os.mkdir(ssl_dir, mode=0o755) date_str = datetime.now().strftime("%Y-%m-%d_%H:%M:%S") cert_file_name = cert_file_path.rsplit('/', 1)[1] target_cert = '%s/%s' % (ssl_dir, cert_file_name) if os.path.isfile(target_cert): shutil.move(target_cert, '%s.%s' % (target_cert, date_str)) shutil.copy(cert_file_path, target_cert) key_file_name = key_file_path.rsplit('/', 1)[1] target_key = '%s/%s' % (ssl_dir, key_file_name) if os.path.isfile(target_key): shutil.move(target_key, '%s.%s' % (target_key, date_str)) shutil.copy(key_file_path, target_key) pat = (r'^(\s*ssl_certificate\s+)\S+;', r'^(\s*ssl_certificate_key\s+)\S+;') repl = (r'\1%s;' % target_cert, r'\1%s;' % target_key) setMng.replace_multiple_in_file('/etc/nginx/conf.d/%s_ssl.conf' % self.provision, pat, repl) pat = (r'^(\s*SSLCertificateFile\s+)\S+', r'^(\s*SSLCertificateKeyFile\s+)\S+') repl = (r'\1%s' % target_cert, r'\1%s' % target_key) setMng.replace_multiple_in_file('/etc/httpd/conf.d/%s_ssl.conf' % self.provision, pat, repl) print("Change SSL Certificate configuration.") self.wp_replace_proto('http', 'https', self.fqdn) fLib.reload_service('httpd') if fLib.check_nginx_valid() == 0: fLib.reload_service('nginx') print('Done') return True else: print('Nginx conf check failed.') return False
def add_authentication(self, url=None, user=None, password=None, rule_id=None): # if not fLib.verify_prov_existed(self.provision): # return False # if not fLib.verify_nginx_prov_existed(self.provision): # return False if self.check_existence_in_file('au_%s_%s' % (self.provision, rule_id), self.path): print('the rule authentication ID already existed') return False if os.path.isfile('/etc/nginx/restrict_access/au_%s_%s' % (self.provision, rule_id)): print('the authentication file already existed') return False if os.path.isfile('/etc/nginx/restrict_access/user_%s_%s' % (self.provision, rule_id)): print('the user conf file already existed') return False self.backup_nginx_conf() output_file = '/etc/nginx/restrict_access/au_%s_%s' % (self.provision, rule_id) if url == 'wp-admin': pattern = ('location', '#auth_basic', '#auth_basic_user_file', 'provision_name', '}') replacement = ('#location', 'auth_basic', 'auth_basic_user_file', 'user_%s_%s' % (self.provision, rule_id), '#}') self.replace_multiple(self.template_file, output_file, pattern, replacement) fLib.execute( 'htpasswd -nb %s %s > /etc/nginx/restrict_access/user_%s_%s' % (user, password, self.provision, rule_id)) self.inject_rule_to_nginx('#Restric filter here', output_file) elif url == 'wp-login': print('can not add restriction rule to wp-login url') return False else: if self.check_existence_in_file(url, self.path): print(' the %s location has been added' % url) return False else: pattern = ('url', '#auth_basic', '#auth_basic_user_file', 'provision_name') replacement = (url, 'auth_basic', 'auth_basic_user_file', 'user_%s_%s' % (self.provision, rule_id)) self.replace_multiple(self.template_file, output_file, pattern, replacement) fLib.execute( 'htpasswd -nb %s %s > /etc/nginx/restrict_access/user_%s_%s' % (user, password, self.provision, rule_id)) self.inject_rule_to_nginx('#Addnew Restrict Filter', output_file) nginx_check = fLib.check_nginx_valid() if nginx_check == 0: fLib.reload_service('nginx') print('Done') return True self.rollback_nginx_only() os.remove(output_file) os.remove('/etc/nginx/restrict_access/user_%s_%s' % (self.provision, rule_id)) return False
def perform(self, action=None): nginx_waf_root_conf = '/etc/nginx/conf.d/kusanagi_naxsi_core.conf' apache_waf_root_conf = '/etc/httpd/conf.d/mod_security.conf' waf_comment = '#kusanagi_comment_do_not_delete;' if action == 'status': if fLib.is_active('nginx') == 0 and os.path.isfile(nginx_waf_root_conf) \ and not self.check_existence_in_file('#kusanagi_comment_do_not_delete;', nginx_waf_root_conf): return 'on' elif fLib.is_active('httpd') == 0 and os.path.isfile(apache_waf_root_conf) \ and not self.check_existence_in_file('#kusanagi_comment_do_not_delete;', apache_waf_root_conf): return 'on' else: return 'off' if action == 'on': print('Turning on') pat = waf_comment repl = '' self.replace_in_file(pat, repl, nginx_waf_root_conf) pat = r'#+\t*\s*include\t*\s*(naxsi\.d/.*)' repl = r'include \1' self.replace_in_file(pat, repl, '/etc/nginx/conf.d/*_http.conf') self.replace_in_file(pat, repl, '/etc/nginx/conf.d/*_ssl.conf') # http-install mod security modules if self.install_httpd_waf_modules() == 0: pat = waf_comment repl = '' self.replace_in_file(pat, repl, apache_waf_root_conf) pat = (r'#+[ \t]*IncludeOptional[ \t]+(modsecurity\.d/.*)', r'#+[ \t]*SecAuditLog[ \t]+(.*)') repl = (r'IncludeOptional \1', r'SecAuditLog \1') self.replace_multiple_in_file('/etc/httpd/conf.d/*_http.conf', pat, repl) self.replace_multiple_in_file('/etc/httpd/conf.d/*_ssl.conf', pat, repl) if action == 'off': print('Turning off') pat = r'^' repl = r'#kusanagi_comment_do_not_delete;' self.replace_in_file(pat, repl, nginx_waf_root_conf) self.replace_in_file(pat, repl, apache_waf_root_conf) pat = r'([^#]+)include[ \t]+(naxsi\.d/.*)' repl = r'\1#include \2' self.replace_in_file(pat, repl, '/etc/nginx/conf.d/*_http.conf') self.replace_in_file(pat, repl, '/etc/nginx/conf.d/*_ssl.conf') pat = (r'([^#]+)IncludeOptional[ \t]+(modsecurity\.d/.*)', r'([^#]+)SecAuditLog[ \t]+(.*)') repl = (r'\1#IncludeOptional \2', r'\1#SecAuditLog \2') self.replace_multiple_in_file('/etc/httpd/conf.d/*_http.conf', pat, repl) self.replace_multiple_in_file('/etc/httpd/conf.d/*_ssl.conf', pat, repl) fLib.reload_service('httpd') if fLib.check_nginx_valid() == 0: fLib.reload_service('nginx') print('Done') return True else: print('Nginx conf check failed.') return False
def f_cache(self, action=None, uri=None): if action == 'status': pat = r"set\s* \$do_not_cache\s*0\s*;\s*#+\s*page\s*cache" if self.check_existence_in_file( pat, '/etc/nginx/conf.d/%s_http.conf' % self.provision): return 'on' else: return 'off' if action == 'on': print('Turning on') pat = r'set\s+\$do_not_cache\s+1\s*;\s+#+\s+page\s+cache' repl = r'set $do_not_cache 0; ## page cache' self.replace_in_file(pat, repl, self.path) if action == 'off': print('Turning off') pat = r'set\s+\$do_not_cache\s+0\s*;\s*#+\s*page\s*cache' repl = r'set $do_not_cache 1; ## page cache' self.replace_in_file(pat, repl, self.path) if action == 'clear': print('Clearing cache') nginx_cache_dir = '/var/cache/nginx/wordpress' p = pathlib.Path(nginx_cache_dir) if p.exists(): res = fLib.execute('ls -dl %s | wc -l' % nginx_cache_dir) # meo hieu de lam gi if p.owner() == 'httpd' and int(res) == 1: fqdn = fLib.get_fqdn(self.provision) if uri: url_unicode = urllib.parse.quote(uri) if not url_unicode.startswith('/', 0, 1): url_unicode = '/%s' % url_unicode command = 'grep -i -a -r -m 1 -E "^KEY.*:https?://%s%s" %s' % ( fqdn, url_unicode, nginx_cache_dir) try: res = subprocess.run(command, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) g = open('/opt/tmp_nginx.conf', 'w') g.write(res.stdout) g.close() g = open('/opt/tmp_nginx.conf', 'r') for line in g: binary_file = line.replace(':KEY:', '').split()[0] os.remove(binary_file) g.close() except subprocess.CalledProcessError as error: if error.returncode > 0: print("URL has not been cached") return True else: command = 'grep -r -E "%s" %s' % (fqdn, nginx_cache_dir) try: res = subprocess.run(command, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) g = open('/opt/tmp_nginx.conf', 'w') g.write(res.stdout) g.close() g = open('/opt/tmp_nginx.conf', 'r') for line in g: binary_file = line.split()[2] os.remove(binary_file) g.close() except subprocess.CalledProcessError as error: if error.returncode > 0: print("No cache found") return True else: print('Nginx cache dir %s is not found' % nginx_cache_dir) return False nginx_check = fLib.check_nginx_valid() if nginx_check == 0: fLib.reload_service('nginx') print('Done') return True else: print( 'Nginx conf check failed. Please run "nginx -t" for more details' ) return False