Security is everyone’s job. NGINX Unit enables many layers of security configuration. Unit naturally separates applications by spawning separate processes for each one, enabling isolation at the process and memory layer. Each application process can be owned by separate users, enabling security at the file permission layer as well. Each application can also have its own Linux namespace specifications. Next, NGINX Unit has full SSL/TLS support, which enables Unit to serve applications through encrypted HTTPS communication. Finally, the system user accounts that are used to run Unit (the account that the unitd daemon runs as, the control socket owner, and the app-specific user and group accounts) enable fine-tuning access rights. All of these security attributes are demonstrated in this chapter.
Use a different system user for each application so that Unit spawns the processes as separate users with their own permissions:
{
"applications"
:
{
"auth-service"
:
{
"type"
:
"ruby"
,
"working_directory"
:
"/var/app/auth/"
,
"script"
:
"/var/app/auth/config.ru"
,
"user"
:
"auth-app"
},
"key-service"
:
{
"type"
:
"external"
,
"working_directory"
:
"/var/app/key/"
,
"executable"
:
"bin/key-app"
,
"user"
:
"key-app"
}
}
}
Unit runs each application as a separate process or group of processes, enabling it to run these processes as separate system users. When configuring an application in Unit, there are attributes for user and group. Using separate system users for each application will provide your applications with further isolation. The example demonstrates two different applications running as separate users in two separate working directories. It is implied that these directories have separate file permissions.
Configure the application to use Linux namespace isolation:
{
"applications"
:
{
"auth-service"
:
{
"type"
:
"php"
,
...
"isolation"
:
{
"namespaces"
:
{
"cgroup"
:
true
,
"credential"
:
true
,
"mount"
:
true
,
"network"
:
true
,
"pid"
:
true
,
"uname"
:
true
},
"uidmap"
:
[
{
"host"
:
1000
,
"container"
:
0
,
"size"
:
1000
}
],
"gidmap"
:
[
{
"host"
:
1000
,
"container"
:
0
,
"size"
:
1000
}
],
"rootfs"
:
"/var/app/sandbox/"
}
}
}
}
This example exercises all of the available Linux namespace configurations for an NGINX Unit application.
A Linux namespace wraps a global system resource in an abstraction that makes it appear to the processes within the namespace that they have their own isolated instance of the global resource. Changes to the global resource are visible to other processes that are members of the namespace but are invisible to other processes.
This NGINX Unit feature provides your application with an isolated runtime environment native to the underlying operating system. This type of isolation is akin to Docker and LXC, as they use Linux namespaces and cgroups to separate containers. This isolation is available on Linux systems and may not be fully supported by every OS that NGINX Unit is capable of running on, such as FreeBSD, MacOS, and Solaris. The uidmap
and gidmap
options are available only if the operating system supports Linux user namespaces.
The rootfs
option provides the ability to confine the application in a directory. This feature enables Linux chroot
abilities of NGINX Unit.
Create a .pem
file that includes your certificate chain and private key:
cat cert.pem ca.pem key.pem |
sudo tee bundle.pem > /dev/null
Upload the bundle.pem file to Unit’s certificate storage under a suitable name:
sudo curl -X PUT --data-binary @bundle.pem--unix-socket /var/run/control.unit.socket
http://localhost/certificates/certificate-name
Configure a listener object to use the certificate. In this example, a file with the object will be written to a file named tls-listener.json for clarity:
{
"*:8443"
:
{
"pass"
:
"applications/app-name"
,
"tls"
:
{
"certificate"
:
"certificate-name"
}
}
}
Submit the tls-listener.json configuration to the Unit API:
sudo curl -X PUT -d @tls-listener.json--unix-socket /var/run/control.unit.socket
http://localhost/config/listeners
This command removes all other listeners that might have been defined previously.
Validate that your application is communicating over TLS:
curl -v https://localhost:8443
This recipe concatenates the certificate, certificate authority chain, and key into a bundle that can be used by NGINX Unit. After the certificate is uploaded to Unit’s certificate store, it can be referenced by listeners. A listener object is constructed using the IP and port on which to accept requests. It references the application via the pass
attribute, as well as the certificate bundle object. The listener object is then submitted to the Unit control interface.
Validating that the TLS certificate is configured properly can be done by making a request to the listener. Using the verbose flag, -v
, when issuing the curl
command will print the TLS handshake operations if the certificate is configured properly.
3.134.102.182