| Linux server27.hostingraja.org 2.6.32-954.3.5.lve1.4.93.el6.x86_64 #1 SMP Wed Oct 4 17:04:29 UTC 2023 x86_64 Path : /opt/imunify360/venv/lib/python3.11/site-packages/im360/plugins/ |
| Current File : //opt/imunify360/venv/lib/python3.11/site-packages/im360/plugins/service_manager.py |
"""Services manager plugin.
It enables/disables various service based on an imunify360 config change.
"""
import asyncio
import logging
from defence360agent.contracts import messages, plugins
from defence360agent import utils
from defence360agent.subsys import svcctl
from im360.contracts import config
from im360.simple_rpc.resident_socket import send_to_socket
from im360.subsys import webshield
__all__ = ["ServiceManager"]
logger = logging.getLogger(__name__)
class ServiceManager(plugins.MessageSink):
"""Service manager plugin: stop/start services based on config changes."""
AUDITD_SHOULD_BE_RUNNING = config.FromConfig("LOGGER", "syscall_monitor")
def __init__(self, *, unitctl=None):
self._lock = asyncio.Lock()
self._services = [
self._ensure_consistent_webshield_state,
self._ensure_consistent_dos_protector_state,
self._ensure_consistent_ual_state,
self._ensure_consistend_auditd_state,
]
self._units = {
"dos_protector": unitctl
or svcctl.imunify360_dos_protector_service(),
"ual": unitctl or svcctl.imunify360_ual_service(),
"auditd": unitctl or svcctl.imunify360_auditd_service(),
}
self._configs = {"dos_protector": {}}
async def create_sink(self, loop):
# on startup ConfigUpdate message is sent to all plugins
pass
async def _ensure_consistent_services_state(self):
for service in self._services:
await service()
@plugins.expect(messages.MessageType.ConfigUpdate)
async def on_config_update(
self, message_ignored: messages.MessageType.ConfigUpdate
):
async with self._lock: # handle concurrent config updates
await self._ensure_consistent_services_state()
@utils.log_error_and_ignore()
@utils.retry_on(webshield.Error, max_tries=2)
async def _ensure_consistent_webshield_state(self):
should_be_running = config.Webshield.ENABLE
if (await webshield.is_running()) is not should_be_running:
if should_be_running:
logger.info(
"WebShield is enabled in the config but it is not running."
" Enabling it..."
)
# enable on boot & start it right now
await webshield.service_enable(now=True)
logger.info("Enabled WebShield")
else:
logger.info(
"WebShield is not enabled in the config but it is running."
" Disabling it..."
)
# disable on boot & stop it right now
await webshield.service_disable(now=True)
logger.info("Disabled WebShield")
await send_to_socket(
msg={
"method": "UPDATE_RULES",
"purpose": "webshield state change",
},
wait_for_response=False,
)
if should_be_running:
await webshield.splashscreen_set_state(
config.Webshield.SPLASH_SCREEN
)
await webshield.cpanelprotection_set_state(
config.Webshield.PANEL_PROTECTION
)
@utils.log_error_and_ignore()
async def __ensure_service_status(
self, unitctl, service_name, should_be_running, reload=False
):
is_running = await unitctl.is_active()
if is_running is not should_be_running:
if should_be_running:
logger.info(
"%s is enabled in the config but it is not"
" running. Enabling it...",
service_name,
)
# enable on boot & start it right now
await unitctl.enable(now=True)
logger.info("Enabled %s", service_name)
else:
logger.info(
"%s is not enabled in the config but it is"
" running. Disabling it...",
service_name,
)
# disable on boot & stop it right now
await unitctl.disable(now=True)
logger.info("Disabled %s", service_name)
else:
if is_running and reload:
await unitctl.reload()
logger.info(
"Reloading %s after config update...", service_name
) # noqa: E501
async def _ensure_consistent_dos_protector_state(self):
unitctl = self._units["dos_protector"]
if not unitctl:
# unsupported platform
return
old_config = self._configs["dos_protector"]
new_config = config.EnhancedDOS.as_dict()
should_be_running = config.EnhancedDOS.ENABLED
await self.__ensure_service_status(
unitctl,
"DosProtector",
should_be_running,
reload=(old_config != new_config),
)
self._configs["dos_protector"] = new_config
async def _ensure_consistent_ual_state(self):
should_be_running = config.UnifiedAccessLogger.ENABLED
unitctl = self._units["ual"]
await self.__ensure_service_status(
unitctl, "UnifiedAccessLogger", should_be_running, reload=False
)
async def _ensure_consistend_auditd_state(self):
unitctl = self._units["auditd"]
if not unitctl:
# unsupported platform
return
await self.__ensure_service_status(
unitctl, "AuditD", self.AUDITD_SHOULD_BE_RUNNING, reload=False
)