Skip to main content

Linux SSHD Policy

Overview

The Linux SSHD Policy manages OpenSSH server configuration on enrolled Linux devices. Swif writes configuration snippets under:

/etc/ssh/sshd_config.d/

Use the policy to configure SSH authentication, allowed groups, connection checks, listening ports, forwarding, and SFTP behavior. Each rule can contain global settings and conditional Match Blocks for particular users, groups, or connections.

The policy supports company-owned and BYOD Linux devices. It manages the SSH server (sshd), rather than the SSH client configuration used to connect to other computers.

Requirements

Requirement

Details

Operating system

Linux

Management

Enrolled in Swif with an agent able to receive and apply policies

SSH server

A compatible OpenSSH server installation

Configuration

The active server configuration must include the policy’s drop-in files

Administrative access

A tested recovery route if an SSH setting prevents new connections

Account preparation

Required users, groups, authentication credentials, and SFTP directories must already be prepared

Installing an SSH client alone does not provide the SSH server. Package names and service management differ between Linux distributions. Confirm compatibility on each distribution before broad deployment.

Before Changing SSH Access

Test on a small device group first. Keep an existing administrative session open and retain console or another tested management route until a new SSH connection succeeds.

Before disabling password authentication, verify a working alternative login method. Before restricting groups, confirm that every required administrator and automation account belongs to an allowed group. Before changing ports, prepare the corresponding network and host access rules.

Create the Policy

  1. In the Swif Admin Dashboard, go to Device Management > Policies and create a policy.

  2. Select Linux SSHD Policy.

  3. Enter a descriptive policy name.

  4. Add an entry under SSHD Rules.

  5. Configure its Priority, Name, and Global Settings.

  6. Add Match Blocks where conditional settings are needed.

  7. Save and assign the policy to a test device or group.

  8. Review the policy result, validate the effective SSH configuration, and test a new connection.

  9. Expand the assignment after testing succeeds.

SSHD Rules

Setting

Description

Default or limit

Priority

Numeric prefix used in the generated filename

Default 10; range 0–99

Name

Human-readable name used with the priority to generate the filename

No explicit default

Global Settings

Directives applied outside conditional Match blocks

Configure only the settings needed

Match Blocks

Conditional directives placed after the rule’s global settings

Each block needs at least one criterion

A rule named baseline with priority 10 may produce a filename such as 10-baseline.conf. Use distinct, descriptive names for your rules.

File Order and Configuration Precedence

The main configuration must include the snippets, normally with a directive such as:

Include /etc/ssh/sshd_config.d/*.conf

OpenSSH expands included filenames in lexical order and generally uses the first value obtained for a directive. Lower-numbered files are intended to load first; a higher priority number does not mean a stronger override. Some directives accumulate values, and Match processing has separate rules.

The location and scope of Include also matter. Validate the complete configuration, including existing files, instead of assessing one snippet in isolation. See Ubuntu’s OpenSSH configuration reference.

Defaults

The policy definition specifies a default of 10 for Priority. It does not specify explicit defaults for the individual SSH directives.

Do not interpret a blank field as a security recommendation or as an explicit no. Review the generated configuration and effective values on the device. OpenSSH and distribution defaults can differ.


Global Settings

Authentication and Access

Swif setting

OpenSSH directive

Values and purpose

Permit Root Login

PermitRootLogin

yes, prohibit-password, forced-commands-only, or no

Password Authentication

PasswordAuthentication

Enable or disable password authentication

Keyboard-Interactive Authentication

KbdInteractiveAuthentication

Enable or disable keyboard-interactive authentication

Max Auth Tries

MaxAuthTries

Authentication attempts per connection; integer of at least 1

Allow Groups

AllowGroups

List of groups whose members may log in

Login Grace Time

LoginGraceTime

Authentication time limit in seconds; integer of at least 0

Permit Root Login options:

  • yes: Allows root authentication subject to other access controls.

  • prohibit-password: Disables password and keyboard-interactive authentication for root.

  • forced-commands-only: Allows root public-key authentication only when the key specifies a forced command.

  • no: Prevents direct root SSH login.

Disabling Password Authentication alone does not disable keyboard-interactive authentication. Preserve keyboard-interactive access if your approved MFA flow requires it. This policy does not expose PubkeyAuthentication or AuthenticationMethods, so configure and verify those separately where required.

Allow Groups is an access restriction, not a group-creation feature. Other SSH allow/deny rules and account controls can still prevent access.

Max Auth Tries limits one connection; it does not configure an operating-system account lockout threshold. Login Grace Time applies before authentication, not to the duration of an authenticated session. A value of 0 removes that authentication time limit.

Connection Checks and Listening Ports

Swif setting

OpenSSH directive

Values and purpose

Client Alive Interval

ClientAliveInterval

Seconds without client data before a response is requested; minimum 0

Client Alive Count Max

ClientAliveCountMax

Unanswered client-alive threshold; minimum 0

Use DNS

UseDNS

Whether sshd performs reverse hostname lookup and forward verification

Port

Port

List of listening TCP ports; each value must be 1–65535

Setting Client Alive Interval to 0 disables these probes. Setting Client Alive Count Max to 0 disables termination through this mechanism. These settings detect an unresponsive client; a responsive client can remain connected without user activity. They are not an idle-user logout timer.

Adding a port here does not configure firewall rules. Verify actual listeners as well as the parsed SSH configuration, especially on systems where a service or socket unit controls listening sockets.

Forwarding and Session Behavior

Swif setting

OpenSSH directive

Values and purpose

X11 Forwarding

X11Forwarding

Enable or disable X11 forwarding

Allow TCP Forwarding

AllowTcpForwarding

yes, no, local, or remote

Permit TTY

PermitTTY

Allow or deny pseudo-terminal allocation

Force Command

ForceCommand

Run a specified command instead of the client’s requested command

Chroot Directory

ChrootDirectory

Filesystem root for the session; supports tokens such as %u

Subsystem > SFTP

Subsystem sftp

SFTP server command, such as internal-sftp

For TCP forwarding, local and remote refer to the SSH client’s perspective. Disabling TTY allocation alone does not prevent non-interactive command execution.

Apply Force Command and Chroot Directory globally only when every affected account should receive those restrictions. For a dedicated file-transfer group, use a Match block instead.

Match Blocks

A Match block applies settings only when its criteria are satisfied.

Field

Matches

Comment

Optional descriptive text above the block

Criteria > User

Login username

Criteria > Group

User’s group membership

Criteria > Host

Remote client hostname, subject to SSH hostname handling

Criteria > Address

Remote client IP address or CIDR range

Criteria > Local Address

Server address receiving the connection

Criteria > Local Port

Server port receiving the connection

Settings

Directives applied to matching connections

Provide at least one criterion. For ordinary positive entries, multiple values within a criterion are alternatives; different criteria must all match. For example, Group filetransfer plus Address 192.0.2.0/24 targets members of that group connecting from that subnet.

Settings That Must Remain Global

The policy form may expose the following fields under Match settings, but OpenSSH does not permit them there:

  • Port

  • Use DNS

  • Subsystem, including SFTP

  • Login Grace Time

Configure these under Global Settings only. A visible field is not proof that OpenSSH accepts it in that scope.

Criteria > Local Port is valid: it selects connections arriving on a port. It does not configure a listening port.

Matching blocks can override global values for supported directives. If several matching blocks set the same directive, the first applicable instance wins. See OpenSSH sshd_config reference.


Configuration Examples

Baseline for Administrators With Tested Key Access

Use this example only after confirming key authentication and an alternative recovery route.

Setting

Example value

Priority

10

Name

baseline

Permit Root Login

no

Password Authentication

Disabled

Keyboard-Interactive Authentication

Disabled, unless required by the approved authentication flow

Max Auth Tries

3

Login Grace Time

60 seconds

X11 Forwarding

Disabled

Client Alive Interval

60 seconds

Client Alive Count Max

3

These are example choices, not Swif defaults. The client-alive values check connection responsiveness. They do not impose a three-minute user inactivity limit.

Leave ports and group restrictions unconfigured until their dependencies have been reviewed. This example disables two authentication methods; it does not itself install keys or enforce a complete key-only authentication configuration.

Restrict SSH to an Approved Group

Set Global Settings > Allow Groups to an existing group, such as:

ssh-admins

Before deployment, verify each required account on the target device:

id adminuser

Replace adminuser with a real account. Confirm the required group appears in its membership, then test a new SSH login after deployment.

Force SFTP for a File-Transfer Group

Add a Match block:

Setting

Value

Comment

File-transfer accounts

Criteria > Group

filetransfer

Settings > Force Command

internal-sftp

Settings > Permit TTY

Disabled

Settings > Allow TCP Forwarding

no

Settings > X11 Forwarding

Disabled

Ensure SFTP is configured globally. Avoid adding another Subsystem sftp declaration without reviewing the existing declaration.

If filesystem confinement is also required, add Settings > Chroot Directory, for example /srv/sftp/%u. Prepare the directories separately: every component of the chroot path must be root-owned and not writable by other users or groups. Put user-writable content in a child directory, and ensure the user’s home path is usable inside the jail. See Ubuntu’s ChrootDirectory documentation.

The example does not configure every forwarding type. SSH-agent and Unix-socket forwarding controls are not exposed by this policy and require separate review for a fully restricted service account.


Verify the Policy

Validate Syntax

After checking the policy result in Swif, run:

sudo /usr/sbin/sshd -t

Use the distribution’s actual sshd path if different. Resolve errors before manually reloading or restarting SSH.

Inspect Effective Settings

sudo /usr/sbin/sshd -T

To evaluate Match rules, supply a representative connection:

sudo /usr/sbin/sshd -T \   -C user=adminuser,host=client.example.com,addr=192.0.2.10,laddr=192.0.2.20,lport=22

Replace the account, client hostname/address, server address, and port with actual test values. Repeat for restricted and unrestricted accounts.

-t checks configuration validity and host-key sanity. -T prints the effective configuration, and -C applies matching connection conditions. These commands validate configuration on disk; they do not prove that a running daemon has loaded it. See OpenSSH sshd command reference.

Test a New Connection

Confirm that the service has loaded the intended configuration using the distribution’s supported service procedure. From a separate terminal, test a new SSH login while keeping the original administrative session open.

For Match rules, test both matching and nonmatching accounts. For the SFTP example, verify file transfer and confirm that an interactive shell is unavailable for the restricted account.


Troubleshooting

Issue

What to check

SSH server package cannot be found

Distribution package repositories, package naming, and compatibility with the agent’s installation workflow

Snippet exists but settings do not apply

Active configuration path, Include directive, file order, Match scope, and whether the daemon loaded the change

“Directive not allowed within a Match block”

Move global-only fields out of Match settings; inspect surrounding files for unexpected Match scope

Login fails after authentication changes

Working keys or approved authentication method, keyboard-interactive/MFA requirements, and account restrictions

Group restriction blocks an administrator

Group existence and membership, plus other allow/deny rules

SFTP login fails

SFTP configuration, chroot ownership, writable child directory, and the home path inside the jail

Changed port is unreachable

Configured ports, actual listening sockets, firewall, routing, and service/socket configuration

Idle users stay connected

Client-alive probes measure responsiveness, not user activity

For an installation or package-resolution error, send Swif Support the Linux distribution/version, agent version, and exact policy error. Do not assume that the policy’s general Linux support confirms every package-manager workflow.

Change or Remove the Policy

Review the effective SSH configuration after changing a rule or removing its assignment. Do not assume that unassignment removes every snippet or restores the configuration that existed before deployment.

Use a tested access route to correct the relevant configuration, validate with sshd -t, and follow the distribution’s service procedure. Confirm a new connection before closing recovery access. Avoid deleting unrelated SSH configuration files.

Did this answer your question?