[#759] Add fail2ban to Plinth UI

Run sudo-required action via actions.superuser_run

Actions related to services those require `sudo` permissions need to
be executed via actions.superuser_run.

NOTE:
If plinth service is started via `sudo ./run --debug` (in dev mode)
all actions will be executed silently. But plinth in user machines
won't be executed with sudo permissions.
This commit is contained in:
nsaikiran 2017-07-14 18:32:19 +05:30 committed by James Valleroy
parent 09f3f23e10
commit a8a5da996e
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
5 changed files with 42 additions and 2 deletions

View File

@ -36,6 +36,7 @@ def add_service_action(subparsers, action, help):
parser = subparsers.add_parser(action, help=help)
parser.add_argument('service', help='name of the service')
def parse_arguments():
"""Return parsed command line arguments as dictionary."""
parser = argparse.ArgumentParser()
@ -48,6 +49,7 @@ def parse_arguments():
add_service_action(subparsers, 'reload', 'reload a service')
add_service_action(subparsers, 'is-running', 'status of a service')
add_service_action(subparsers, 'is-enabled', 'status a service')
add_service_action(subparsers, 'unmask', 'unmask a service')
subparsers.add_parser('list', help='List of running system services')
@ -75,6 +77,10 @@ def subcommand_reload(arguments):
action_utils.service_reload(arguments.service)
def subcommand_unmask(arguments):
action_utils.service_unmask(arguments.service)
def subcommand_is_enabled(arguments):
print(action_utils.service_is_enabled(arguments.service))

View File

@ -88,6 +88,11 @@ def service_disable(service_name):
subprocess.call(['systemctl', 'disable', service_name])
def service_unmask(service_name):
"""Unmask a service"""
subprocess.call(['systemctl', 'unmask', service_name])
def service_start(service_name):
"""Start a service with systemd or sysvinit."""
if is_systemd_running():

View File

@ -25,12 +25,15 @@ from plinth import actions
from plinth.menu import main_menu
version = 1
version = 2
is_essential = True
title = _('Security')
managed_packages = ['fail2ban']
managed_services = ['fail2ban']
ACCESS_CONF_FILE = '/etc/security/access.conf'
ACCESS_CONF_SNIPPET = '-:ALL EXCEPT root fbx (admin) (sudo):ALL'
@ -42,6 +45,17 @@ def init():
menu.add_urlname(title, 'glyphicon-lock', 'security:index')
def setup(helper, old_version=None):
"""Install the required packages"""
helper.install(managed_packages)
setup_fail2ban()
def setup_fail2ban():
actions.superuser_run('service', ['unmask', 'fail2ban'])
actions.superuser_run('service', ['enable', 'fail2ban'])
def get_restricted_access_enabled():
"""Return whether restricted access is enabled"""
with open(ACCESS_CONF_FILE, 'r') as conffile:

View File

@ -31,3 +31,9 @@ class SecurityForm(forms.Form):
'group will be able to log in to console or via SSH. '
'Console users may be able to access some services '
'without further authorization.'))
fail2ban_enabled = forms.BooleanField(
label=_('Fail2ban (recommended)'), required=False,
help_text=_('When this option is enabled, fail2ban will limit brute force '
'break-in attempts to the SSH server and other password protected '
'internet-services which are enabled.'
))

View File

@ -25,6 +25,8 @@ from django.utils.translation import ugettext as _
from .forms import SecurityForm
from plinth.modules import security
from plinth import actions
from plinth import action_utils
def index(request):
@ -49,7 +51,8 @@ def index(request):
def get_status(request):
"""Return the current status"""
return {'restricted_access': security.get_restricted_access_enabled()}
return {'restricted_access': security.get_restricted_access_enabled(),
'fail2ban_enabled': action_utils.service_is_enabled('fail2ban')}
def _apply_changes(request, old_status, new_status):
@ -64,3 +67,9 @@ def _apply_changes(request, old_status, new_status):
.format(exception=exception))
else:
messages.success(request, _('Updated security configuration'))
if old_status['fail2ban_enabled'] != new_status['fail2ban_enabled']:
if new_status['fail2ban_enabled']:
actions.superuser_run('service',['enable','fail2ban'])
else:
actions.superuser_run('service',['disable','fail2ban'])