Merge pull request #164 from WordOps/updating-configuration

Updating configuration
This commit is contained in:
VirtuBox
2019-09-26 16:02:34 +02:00
committed by GitHub
17 changed files with 244 additions and 211 deletions

View File

@@ -8,15 +8,39 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### v3.9.x - [Unreleased]
### v3.9.9.1 - 2019-09-26
#### Added
- [SECURE] Allow new ssh port with UFW when running `wo secure --sshport`
- [STACK] Additional Nginx directives to prevent access to log files or backup from web browser
- [CORE] apt-mirror-updater to select the fastest debian/ubuntu mirror with automatic switching between mirrors if the current mirror is being updated
- [SITE] add `--force` to force Let's Encrypt certificate issuance even if DNS check fail
- [STACK] check if another mta is installed before installing sendmail
- [SECURE] `--allowpassword` to allow password when using `--ssh` with `wo secure`
#### Changed
- [SECURE] Improved sshd_config template according to Mozilla Infosec guidelines
- [STACK] Always add stack configuration into Git before making changes to make rollback easier
- [STACK] Render php-fpm pools configuration from template
- [STACK] Adminer updated to v4.7.3
#### Fixed
- [STACK] UFW setup after removing all stacks with `wo stack purge --all`
- [CONFIG] Invalid CORS header
- [STACK] PHP-FPM stack upgrade failure due to pool configuration
### v3.9.9 - 2019-09-24
#### Added
- [STACK] UFW now available as a stack with flag `--ufw`
- [SECURE] `wo stack secure --ssh` to harden ssh security
- [SECURE] `wo stack secure --sshport` to change ssh port
- [SECURE] `wo secure --ssh` to harden ssh security
- [SECURE] `wo secure --sshport` to change ssh port
- [SITE] check domain DNS records before issuing a new certificate without DNS API
- [STACK] Acme challenge with DNS Alias mode [acme.sh wiki](https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode)
- [STACK] Acme challenge with DNS Alias mode `--dnsalias=aliasdomain.tld` [acme.sh wiki](https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode)
#### Changed

View File

@@ -25,7 +25,7 @@ if not os.path.exists('/var/lib/wo/'):
os.makedirs('/var/lib/wo/')
setup(name='wo',
version='3.9.9',
version='3.9.9.1',
description=long_description,
long_description=long_description,
classifiers=[],
@@ -56,6 +56,7 @@ setup(name='wo',
'SQLAlchemy',
'requests',
'distro',
'apt-mirror-updater',
],
data_files=[('/etc/wo', ['config/wo.conf']),
('/etc/wo/plugins.d', conf),

View File

@@ -4,6 +4,7 @@ import os
from cement.core import handler, hook
from cement.core.controller import CementBaseController, expose
from wo.core.fileutils import WOFileUtils
from wo.core.git import WOGit
from wo.core.logging import Log
from wo.core.random import RANDOM
@@ -37,6 +38,9 @@ class WOSecureController(CementBaseController):
help='set custom ssh port', action='store_true')),
(['--ssh'], dict(
help='harden ssh security', action='store_true')),
(['--allowpassword'], dict(
help='allow password authentification '
'when hardening ssh security', action='store_true')),
(['--force'],
dict(help='force execution without being prompt',
action='store_true')),
@@ -156,7 +160,7 @@ class WOSecureController(CementBaseController):
def secure_ssh(self):
"""Harden ssh security"""
pargs = self.app.pargs
if not pargs.force:
if not pargs.force and not pargs.allowpassword:
start_secure = input('Are you sure you to want to'
' harden SSH security ?'
'\nSSH login with password will not '
@@ -165,6 +169,8 @@ class WOSecureController(CementBaseController):
'Harden SSH security [y/N]')
if start_secure != "Y" and start_secure != "y":
Log.error(self, "Not hardening SSH security")
WOGit.add(self, ["/etc/ssh"],
msg="Adding SSH into Git")
Log.debug(self, "check if /etc/ssh/sshd_config exist")
if os.path.isfile('/etc/ssh/sshd_config'):
Log.debug(self, "looking for the current ssh port")
@@ -178,7 +184,11 @@ class WOSecureController(CementBaseController):
sudo_user = os.getenv('SUDO_USER')
else:
sudo_user = ''
data = dict(sshport=current_ssh_port, allowpass='no',
if pargs.allowpassword:
wo_allowpassword = 'yes'
else:
wo_allowpassword = 'no'
data = dict(sshport=current_ssh_port, allowpass=wo_allowpassword,
user=sudo_user)
WOTemplate.deploy(self, '/etc/ssh/sshd_config',
'sshd.mustache', data)
@@ -213,8 +223,23 @@ class WOSecureController(CementBaseController):
WOShellExec.cmd_exec(self, "sed -i \"s/Port.*/Port "
"{port}/\" /etc/ssh/sshd_config"
.format(port=pargs.user_input))
# allow new ssh port if ufw is enabled
if os.path.isfile('/etc/ufw/ufw.conf'):
# add rule for proftpd with UFW
if WOFileUtils.grepcheck(
self, '/etc/ufw/ufw.conf', 'ENABLED=yes'):
try:
WOShellExec.cmd_exec(
self, 'ufw limit {0}'.format(pargs.user_input))
WOShellExec.cmd_exec(
self, 'ufw reload')
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to add UFW rule")
# add ssh into git
WOGit.add(self, ["/etc/ssh"],
msg="Adding changed SSH port into Git")
# restart ssh service
if not WOService.restart_service(self, 'ssh'):
Log.error(self, "service SSH restart failed.")
Log.info(self, "Successfully changed SSH port to {port}"

View File

@@ -368,6 +368,9 @@ class WOSiteCreateController(CementBaseController):
action='store' or 'store_const',
choices=('on', 'subdomain', 'wildcard'),
const='on', nargs='?')),
(['--force'],
dict(help="force Let's Encrypt certificate issuance",
action='store_true')),
(['--dns'],
dict(help="choose dns provider api for letsencrypt",
action='store' or 'store_const',
@@ -796,9 +799,11 @@ class WOSiteCreateController(CementBaseController):
else:
# check DNS records before issuing cert
if not acmedata['dns'] is True:
if not WOAcme.check_dns(self, acme_domains):
Log.error(self,
"Aborting SSL certificate issuance")
if not pargs.force:
if not WOAcme.check_dns(self, acme_domains):
Log.error(self,
"Aborting SSL "
"certificate issuance")
Log.debug(self, "Setup Cert with acme.sh for {0}"
.format(wo_domain))
if WOAcme.setupletsencrypt(
@@ -806,9 +811,10 @@ class WOSiteCreateController(CementBaseController):
WOAcme.deploycert(self, wo_domain)
else:
if not acmedata['dns'] is True:
if not WOAcme.check_dns(self, acme_domains):
Log.error(self,
"Aborting SSL certificate issuance")
if not pargs.force:
if not WOAcme.check_dns(self, acme_domains):
Log.error(self,
"Aborting SSL certificate issuance")
if WOAcme.setupletsencrypt(
self, acme_domains, acmedata):
WOAcme.deploycert(self, wo_domain)
@@ -885,6 +891,9 @@ class WOSiteUpdateController(CementBaseController):
choices=('on', 'off', 'renew', 'subdomain',
'wildcard', 'clean', 'purge'),
const='on', nargs='?')),
(['--force'],
dict(help="force LetsEncrypt certificate issuance/renewal",
action='store_true')),
(['--dns'],
dict(help="choose dns provider api for letsencrypt",
action='store' or 'store_const',
@@ -901,9 +910,6 @@ class WOSiteUpdateController(CementBaseController):
dict(help="update to proxy site", nargs='+')),
(['--all'],
dict(help="update all sites", action='store_true')),
(['--force'],
dict(help="force letsencrypt certificate renewal",
action='store_true')),
]
@expose(help="Update site type or cache")
@@ -1446,10 +1452,13 @@ class WOSiteUpdateController(CementBaseController):
else:
# check DNS records before issuing cert
if not acmedata['dns'] is True:
if not WOAcme.check_dns(self, acme_domains):
Log.error(
self,
"Aborting SSL certificate issuance")
if not pargs.force:
if not WOAcme.check_dns(self,
acme_domains):
Log.error(
self,
"Aborting SSL certificate "
"issuance")
Log.debug(self, "Setup Cert with acme.sh for {0}"
.format(wo_domain))
if WOAcme.setupletsencrypt(
@@ -1460,10 +1469,11 @@ class WOSiteUpdateController(CementBaseController):
else:
# check DNS records before issuing cert
if not acmedata['dns'] is True:
if not WOAcme.check_dns(self, acme_domains):
Log.error(
self,
"Aborting SSL certificate issuance")
if not pargs.force:
if not WOAcme.check_dns(self, acme_domains):
Log.error(
self,
"Aborting SSL certificate issuance")
if WOAcme.setupletsencrypt(
self, acme_domains, acmedata):
WOAcme.deploycert(self, wo_domain)

View File

@@ -930,16 +930,9 @@ def updatewpuserpassword(self, wo_domain, wo_site_webroot):
wo_wp_pass = ''
WOFileUtils.chdir(self, '{0}/htdocs/'.format(wo_site_webroot))
# Check if wo_domain is wordpress install
try:
is_wp = WOShellExec.cmd_exec(self, "wp --allow-root core"
" version")
except CommandExecutionError as e:
Log.debug(self, "{0}".format(e))
raise SiteError("is WordPress site? check command failed ")
# Exit if wo_domain is not wordpress install
if not is_wp:
if not WOShellExec.cmd_exec(self, "wp --allow-root core"
" is-installed"):
# Exit if wo_domain is not wordpress install
Log.error(self, "{0} does not seem to be a WordPress site"
.format(wo_domain))
@@ -1333,8 +1326,6 @@ def doCleanupAction(self, domain='', webroot='', dbname='', dbuser='',
if os.path.isfile('/etc/nginx/sites-available/{0}'
.format(domain)):
removeNginxConf(self, domain)
if os.path.isdir('/etc/letsencrypt/renewal/{0}_ecc'
.format(domain)):
removeAcmeConf(self, domain)
if webroot:

View File

@@ -129,7 +129,6 @@ class WOStackController(CementBaseController):
pargs.php73 = True
pargs.redis = True
pargs.proftpd = True
pargs.security = True
if pargs.web:
pargs.nginx = True
@@ -152,7 +151,6 @@ class WOStackController(CementBaseController):
if pargs.security:
pargs.fail2ban = True
pargs.clamav = True
pargs.ufw = True
# Nginx
if pargs.nginx:
@@ -261,19 +259,24 @@ class WOStackController(CementBaseController):
# UFW
if pargs.ufw:
if not WOFileUtils.grep(
self, '/etc/ufw/ufw.conf', 'ENABLED=yes'):
Log.debug(self, "Setting apt_packages variable for UFW")
apt_packages = apt_packages + ["ufw"]
Log.debug(self, "Setting apt_packages variable for UFW")
apt_packages = apt_packages + ["ufw"]
# sendmail
if pargs.sendmail:
Log.debug(self, "Setting apt_packages variable for Sendmail")
if not WOAptGet.is_installed(self, 'sendmail'):
if (not WOAptGet.is_installed(self, 'sendmail') and
not WOAptGet.is_installed(self, 'postfix')):
apt_packages = apt_packages + ["sendmail"]
else:
Log.debug(self, "Sendmail already installed")
Log.info(self, "Sendmail already installed")
if WOAptGet.is_installed(self, 'sendmail'):
Log.debug(self, "Sendmail already installed")
Log.info(self, "Sendmail already installed")
else:
Log.debug(
self, "Another mta (Postfix) is already installed")
Log.info(
self, "Another mta (Postfix) is already installed")
# proftpd
if pargs.proftpd:
@@ -521,7 +524,6 @@ class WOStackController(CementBaseController):
(not pargs.php73)):
pargs.web = True
pargs.admin = True
pargs.security = True
if pargs.all:
pargs.web = True

View File

@@ -43,7 +43,7 @@ def pre_pref(self, apt_packages):
WORepo.add_key(self, '0xcbcb082a1bb943db',
keyserver='keys.gnupg.net')
WORepo.add_key(self, '0xF1656F24C74CD1D8',
keyserver='hkp://keys.gnupg.net')
keyserver='keys.gnupg.net')
if "mariadb-server" in apt_packages:
# generate random 24 characters root password
chars = ''.join(random.sample(string.ascii_letters, 24))
@@ -153,11 +153,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
ngxcnf = '/etc/nginx/conf.d'
ngxcom = '/etc/nginx/common'
ngxroot = '/var/www/'
if upgrade:
if os.path.isdir('/etc/nginx'):
WOGit.add(self,
["/etc/nginx"],
msg="Adding Nginx into Git")
WOGit.add(self, ["/etc/nginx"], msg="Adding Nginx into Git")
data = dict(tls13=True)
WOTemplate.deploy(self,
'/etc/nginx/nginx.conf',
@@ -490,6 +486,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
WOService.restart_service(self, 'nginx')
if set(WOVariables.wo_php).issubset(set(apt_packages)):
WOGit.add(self, ["/etc/php"], msg="Adding PHP into Git")
Log.info(self, "Configuring php7.2-fpm")
ngxroot = '/var/www/'
# Create log directories
@@ -527,72 +524,32 @@ def post_pref(self, apt_packages, packages, upgrade=False):
"/etc/php/7.2/fpm/php.ini")
config.write(configfile)
# Parse /etc/php/7.2/fpm/php-fpm.conf
# Render php-fpm pool template for php7.3
data = dict(pid="/run/php/php7.2-fpm.pid",
error_log="/var/log/php/7.2/fpm.log",
error_log="/var/log/php7.2-fpm.log",
include="/etc/php/7.2/fpm/pool.d/*.conf")
Log.debug(self, "writting php7.2 configuration into "
"/etc/php/7.2/fpm/php-fpm.conf")
wo_php_fpm = open('/etc/php/7.2/fpm/php-fpm.conf',
encoding='utf-8', mode='w')
self.app.render((data), 'php-fpm.mustache', out=wo_php_fpm)
wo_php_fpm.close()
WOTemplate.deploy(
self, '/etc/php/7.2/fpm/php-fpm.conf',
'php-fpm.mustache', data)
if not os.path.isfile('/etc/php/7.2/fpm/pool.d/www.conf.orig'):
WOFileUtils.copyfile(self, '/etc/php/7.2/fpm/pool.d/www.conf',
'/etc/php/7.2/fpm/pool.d/www.conf.orig')
# Parse /etc/php/7.2/fpm/pool.d/www.conf
config = configparser.ConfigParser()
config.read_file(codecs.open('/etc/php/7.2/fpm/'
'pool.d/www.conf.orig',
"r", "utf8"))
config['www']['ping.path'] = '/ping'
config['www']['pm.status_path'] = '/status'
config['www']['pm.max_requests'] = '1500'
config['www']['pm.max_children'] = '50'
config['www']['pm.start_servers'] = '10'
config['www']['pm.min_spare_servers'] = '5'
config['www']['pm.max_spare_servers'] = '15'
config['www']['request_terminate_timeout'] = '300'
config['www']['pm'] = 'ondemand'
config['www']['chdir'] = '/'
config['www']['prefix'] = '/var/run/php'
config['www']['listen'] = 'php72-fpm.sock'
config['www']['listen.mode'] = '0660'
config['www']['listen.backlog'] = '32768'
config['www']['catch_workers_output'] = 'yes'
with codecs.open('/etc/php/7.2/fpm/pool.d/www.conf',
encoding='utf-8', mode='w') as configfile:
Log.debug(self, "Writing PHP 7.2 configuration into "
"/etc/php/7.2/fpm/pool.d/www.conf")
config.write(configfile)
with open("/etc/php/7.2/fpm/pool.d/www.conf",
encoding='utf-8', mode='a') as myfile:
myfile.write("\nphp_admin_value[open_basedir] "
"= \"/var/www/:/usr/share/php/:"
"/tmp/:/var/run/nginx-cache/:"
"/dev/shm:/dev/urandom\"\n")
# Generate /etc/php/7.2/fpm/pool.d/www-two.conf
WOFileUtils.copyfile(self, "/etc/php/7.2/fpm/pool.d/www.conf",
"/etc/php/7.2/fpm/pool.d/www-two.conf")
WOFileUtils.searchreplace(self, "/etc/php/7.2/fpm/pool.d/"
"www-two.conf", "[www]", "[www-two]")
config = configparser.ConfigParser()
config.read('/etc/php/7.2/fpm/pool.d/www-two.conf')
config['www-two']['listen'] = 'php72-two-fpm.sock'
with open('/etc/php/7.2/fpm/pool.d/www-two.conf',
encoding='utf-8', mode='w') as confifile:
Log.debug(self, "writting PHP7.2 configuration into "
"/etc/php/7.2/fpm/pool.d/www-two.conf")
config.write(confifile)
data = dict(pool='www-php72', listen='php72-fpm.sock',
user='www-data',
group='www-data', listenuser='root',
listengroup='www-data', openbasedir=True)
WOTemplate.deploy(self, '/etc/php/7.2/fpm/pool.d/www.conf',
'php-pool.mustache', data)
data = dict(pool='www-two-php72', listen='php72-two-fpm.sock',
user='www-data',
group='www-data', listenuser='root',
listengroup='www-data', openbasedir=True)
WOTemplate.deploy(self, '/etc/php/7.2/fpm/pool.d/www-two.conf',
'php-pool.mustache', data)
# Generate /etc/php/7.2/fpm/pool.d/debug.conf
WOFileUtils.copyfile(self, "/etc/php/7.2/fpm/pool.d/www.conf",
"/etc/php/7.2/fpm/pool.d/debug.conf")
WOFileUtils.searchreplace(self, "/etc/php/7.2/fpm/pool.d/"
"debug.conf", "[www]", "[debug]")
"debug.conf", "[www-php72]", "[debug]")
config = configparser.ConfigParser()
config.read('/etc/php/7.2/fpm/pool.d/debug.conf')
config['debug']['listen'] = '127.0.0.1:9172'
@@ -663,6 +620,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
# PHP7.3 configuration
if set(WOVariables.wo_php73).issubset(set(apt_packages)):
WOGit.add(self, ["/etc/php"], msg="Adding PHP into Git")
Log.info(self, "Configuring php7.3-fpm")
ngxroot = '/var/www/'
# Create log directories
@@ -700,72 +658,32 @@ def post_pref(self, apt_packages, packages, upgrade=False):
"/etc/php/7.3/fpm/php.ini")
config.write(configfile)
# Parse /etc/php/7.3/fpm/php-fpm.conf
# Render php-fpm pool template for php7.3
data = dict(pid="/run/php/php7.3-fpm.pid",
error_log="/var/log/php7.3-fpm.log",
include="/etc/php/7.3/fpm/pool.d/*.conf")
Log.debug(self, "writting php 7.3 configuration into "
"/etc/php/7.3/fpm/php-fpm.conf")
wo_php_fpm = open('/etc/php/7.3/fpm/php-fpm.conf',
encoding='utf-8', mode='w')
self.app.render((data), 'php-fpm.mustache', out=wo_php_fpm)
wo_php_fpm.close()
WOTemplate.deploy(
self, '/etc/php/7.3/fpm/php-fpm.conf',
'php-fpm.mustache', data)
# Parse /etc/php/7.3/fpm/pool.d/www.conf
if not os.path.isfile('/etc/php/7.3/fpm/pool.d/www.conf.orig'):
WOFileUtils.copyfile(self, '/etc/php/7.3/fpm/pool.d/www.conf',
'/etc/php/7.3/fpm/pool.d/www.conf.orig')
config = configparser.ConfigParser()
config.read_file(codecs.open('/etc/php/7.3/fpm/'
'pool.d/www.conf.orig',
"r", "utf8"))
config['www']['ping.path'] = '/ping'
config['www']['pm.status_path'] = '/status'
config['www']['pm.max_requests'] = '1500'
config['www']['pm.max_children'] = '50'
config['www']['pm.start_servers'] = '10'
config['www']['pm.min_spare_servers'] = '5'
config['www']['pm.max_spare_servers'] = '15'
config['www']['request_terminate_timeout'] = '300'
config['www']['pm'] = 'ondemand'
config['www']['chdir'] = '/'
config['www']['prefix'] = '/var/run/php'
config['www']['listen'] = 'php73-fpm.sock'
config['www']['listen.mode'] = '0660'
config['www']['listen.backlog'] = '32768'
config['www']['catch_workers_output'] = 'yes'
with codecs.open('/etc/php/7.3/fpm/pool.d/www.conf',
encoding='utf-8', mode='w') as configfile:
Log.debug(self, "writting PHP 7.3 configuration into "
"/etc/php/7.3/fpm/pool.d/www.conf")
config.write(configfile)
with open("/etc/php/7.3/fpm/pool.d/www.conf",
encoding='utf-8', mode='a') as myfile:
myfile.write("\nphp_admin_value[open_basedir] "
"= \"/var/www/:/usr/share/php/:"
"/tmp/:/var/run/nginx-cache/:"
"/dev/shm:/dev/urandom\"\n")
# Generate /etc/php/7.3/fpm/pool.d/www-two.conf
WOFileUtils.copyfile(self, "/etc/php/7.3/fpm/pool.d/www.conf",
"/etc/php/7.3/fpm/pool.d/www-two.conf")
WOFileUtils.searchreplace(self, "/etc/php/7.3/fpm/pool.d/"
"www-two.conf", "[www]", "[www-two]")
config = configparser.ConfigParser()
config.read('/etc/php/7.3/fpm/pool.d/www-two.conf')
config['www-two']['listen'] = 'php73-two-fpm.sock'
with open('/etc/php/7.3/fpm/pool.d/www-two.conf',
encoding='utf-8', mode='w') as confifile:
Log.debug(self, "writting PHP7.3 configuration into "
"/etc/php/7.3/fpm/pool.d/www-two.conf")
config.write(confifile)
data = dict(pool='www-php73', listen='php73-fpm.sock',
user='www-data',
group='www-data', listenuser='root',
listengroup='www-data', openbasedir=True)
WOTemplate.deploy(self, '/etc/php/7.3/fpm/pool.d/www.conf',
'php-pool.mustache', data)
data = dict(pool='www-two-php73', listen='php73-two-fpm.sock',
user='www-data',
group='www-data', listenuser='root',
listengroup='www-data', openbasedir=True)
WOTemplate.deploy(self, '/etc/php/7.3/fpm/pool.d/www-two.conf',
'php-pool.mustache', data)
# Generate /etc/php/7.3/fpm/pool.d/debug.conf
WOFileUtils.copyfile(self, "/etc/php/7.3/fpm/pool.d/www.conf",
"/etc/php/7.3/fpm/pool.d/debug.conf")
WOFileUtils.searchreplace(self, "/etc/php/7.3/fpm/pool.d/"
"debug.conf", "[www]", "[debug]")
"debug.conf", "[www-php73]", "[debug]")
config = configparser.ConfigParser()
config.read('/etc/php/7.3/fpm/pool.d/debug.conf')
config['debug']['listen'] = '127.0.0.1:9173'
@@ -836,6 +754,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
# create mysql config if it doesn't exist
if "mariadb-server" in apt_packages:
WOGit.add(self, ["/etc/mysql"], msg="Adding MySQL into Git")
if not os.path.isfile("/etc/mysql/my.cnf"):
config = ("[mysqld]\nwait_timeout = 30\n"
"interactive_timeout=60\nperformance_schema = 0"
@@ -889,6 +808,8 @@ def post_pref(self, apt_packages, packages, upgrade=False):
# create fail2ban configuration files
if set(WOVariables.wo_fail2ban).issubset(set(apt_packages)):
WOGit.add(self, ["/etc/fail2ban"],
msg="Adding Fail2ban into Git")
if not os.path.isfile("/etc/fail2ban/jail.d/custom.conf"):
Log.info(self, "Configuring Fail2Ban")
data = dict()
@@ -914,6 +835,8 @@ def post_pref(self, apt_packages, packages, upgrade=False):
# Proftpd configuration
if "proftpd-basic" in apt_packages:
WOGit.add(self, ["/etc/proftpd"],
msg="Adding ProFTPd into Git")
if os.path.isfile("/etc/proftpd/proftpd.conf"):
Log.info(self, "Configuring ProFTPd")
Log.debug(self, "Setting up Proftpd configuration")
@@ -936,32 +859,28 @@ def post_pref(self, apt_packages, packages, upgrade=False):
WOFileUtils.chmod(self, "/etc/proftpd/ssl/proftpd.key", 0o700)
WOFileUtils.chmod(self, "/etc/proftpd/ssl/proftpd.crt", 0o700)
data = dict()
Log.debug(self, 'Writting the proftpd configuration to '
'file /etc/proftpd/tls.conf')
wo_proftpdconf = open('/etc/proftpd/tls.conf',
encoding='utf-8', mode='w')
self.app.render((data), 'proftpd-tls.mustache',
out=wo_proftpdconf)
wo_proftpdconf.close()
WOTemplate.deploy(self, '/etc/proftpd/tls.conf',
'proftpd-tls.mustache', data)
WOFileUtils.searchreplace(self, "/etc/proftpd/"
"proftpd.conf",
"#Include /etc/proftpd/tls.conf",
"Include /etc/proftpd/tls.conf")
WOService.restart_service(self, 'proftpd')
# add rule for proftpd with UFW
if WOFileUtils.grepcheck(
self, '/etc/ufw/ufw.conf', 'ENABLED=yes'):
try:
WOShellExec.cmd_exec(
self, "ufw limit 21")
WOShellExec.cmd_exec(
self, "ufw allow 49000:50000/tcp")
WOShellExec.cmd_exec(
self, "ufw reload")
except CommandExecutionError as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to add UFW rule")
if os.path.isfile('/etc/ufw/ufw.conf'):
# add rule for proftpd with UFW
if WOFileUtils.grepcheck(
self, '/etc/ufw/ufw.conf', 'ENABLED=yes'):
try:
WOShellExec.cmd_exec(
self, "ufw limit 21")
WOShellExec.cmd_exec(
self, "ufw allow 49000:50000/tcp")
WOShellExec.cmd_exec(
self, "ufw reload")
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to add UFW rules")
if ((os.path.isfile("/etc/fail2ban/jail.d/custom.conf")) and
(not WOFileUtils.grep(
@@ -1021,6 +940,8 @@ def post_pref(self, apt_packages, packages, upgrade=False):
# set maxmemory 10% for ram below 512MB and 20% for others
# set maxmemory-policy allkeys-lru
# enable systemd service
WOGit.add(self, ["/etc/redis"],
msg="Adding Redis into Git")
Log.debug(self, "Enabling redis systemd service")
WOShellExec.cmd_exec(self, "systemctl enable redis-server")
if (os.path.isfile("/etc/redis/redis.conf") and
@@ -1029,7 +950,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
Log.wait(self, "Tuning Redis configuration")
with open("/etc/redis/redis.conf",
"a") as redis_file:
redis_file.write("\n# WordOps v3.9.8\n")
redis_file.write("\n# WordOps v3.9.9\n")
wo_ram = psutil.virtual_memory().total / (1024 * 1024)
if wo_ram < 1024:
Log.debug(self, "Setting maxmemory variable to "
@@ -1069,8 +990,10 @@ def post_pref(self, apt_packages, packages, upgrade=False):
"tcp-backlog 32768")
WOFileUtils.chown(self, '/etc/redis/redis.conf',
'redis', 'redis', recursive=False)
WOService.restart_service(self, 'redis-server')
Log.valide(self, "Tuning Redis configuration")
WOGit.add(self, ["/etc/redis"],
msg="Adding Redis into Git")
WOService.restart_service(self, 'redis-server')
# ClamAV configuration
if set(WOVariables.wo_clamav).issubset(set(apt_packages)):
@@ -1405,13 +1328,10 @@ def post_pref(self, apt_packages, packages, upgrade=False):
Log.debug(self, "configration Anemometer")
data = dict(host=WOVariables.wo_mysql_host, port='3306',
user='anemometer', password=chars)
wo_anemometer = open('{0}22222/htdocs/db/anemometer'
'/conf/config.inc.php'
.format(WOVariables.wo_webroot),
encoding='utf-8', mode='w')
self.app.render((data), 'anemometer.mustache',
out=wo_anemometer)
wo_anemometer.close()
WOTemplate.deploy(self, '{0}22222/htdocs/db/anemometer'
'/conf/config.inc.php'
.format(WOVariables.wo_webroot),
'anemometer.mustache', data)
# pt-query-advisor
if any('/usr/bin/pt-query-advisor' == x[1]

View File

@@ -212,7 +212,6 @@ class WOStackUpgradeController(CementBaseController):
if ["php7.3-fpm"] in apt_packages:
WOAptGet.remove(self, ['php7.3-fpm'],
auto=False, purge=True)
# check if nginx upgrade is blocked
if os.path.isfile(
'/etc/apt/preferences.d/nginx-block'):

View File

@@ -12,7 +12,7 @@ location @empty_gif {
}
# Cache static files
location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|ttf|m4a|mp4|ttf|rss|atom|jpe?g|gif|cur|heic|png|tiff|ico|webm|mp3|aac|tgz|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|swf|webp|json|webmanifest)$ {
more_set_headers 'Access-Control-Allow-Origin : "*"';
more_set_headers 'Access-Control-Allow-Origin : *';
more_set_headers "Cache-Control : public, no-transform";
access_log off;
log_not_found off;
@@ -20,7 +20,7 @@ location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|ttf|m4a|mp4|ttf|rss|atom|jpe?
}
# Cache css & js files
location ~* \.(?:css(\.map)?|js(\.map)?)$ {
more_set_headers 'Access-Control-Allow-Origin : "*"';
more_set_headers 'Access-Control-Allow-Origin : *';
more_set_headers "Cache-Control : public, no-transform";
access_log off;
log_not_found off;

View File

@@ -66,7 +66,7 @@ http {
more_set_headers "X-Frame-Options : SAMEORIGIN";
more_set_headers "X-Xss-Protection : 1; mode=block";
more_set_headers "X-Content-Type-Options : nosniff";
more_set_headers "Referrer-Policy : strict-origin-when-cross-origin";
more_set_headers "Referrer-Policy : no-referrer, strict-origin-when-cross-origin";
more_set_headers "X-Download-Options : noopen";
# oscp settings

View File

@@ -0,0 +1,23 @@
[{{pool}}]
user = {{user}}
group = {{group}}
listen = {{listen}}
listen.owner = {{listenuser}}
listen.group = {{listengroup}}
pm = ondemand
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 15
ping.path = /ping
pm.status_path = /status
pm.max_requests = 1500
request_terminate_timeout = 300
chdir = /
prefix = /var/run/php
listen.mode = 0660
listen.backlog = 32768
catch_workers_output = yes
{{#openbasedir}}php_admin_value[open_basedir] = "/var/www/:/usr/share/php/:/tmp/:/var/run/nginx-cache/"{{/openbasedir}}

View File

@@ -33,8 +33,11 @@ X11Forwarding yes
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
# override default of no subsystems
Subsystem sftp /usr/lib/openssh/sftp-server
# LogLevel VERBOSE logs user's key fingerprint on login. Needed to have a clear audit track of which key was using to log in.
LogLevel VERBOSE
# Log sftp level file access (read/write/etc.) that would not be easily logged otherwise.
Subsystem sftp /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO
# Host keys the client accepts - order here is honored by OpenSSH
HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256
@@ -42,4 +45,8 @@ HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,
# use strong ciphers
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
# Use kernel sandbox mechanisms where possible in unprivileged processes
# Systrace on OpenBSD, Seccomp on Linux, seatbelt on MacOSX/Darwin, rlimit elsewhere.
UsePrivilegeSeparation sandbox

View File

@@ -40,15 +40,15 @@ location @robots {
location /wp-content/uploads {
location ~ \.(png|jpe?g)$ {
add_header Vary "Accept-Encoding";
add_header "Access-Control-Allow-Origin" "*";
more_set_headers '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
location ~* \.(php|gz|log|zip|tar|rar)$ {
#Prevent Direct Access Of PHP Files & BackupsFrom Web Browsers
deny all;
}
}
@@ -56,7 +56,7 @@ location /wp-content/uploads {
location /wp-content/plugins/ewww-image-optimizer/images {
location ~ \.(png|jpe?g)$ {
add_header Vary "Accept-Encoding";
add_header "Access-Control-Allow-Origin" "*";
more_set_headers 'Access-Control-Allow-Origin : *';
add_header Cache-Control "public, no-transform";
access_log off;
log_not_found off;
@@ -72,7 +72,7 @@ location /wp-content/plugins/ewww-image-optimizer/images {
location /wp-content/cache {
# Cache css & js files
location ~* \.(?:css(\.map)?|js(\.map)?|.html)$ {
add_header "Access-Control-Allow-Origin" "*";
more_set_headers 'Access-Control-Allow-Origin : *';
access_log off;
log_not_found off;
expires 30d;

View File

@@ -18,7 +18,7 @@ class WOAptGet():
"""
try:
with open('/var/log/wo/wordops.log', 'a') as f:
proc = subprocess.Popen('apt-get update',
proc = subprocess.Popen('apt-mirror-updater -u',
shell=True,
stdin=None, stdout=f,
stderr=subprocess.PIPE,

View File

@@ -202,6 +202,37 @@ class WOFileUtils():
Log.debug(self, "{0}".format(e.strerror))
Log.error(self, "Unable to change owner : {0}".format(path))
def wpperm(self, path, harden=False):
"""
Fix WordPress site permissions
path : WordPress site path
harden : set 750/640 instead of 755/644
"""
userid = pwd.getpwnam('www-data')[2]
groupid = pwd.getpwnam('www-data')[3]
try:
Log.debug(self, "Fixing WordPress permissions of {0}"
.format(path))
if harden:
dperm = '0o750'
fperm = '0o640'
else:
dperm = '0o755'
fperm = '0o644'
for root, dirs, files in os.walk(path):
for d in dirs:
os.chown(os.path.join(root, d), userid,
groupid)
os.chmod(os.path.join(root, d), dperm)
for f in files:
os.chown(os.path.join(root, d), userid,
groupid)
os.chmod(os.path.join(root, f), fperm)
except OSError as e:
Log.debug(self, "{0}".format(e.strerror))
Log.error(self, "Unable to change owner : {0}".format(path))
def mkdir(self, path):
"""
create directories.

View File

@@ -74,7 +74,7 @@ class WOGit:
try:
Log.debug(self, "WOGit: git reset HEAD~ at {0}"
.format(path))
git.reset("--hard HEAD~")
git.reset("HEAD~", "--hard")
except ErrorReturnCode as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to git reset at {0} "

View File

@@ -11,10 +11,10 @@ class WOVariables():
"""Intialization of core variables"""
# WordOps version
wo_version = "3.9.9"
wo_version = "3.9.9.1"
# WordOps packages versions
wo_wp_cli = "2.3.0"
wo_adminer = "4.7.2"
wo_adminer = "4.7.3"
wo_phpmyadmin = "4.9.1"
wo_extplorer = "2.1.13"
wo_dashboard = "1.2"