DEV Community

Cover image for Secure SSH Shell Applications
Richard Chamberlain
Richard Chamberlain

Posted on

Secure SSH Shell Applications

While modern software often leans heavily on graphical interfaces and web applications, command-line-based applications are still very much alive and in use. In fact, SSH-based shell applications remain a lightweight, efficient way for users to interact with terminal-based programs. However, if not configured carefully, these applications can inadvertently provide users with unrestricted shell access — something that’s often not intended.

The good news? Securing SSH shell applications is straightforward and can be done quickly with a few well-placed configurations. This article walks through how to set up a terminal-based application accessed via SSH and secure it in a way that restricts users to just the application.


Table of Contents

  1. What is an SSH Shell Application?
  2. Setting Up the Application
  3. Configuring SSH for Application Access
  4. Console Access Considerations
  5. Summary

What is an SSH Shell Application?

SSH Shell Applications are terminal-based programs that users can run remotely by connecting over SSH. They are especially handy in environments where minimal resource usage is critical or where web interfaces are overkill.

Users can connect using SSH clients like PuTTY, Termius, or native Linux/macOS terminals. These apps are lightweight, fast, and easy to distribute. Because they don’t rely on the user’s home environment or graphical stack, they can also add an extra layer of separation and security.

However, without careful planning, a user might break out of the application into a standard shell — unintentionally or otherwise. That’s why additional steps must be taken to confine users strictly to the app’s environment.


Setting Up the Application

For our example, we'll use a simple, self-contained Python application placed in /opt/test_app/app_entrypoint.py. A key part of securing this app is disabling critical control characters like Ctrl+C and Ctrl+Z, which would otherwise interrupt the application or suspend it to the background, potentially giving the user shell access.

Here’s how we disable those signals:

import signal

def disable_signals():
    # Ignore Ctrl+C (SIGINT) and Ctrl+Z (SIGTSTP)
    signal.signal(signal.SIGINT, signal.SIG_IGN)
    signal.signal(signal.SIGTSTP, signal.SIG_IGN)
Enter fullscreen mode Exit fullscreen mode

To handle attempts to exit via Ctrl+D (EOF), the app should catch the EOFError:

import time

while True:
    try:
        choice = input("Select an option [1-4]: ").strip()
    except EOFError:
        print("\n❌ Ctrl+D detected. Exiting securely.")
        time.sleep(1)
        break
Enter fullscreen mode Exit fullscreen mode

This ensures that if a user tries to drop out of the app with Ctrl+D, the application exits cleanly and ends the SSH session — preventing shell access.

👉 You can find the full code here.

If your application is not able to integrate these signal-handling and input restrictions directly (for example, if it's a third-party binary or legacy script), a wrapper script can be used instead. The wrapper acts as a secure launch layer, applying these restrictions before executing the app. You can find a sample wrapper script here.


Configuring SSH for Application Access

There are two main ways to launch an SSH shell app:

  1. From the user's .bashrc or similar login script.
  2. Directly from the SSH daemon (sshd) configuration.

This article focuses on the second method, which is cleaner and more secure.

First, a dedicated Linux group (e.g., app_group) is created to contain the application users. Then, we use SSHD's Match Group directive to force members of that group to run only the application.

Here's a sample snippet added to /etc/ssh/sshd_config:

Match Group app_group
    ForceCommand /opt/test_app/app_entrypoint.py
    PermitTTY yes
    AllowTcpForwarding no
    X11Forwarding no
Enter fullscreen mode Exit fullscreen mode

This configuration ensures that:

  • Users in app_group are automatically placed into the application.
  • PermitTTY yes allows for interactive input.
  • AllowTcpForwarding and X11Forwarding are disabled to prevent the session from being misused as a jump host.

Regular system administrators or non-application users are unaffected and continue to log in normally.


Console Access Considerations

While SSH access is now locked down, don’t forget about direct console access or users logging in via su - app_user. In these cases, users can still access the full shell unless additional safeguards are in place.

To block non-SSH logins (such as physical terminal or su sessions), add the following to the app user’s .bashrc:

if [ -z "$SSH_CONNECTION" ]; then
  echo "🚫 Direct login is not allowed."
  exit 1
fi
Enter fullscreen mode Exit fullscreen mode

This script checks whether the session is initiated over SSH. If it’s not, the login is terminated immediately.


Summary

In this guide, we’ve walked through how to:

  • Create a simple terminal-based application.
  • Restrict user access to that app only via SSH.
  • Prevent users from breaking out of the application into the shell.
  • Secure against direct console or su access.

These steps don't indicate a lack of trust in users. Most end users don’t have the means or intent to break out of restricted environments — but we always prepare for the worst. If a threat actor ever gains access to one of these accounts, these protections act as a vital layer of defense.

Security is all about layers. Beyond giving users access to the tools or files they need, we must always ask: Do they need shell access too? If the answer is no, let’s make sure the system enforces it.

Need Linux expertise? I help businesses streamline servers, secure infrastructure, and automate workflows. Whether you're troubleshooting, optimizing, or building from scratch—I've got you covered.

📬 Drop a comment or email me to collaborate. For more tutorials, tools, and insights, visit sebostechnology.com.

☕ Did you find this article helpful?
Consider supporting more content like this by buying me a coffee:
Buy Me A Coffee
Your support helps me write more Linux tips, tutorials, and deep dives.

Top comments (0)