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.

πŸ’‘
SELinux is now the default security framework in both Tumbleweed and Leap, replacing AppArmor. While AppArmor was more lenient and easier to ignore, SELinux is strict, and unless explicitly configured, it will block non-standard or improperly installed software like NoMachine.

This article provides a detailed, step-by-step guide to configuring NoMachine on openSUSE Leap 16 in a secure, maintainable, and production-ready manner.

πŸ’‘
These solutions are also applicable to other SELinux-enabled distributions, such as RHEL 10, Fedora, and AlmaLinux, with minor adjustments for specific file paths or audit logs, but the overall approach (custom systemd service, SELinux module, and execstack fix) remains the same.

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:

  1. 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.
  1. 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.
  1. 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, the systemd 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.

πŸ’‘
Note: From hands-on experience with both .rpm/.deb packages and .tar.gz installations, I know that the nxserver.service file is present in the installation directory, but it requires manual registration under certain conditions.

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.
πŸ’‘
Important: This failure is an expected outcome. The resolution for this SELinux-related issue is detailed in the next section.

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.

πŸ’‘
A denial occurs whenever SELinux prevents a service, application, file, or other object from accessing a resource. Each denial is recorded in the Access Vector Cache (AVC), which is why such messages are often called AVC denials.
--- config: theme: redux-color --- sequenceDiagram actor Subject participant OM as Object Manager participant AVC as Access Vector Cache participant SS as Security Server participant SP as Security Policy Subject->>OM: Request access to object activate OM OM->>OM: Identify action and object OM->>AVC: Query: Is action allowed? activate AVC alt Decision in cache AVC-->>OM: Return cached decision (allow/deny) else Decision not in cache AVC->>SS: Request security decision activate SS SS->>SP: Query security policy activate SP SP-->>SS: Return policy rules deactivate SP SS->>SS: Make decision based on policy SS-->>AVC: Return decision (allow/deny) deactivate SS AVC->>AVC: Store decision in cache AVC-->>OM: Return decision (allow/deny) end deactivate AVC alt Access allowed OM->>Subject: Grant access else Access denied OM->>Subject: Deny access (AVC denial logged) end deactivate OM
πŸ’‘
When creating custom SELinux policies, it is essential to adhere to the principle of least privilege. Do not use broad, permissive rules (like allowing all access to a whole directory) just to silence a denial. Instead, grant NoMachine (or whatever service/binary you are dealing with) only the specific permissions (types, classes, and accesses) required for its function.

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
πŸ’‘
Note: Instead of maintaining multiple .te files for SELinux policies, merging them into a single consolidated .te file (e.g., nxserver-daemon.te) simplifies management and ensures a clean policy structure. Additionally, these .te files can be version-controlled using tools like Git to track changes, maintain a history of policy updates, and facilitate collaboration or rollback if needed.

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).

  1. Start the service:
    • Run sudo systemctl start <service-name>.service.
    • Check status with sudo systemctl status <service-name>.service to confirm failure.
  2. Identify SELinux denials:
    • Search audit logs for denials related to the service’s process:
  3. Create and apply policy:
    • Generate a policy module from denials:
    • Install the policy:
  4. 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.
  5. Verify operation:
    • Confirm the service is active (running) with sudo systemctl status <service-name>.service.

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 like nxserver.
  • 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 an X).
  • 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 {}
πŸ’‘
Security Advisory: Avoid using setsebool -P selinuxuser_execstack 1 as a solution. This boolean allows any user-space process to request an executable stack, effectively disabling SELinux protections globally. Instead, prefer clearing the unnecessary executable stack flag on the specific library or binary using execstack -c, which enhances security by enforcing modern protections on legacy components. If the executable stack is genuinely required, create a targeted SELinux policy module for the affected binary. These approaches maintain least-privilege security while resolving functionality issues safely.

6.0 Conclusion

Configuring NoMachine 9.1.24 on openSUSE Leap 16 with SELinux in enforcing mode required addressing three primary challenges:

  1. Missing systemd service: resolved by manually deploying and enabling the nxserver.service unit file.
  2. 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.
  3. Executable stack issue with nxplayer: mitigated by clearing the unnecessary executable stack flag on libnxcim.so using execstack, 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

GitHub - SELinuxProject/selinux-notebook: The SELinux Notebook
The SELinux Notebook. Contribute to SELinuxProject/selinux-notebook development by creating an account on GitHub.
Configuring SELinux | openSUSE Leap 15.6
In this chapter, you learn how to set up and manage SELinux on openSUSE Leap. The following topics are covered:
Using SELinux | Red Hat Enterprise Linux | 8 | Red Hat Documentation
Using SELinux | Red Hat Enterprise Linux | 8 | Red Hat Documentation
System and Service Manager
The linker’s warnings about executable stacks and segments
This article talks about some new warning messages that have been added to the BFD linker. What they mean, why they are important and what can be done to prevent or silence them.
Too Subtle to Notice: Investigating Executable Stack Issues in Linux Systems - NDSS Symposium
The Network and Distributed System Security (NDSS) Symposium