security: Remove restricted access setting and configuration

Closes: #2276.

Functionality all over the system keeps failing due this approach. The latest is
changing hostname in ejabberd Mnesia database fails (#2276). Further, users
connecting FreedomBox to a monitor can't use a GUI.

Tests:

- Without patches, enable restricted access. Apply patches and setup.py install.
Security app is updated. Restricted access is disabled and
/etc/security/access.d/{50freedombox.conf, 10freedombox-security.conf,
10freedombox-performance.conf} are removed. It is possible to login into
non-admin account via SSH.

- On a fresh install, the configuration files are not found.

- Security page does not show 'restrict console logins' option.

- Updating security app setting works. Message 'Configuration updated.' is
shown.

- First boot succeeds. Restrict console login is not enabled.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2022-11-11 11:52:11 -08:00 committed by James Valleroy
parent c20f640641
commit 253540fb3d
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
11 changed files with 12 additions and 121 deletions

View File

@ -23,3 +23,5 @@ rm_conffile /etc/apache2/sites-available/plinth.conf 22.16~
rm_conffile /etc/apache2/sites-available/plinth-ssl.conf 22.16~
rm_conffile /etc/fail2ban/jail.d/wordpress-auth-freedombox.conf 22.22~
rm_conffile /etc/fail2ban/filter.d/wordpress-auth-freedombox.conf 22.22~
rm_conffile /etc/security/access.d/10freedombox-performance.conf 22.25~
rm_conffile /etc/security/access.d/10freedombox-security.conf 22.25~

View File

@ -22,7 +22,7 @@ class SecurityApp(app_module.App):
app_id = 'security'
_version = 7
_version = 8
can_be_disabled = False
@ -57,11 +57,8 @@ class SecurityApp(app_module.App):
service_privileged.reload('fail2ban')
# Migrate to new config file.
enabled = privileged.get_restricted_access_enabled()
set_restricted_access(False)
if enabled:
set_restricted_access(True)
# Drop the legacy restriction access configuration
privileged.disable_restricted_access()
def enable_fail2ban():
@ -70,14 +67,6 @@ def enable_fail2ban():
service_privileged.enable('fail2ban')
def set_restricted_access(enabled):
"""Enable or disable restricted access."""
if enabled:
privileged.enable_restricted_access()
else:
privileged.disable_restricted_access()
def get_apps_report():
"""Return a security report for each app."""
lines = subprocess.check_output(['debsecan']).decode().split('\n')

View File

@ -1,2 +0,0 @@
# allow debsecan cron job
+:daemon:cron

View File

@ -9,12 +9,6 @@ from django.utils.translation import gettext_lazy as _
class SecurityForm(forms.Form):
"""Security configuration form"""
restricted_access = forms.BooleanField(
label=_('Restrict console logins (recommended)'), required=False,
help_text=_('When this option is enabled, only users in the "admin" '
'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 '

View File

@ -12,18 +12,6 @@ OLD_ACCESS_CONF_SNIPPET = '-:ALL EXCEPT root fbx (admin) (sudo):ALL'
ACCESS_CONF_SNIPPETS = [OLD_ACCESS_CONF_SNIPPET, ACCESS_CONF_SNIPPET]
@privileged
def enable_restricted_access():
"""Restrict console login to users in admin or sudo group."""
try:
os.mkdir(os.path.dirname(ACCESS_CONF_FILE))
except FileExistsError:
pass
with open(ACCESS_CONF_FILE, 'w', encoding='utf-8') as conffile:
conffile.write(ACCESS_CONF_SNIPPET + '\n')
@privileged
def disable_restricted_access():
"""Don't restrict console login to users in admin or sudo group."""
@ -39,18 +27,3 @@ def disable_restricted_access():
os.remove(ACCESS_CONF_FILE)
except OSError:
pass
def get_restricted_access_enabled():
"""Return whether restricted access is enabled."""
with open(ACCESS_CONF_FILE_OLD, 'r', encoding='utf-8') as conffile:
if any(line.strip() in ACCESS_CONF_SNIPPETS
for line in conffile.readlines()):
return True
try:
with open(ACCESS_CONF_FILE, 'r', encoding='utf-8') as conffile:
return any(line.strip() in ACCESS_CONF_SNIPPETS
for line in conffile.readlines())
except FileNotFoundError:
return False

View File

@ -16,39 +16,7 @@ def fixture_background(session_browser):
functional.login(session_browser)
def test_restricted_console_logins(session_browser):
"""Test enabling and disabling restricted console logins."""
_enable_restricted_logins(session_browser, False)
assert not _get_restricted_logins(session_browser)
_enable_restricted_logins(session_browser, True)
assert _get_restricted_logins(session_browser)
@pytest.mark.backups
def test_backup_restore(session_browser):
"""Test backup and restore of configuration."""
_enable_restricted_logins(session_browser, True)
functional.backup_create(session_browser, 'security', 'test_security')
_enable_restricted_logins(session_browser, False)
functional.backup_restore(session_browser, 'security', 'test_security')
assert _get_restricted_logins(session_browser)
def _enable_restricted_logins(browser, should_enable):
"""Enable/disable restricted logins in security module."""
functional.nav_to_module(browser, 'security')
if should_enable:
browser.check('security-restricted_access')
else:
browser.uncheck('security-restricted_access')
functional.submit(browser, form_class='form-configuration')
def _get_restricted_logins(browser):
"""Return whether restricted console logins is enabled."""
functional.nav_to_module(browser, 'security')
return browser.find_by_name('security-restricted_access').first.checked

View File

@ -11,7 +11,6 @@ from plinth.modules.upgrades import is_backports_requested
from plinth.privileged import service as service_privileged
from plinth.views import AppView
from . import privileged
from .forms import SecurityForm
@ -43,31 +42,19 @@ class SecurityAppView(AppView):
def get_status(request):
"""Return the current status."""
return {
'restricted_access': privileged.get_restricted_access_enabled(),
'fail2ban_enabled': action_utils.service_is_enabled('fail2ban')
}
return {'fail2ban_enabled': action_utils.service_is_enabled('fail2ban')}
def _apply_changes(request, old_status, new_status):
"""Apply the form changes."""
if old_status['restricted_access'] != new_status['restricted_access']:
try:
security.set_restricted_access(new_status['restricted_access'])
except Exception as exception:
messages.error(
request,
_('Error setting restricted access: {exception}').format(
exception=exception))
else:
messages.success(request, _('Updated security configuration'))
if old_status['fail2ban_enabled'] != new_status['fail2ban_enabled']:
if new_status['fail2ban_enabled']:
service_privileged.enable('fail2ban')
else:
service_privileged.disable('fail2ban')
messages.success(request, _('Configuration updated.'))
def report(request):
"""Serve the security report page."""

View File

@ -18,7 +18,6 @@ from django.utils.translation import gettext_lazy
import plinth.forms
import plinth.modules.ssh.privileged as ssh_privileged
from plinth.modules import first_boot
from plinth.modules.security import set_restricted_access
from plinth.utils import is_user_admin
from . import get_last_admin_user, privileged
@ -392,15 +391,6 @@ class FirstBootForm(ValidNewUsernameCheckMixin, auth.forms.UserCreationForm):
self.login_user(self.cleaned_data['username'],
self.cleaned_data['password1'])
# Restrict console login to users in admin or sudo group
try:
set_restricted_access(True)
except Exception as error:
messages.error(
self.request,
_('Failed to restrict console access: {error}'.format(
error=error)))
return user
def login_user(self, username, password):

View File

@ -13,7 +13,6 @@ import subprocess
import pytest
from plinth import action_utils
from plinth.modules.security import privileged as security_privileged
from plinth.modules.users import privileged
from plinth.tests import config as test_config
@ -87,18 +86,6 @@ def _try_login_to_ssh(username, password, returncode=0):
return process.returncode == returncode
@pytest.fixture(name='disable_restricted_access', autouse=True)
def fixture_disable_restricted_access(needs_root, load_cfg):
"""Disable console login restrictions."""
restricted_access = security_privileged.get_restricted_access_enabled()
if restricted_access:
security_privileged.disable_restricted_access()
yield
security_privileged.enable_restricted_access()
else:
yield
@pytest.fixture(name='auto_cleanup_users_groups', autouse=True)
def fixture_auto_cleanup_users_groups(needs_root, load_cfg):
"""Remove all the users and groups created during tests."""

View File

@ -2,6 +2,8 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
FreedomBox Service setup file.
isort:skip_file
"""
import collections
@ -55,6 +57,8 @@ REMOVED_FILES = [
'/etc/apt/preferences.d/50freedombox3.pref',
'/etc/apache2/sites-available/plinth.conf',
'/etc/apache2/sites-available/plinth-ssl.conf',
'/etc/security/access.d/10freedombox-performance.conf',
'/etc/security/access.d/10freedombox-security.conf',
]
LOCALE_PATHS = ['plinth/locale']