2019-09-04 20:36:15 +02:00
|
|
|
import getpass
|
2019-09-23 12:11:15 +02:00
|
|
|
import os
|
2019-09-04 20:36:15 +02:00
|
|
|
|
2018-11-13 21:55:59 +01:00
|
|
|
from cement.core import handler, hook
|
2019-09-04 20:36:15 +02:00
|
|
|
from cement.core.controller import CementBaseController, expose
|
|
|
|
|
|
2018-11-13 21:55:59 +01:00
|
|
|
from wo.core.git import WOGit
|
2019-09-04 20:36:15 +02:00
|
|
|
from wo.core.logging import Log
|
2019-09-22 17:00:35 +02:00
|
|
|
from wo.core.random import RANDOM
|
2018-11-13 21:55:59 +01:00
|
|
|
from wo.core.services import WOService
|
2019-09-04 20:36:15 +02:00
|
|
|
from wo.core.shellexec import WOShellExec
|
2019-09-23 12:11:15 +02:00
|
|
|
from wo.core.template import WOTemplate
|
2019-09-04 20:36:15 +02:00
|
|
|
from wo.core.variables import WOVariables
|
2018-11-13 21:55:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def wo_secure_hook(app):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WOSecureController(CementBaseController):
|
|
|
|
|
class Meta:
|
|
|
|
|
label = 'secure'
|
|
|
|
|
stacked_on = 'base'
|
|
|
|
|
stacked_type = 'nested'
|
2019-09-19 14:07:34 +02:00
|
|
|
description = (
|
|
|
|
|
'Secure command provide the ability to'
|
|
|
|
|
'adjust settings for backend and to harden server security.')
|
2018-11-13 21:55:59 +01:00
|
|
|
arguments = [
|
|
|
|
|
(['--auth'],
|
2019-09-19 14:07:34 +02:00
|
|
|
dict(help='secure backend authentification',
|
|
|
|
|
action='store_true')),
|
2018-11-13 21:55:59 +01:00
|
|
|
(['--port'],
|
2019-09-19 14:07:34 +02:00
|
|
|
dict(help='set backend port', action='store_true')),
|
2018-11-13 21:55:59 +01:00
|
|
|
(['--ip'],
|
2019-09-19 14:07:34 +02:00
|
|
|
dict(help='set backend whitelisted ip', action='store_true')),
|
2019-09-23 12:11:15 +02:00
|
|
|
(['--sshport'], dict(
|
2019-09-21 19:12:46 +02:00
|
|
|
help='set custom ssh port', action='store_true')),
|
2019-09-23 12:11:15 +02:00
|
|
|
(['--ssh'], dict(
|
|
|
|
|
help='harden ssh security', action='store_true')),
|
2019-09-24 02:44:33 +02:00
|
|
|
(['--force'],
|
|
|
|
|
dict(help='force execution without being prompt',
|
2019-09-21 19:12:46 +02:00
|
|
|
action='store_true')),
|
2018-11-13 21:55:59 +01:00
|
|
|
(['user_input'],
|
|
|
|
|
dict(help='user input', nargs='?', default=None)),
|
|
|
|
|
(['user_pass'],
|
|
|
|
|
dict(help='user pass', nargs='?', default=None))]
|
|
|
|
|
usage = "wo secure [options]"
|
|
|
|
|
|
|
|
|
|
@expose(hide=True)
|
|
|
|
|
def default(self):
|
2019-08-07 02:45:26 +02:00
|
|
|
pargs = self.app.pargs
|
|
|
|
|
if pargs.auth:
|
2019-03-19 16:58:35 +01:00
|
|
|
self.secure_auth()
|
2019-08-07 02:45:26 +02:00
|
|
|
if pargs.port:
|
2019-03-19 16:58:35 +01:00
|
|
|
self.secure_port()
|
2019-08-07 02:45:26 +02:00
|
|
|
if pargs.ip:
|
2019-03-19 16:58:35 +01:00
|
|
|
self.secure_ip()
|
2019-09-23 12:11:15 +02:00
|
|
|
if pargs.sshport:
|
|
|
|
|
self.secure_ssh_port()
|
|
|
|
|
if pargs.ssh:
|
|
|
|
|
self.secure_ssh()
|
2018-11-13 21:55:59 +01:00
|
|
|
|
|
|
|
|
@expose(hide=True)
|
|
|
|
|
def secure_auth(self):
|
|
|
|
|
"""This function secures authentication"""
|
2019-09-23 13:09:15 +02:00
|
|
|
WOGit.add(self, ["/etc/nginx"],
|
|
|
|
|
msg="Add Nginx to into Git")
|
2019-08-07 02:45:26 +02:00
|
|
|
pargs = self.app.pargs
|
2019-09-19 14:07:34 +02:00
|
|
|
passwd = RANDOM.long(self)
|
2019-08-07 02:45:26 +02:00
|
|
|
if not pargs.user_input:
|
2018-11-13 21:55:59 +01:00
|
|
|
username = input("Provide HTTP authentication user "
|
|
|
|
|
"name [{0}] :".format(WOVariables.wo_user))
|
2019-08-07 02:45:26 +02:00
|
|
|
pargs.user_input = username
|
2018-11-13 21:55:59 +01:00
|
|
|
if username == "":
|
2019-08-07 02:45:26 +02:00
|
|
|
pargs.user_input = WOVariables.wo_user
|
|
|
|
|
if not pargs.user_pass:
|
2018-11-13 21:55:59 +01:00
|
|
|
password = getpass.getpass("Provide HTTP authentication "
|
|
|
|
|
"password [{0}] :".format(passwd))
|
2019-08-07 02:45:26 +02:00
|
|
|
pargs.user_pass = password
|
2018-11-13 21:55:59 +01:00
|
|
|
if password == "":
|
2019-08-07 02:45:26 +02:00
|
|
|
pargs.user_pass = passwd
|
2018-11-13 21:55:59 +01:00
|
|
|
Log.debug(self, "printf username:"
|
|
|
|
|
"$(openssl passwd -crypt "
|
|
|
|
|
"password 2> /dev/null)\n\""
|
|
|
|
|
"> /etc/nginx/htpasswd-wo 2>/dev/null")
|
|
|
|
|
WOShellExec.cmd_exec(self, "printf \"{username}:"
|
|
|
|
|
"$(openssl passwd -crypt "
|
|
|
|
|
"{password} 2> /dev/null)\n\""
|
|
|
|
|
"> /etc/nginx/htpasswd-wo 2>/dev/null"
|
2019-08-07 02:45:26 +02:00
|
|
|
.format(username=pargs.user_input,
|
|
|
|
|
password=pargs.user_pass),
|
2018-11-13 21:55:59 +01:00
|
|
|
log=False)
|
|
|
|
|
WOGit.add(self, ["/etc/nginx"],
|
|
|
|
|
msg="Adding changed secure auth into Git")
|
|
|
|
|
|
|
|
|
|
@expose(hide=True)
|
|
|
|
|
def secure_port(self):
|
|
|
|
|
"""This function Secures port"""
|
2019-09-23 13:09:15 +02:00
|
|
|
WOGit.add(self, ["/etc/nginx"],
|
|
|
|
|
msg="Add Nginx to into Git")
|
2019-08-07 02:45:26 +02:00
|
|
|
pargs = self.app.pargs
|
|
|
|
|
if pargs.user_input:
|
2019-09-23 13:09:15 +02:00
|
|
|
while ((not pargs.user_input.isdigit()) and
|
2019-09-23 14:24:16 +02:00
|
|
|
(not pargs.user_input < 65536)):
|
2018-11-13 21:55:59 +01:00
|
|
|
Log.info(self, "Please enter a valid port number ")
|
2019-08-07 02:45:26 +02:00
|
|
|
pargs.user_input = input("WordOps "
|
2019-09-05 11:47:04 +02:00
|
|
|
"admin port [22222]:")
|
2019-08-07 02:45:26 +02:00
|
|
|
if not pargs.user_input:
|
2018-11-13 21:55:59 +01:00
|
|
|
port = input("WordOps admin port [22222]:")
|
|
|
|
|
if port == "":
|
2019-09-23 13:09:15 +02:00
|
|
|
port = 22222
|
2019-09-23 14:24:16 +02:00
|
|
|
while (not port.isdigit()) and (port != "") and (not port < 65536):
|
2018-11-13 21:55:59 +01:00
|
|
|
Log.info(self, "Please Enter valid port number :")
|
|
|
|
|
port = input("WordOps admin port [22222]:")
|
2019-08-07 02:45:26 +02:00
|
|
|
pargs.user_input = port
|
2019-04-23 19:03:42 +02:00
|
|
|
WOShellExec.cmd_exec(self, "sed -i \"s/listen.*/listen "
|
|
|
|
|
"{port} default_server ssl http2;/\" "
|
|
|
|
|
"/etc/nginx/sites-available/22222"
|
2019-08-07 02:45:26 +02:00
|
|
|
.format(port=pargs.user_input))
|
2018-11-13 21:55:59 +01:00
|
|
|
WOGit.add(self, ["/etc/nginx"],
|
|
|
|
|
msg="Adding changed secure port into Git")
|
|
|
|
|
if not WOService.reload_service(self, 'nginx'):
|
|
|
|
|
Log.error(self, "service nginx reload failed. "
|
|
|
|
|
"check issues with `nginx -t` command")
|
|
|
|
|
Log.info(self, "Successfully port changed {port}"
|
2019-08-07 02:45:26 +02:00
|
|
|
.format(port=pargs.user_input))
|
2018-11-13 21:55:59 +01:00
|
|
|
|
|
|
|
|
@expose(hide=True)
|
|
|
|
|
def secure_ip(self):
|
|
|
|
|
"""IP whitelisting"""
|
2019-09-23 13:09:15 +02:00
|
|
|
WOGit.add(self, ["/etc/nginx"],
|
|
|
|
|
msg="Add Nginx to into Git")
|
2019-08-07 02:45:26 +02:00
|
|
|
pargs = self.app.pargs
|
|
|
|
|
if not pargs.user_input:
|
2018-11-13 21:55:59 +01:00
|
|
|
ip = input("Enter the comma separated IP addresses "
|
|
|
|
|
"to white list [127.0.0.1]:")
|
2019-08-07 02:45:26 +02:00
|
|
|
pargs.user_input = ip
|
2018-11-13 21:55:59 +01:00
|
|
|
try:
|
2019-08-07 02:45:26 +02:00
|
|
|
user_ip = pargs.user_input.split(',')
|
2018-11-13 21:55:59 +01:00
|
|
|
except Exception as e:
|
2019-07-29 15:08:49 +02:00
|
|
|
Log.debug(self, "{0}".format(e))
|
2018-11-13 21:55:59 +01:00
|
|
|
user_ip = ['127.0.0.1']
|
|
|
|
|
for ip_addr in user_ip:
|
|
|
|
|
if not ("exist_ip_address "+ip_addr in open('/etc/nginx/common/'
|
2019-03-19 16:58:35 +01:00
|
|
|
'acl.conf').read()):
|
2018-11-13 21:55:59 +01:00
|
|
|
WOShellExec.cmd_exec(self, "sed -i "
|
|
|
|
|
"\"/deny/i allow {whitelist_address}\;\""
|
|
|
|
|
" /etc/nginx/common/acl.conf"
|
|
|
|
|
.format(whitelist_address=ip_addr))
|
|
|
|
|
WOGit.add(self, ["/etc/nginx"],
|
|
|
|
|
msg="Adding changed secure ip into Git")
|
|
|
|
|
|
|
|
|
|
Log.info(self, "Successfully added IP address in acl.conf file")
|
|
|
|
|
|
2019-09-23 12:11:15 +02:00
|
|
|
@expose(hide=True)
|
|
|
|
|
def secure_ssh(self):
|
|
|
|
|
"""Harden ssh security"""
|
2019-09-24 02:44:33 +02:00
|
|
|
pargs = self.app.pargs
|
|
|
|
|
if not pargs.force:
|
|
|
|
|
start_secure = input('Are you sure you to want to'
|
|
|
|
|
' harden SSH security ?'
|
|
|
|
|
'\nSSH login with password will not '
|
|
|
|
|
'be possible anymore. Please make sure '
|
|
|
|
|
'you are already using SSH Keys.\n'
|
|
|
|
|
'Harden SSH security [y/N]')
|
|
|
|
|
if start_secure != "Y" and start_secure != "y":
|
|
|
|
|
Log.error(self, "Not hardening SSH security")
|
2019-09-23 12:38:16 +02:00
|
|
|
Log.debug(self, "check if /etc/ssh/sshd_config exist")
|
2019-09-23 12:35:11 +02:00
|
|
|
if os.path.isfile('/etc/ssh/sshd_config'):
|
2019-09-23 12:38:16 +02:00
|
|
|
Log.debug(self, "looking for the current ssh port")
|
2019-09-23 12:35:11 +02:00
|
|
|
for line in open('/etc/ssh/sshd_config', encoding='utf-8'):
|
|
|
|
|
if 'Port' in line:
|
|
|
|
|
ssh_line = line.strip()
|
2019-09-23 12:11:15 +02:00
|
|
|
break
|
2019-09-23 12:42:58 +02:00
|
|
|
port = (ssh_line).split(' ')
|
|
|
|
|
current_ssh_port = (port[1]).strip()
|
2019-09-23 13:46:31 +02:00
|
|
|
if os.getenv('SUDO_USER'):
|
2019-09-23 15:43:23 +02:00
|
|
|
sudo_user = os.getenv('SUDO_USER')
|
2019-09-23 13:46:31 +02:00
|
|
|
else:
|
|
|
|
|
sudo_user = ''
|
|
|
|
|
data = dict(sshport=current_ssh_port, allowpass='no',
|
|
|
|
|
user=sudo_user)
|
2019-09-23 16:35:20 +02:00
|
|
|
WOTemplate.deploy(self, '/etc/ssh/sshd_config',
|
2019-09-23 12:42:58 +02:00
|
|
|
'sshd.mustache', data)
|
2019-09-23 13:09:15 +02:00
|
|
|
WOGit.add(self, ["/etc/ssh"],
|
|
|
|
|
msg="Adding changed SSH port into Git")
|
|
|
|
|
if not WOService.restart_service(self, 'ssh'):
|
|
|
|
|
Log.error(self, "service SSH restart failed.")
|
|
|
|
|
Log.info(self, "Successfully harden SSH security")
|
2019-09-23 12:35:11 +02:00
|
|
|
else:
|
|
|
|
|
Log.error(self, "SSH config file not found")
|
2019-09-23 12:11:15 +02:00
|
|
|
|
2019-09-23 13:09:15 +02:00
|
|
|
@expose(hide=True)
|
|
|
|
|
def secure_ssh_port(self):
|
|
|
|
|
"""Change SSH port"""
|
|
|
|
|
WOGit.add(self, ["/etc/ssh"],
|
|
|
|
|
msg="Adding changed SSH port into Git")
|
|
|
|
|
pargs = self.app.pargs
|
|
|
|
|
if pargs.user_input:
|
|
|
|
|
while ((not pargs.user_input.isdigit()) and
|
2019-09-23 14:24:16 +02:00
|
|
|
(not pargs.user_input < 65536)):
|
2019-09-23 13:09:15 +02:00
|
|
|
Log.info(self, "Please enter a valid port number ")
|
|
|
|
|
pargs.user_input = input("Server "
|
|
|
|
|
"SSH port [22]:")
|
|
|
|
|
if not pargs.user_input:
|
|
|
|
|
port = input("Server SSH port [22]:")
|
|
|
|
|
if port == "":
|
|
|
|
|
port = 22
|
2019-09-23 14:24:16 +02:00
|
|
|
while (not port.isdigit()) and (port != "") and (not port < 65536):
|
2019-09-23 13:09:15 +02:00
|
|
|
Log.info(self, "Please Enter valid port number :")
|
|
|
|
|
port = input("Server SSH port [22]:")
|
|
|
|
|
pargs.user_input = port
|
2019-09-24 02:47:06 +02:00
|
|
|
WOShellExec.cmd_exec(self, "sed -i \"s/Port.*/Port "
|
|
|
|
|
"{port}/\" /etc/ssh/sshd_config"
|
2019-09-24 02:47:49 +02:00
|
|
|
.format(port=pargs.user_input))
|
2019-09-23 13:09:15 +02:00
|
|
|
WOGit.add(self, ["/etc/ssh"],
|
|
|
|
|
msg="Adding changed SSH port into Git")
|
|
|
|
|
if not WOService.restart_service(self, 'ssh'):
|
|
|
|
|
Log.error(self, "service SSH restart failed.")
|
|
|
|
|
Log.info(self, "Successfully changed SSH port to {port}"
|
|
|
|
|
.format(port=pargs.user_input))
|
|
|
|
|
|
2018-11-13 21:55:59 +01:00
|
|
|
|
|
|
|
|
def load(app):
|
2019-09-24 00:01:20 +02:00
|
|
|
app.handler.register(WOSecureController)
|
2019-09-24 00:04:32 +02:00
|
|
|
app.hook.register('post_argument_parsing', wo_secure_hook)
|