{{ summaryTitle }}
{{ summaryValue }}

{{ summaryLine }}

Manager{{ resultsReady ? values.manager_label : '—' }} Type{{ resultsReady ? values.type_label : '—' }} Review{{ resultsReady ? `${values.warning_count} flagged` : '—' }}
{{ summaryAnnouncement }}
systemd service drafting inputs
Presets are editable examples, not host detection.
System is typical for server daemons; user is scoped to the signed-in account.
Use a short unit basename such as example-worker.
Name the workload for operators.
Login-shell aliases and environment are not inherited.
User-manager units omit User= and run as their owning user.
Leave blank only when the manager default is intentional.
notify and dbus require matching application behavior; forking normally needs PIDFile.
Use the exact well-known name acquired by the service.
on-failure is a conservative starting point for long-running services.
Whole seconds from 0 to 86,400.
s
Choose configured network only when startup genuinely depends on it.
Repo-authored starting profiles still need systemd-analyze security and workload tests.
Use multi-user.target for typical system services or default.target for typical user services.
Leave blank to use the account's primary group.
One KEY=value per line; use EnvironmentFile for secrets.
The browser does not inspect or create this file.
Leave blank when the application has no reload protocol.
Foreground services often need only systemd's normal stop signal.
Verify that the daemon really writes this file.
Optional whole seconds; blank preserves the manager default.
s
Optional whole seconds; blank preserves the manager default.
s
Use a relative directory name, not `/var/lib/...`.
Useful for sockets, PID files, and ephemeral state.
One absolute path per line.
Optional stable journal identifier.
The neutral default is off.
{{ remain_after_exit ? 'Completed state remains active' : 'Normal inactive state after exit' }}
{{ unitExportAnnouncement }}
{{ values.unit_text }}
{{ chartExportAnnouncement }}

The chart renderer is unavailable. Section counts remain available in the directive ledger.

SectionDirectiveValueRationaleCopy
{{ row.section }}{{ row.directive }}{{ row.value }}{{ row.rationale }}
{{ tableExportAnnouncement }}
LevelCheckFindingNext actionCopy
{{ row.level }}{{ row.check }}{{ row.finding }}{{ row.action }}
{{ tableExportAnnouncement }}
StepCommand or pathPurposeCopy
{{ row.step }}{{ row.command }}{{ row.purpose }}
{{ tableExportAnnouncement }}

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 with User= and Group=.
User manager
Runs services owned by one signed-in account, commonly from ~/.config/systemd/user. The unit does not need a User= 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.target for a system service or default.target for 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.

  1. Choose System manager or User manager, name the service, and enter an absolute ExecStart command for the foreground workload.
  2. Select the Service type, restart policy, startup dependency, install target, and hardening profile. Use notify, dbus, or forking only when the application follows that lifecycle.
  3. Add the working directory, environment source, timeouts, managed directories, and writable paths that the workload genuinely needs. Put one KEY=value assignment per environment line.
  4. 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.
  5. 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

Core systemd unit validation and emission rules
DecisionExact rule
FilenameRemove a trailing .service, replace unsafe runs with hyphens, trim leading punctuation, and append .service. A changed name produces a review warning.
Manager scopeSystem units may emit User= and Group=. User-manager units omit both and run as the owning account.
Process typeType=dbus requires a valid dot-separated BusName. Type=oneshot rejects Restart=always and Restart=on-success.
Restart and timeoutsRestartSec 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 orderConfigured-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.
EnvironmentEach inline assignment must use a valid shell-style key followed by =. Values are escaped and quoted; secret-looking names produce a review item.
Install targetThe value must be one target unit name ending in .target with no whitespace.
Writable pathsEvery 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.

Systemd hardening profile composition
ProfileAdded restrictionsMain review boundary
Compatibility / offNo generated hardening directivesThe workload keeps the manager's ordinary access.
Standard baselineNoNewPrivileges, PrivateTmp, ProtectSystem=full, ProtectHome=read-onlyConfirm writes outside managed application paths.
Network-service sandboxStandard restrictions plus private devices, SUID/SGID restriction, and Unix/IPv4/IPv6 address-family limitsNon-IP protocols and device access may fail.
Strict filesystemStrict filesystem and home protection, kernel and cgroup protections, SUID/SGID limits, locked personality, and no writable executable memoryDeclare required state, runtime, or writable paths; test JIT runtimes.
Locked-down non-JITStrict restrictions plus private devices, clock and hostname protection, realtime restriction, and native system-call architectureContainer 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.

System and user unit activation differences
ScopeUnit pathManager commands
System/etc/systemd/system/name.servicesudo systemctl daemon-reload and sudo systemctl enable --now name.service
User~/.config/systemd/user/name.servicesystemctl --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 EnvironmentFile or 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: