systemd Unit Generator
Draft a systemd service unit from workload, account, restart and hardening choices with local review findings and host verification commands.{{ summaryTitle }}
{{ summaryLine }}
{{ values.unit_text }}
The chart renderer is unavailable. Section counts remain available in the directive ledger.
| Section | Directive | Value | Rationale | Copy |
|---|---|---|---|---|
| {{ row.section }} | {{ row.directive }} | {{ row.value }} | {{ row.rationale }} |
| Level | Check | Finding | Next action | Copy |
|---|---|---|---|---|
| {{ row.level }} | {{ row.check }} | {{ row.finding }} | {{ row.action }} |
| Step | Command or path | Purpose | Copy |
|---|---|---|---|
| {{ row.step }} | {{ row.command }} | {{ row.purpose }} |
A background command becomes an operable Linux service only when its lifecycle is explicit. The service manager needs to know what to start, how readiness is reported, which failures justify a restart, what resources the process may access, and when the unit should be enabled. Those choices belong in a service unit rather than in shell history or an undocumented boot script.
Most service units have three sections. [Unit] names the workload and expresses ordering or dependency relationships. [Service] defines process startup, identity, environment, restart behavior, and sandboxing. [Install] records the target used when an administrator enables the unit; it does not start the process by itself.
- System manager
- Runs machine services, commonly from
/etc/systemd/system, and can assign a dedicated account withUser=andGroup=. - User manager
- Runs services owned by one signed-in account, commonly from
~/.config/systemd/user. The unit does not need aUser=directive because the manager already has an owner. - Service type
- Defines when startup is considered complete and which process model systemd should expect.
- Install target
- The target that receives an enable-time relationship, commonly
multi-user.targetfor a system service ordefault.targetfor a user service.
Type=exec is a useful starting point for a foreground command because an execution failure can be reported during startup. notify and notify-reload require the application to send the matching service notifications. dbus needs the well-known bus name the process acquires, while forking is for a daemon that truly moves into the background and often needs a PID file.
Hardening is a compatibility decision as well as a security decision. Read-only filesystem settings, private devices, restricted address families, and writable-executable-memory limits can block a workload that was never tested under them. Start with a justified profile, allow only the paths the service needs, and verify the actual program on the target host.
A syntactically clean unit can still fail because an account, executable, directory, environment file, kernel feature, or dependency is missing. Service status also cannot prove that the application performs its real work. Validation must continue from parser checks to activation, logs, and one workload-specific outcome.
How to Use This Tool:
Use a preset as an editable example, then replace every path and account with values from the target host.
- Choose System manager or User manager, name the service, and enter an absolute ExecStart command for the foreground workload.
- Select the Service type, restart policy, startup dependency, install target, and hardening profile. Use
notify,dbus, orforkingonly when the application follows that lifecycle. - Add the working directory, environment source, timeouts, managed directories, and writable paths that the workload genuinely needs. Put one
KEY=valueassignment per environment line. - Read Review findings. Resolve warnings about paths, root execution, one-shot restart conflicts, missing PID files, strict filesystem writes, runtime compatibility, or likely inline secrets.
- Follow Activation plan on the target host. Verify the unit, reload the correct manager, enable or start it, inspect status and journal output, then test the application's real output.
Interpreting Results:
Ready for host verification means no local Warning or Review finding was produced. Review needed counts both levels but not informational notes. Neither state confirms that the installed systemd version accepts every directive or that host accounts, permissions, paths, sockets, and application protocols are correct.
Read the generated unit beside the directive ledger, then run the supplied systemd-analyze verify command on the destination. After startup, inspect service status and journal messages. Finish with a workload check such as a responding socket, updated queue, created file, or successful request; an active process alone is incomplete evidence.
Technical Details:
A service unit is assembled from validated directives in fixed section order: [Unit], [Service], then [Install]. Empty optional values are omitted. Repeated directives such as Environment= and ReadWritePaths= retain one line per accepted entry.
Rule Core
| Decision | Exact rule |
|---|---|
| Filename | Remove a trailing .service, replace unsafe runs with hyphens, trim leading punctuation, and append .service. A changed name produces a review warning. |
| Manager scope | System units may emit User= and Group=. User-manager units omit both and run as the owning account. |
| Process type | Type=dbus requires a valid dot-separated BusName. Type=oneshot rejects Restart=always and Restart=on-success. |
| Restart and timeouts | RestartSec accepts 0 through 86,400 whole seconds and is omitted when restart is no. Optional start and stop timeouts accept 0 through 604,800 seconds. |
| Network order | Configured-network readiness emits both Wants=network-online.target and After=network-online.target. Basic network order emits only After=network.target; no-network order emits neither. |
| Environment | Each inline assignment must use a valid shell-style key followed by =. Values are escaped and quoted; secret-looking names produce a review item. |
| Install target | The value must be one target unit name ending in .target with no whitespace. |
| Writable paths | Every ReadWritePaths entry must be absolute. |
Restart policy does not replace a correct service type. A forking daemon without a PID file is flagged because main-process tracking may be ambiguous. Notification types are flagged for protocol confirmation, and a one-shot command without RemainAfterExit=yes is expected to become inactive after successful completion.
Transformation Core
Validated inputs become directive rows, directive rows become unit text, and the same normalized values drive the review findings and activation commands. A system-scoped Node worker with Type=exec, Restart=on-failure, a 5-second delay, and configured-network ordering produces Description, Wants, After, Type, User, WorkingDirectory, ExecStart, Restart, RestartSec, hardening, and WantedBy directives when their values are present.
| Profile | Added restrictions | Main review boundary |
|---|---|---|
| Compatibility / off | No generated hardening directives | The workload keeps the manager's ordinary access. |
| Standard baseline | NoNewPrivileges, PrivateTmp, ProtectSystem=full, ProtectHome=read-only | Confirm writes outside managed application paths. |
| Network-service sandbox | Standard restrictions plus private devices, SUID/SGID restriction, and Unix/IPv4/IPv6 address-family limits | Non-IP protocols and device access may fail. |
| Strict filesystem | Strict filesystem and home protection, kernel and cgroup protections, SUID/SGID limits, locked personality, and no writable executable memory | Declare required state, runtime, or writable paths; test JIT runtimes. |
| Locked-down non-JIT | Strict restrictions plus private devices, clock and hostname protection, realtime restriction, and native system-call architecture | Container engines and other privileged runtimes are likely to need a less restrictive starting point. |
ProtectSystem=strict is flagged when no StateDirectory, RuntimeDirectory, or writable path is declared. Commands suggesting Node, Java, Ruby, .NET, or PHP receive a writable-executable-memory review under strict profiles. These checks are repo-authored cautions, not results from running systemd-analyze security on the destination.
| Scope | Unit path | Manager commands |
|---|---|---|
| System | /etc/systemd/system/name.service | sudo systemctl daemon-reload and sudo systemctl enable --now name.service |
| User | ~/.config/systemd/user/name.service | systemctl --user daemon-reload and systemctl --user enable --now name.service |
Security and Host Limits:
The draft is produced in the browser and the target host is not inspected. Review inline environment values before copying because generated text, clipboard history, tickets, and chat messages can expose credentials.
- Use a protected
EnvironmentFileor another host-approved secret mechanism for sensitive values. - Prefer a dedicated system account when root privileges are unnecessary.
- Test every hardening restriction against startup and normal workload behavior.
- Check the installed systemd version because directive support and behavior can vary by release and distribution.
- For user services that must run without an active login, separately review whether lingering is appropriate for that account.
References:
- systemd.service, systemd project.
- systemd.exec, systemd project.
- How to create a systemd service unit, Simplified Guide.
- How to create a user systemd service unit, Simplified Guide.