RED HAT ENTERPRISE LINUX
Start, Stop & Boot-Enable
Services with systemctl
Start and stop services and configure services to start automatically at boot
CIS126RH | RHEL System Administration 1
Mesa Community College
On RHEL 9, every service is a systemd unit. The systemctl command
is the universal tool for starting, stopping, restarting, enabling, and disabling
services. Understanding the critical distinction between the current running
state (started or stopped right now) and the boot-time state
(enabled or disabled for automatic startup) is the foundation of reliable service
administration. This module covers both dimensions and the --now flag
that combines them. These skills are tested extensively on the RHCSA exam.
Learning Objectives
- Explain the two independent service state dimensions — Distinguish between the current running state (active/inactive) and the boot-time state (enabled/disabled), and explain how they interact
-
Start, stop, and restart services —
Use
systemctl start,stop, andrestartto control the immediate running state of services -
Enable and disable services at boot —
Use
systemctl enableanddisable— with and without the--nowflag — to configure persistent boot-time behaviour -
Verify and troubleshoot service state —
Use
systemctl status,is-active,is-enabled, andjournalctl -uto confirm service state and diagnose failures
The Two Independent Dimensions
Every systemd service has two completely independent state dimensions. Changing one does not change the other.
| Dimension | Values | What it controls | Commands |
|---|---|---|---|
| Running state | active / inactive / failed | Whether the service is running right now | start, stop, restart |
| Boot state | enabled / disabled / masked | Whether the service starts automatically at boot | enable, disable, mask |
This creates four valid combinations:
| Running state | Boot state | Meaning |
|---|---|---|
| active | enabled | Running now and will start at next boot — most common for production services |
| active | disabled | Running now but will NOT start at next boot — temporary start |
| inactive | enabled | Not running now but WILL start at next boot — enabled but not yet started |
| inactive | disabled | Not running and will not start at boot — fully off |
Starting and Stopping Services
These commands change the running state only — they have no effect on whether the service starts at boot.
# Start a service immediately
$ sudo systemctl start sshd
$ sudo systemctl start httpd
# Stop a running service
$ sudo systemctl stop sshd
# Restart a service (stop then start)
$ sudo systemctl restart httpd
# Reload configuration without stopping (if the service supports it)
$ sudo systemctl reload sshd
# Reload if supported, otherwise restart
$ sudo systemctl reload-or-restart httpd
# Check if the service is currently running
$ systemctl is-active sshd
active
$ systemctl is-active httpd
inactive
Starting a service with systemctl start is temporary. If the
service is disabled, it will not start at the next reboot. To make it
permanent, also run systemctl enable.
Enabling and Disabling at Boot
These commands configure the boot state only — they have no immediate effect on whether the service is currently running.
# Enable a service — creates a symlink for boot-time start
$ sudo systemctl enable sshd
Created symlink /etc/systemd/system/multi-user.target.wants/sshd.service
→ /usr/lib/systemd/system/sshd.service.
# Disable a service — removes the boot-time symlink
$ sudo systemctl disable sshd
Removed /etc/systemd/system/multi-user.target.wants/sshd.service.
# Check if a service is enabled
$ systemctl is-enabled sshd
enabled
$ systemctl is-enabled httpd
disabled
# The --now flag: combine enable + start in one command
$ sudo systemctl enable --now httpd
# Equivalent to: systemctl enable httpd && systemctl start httpd
# The --now flag: combine disable + stop
$ sudo systemctl disable --now httpd
How enable Works: Symlinks
Understanding the symlink mechanism explains why enable/disable is persistent and why it is separate from start/stop.
# After systemctl enable sshd:
$ ls -la /etc/systemd/system/multi-user.target.wants/sshd.service
lrwxrwxrwx. 1 root root 36 May 25 10:00
/etc/systemd/system/multi-user.target.wants/sshd.service
→ /usr/lib/systemd/system/sshd.service
# The actual unit file (read-only, managed by packages)
$ cat /usr/lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
...
[Install]
WantedBy=multi-user.target
# Boot sequence: systemd reads .wants dirs → starts linked units
# /etc/systemd/system/multi-user.target.wants/ (user-created symlinks)
$ ls /etc/systemd/system/multi-user.target.wants/
auditd.service chronyd.service crond.service sshd.service ...
WantedBy=multi-user.target in the unit file's [Install]
section tells enable to create the symlink in
multi-user.target.wants/. Different targets have different .wants
directories.
Reading systemctl status
systemctl status shows both state dimensions plus recent log entries —
the single most useful diagnostic command.
$ systemctl status sshd
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
Active: active (running) since Mon 2026-05-25 07:00:00 MST; 14h ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 872 (sshd)
Tasks: 1 (limit: 49152)
Memory: 5.2M
CPU: 203ms
CGroup: /system.slice/sshd.service
└─872 sshd: /usr/sbin/sshd -D [listener]
May 25 07:00:01 servera systemd[1]: Starting OpenSSH server daemon...
May 25 07:00:01 servera sshd[872]: Server listening on 0.0.0.0 port 22.
May 25 09:05:21 servera sshd[872]: Accepted publickey for student
# The Loaded line shows: UNIT FILE PATH; BOOT STATE; preset
# The Active line shows: RUNNING STATE; duration
Loaded line: enabled or disabled (boot state).
Active line: active (running), inactive (dead), or failed (running state).
Log lines at the bottom: recent events — almost always show why a failed service crashed.
All Service States
| Active state | Meaning | Common action |
|---|---|---|
active (running) | Service is running with one or more processes | Normal — no action |
active (exited) | Service ran to completion successfully (one-shot) | Normal for setup scripts |
active (waiting) | Service is waiting for an event or socket | Normal for socket-activated services |
inactive (dead) | Service is not running and has not failed | Start if needed |
failed | Service exited with non-zero status or was killed | Read log lines; fix and restart |
activating | Service is starting up | Wait; re-check if it stays here |
deactivating | Service is shutting down | Normal; investigate if it stays here |
| Boot state | Meaning |
|---|---|
enabled | Will start automatically at boot (symlink exists) |
disabled | Will NOT start at boot (symlink removed) |
masked | Cannot be started by any means — symlink points to /dev/null |
static | No [Install] section — enabled by other units' dependencies only |
Masking Services
Masking prevents a service from being started by any means — manually, by other units, or at boot. It is stronger than simply disabling.
# Mask a service (creates a /dev/null symlink)
$ sudo systemctl mask postfix
Created symlink /etc/systemd/system/postfix.service → /dev/null.
# Any attempt to start a masked service fails
$ sudo systemctl start postfix
Failed to start postfix.service: Unit postfix.service is masked.
# Unmask to restore normal behaviour
$ sudo systemctl unmask postfix
Removed /etc/systemd/system/postfix.service.
# After unmask, service returns to disabled state
$ systemctl is-enabled postfix
disabled
# Compare disable vs mask
$ systemctl is-enabled postfix # after disable: "disabled"
$ systemctl start postfix # after disable: succeeds (if configured correctly)
$ systemctl is-enabled postfix # after mask: "masked"
$ systemctl start postfix # after mask: FAILS
Listing Services
# List all loaded service units
$ systemctl list-units --type=service
UNIT LOAD ACTIVE SUB DESCRIPTION
auditd.service loaded active running Security Auditing Service
chronyd.service loaded active running NTP client/server
crond.service loaded active running Command Scheduler
sshd.service loaded active running OpenSSH server daemon
...
# List only failed services
$ systemctl list-units --type=service --state=failed
# List all installed unit files (includes disabled)
$ systemctl list-unit-files --type=service
UNIT FILE STATE PRESET
auditd.service enabled enabled
chronyd.service enabled enabled
httpd.service disabled disabled
postfix.service disabled enabled
...
# Show only enabled unit files
$ systemctl list-unit-files --type=service --state=enabled
list-units shows currently loaded units (running or recently failed).
list-unit-files shows all installed unit files regardless of whether
they are currently loaded — including disabled services.
The --now Flag
The --now flag combines a boot state change with an immediate
running state change — completing both dimensions in one command.
# Enable AND start immediately — the most common deployment pattern
$ sudo systemctl enable --now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service
→ /usr/lib/systemd/system/httpd.service.
# httpd is now ENABLED (will start at boot) AND ACTIVE (running now)
# Disable AND stop immediately
$ sudo systemctl disable --now httpd
# httpd is now DISABLED (won't start at boot) AND INACTIVE (stopped now)
# Verify both dimensions after enable --now
$ systemctl is-enabled httpd
enabled
$ systemctl is-active httpd
active
# The full deployment workflow: install → enable --now → verify
$ sudo dnf install -y httpd
$ sudo systemctl enable --now httpd
$ systemctl status httpd
When asked to "configure SERVICE to start automatically" or "ensure SERVICE is running
and starts at boot", the answer is almost always:
sudo systemctl enable --now SERVICE followed by
systemctl status SERVICE to verify.
Diagnosing a Failed Service
When systemctl status shows failed, the log lines
at the bottom of the output are the first place to look.
$ systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled)
Active: failed (Result: exit-code) since Mon 2026-05-25 10:00:00 MST
Process: 5432 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (status=1/FAILURE)
Main PID: 5432 (code=exited, status=1/FAILURE)
May 25 10:00 servera httpd[5432]: AH00526: Syntax error on line 47 of /etc/httpd/conf/httpd.conf
May 25 10:00 servera systemd[1]: httpd.service: Main process exited, code=exited
May 25 10:00 servera systemd[1]: httpd.service: Failed with result 'exit-code'.
# For more detail, check the full journal
$ journalctl -u httpd --since "10 minutes ago"
# After fixing the configuration error:
$ sudo systemctl start httpd
$ systemctl status httpd
1. Read the log lines in status output. 2. If insufficient, run
journalctl -u SERVICE. 3. Fix the identified problem. 4. Start the service.
5. Verify with status again.
Service Unit Files
Understanding the unit file structure helps administrators know where to look for configuration and how to override settings without modifying package files.
# View a service unit file
$ systemctl cat sshd
# /usr/lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.target
Wants=sshd-keygen.target
[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
# Create an override without editing the package file
$ sudo systemctl edit sshd # creates /etc/systemd/system/sshd.service.d/override.conf
systemctl Quick Reference
| Task | Command |
|---|---|
| Start a service now | sudo systemctl start SERVICE |
| Stop a running service | sudo systemctl stop SERVICE |
| Restart a service | sudo systemctl restart SERVICE |
| Reload config without stopping | sudo systemctl reload SERVICE |
| Safe reload or restart | sudo systemctl reload-or-restart SERVICE |
| Enable at boot only | sudo systemctl enable SERVICE |
| Enable at boot AND start now | sudo systemctl enable --now SERVICE |
| Disable at boot only | sudo systemctl disable SERVICE |
| Disable AND stop now | sudo systemctl disable --now SERVICE |
| Prevent any start (mask) | sudo systemctl mask SERVICE |
| Remove mask | sudo systemctl unmask SERVICE |
| View full status (both dimensions + logs) | systemctl status SERVICE |
| Check if running | systemctl is-active SERVICE |
| Check if enabled | systemctl is-enabled SERVICE |
| List all running services | systemctl list-units --type=service |
| List all installed services | systemctl list-unit-files --type=service |
| View unit file contents | systemctl cat SERVICE |
| View service logs | journalctl -u SERVICE |
Systemd Targets and the Boot Process
Services are enabled into a target — a named group of units that must be active for the system to be in a particular state.
# View the default boot target
$ systemctl get-default
multi-user.target
# Common targets
poweroff.target # system shutdown
rescue.target # single-user / rescue mode
multi-user.target # full multi-user, no GUI (typical server)
graphical.target # multi-user + graphical (desktop)
# Change the default boot target
$ sudo systemctl set-default multi-user.target
Created symlink /etc/systemd/system/default.target
→ /usr/lib/systemd/system/multi-user.target.
# Most services use WantedBy=multi-user.target in [Install]
# enable creates the symlink in multi-user.target.wants/
RHEL server installations default to multi-user.target — full network
and multi-user support without a graphical interface. Desktop installations default
to graphical.target. Services enabled with
WantedBy=multi-user.target start in both targets.
Common Mistakes
| Mistake | What goes wrong | Correct approach |
|---|---|---|
| Starting a service without enabling it | Service runs until reboot but never starts again — task is incomplete | Use systemctl enable --now SERVICE to do both in one command |
| Enabling a service without starting it | Service will start at next boot but is not running now — incomplete | Use systemctl enable --now SERVICE |
| Not verifying service state after enabling | Service may have failed to start — task appears complete but service is not running | Always run systemctl status SERVICE after enable --now |
| Confusing reload and restart | Using restart drops all active connections unnecessarily | Use reload for config changes when the service supports it |
| Editing unit files in /usr/lib/systemd/system/ | Changes are overwritten by the next package update | Use systemctl edit SERVICE to create drop-in overrides in /etc/ |
| Confusing disabled with masked | A disabled service can still be started manually; a masked service cannot | Use disable for normal disabling; mask only when the service must never run |
Knowledge Check
Answer these before moving to the next slide.
- A service is active (running) but disabled. What happens to it after the next system reboot, and what command makes it persist?
- Write the single command to install and make
httpdboth running now and configured to start automatically at every future boot. systemctl status httpdshows:Active: failed (Result: exit-code). What do you look at next, and what is the likely fix workflow?- What is the difference between
systemctl disable httpdandsystemctl mask httpd? - You need to apply a change to
sshd_configwithout dropping any active SSH sessions. Which systemctl command applies the change? - After creating a custom service unit file at
/etc/systemd/system/myapp.service, what command must you run before systemctl can manage it?
Knowledge Check — Answers
- After reboot, the service will be stopped (inactive) — it was
disabled so systemd does not start it at boot. The service runs only when manually
started. Fix:
sudo systemctl enable SERVICE(enables for boot only) orsudo systemctl enable --now SERVICE(also starts it now, though it is already running). sudo dnf install -y httpdthensudo systemctl enable --now httpd. The--nowflag both creates the boot-time symlink and starts the service immediately.- Read the log lines at the bottom of the
statusoutput — they almost always identify the error (configuration syntax, missing file, permission denied). If needed:journalctl -u httpd --since "10 minutes ago". Fix the identified problem, thensudo systemctl start httpd, then verify withsystemctl status httpd. disableremoves the boot-time symlink — the service will not start at boot, but can still be started manually withsystemctl start.maskcreates a symlink to/dev/null— the service cannot be started by any means (manual, boot, or dependency) until unmasked.sudo systemctl reload sshd— sends SIGHUP to the sshd process, which causes it to re-readsshd_configwithout terminating. Existing SSH sessions are not interrupted.sudo systemctl daemon-reload— this command tells systemd to re-scan all unit file locations and load the new unit. Without it, systemctl enable will not find the new unit file.
Key Takeaways
-
Services have two independent dimensions: running state and boot state.
start/stop/restartchange the running state (now, temporary).enable/disablechange the boot state (persistent, next reboot).enable --nowchanges both at once — the exam standard pattern. -
systemctl statusshows both dimensions and recent logs.Loadedline shows the boot state (enabled/disabled).Activeline shows the running state. Log lines at the bottom identify why a failed service crashed. -
The deployment workflow: install →
enable --now→ verify. Always runsystemctl status SERVICEafter deploying. Usejournalctl -u SERVICEfor more log detail when needed. Usereloadinstead ofrestartwhen sessions must not be dropped. -
mask is stronger than disable; daemon-reload is required for new units.
maskprevents any start — even manual.disableprevents boot-time start only. After creating or modifying a unit file, runsystemctl daemon-reloadbefore attempting to enable or start it.
Graded Lab
- Install
httpdwith dnf. Runsystemctl is-active httpdandsystemctl is-enabled httpdto confirm it is inactive and disabled immediately after installation (both dimensions are off). - Use
systemctl enable --now httpdto make httpd run now and start at every boot. Verify both dimensions withsystemctl status httpd— confirm the Loaded line shows enabled and the Active line shows active (running). - Run
systemctl stop httpd. Confirm withsystemctl is-activeit is inactive. Runsystemctl is-enabledto confirm it is still enabled. Start it again withsystemctl start httpd. This demonstrates the two dimensions are independent. - Use
systemctl disable httpd. Confirm withsystemctl is-enabledit is disabled. Confirm withsystemctl is-activeit is still running. This demonstrates disable does not stop the service. - Mask
postfixwithsystemctl mask. Attemptsystemctl start postfixand observe the failure. Unmask it and confirm the start succeeds (if postfix is installed) or the error changes to a different one. - Reboot the system. After reboot, confirm that
httpdis NOT running (disabled in task 4) and thatsshdIS running (enabled by default). This confirms the boot state controls persistent behaviour.
"Start and stop services and configure services to start automatically at boot."
The exam answer: systemctl enable --now SERVICE followed by
systemctl status SERVICE to verify both dimensions.