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 <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2024-04-12 13:38:11 -07:00 committed by James Valleroy
parent 3f8874f461
commit e7e1a6b41d
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
2 changed files with 6 additions and 54 deletions

View File

@ -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)

View File

@ -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]: