From e7e1a6b41d1e643df38c3af107d97c665b546d27 Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Fri, 12 Apr 2024 13:38:11 -0700 Subject: [PATCH] nextcloud: Drop network namespacing in container, use host network - This is not ideal and reduces security. However it simplifies quite a bit of setup. - Services on the host network are already exposed to the container (however, they could easily be protected with firewall rules). - Container has full access to external networks already. So this part does not change. - This setup would be at par with how other services run on FreedomBox right now. We can think of generalized solution for all the apps later. - FirewallLocalProtection for the single service the runs in the container works as usual without change. Signed-off-by: Sunil Mohan Adapa Reviewed-by: James Valleroy --- plinth/action_utils.py | 38 +++----------------------- plinth/modules/nextcloud/privileged.py | 22 ++------------- 2 files changed, 6 insertions(+), 54 deletions(-) diff --git a/plinth/action_utils.py b/plinth/action_utils.py index 8df737493..97201bb32 100644 --- a/plinth/action_utils.py +++ b/plinth/action_utils.py @@ -489,51 +489,27 @@ def is_package_manager_busy(): return False -def podman_create(network_name: str, subnet: str, bridge_ip: str, - host_port: str, container_port: str, container_ip: str, - container_name: str, image_name: str, +def podman_create(container_name: str, image_name: str, volumes: dict[str, str] | None = None, env: dict[str, str] | None = None): """Remove and recreate a podman container.""" - service_stop(f'{network_name}-network.service') service_stop(container_name) - subprocess.run(['podman', 'network', 'rm', '--force', network_name], - check=False) - directory = pathlib.Path('/etc/containers/systemd') directory.mkdir(parents=True, exist_ok=True) - # Create bridge network - network_file = directory / f'{network_name}.network' - contents = f'''[Network] -DNS={bridge_ip} -Driver=bridge -Gateway={bridge_ip} -NetworkName={network_name} -Subnet={subnet} -PodmanArgs=--interface-name={network_name} -''' - network_file.write_text(contents) - service_file = directory / f'{container_name}.container' volume_lines = '\n'.join([ f'Volume={source}:{dest}' for source, dest in (volumes or {}).items() ]) env_lines = '\n'.join( [f'Environment={key}={value}' for key, value in (env or {}).items()]) - contents = f'''[Unit] -Requires=nextcloud-fbx-network.service -After=nextcloud-fbx-network.service - -[Container] + contents = f'''[Container] AutoUpdate=registry ContainerName=%N {env_lines} Image={image_name} -IP={container_ip} -Network={network_name} -PublishPort=127.0.0.1:{host_port}:{container_port} +Network=host {volume_lines} [Service] @@ -546,16 +522,10 @@ WantedBy=default.target service_daemon_reload() -def podman_uninstall(container_name: str, network_name: str, volume_name: str, - image_name: str): +def podman_uninstall(container_name: str, volume_name: str, image_name: str): """Remove a podman container's components and systemd unit.""" subprocess.run(['podman', 'volume', 'rm', volume_name], check=True) subprocess.run(['podman', 'image', 'rm', image_name], check=True) - subprocess.run(['podman', 'network', 'rm', '--force', network_name], - check=True) - network_file = pathlib.Path( - '/etc/containers/systemd/') / f'{network_name}.network' - network_file.unlink(missing_ok=True) service_file = pathlib.Path( '/etc/containers/systemd/') / f'{container_name}.container' service_file.unlink(missing_ok=True) diff --git a/plinth/modules/nextcloud/privileged.py b/plinth/modules/nextcloud/privileged.py index 12479b7c9..dd19ef49a 100644 --- a/plinth/modules/nextcloud/privileged.py +++ b/plinth/modules/nextcloud/privileged.py @@ -15,9 +15,6 @@ import augeas from plinth import action_utils from plinth.actions import privileged -NETWORK_NAME = 'nextcloud-fbx' -BRIDGE_IP = '172.16.16.1' -CONTAINER_IP = '172.16.16.2' CONTAINER_NAME = 'nextcloud-freedombox' SERVICE_NAME = 'nextcloud-freedombox' VOLUME_NAME = 'nextcloud-volume-freedombox' @@ -58,15 +55,10 @@ def setup(): '/run/slapd/ldapi': '/run/slapd/ldapi', VOLUME_NAME: '/var/www/html' } - env = {'TRUSTED_PROXIES': BRIDGE_IP, 'OVERWRITEWEBROOT': '/nextcloud'} - action_utils.podman_create(network_name=NETWORK_NAME, - subnet='172.16.16.0/24', bridge_ip=BRIDGE_IP, - host_port='8181', container_port='80', - container_ip=CONTAINER_IP, - container_name=CONTAINER_NAME, + env = {'TRUSTED_PROXIES': '127.0.0.1', 'OVERWRITEWEBROOT': '/nextcloud'} + action_utils.podman_create(container_name=CONTAINER_NAME, image_name=IMAGE_NAME, volumes=volumes, env=env) action_utils.service_start(CONTAINER_NAME) - _configure_firewall(action='add', interface_name=NETWORK_NAME) # OCC isn't immediately available after the container is spun up. # Wait until CAN_INSTALL file is available. @@ -156,14 +148,6 @@ def set_default_phone_region(region: str): _run_occ('config:system:set', 'default_phone_region', '--value', region) -def _configure_firewall(action, interface_name): - subprocess.run([ - 'firewall-cmd', '--permanent', '--zone=trusted', - f'--{action}-interface={interface_name}' - ], check=True) - action_utils.service_restart('firewalld') - - def _database_query(query: str): """Run a database query.""" subprocess.run(['mysql'], input=query.encode(), check=True) @@ -292,9 +276,7 @@ WantedBy=timers.target def uninstall(): """Uninstall Nextcloud""" _drop_database() - _configure_firewall(action='remove', interface_name=NETWORK_NAME) action_utils.podman_uninstall(container_name=CONTAINER_NAME, - network_name=NETWORK_NAME, volume_name=VOLUME_NAME, image_name=IMAGE_NAME) for path in [_cron_service_file, _cron_timer_file]: