NoMachine on openSUSE Leap 16: SELinux-respecting installation with a reusable troubleshooting framework
Don't compromise security. Learn the SELinux-respecting way to install NoMachine on openSUSE Leap 16. This guide provides a reusable policy framework based on least privilege to fix persistent Systemd and execstack errors with custom policy.
1.0 Introduction
NoMachine is a cornerstone of my daily workflow, enabling seamless remote desktop access across diverse environments, including virtual machines on Azure, AWS, and Google Cloud, as well as local LAN systems. Its performance and flexibility make it indispensable for managing complex, multi-environment setups. However, installing NoMachine 9.1.24 on openSUSE Leap 16 presented unexpected challenges that disrupted its out-of-the-box functionality:
- Missing systemd service files: The installation did not include systemd service files, preventing proper management of the
nxserver
service. - SELinux denials: With SELinux enabled in enforcing mode, critical NoMachine operations were blocked.
- Executable stack issue: The
nxplayer
component required an executable stack, triggering both functional failures and security concerns.
While disabling SELinux with a single command (setenforce 0
) is a common shortcut for bypassing these issues, this approach must be avoided. Disabling SELinux compromises system security and undermines the integrity of a hardened environment. Instead, I addressed each issue methodically by creating a custom systemd unit, developing a tailored SELinux policy module, and resolving the executable stack requirement securely.
This article provides a detailed, step-by-step guide to configuring NoMachine on openSUSE Leap 16 in a secure, maintainable, and production-ready manner.
2.0 Environment details
This section outlines the system and software configuration where the NoMachine installation issues were encountered. These details are relevant for users operating in similarly hardened or minimal Linux environments, particularly those with SELinux in enforcing mode. The chosen desktop environment (GNOME, in this case) has no bearing on the steps described in this guide, as the solutions apply to any desktop environment.
2.1 System information
Property | Details |
---|---|
Distribution | openSUSE Leap 16 |
Kernel | 6.12.0-160000.5-default #1 SMP PREEMPT_DYNAMIC Wed Sep 10 15:26:25 UTC 2025 (3545bbd) |
Architecture | x86_64 |
SELinux | Enabled (Enforcing mode) |
Desktop Environment | GNOME (Minimal installation via zypper in gnome-shell ). The desktop environment was intentionally omitted during setup using Agama to maintain a lightweight configuration. |
2.2 NoMachine information
Property | Details |
---|---|
Product | NoMachine (Free Edition) |
Version | 9.1.24 |
3.0 NoMachine installation issues and solutions
This section outlines issues encountered during the installation of NoMachine 9.1.24 on openSUSE Leap 16. It provides detailed solutions to resolve these problems, ensuring proper service management and enabling remote access functionality.
3.1 Problem: Failed installation and missing systemd service
The primary issue encountered when installing the NoMachine RPM package (nomachine_9.1.24_6_x86_64.rpm
) was the failure to deploy the necessary systemd
service files. This omission prevents the nxserver
daemon from being managed by systemctl
, which is critical for automatic startup on boot and reliable service control in a production environment.
3.1.1 Diagnosis of installation errors
The installation attempt produced the following output, which highlights three distinct issues that require analysis.
Installation log output:
Refreshing service 'openSUSE'.
...
nomachine_9.1.24_6_x86_64.rpm: Package header is not signed!
nomachine-9.1.24-6.x86_64 (Plain RPM files cache): Signature verification failed [6-File is unsigned]
Abort, retry, ignore? [a/r/i] (a): i
...
NX> 700 Starting installation at: Thu, 09 Oct 2025 09:50:28.
NX> 700 Using installation profile: SUSE.
NX> 700 Installation log is: /usr/NX/var/log/install.log.
NX> 700 Installing nxrunner version: 9.1.24.
NX> 700 Installing nxplayer version: 9.1.24.
NX> 700 Installing nxnode version: 9.1.24.
/usr/NX/scripts/setup/nxnode: line 11303: /usr/etc/pam.d/su: No such file or directory
NX> 700 Installing nxserver version: 9.1.24.
NX> 700 ERROR: Cannot enable systemd service: nxserver.service.
NX> 700 ERROR: Cannot enable systemd service: .
NX> 700 Server install completed with warnings.
NX> 700 Please review the install log for details.
NX> 700 Installation completed with errors at: Thu, 09 Oct 2025 09:50:47.
NX> 700 NoMachine was configured to run the following services:
NX> 700 NX service on port: 4000
...
Analysis of key observations:
- Unsigned RPM package: The signature verification failure is an intentional design choice by NoMachine. From NoMachine knowledge base article AR05S01128:
NoMachine packages for Linux are at the moment not signed to prevent warnings when the user doesn't have the installed publisher certificate.
- Missing PAM file: The error related to
/usr/etc/pam.d/su
is a known issue specific to openSUSE's directory structure and does not affect functionality. From NoMachine knowledge base article TR10V11223:
During the installation of NoMachine on openSUSE, the following message is issued: ... /usr/NX/scripts/setup/nxnode: line 11247: /usr/etc/pam.d/su: No such file or directory
... Sessions are working properly and such message can be ignored.
- Critical error: systemd service failure: The message
ERROR: Cannot enable systemd service: nxserver.service
is the most critical issue. While the unsigned RPM and missing PAM file are cosmetic issues, thesystemd
failure is a functional blocker that must be resolved manually.
3.1.2 Solution: Manual systemd service configuration
The NoMachine package includes a predefined systemd unit file, typically located at /usr/NX/scripts/systemd/nxserver.service
after installation. However, depending on the installation method or errors, this unit file may not be automatically registered with systemd. The following procedure describes how to manually configure and enable the nxserver
systemd service.
3.1.2.1 Step 1: Deploy the systemd unit file
Manually copy the nxserver.service
file from the NoMachine installation directory to the system-wide systemd
directory.
# Optional: Check if a custom service file already exists to avoid overwriting
ls /etc/systemd/system/nxserver.service
# Copy the service file
sudo cp /usr/NX/scripts/systemd/nxserver.service /etc/systemd/system/
3.1.2.2 Step 2: Reload the systemd daemon
Instruct systemd
to reload its configuration to recognize the new service file.
sudo systemctl daemon-reload
3.1.2.3 Step 3: Enable and start the service
Enable the nxserver
service to start automatically on boot and then start it manually for the current session.
# Enable the service
sudo systemctl enable nxserver.service
# Expected Output:
# Created symlink /etc/systemd/system/multi-user.target.wants/nxserver.service β /etc/systemd/system/nxserver.service.
# Start the service
sudo systemctl start nxserver.service
3.1.2.4 Step 4: Verify the service status (and anticipate failure)
Check the status of the service. Note that it is expected to fail at this stage due to SELinux policy restrictions.
sudo systemctl status nxserver.service
You will likely see output indicating a failure, which confirms that systemd
is attempting to manage the service but is being blocked by SELinux.
Γ nxserver.service - NoMachine Server daemon
Loaded: loaded (/etc/systemd/system/nxserver.service; enabled; preset: disabled)
Active: failed (Result: start-limit-hit) since Thu 09 Oct 2025 09:52:45 CEST; 5s ago
Duration: 15ms
Invocation: 99bc681d83be4325b9e070a8596bf80b
Process: 9476 ExecStart=/etc/NX/nxserver --daemon (code=exited, status=203/EXEC)
Main PID: 9476 (code=exited, status=203/EXEC)
Oct 09 09:52:45 systemd[1]: nxserver.service: Start request repeated too quickly.
Oct 09 09:52:45 systemd[1]: nxserver.service: Failed with result 'start-limit-hit'.
Oct 09 09:52:45 systemd[1]: Failed to start NoMachine Server daemon.
3.1.3 Firewall Configuration
The installation log confirms that NoMachine listens on TCP port 4000
. Ensure your system's firewall allows incoming connections on this port. If you are using firewalld
, execute the following commands:
sudo firewall-cmd --add-port=4000/tcp --permanent
sudo firewall-cmd --reload
With the systemd
service file in place, proceed to the next section to address the SELinux policy conflict.
4.0 Resolving NoMachine systemd service failures due to SELinux denials
This guide outlines how to fix NoMachine service (nxserver
) startup failures caused by SELinux denials and provides a reusable framework for troubleshooting similar SELinux-related service issues.
4.1 Problem: SELinux denials
The nxserver
may fail to start after installation due to SELinux in enforcing mode blocking required permissions for nxserver
binaries. The systemctl status
output often indicates errors like start-limit-hit
or code=exited, status=203/EXEC
.
4.2 Solution: Custom SELinux policy for NoMachine
Follow these steps to create and apply a custom SELinux policy to allow nxserver
to run.
4.2.1 Step 1: Verify service failure
Confirm the NoMachine service is failing to start.
sudo systemctl start nxserver.service
sudo systemctl status nxserver.service
Check for a failed
state in the output. If confirmed, proceed to the next step.
4.2.2 Step 2: Generate SELinux policy from audit logs
Use ausearch
and audit2allow
to identify SELinux denials and create a policy module.
sudo ausearch -c '(nxserver)' --raw | audit2allow -M nxserver-policy
This command generates:
nxserver-policy.te
: A readable Type Enforcement file with the rules.nxserver-policy.pp
: A compiled policy module for installation.
4.2.3 Step 3: Install policy and retest
Apply the policy and attempt to restart the service.
sudo semodule -i nxserver-policy.pp
sudo systemctl start nxserver.service
sudo systemctl status nxserver.service
If the service still fails (which it will), a new SELinux denial may have surfaced. Repeat Step 2 to capture the new denial and update the policy files, then repeat Step 3 to install the updated policy. Iterate until the service starts successfully.
4.2.3.1 Merge .te
files for a clean policy
To address two separate SELinux denials encountered during the NoMachine service setup, I merged the corresponding .te
files into a single consolidated .te
file to simplify management and ensure a clean policy structure:
module nxserver-daemon 1.0;
require {
# from the first .te file
type init_t;
type nx_exec_t;
class file execute;
# from the second .te file
class file { execute open read };
}
#============= init_t ==============
# from the first .te file
allow init_t nx_exec_t:file execute;
# from the second .te file
allow init_t nx_exec_t:file { open read };
The above .te
file can be further refined:
module nxserver-daemon 1.0;
require {
type init_t;
type nx_exec_t;
class file { execute open read };
}
#============= init_t ==============
# Allow the systemd init process to execute, open, and read the nxserver binary
allow init_t nx_exec_t:file { execute open read };
Saved this as nxserver-daemon.te
.
checkmodule -M -m -o nxserver-daemon.mod nxserver-daemon.te
semodule_package -o nxserver-daemon.pp -m nxserver-daemon.mod
4.2.4 Step 5: Confirm success
Verify the service is running.
sudo systemctl status nxserver.service
The output should show active (running)
β nxserver.service - NoMachine Server daemon
Loaded: loaded (/etc/systemd/system/nxserver.service; enabled; preset: disabled)
Active: active (running) since Thu 2025-10-09 10:16:33 CEST; 6s ago
Invocation: 2c5da753407a4266a8129f2ed3b8f421
Main PID: 12546 (nxserver.bin)
Tasks: 69 (limit: 9428)
CPU: 2.766s
CGroup: /system.slice/nxserver.service
ββ12546 /usr/NX/bin/nxserver.bin --daemon
ββ12603 /usr/NX/bin/nxd
ββ12677 /usr/NX/bin/nxexec --node /usr/NX/bin/nxexec --nopam --user msiyer --priority realtime --mode 0 --pid 47
ββ12678 /usr/NX/bin/nxnode.bin
ββ12704 /usr/NX/bin/nxrunner.bin --monitor --pid 4519
4.3 General framework for SELinux service troubleshooting
This iterative framework can resolve SELinux-related issues for any service, ensuring minimal permissions are granted (principle of least privilege).
- Start the service:
- Run
sudo systemctl start <service-name>.service
. - Check status with
sudo systemctl status <service-name>.service
to confirm failure.
- Run
- Identify SELinux denials:
- Search audit logs for denials related to the serviceβs process:
- Create and apply policy:
- Generate a policy module from denials:
- Install the policy:
- Iterate as needed:
- Restart the service and check its status.
- If it fails, repeat steps 2β3 to address additional denials until the service runs.
- Verify operation:
- Confirm the service is active (running) with
sudo systemctl status <service-name>.service
.
- Confirm the service is active (running) with
This framework is reusable for any SELinux-blocked service, such as httpd
, sshd
, or custom applications.
4.4 Optional: Manage with Cockpit web UI
For a user-friendly alternative, use Cockpit to manage SELinux and services via a web interface.
4.4.1 Install Cockpit
- openSUSE:
- RHEL/Fedora-based systems:
4.4.2 Enable Cockpit
Start and enable the Cockpit socket for persistent access.
sudo systemctl enable --now cockpit.socket
4.4.3 Access Cockpit
Navigate to https://<server-ip>:9090
in a web browser and log in with system credentials.
4.4.4 Features for SELinux and service management
- SELinux Denials: View and resolve denials with suggested policy fixes.
- Policy Management: Install or remove SELinux policy modules with one click.
- Service Control: Start, stop, or monitor
systemd
services likenxserver
. - Log Access: Review system and audit logs directly in the UI.
5.0 Resolving NoMachine Player GUI launch failure
When attempting to launch the NoMachine Player GUI, the application fails silently due to SELinux denial related to executable stack. ausearch
will show the exact cause for the denial:
type=AVC msg=audit(1759996484.184:482): avc: denied { execstack } for pid=9676 comm="nxplayer.bin" scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=process permissive=0
If /usr/NX/bin/nxplayer
is run from terminal, the following output can be observed:
/usr/NX/bin/nxplayer.bin: error while loading shared libraries: libnxcim.so: cannot enable executable stack as shared object requires: Permission denied
5.1 Problem: Executable stack SELinux denial
The libnxcim.so
library contains an internal flag requesting an executable stack. Modern Linux distributions enforce security policies (like NX/DEP and SELinux) that strictly block shared libraries from enabling an executable stack to mitigate memory exploit risks, such as buffer overflows. Since the library likely doesn't require this flag, it results in a launch failure.
5.2 Solution: Clear the executable stack flag
For libnxcim.so
, the executable stack flag is usually unnecessary and can be safely cleared using the execstack
utility.
5.2.1 Step 1: Verify the flag status
Use execstack -q
to check if the executable stack flag is set on the library.
execstack -q /usr/NX/lib/libnxcim.so
Output | Status |
---|---|
X /usr/NX/lib/libnxcim.so |
Flag is set (Problem confirmed) |
- /usr/NX/lib/libnxcim.so |
Flag is cleared |
5.2.2 Step 2: Clear the flag
Use execstack -c
with sudo
to remove the executable stack flag.
sudo execstack -c /usr/NX/lib/libnxcim.so
5.2.3 Step 3: Verify the fix
Re-check the flag status. The output should now show a dash (-
).
execstack -q /usr/NX/lib/libnxcim.so
# Output: - /usr/NX/lib/libnxcim.so
5.2.4 Step 4: Test NoMachine Player
Launch the player. The GUI should now open successfully.
/usr/NX/bin/nxplayer
5.3 General framework for executable stack issues
This procedure applies to resolving the "cannot enable executable stack" error for any binary or library on a Linux system.
5.4.1 Identify and locate the library
- Error: Run the failing binary (
<path-to-binary>
) in the terminal and note the name of the problematic library (e.g.,libXYZ.so
). - Path: Find the library's full path using the
find
command:
5.4.2 Check and clear the flag
- Check:
execstack -q <library-path>
(look for anX
). - Clear:
sudo execstack -c <library-path>
. - Recheck:
execstack -q <library-path>
(ensure it now shows-
).
5.4.3 Handle crashes (if necessary)
If clearing the flag results in a crash, the library requires the executable stack. Do not run the binary as root. Instead, temporarily allow the executable stack via a targeted SELinux policy:
# 1. Inspect audit logs and generate a policy module file (.te)
sudo ausearch -m avc -ts recent | grep <binary-name> | audit2allow -M <policy-name>
# 2. Compile and install the policy module
sudo semodule -i <policy-name>.pp
This approach allows the specific application/library to use an executable stack without disabling the security feature system-wide.
5.4.4 Optional: Batch clearing for multiple libraries
You can automate the process for a directory of libraries, but extreme caution and thorough testing are required as it might cause instability if a library genuinely needs the flag.
# Finds all .so files in the target directory with the 'X' flag and clears it.
find /path/to/libs -type f -name "*.so" -exec execstack -q {} \; | \
grep "X" | awk '{print $2}' | xargs -I {} sudo execstack -c {}
6.0 Conclusion
Configuring NoMachine 9.1.24 on openSUSE Leap 16 with SELinux in enforcing mode required addressing three primary challenges:
- Missing systemd service: resolved by manually deploying and enabling the
nxserver.service
unit file. - SELinux denials blocking nxserver: addressed by generating, merging, and installing a consolidated SELinux policy (
nxserver-daemon.te
) to grant the necessary permissions while maintaining a secure, least-privilege environment. - Executable stack issue with nxplayer: mitigated by clearing the unnecessary executable stack flag on
libnxcim.so
usingexecstack
, ensuring the GUI launched successfully without weakening overall system security.
From my hands-on experience, these solutions create a production-ready NoMachine setup that preserves the integrity of a hardened system. The frameworks provided for SELinux troubleshooting and executable stack resolution are reusable across other SELinux-enabled distributions such as RHEL 10, Fedora, and AlmaLinux, offering a consistent methodology for resolving similar issues.
By avoiding shortcuts like disabling SELinux, this approach maintains a secure, maintainable, and auditable environment for remote desktop access. Additionally, version-controlling .te
policy files using tools like Git facilitates policy management, tracking, and collaboration over time, ensuring long-term maintainability.
7.0 References

