|
@@ -0,0 +1,69 @@
|
|
|
+[Unit]
|
|
|
+Description=listmonk mailing list and newsletter manager (%I)
|
|
|
+ConditionPathExists=/etc/listmonk/%i.toml
|
|
|
+Wants=network.target
|
|
|
+# The PostgreSQL database may not be on the same host but if it
|
|
|
+# is listmonk should wait for it to start up.
|
|
|
+After=postgresql.service
|
|
|
+
|
|
|
+[Service]
|
|
|
+Type=simple
|
|
|
+EnvironmentFile=-/etc/default/listmonk
|
|
|
+EnvironmentFile=-/etc/default/listmonk-%i
|
|
|
+ExecStartPre=/usr/bin/mkdir -p "${HOME}/uploads"
|
|
|
+ExecStartPre=/usr/bin/listmonk --config /etc/listmonk/%i.toml --upgrade --yes
|
|
|
+ExecStart=/usr/bin/listmonk --config /etc/listmonk/%i.toml $SYSTEMD_LISTMONK_ARGS
|
|
|
+Restart=on-failure
|
|
|
+
|
|
|
+# Create dynamic users for listmonk service instances
|
|
|
+# but create a state directory for uploads in /var/lib/private/%i.
|
|
|
+DynamicUser=True
|
|
|
+StateDirectory=listmonk-%i
|
|
|
+Environment=HOME=%S/listmonk-%i
|
|
|
+WorkingDirectory=%S/listmonk-%i
|
|
|
+
|
|
|
+# Use systemd’s ability to disable security-sensitive features
|
|
|
+# that listmonk does not explicitly need.
|
|
|
+# NoNewPrivileges should be enabled by DynamicUser=yes but systemd-analyze
|
|
|
+# still recommended to explicitly enable it.
|
|
|
+NoNewPrivileges=True
|
|
|
+# listmonk doesn’t need any capabilities as defined by the linux kernel
|
|
|
+# see: https://man7.org/linux/man-pages/man7/capabilities.7.html
|
|
|
+CapabilityBoundingSet=
|
|
|
+# listmonk only executes native code with no need for any other ABIs.
|
|
|
+SystemCallArchitectures=native
|
|
|
+# Only enable a reasonable set of system calls.
|
|
|
+# see: https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=
|
|
|
+SystemCallFilter=@system-service
|
|
|
+SystemCallFilter=~@privileged @resources
|
|
|
+# ProtectSystem=strict, which is implied by DynamicUser=True, already disabled write calls
|
|
|
+# to the entire filesystem hierarchy, leaving only /dev/, /proc/, and /sys/ writable.
|
|
|
+# listmonk doesn’t need access to those so might as well disable them.
|
|
|
+PrivateDevices=True
|
|
|
+ProtectControlGroups=True
|
|
|
+ProtectKernelTunables=True
|
|
|
+# Make /home/, /root/, and /run/user/ inaccessible.
|
|
|
+ProtectHome=True
|
|
|
+# listmonk doesn’t handle any specific device nodes.
|
|
|
+DeviceAllow=False
|
|
|
+# listmonk doesn’t make use of linux namespaces.
|
|
|
+RestrictNamespaces=True
|
|
|
+# listmonk doesn’t need realtime scheduling.
|
|
|
+RestrictRealtime=True
|
|
|
+# Make sure files created by listmonk are only readable by itself and
|
|
|
+# others in the listmonk system group.
|
|
|
+UMask=0027
|
|
|
+# Disable memory mappings that are both writable and executable.
|
|
|
+MemoryDenyWriteExecute=True
|
|
|
+# listmonk doesn’t make use of linux personality switching.
|
|
|
+LockPersonality=True
|
|
|
+# listmonk only needs to support the IPv4 and IPv6 address families.
|
|
|
+RestrictAddressFamilies=AF_INET AF_INET6
|
|
|
+# listmonk doesn’t need to load any linux kernel modules.
|
|
|
+ProtectKernelModules=True
|
|
|
+# Create a sandboxed environment where the system users are mapped to a
|
|
|
+# service-specific linux kernel namespace.
|
|
|
+PrivateUsers=True
|
|
|
+
|
|
|
+[Install]
|
|
|
+WantedBy=multi-user.target
|