For most Linux distributions, Systemd will be the officially support init process. This will, among many other things, monitor our processes like SysVInit and Upstart did. Get a leg up and learn how to use it now!We'll see how to use Systemd to monitor a process. For this video, we'll create a small Golang utility to listen for HTTP connections and respond to them.
Systemd will monitor this listener and ensure it stays running!
I spun up a fresh CentOS system for this video and installed vim and golang to start:
sudo yum install vim golang
SELinux
Let's check SELinux and see if it might get in our way.
$ sestatus
SELinux status: enabled
Current mode: enforcing
It's enabled, and I didn't show it, but it's also enforcing. If we run into issues, we'll see about making it let us use this port the Golang listener will use.
Golang Listener
Here's the Go code used to make a (stupid) listener, found in /opt/listen.go
in this video:
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there!")
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8181", nil)
}
This is in file "listener.go". To build it, we can simply run:
go build listen.go
Now if we run the "listen" command generated, we will have a web listener listening on all networks on port 8181. Because this is a high port, SELinux did not block it's use.
Web User
We don't want the listener to run as user root, so I make a new user to run it as. This will be an administrative user, which is to say, one that is not meant to be logged in as (no shell, lower uid/sid, no home directory).
adduser -r -M -s /bin/false www-data
-r
- Make a system user-M
- Don't create a home directory-s /bin/false
- Don't assign a shell (or more accurately, make the shell /bin/false, so the user cannot be logged into)www-data
- the user we create
We can see more information about this user in the /etc/passwd
file:
cat /etc/passwd | grep www
Systemd Unit File
Let's finally create the Systemd unit file that will control this Golang listener.
In general, we'll find Unit files and other configuration in /etc/systemd
, however these are mostly symlinks to files found in /usr/lib/systemd/system
. It's in this latter directory that we'll make our unit file.
Create the file: sudo vim /usr/lib/systemd/system/goweb.service
Here's the file itself:
[Unit]
Description=Webhook
[Service]
User=deployer
Group=www-data
Restart=on-failure
ExecStart=/opt/listen
[Install]
WantedBy=multi-user.target
Then run:
sudo systemctl enable goweb.service
sudo service goweb status
sudo service goweb start
And that's it! We can further control this service with the systemctl
command:
systemctl list-unit-files | grep goweb
systemctl enable goweb
systemctl is-enabled goweb
systemctl disable goweb
A Bigger Example
Here's a larger example with more things you can do!
[Unit]
Description=Webhook
After=another.target
After=some.service
[Service]
Type=simple # forking, oneshot
User=deployer
Group=www-data
WorkingDirectory=/opt
Restart=on-failure
Environment=VAR1=whatever "VAR2=something else"
EnvironmentFile=/path/to/file/with/variables
ExecStartPre=/run/some/command
ExecStartPre=/run/some/other/command
ExecStart=/usr/bin/node /opt/webhook/server.js
ExecStartPost=/lastly/run/this
[Install]
WantedBy=multi-user.target