Skip to content

Commit a87c92a

Browse files
committed
Custom promise type for managing global sshd configuration
Ticket: ENT-13797 Signed-off-by: Lars Erik Wik <lars.erik.wik@northern.tech>
1 parent c817bb3 commit a87c92a

File tree

7 files changed

+611
-0
lines changed

7 files changed

+611
-0
lines changed

cfbs.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,15 @@
302302
"append enable.cf services/init.cf"
303303
]
304304
},
305+
"promise-type-sshd": {
306+
"description": "Promise type to configure sshd.",
307+
"subdirectory": "promise-types/sshd",
308+
"dependencies": ["library-for-promise-types-in-python"],
309+
"steps": [
310+
"copy sshd_promise_type.py modules/promises/",
311+
"append enable.cf services/init.cf"
312+
]
313+
},
305314
"promise-type-systemd": {
306315
"description": "Promise type to manage systemd services.",
307316
"subdirectory": "promise-types/systemd",

promise-types/sshd/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Northern.tech
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

promise-types/sshd/README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# `sshd` promise type
2+
3+
Configures sshd and restarts the service when configuration changes.
4+
5+
## Promiser
6+
The sshd configuration keyword to manage (e.g. `PermitRootLogin`, `AllowUsers`).
7+
Each promise manages a single directive in the drop-in config file.
8+
9+
## Attributes
10+
- `value` (required) — the value for the directive, either a string or an slist
11+
12+
## What the module manages internally
13+
1. **Include directive** — ensures the base `sshd_config` includes the drop-in directory (`sshd_config.d/`) as its first non-comment directive
14+
2. **Drop-in directory** — creates the drop-in directory if it doesn't exist
15+
3. **Drop-in file** — writes directives to `sshd_config.d/00-cfengine.conf`
16+
4. **Service restart** — restarts sshd if configuration was changed and the service is already running
17+
5. **Verification** — verifies the desired directive appears in the effective sshd config (`sshd -T`)
18+
19+
## Conflicting promisers
20+
Having multiple promises with the same sshd keyword is not recommended.
21+
In case of conflicting promisers, the agent will attempt to converge the correct state for each one in the order they are evaluated.
22+
This means the last promise wins and determines the final value in the configuration file.
23+
It will also cause multiple restarts of the sshd service, which may be disruptive.
24+
25+
## What the module does NOT do
26+
- Install sshd — that is a `packages:` promise
27+
- Ensure sshd is running — that is a `services:` promise
28+
- Manage match blocks — those are a policy-level concern
29+
30+
## Policy
31+
```cf3
32+
bundle agent sshd_config
33+
{
34+
packages:
35+
"openssh-server" policy => "present";
36+
37+
services:
38+
"sshd" service_policy => "start";
39+
40+
vars:
41+
"allowed_users" slist => { "alice", "bob" };
42+
43+
sshd:
44+
"PermitRootLogin" value => "no";
45+
"PasswordAuthentication" value => "no";
46+
"Port" value => "22";
47+
"AllowUsers" value => @(allowed_users);
48+
}
49+
```
50+
51+
## Authors
52+
53+
This software was created by the team at [Northern.tech](https://northern.tech), with many contributions from the community.
54+
Thanks everyone!
55+
56+
## Contribute
57+
58+
Feel free to open pull requests to expand this documentation, add features, or fix problems.
59+
You can also pick up an existing task or file an issue in [our bug tracker](https://northerntech.atlassian.net/).
60+
61+
## License
62+
63+
This software is licensed under the MIT License. See LICENSE in the root of the repository for the full license text.

promise-types/sshd/enable.cf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
promise agent sshd
2+
# @brief Define sshd promise type
3+
{
4+
path => "$(sys.workdir)/modules/promises/sshd_promise_type.py";
5+
interpreter => "/usr/bin/python3";
6+
}

promise-types/sshd/example.cf

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
promise agent sshd
2+
# @brief Define sshd promise type
3+
{
4+
path => "$(sys.workdir)/modules/promises/sshd_promise_type.py";
5+
interpreter => "/usr/bin/python3";
6+
}
7+
8+
bundle agent example
9+
{
10+
packages:
11+
"openssh-server" policy => "present";
12+
13+
services:
14+
"sshd" service_policy => "start";
15+
16+
vars:
17+
"allowed_users" slist => { "alice", "bob" };
18+
19+
sshd:
20+
"PermitRootLogin" value => "no";
21+
"PasswordAuthentication" value => "no";
22+
"Port" value => "22";
23+
"AllowUsers" value => @(allowed_users);
24+
}
25+
26+
bundle agent __main__
27+
{
28+
methods:
29+
"example";
30+
}

0 commit comments

Comments
 (0)