2023-08-15 15:43:21 +02:00
# OpenSSH Server
2014-12-18 23:12:51 +01:00
2021-08-17 14:24:08 +02:00
[![Ansible Lint ](https://github.com/willshersystems/ansible-sshd/actions/workflows/ansible-lint.yml/badge.svg )](https://github.com/willshersystems/ansible-sshd/actions/workflows/ansible-lint.yml)
[![Ansible Galaxy ](http://img.shields.io/badge/galaxy-willshersystems.sshd-660198.svg?style=flat )](https://galaxy.ansible.com/willshersystems/sshd/)
2016-02-18 14:43:14 +01:00
2014-12-22 21:18:35 +01:00
This role configures the OpenSSH daemon. It:
2014-12-18 23:12:51 +01:00
2015-01-12 22:40:04 +01:00
* By default configures the SSH daemon with the normal OS defaults.
2020-10-26 13:16:30 +01:00
* Works across a variety of `UN*X` distributions
2015-01-12 22:40:04 +01:00
* Can be configured by dict or simple variables
* Supports Match sets
2020-11-04 16:00:51 +01:00
* Supports all `sshd_config` options. Templates are programmatically generated.
2021-10-18 16:07:58 +02:00
(see [`meta/make_option_lists` ](meta/make_option_lists ))
2020-11-04 16:00:51 +01:00
* Tests the `sshd_config` before reloading sshd.
2015-01-12 22:40:04 +01:00
2015-01-13 14:29:53 +01:00
**WARNING** Misconfiguration of this role can lock you out of your server!
Please test your configuration and its interaction with your users configuration
before using in production!
**WARNING** Digital Ocean allows root with passwords via SSH on Debian and
Ubuntu. This is not the default assigned by this module - it will set
`PermitRootLogin without-password` which will allow access via SSH key but not
via simple password. If you need this functionality, be sure to set
2020-09-23 14:06:35 +02:00
`sshd_PermitRootLogin yes` for those hosts.
2015-01-13 14:29:53 +01:00
2023-08-15 15:43:21 +02:00
## Requirements
2015-01-12 22:40:04 +01:00
Tested on:
2022-05-02 18:38:50 +02:00
* Ubuntu precise, trusty, xenial, bionic, focal, jammy
2021-08-17 14:24:08 +02:00
* [![Run tests on Ubuntu latest ](https://github.com/willshersystems/ansible-sshd/actions/workflows/ansible-ubuntu.yml/badge.svg )](https://github.com/willshersystems/ansible-sshd/actions/workflows/ansible-ubuntu.yml)
2023-06-13 12:01:50 +02:00
* Debian wheezy, jessie, stretch, buster, bullseye, bookworm
2022-04-11 14:41:32 +02:00
* [![Run tests on Debian ](https://github.com/willshersystems/ansible-sshd/actions/workflows/ansible-debian-check.yml/badge.svg )](https://github.com/willshersystems/ansible-sshd/actions/workflows/ansible-debian-check.yml)
2021-05-05 18:37:58 +02:00
* EL 6, 7, 8, 9 derived distributions
2022-04-11 14:41:32 +02:00
* [![Run tests on CentOS ](https://github.com/willshersystems/ansible-sshd/actions/workflows/ansible-centos-check.yml/badge.svg )](https://github.com/willshersystems/ansible-sshd/actions/workflows/ansible-centos-check.yml)
2022-05-02 18:38:50 +02:00
* All Fedora
2021-08-17 14:24:08 +02:00
* [![Run tests on Fedora latest ](https://github.com/willshersystems/ansible-sshd/actions/workflows/ansible-fedora.yml/badge.svg )](https://github.com/willshersystems/ansible-sshd/actions/workflows/ansible-fedora.yml)
2023-01-13 12:24:07 +01:00
* Latest Alpine
* [![Run tests on Alpine ](https://github.com/willshersystems/ansible-sshd/actions/workflows/ansible-alpine.yml/badge.svg )](https://github.com/willshersystems/ansible-sshd/actions/workflows/ansible-alpine.yml)
2021-08-17 14:24:08 +02:00
* FreeBSD 10.1
2016-10-19 21:33:15 +02:00
* OpenBSD 6.0
2019-07-10 19:07:07 +02:00
* AIX 7.1, 7.2
2022-09-14 20:18:37 +02:00
* OpenWrt 21.03
2015-01-12 22:40:04 +01:00
It will likely work on other flavours and more direct support via suitable
[vars/ ](vars/ ) files is welcome.
2022-12-13 17:55:13 +01:00
### Optional requirements
If you want to use advanced functionality of this role that can configure
firewall and selinux for you, which is mostly useful when custom port is used,
the role requires additional collections which are specified in
`meta/collection-requirements.yml` . These are not automatically installed.
2023-11-17 14:44:54 +01:00
If you want to manage `rpm-ostree` systems, additional collections are required.
2022-12-13 17:55:13 +01:00
You must install them like this:
2023-08-15 15:43:21 +02:00
```bash
2022-12-13 17:55:13 +01:00
ansible-galaxy install -vv -r meta/collection-requirements.yml
```
For more information, see `sshd_manage_firewall` and `sshd_manage_selinux`
2023-11-17 14:44:54 +01:00
options below, and the `rpm-ostree` section. This additional functionality is
supported only on Red Hat based Linux.
2022-12-13 17:55:13 +01:00
2023-08-15 15:43:21 +02:00
## Role variables
### Primary role variables
2015-01-12 22:40:04 +01:00
2020-11-04 16:00:51 +01:00
Unconfigured, this role will provide a `sshd_config` that matches the OS default,
2015-01-12 22:40:04 +01:00
minus the comments and in a different order.
2023-08-15 15:43:21 +02:00
#### sshd_enable
2018-09-08 09:14:39 +02:00
2020-11-04 16:00:51 +01:00
If set to *false* , the role will be completely disabled. Defaults to *true* .
2018-09-08 09:14:39 +02:00
2023-08-15 15:43:21 +02:00
#### sshd_skip_defaults
2015-01-12 22:40:04 +01:00
2020-11-04 16:00:51 +01:00
If set to *true* , don't apply default values. This means that you must have a
complete set of configuration defaults via either the `sshd` dict, or
2021-06-10 21:46:06 +02:00
`sshd_Key` variables. Defaults to *false* unless `sshd_config_namespace` is
2022-08-17 16:34:35 +02:00
set or `sshd_config_file` points to a drop-in directory to avoid recursive include.
2015-01-13 18:42:10 +01:00
2023-08-15 15:43:21 +02:00
#### sshd_manage_service
2015-06-25 15:54:24 +02:00
2020-11-04 16:00:51 +01:00
If set to *false* , the service/daemon won't be **managed** at all, i.e. will not
try to enable on boot or start or reload the service. Defaults to *true*
2019-07-10 19:07:07 +02:00
unless: Running inside a docker container (it is assumed ansible is used during
2020-09-23 14:06:35 +02:00
build phase) or AIX (Ansible `service` module does not currently support `enabled`
2019-07-10 19:07:07 +02:00
for AIX)
2015-06-25 15:54:24 +02:00
2023-08-15 15:43:21 +02:00
#### sshd_allow_reload
2015-01-13 18:42:10 +01:00
2024-01-29 18:55:43 +01:00
If set to *false* , a reload of sshd won't happen on change. This can help with
2015-01-13 18:44:00 +01:00
troubleshooting. You'll need to manually reload sshd if you want to apply the
2020-11-04 16:00:51 +01:00
changed configuration. Defaults to the same value as `sshd_manage_service` .
(Except on AIX, where `sshd_manage_service` is default *false* , but
`sshd_allow_reload` is default *true* )
2015-01-13 18:42:10 +01:00
2023-08-15 15:43:21 +02:00
#### sshd_install_service
2018-09-07 01:31:02 +02:00
2020-11-04 16:00:51 +01:00
If set to *true* , the role will install service files for the ssh service.
Defaults to *false* .
2018-09-07 01:31:02 +02:00
The templates for the service files to be used are pointed to by the variables
2023-08-15 15:43:21 +02:00
* `sshd_service_template_service` (**default**: `templates/sshd.service.j2` )
* `sshd_service_template_at_service` (**default**: `templates/sshd@.service.j2` )
* `sshd_service_template_socket` (**default**: `templates/sshd.socket.j2` )
2018-09-07 01:31:02 +02:00
Using these variables, you can use your own custom templates. With the above
default templates, the name of the installed ssh service will be provided by
the `sshd_service` variable.
2023-08-15 15:43:21 +02:00
#### sshd_manage_firewall
2022-12-13 17:55:13 +01:00
2024-01-29 18:55:43 +01:00
If set to *true* , the SSH port(s) will be opened in firewall. Note, this
2022-12-13 17:55:13 +01:00
works only on Red Hat based OS. The default is *false* .
NOTE: `sshd_manage_firewall` is limited to *adding* ports. It cannot be used
for *removing* ports. If you want to remove ports, you will need to use the
firewall system role directly.
2023-08-15 15:43:21 +02:00
#### sshd_manage_selinux
2022-12-13 17:55:13 +01:00
2024-01-29 18:55:43 +01:00
If set to *true* , the selinux will be configured to allow sshd listening
2022-12-13 17:55:13 +01:00
on the given SSH port(s). Note, this works only on Red Hat based OS.
The default is *false* .
NOTE: `sshd_manage_selinux` is limited to *adding* policy. It cannot be used
for *removing* policy. If you want to remove ports, you will need to use the
selinux system role directly.
2023-08-15 15:43:21 +02:00
#### sshd
2015-01-13 18:42:10 +01:00
A dict containing configuration. e.g.
2014-12-22 21:18:35 +01:00
```yaml
2014-12-21 21:39:44 +01:00
sshd:
Compression: delayed
ListenAddress:
- 0.0.0.0
```
2014-12-18 23:12:51 +01:00
2023-08-29 14:03:02 +02:00
#### sshd_`<OptionName>`
2015-01-13 18:42:10 +01:00
Simple variables can be used rather than a dict. Simple values override dict
values. e.g.:
2014-12-22 21:18:35 +01:00
```yaml
sshd_Compression: off
```
2020-11-04 16:00:51 +01:00
In all cases, booleans are correctly rendered as yes and no in sshd
configuration. Lists can be used for multiline configuration items. e.g.
2014-12-25 13:13:34 +01:00
```yaml
sshd_ListenAddress:
- 0.0.0.0
2015-01-12 22:40:04 +01:00
- '::'
2014-12-25 13:13:34 +01:00
```
2015-01-13 18:42:10 +01:00
Renders as:
2023-08-15 15:43:21 +02:00
```text
2015-01-13 18:42:10 +01:00
ListenAddress 0.0.0.0
ListenAddress ::
```
2023-08-15 15:43:21 +02:00
#### sshd_match, sshd_match_1 through sshd_match_9
2015-01-13 18:42:10 +01:00
2020-11-21 00:34:24 +01:00
A list of dicts or just a dict for a Match section. Note, that these variables
do not override match blocks as defined in the `sshd` dict. All of the sources
2022-04-11 13:53:06 +02:00
will be reflected in the resulting configuration file. The use of
`sshd_match_*` variant is deprecated and no longer recommended.
2014-12-25 13:13:34 +01:00
2023-08-15 15:43:21 +02:00
#### sshd_backup
2020-11-04 16:00:51 +01:00
When set to *false* , the original `sshd_config` file is not backed up. Default
is *true* .
2023-08-15 15:43:21 +02:00
#### sshd_sysconfig
2020-11-04 16:00:51 +01:00
On RHEL-based systems, sysconfig is used for configuring more details of sshd
service. If set to *true* , this role will manage also the `/etc/sysconfig/sshd`
2022-05-02 16:32:31 +02:00
configuration file based on the following configurations. Default is *false* .
2020-11-04 16:00:51 +01:00
2023-08-15 15:43:21 +02:00
#### sshd_sysconfig_override_crypto_policy
2020-11-04 16:00:51 +01:00
In RHEL8-based systems, this can be used to override system-wide crypto policy
2022-05-02 16:32:31 +02:00
by setting to *true* . Without this option, changes to ciphers, MACs, public
key algorithms will have no effect on the resulting service in RHEL8. Defaults
to *false* .
2020-11-04 16:00:51 +01:00
2023-08-15 15:43:21 +02:00
#### sshd_sysconfig_use_strong_rng
2020-11-04 16:00:51 +01:00
2022-05-02 16:32:31 +02:00
In RHEL-based systems (before RHEL9), this can be used to force sshd to reseed
openssl random number generator with the given amount of bytes as an argument.
The default is *0* , which disables this functionality. It is not recommended to
turn this on if the system does not have hardware random number generator.
2020-11-04 16:00:51 +01:00
2023-08-15 15:43:21 +02:00
#### sshd_config_file
2020-10-26 15:54:56 +01:00
The path where the openssh configuration produced by this role should be saved.
2022-04-28 11:08:06 +02:00
This is useful mostly when generating configuration snippets to Include from
drop-in directory (default in Fedora and RHEL9).
2022-08-17 16:34:35 +02:00
When this path points to a drop-in directory (like
2024-02-13 18:19:17 +01:00
`/etc/ssh/sshd_config.d/00-custom.conf` ), the main configuration file (defined
2022-08-17 16:34:35 +02:00
with the variable `sshd_main_config_file` ) is checked to contain a proper
`Include` directive.
2020-10-26 15:54:56 +01:00
2024-03-18 19:20:31 +01:00
#### sshd_main_config_file
When the system is using drop-in directory, this option can be used to set
a path to the main configuration file and let you configure only the drop-in
configuration file using `sshd_config_file` . This is useful in cases when
you need to configure second independent sshd service with different
configuration file. This is also the file used in the service file.
On systems without drop-in directory, it defaults to `None` . Otherwise it
defaults to `/etc/ssh/sshd_config` . When the `sshd_config_file` is set
outside of the drop in directory (its parent directory is not
`sshd_main_config_file` ~ '.d'), this variable is ignored.
2023-08-15 15:43:21 +02:00
#### sshd_config_namespace
2021-05-20 16:52:29 +02:00
By default (*null*), the role defines whole content of the configuration file
2021-05-27 14:33:50 +02:00
including system defaults. You can use this variable to invoke this role from
2022-08-17 16:34:35 +02:00
other roles or from multiple places in a single playbook as an alternative to
using a drop-in directory. The `sshd_skip_defaults` is ignored and no system
2021-05-27 15:26:59 +02:00
defaults are used in this case.
2021-05-27 14:33:50 +02:00
When this variable is set, the role places the configuration that you specify
to configuration snippets in a existing configuration file under the given
namespace. You need to select different namespaces when invoking the role
several times.
Note that limitations of the openssh configuration file still apply. For
example, only the first option specified in a configuration file is effective
for most of the variables.
Technically, the role places snippets in `Match all` blocks, unless they contain
other match blocks, to ensure they are applied regardless of the previous match
blocks in the existing configuration file. This allows configuring any
non-conflicting options from different roles invocations.
2021-05-20 16:52:29 +02:00
2023-08-15 15:43:21 +02:00
#### sshd_config_owner, sshd_config_group, sshd_config_mode
2021-06-02 12:39:31 +02:00
2024-01-29 18:55:43 +01:00
Use these variables to set the ownership and permissions for the openssh
configuration file that this role produces.
2021-06-02 12:39:31 +02:00
2023-08-15 15:43:21 +02:00
#### sshd_verify_hostkeys
2021-06-02 12:39:31 +02:00
By default (*auto*), this list contains all the host keys that are present in
2022-04-11 13:53:06 +02:00
the produced configuration file. If there are none, the OpenSSH default list
will be used after excluding non-FIPS approved keys in FIPS mode. The paths
2022-05-02 16:32:31 +02:00
are checked for presence and new keys are generated if they are missing.
Additionally, permissions and file owners are set to sane defaults. This is
useful if the role is used in deployment stage to make sure the service is
able to start on the first attempt.
To disable this check, set this to empty list.
2021-06-02 12:39:31 +02:00
2023-08-15 15:43:21 +02:00
#### sshd_hostkey_owner, sshd_hostkey_group, sshd_hostkey_mode
2021-06-02 12:39:31 +02:00
Use these variables to set the ownership and permissions for the host keys from
the above list.
2021-05-20 16:52:29 +02:00
2018-09-07 01:31:02 +02:00
### Secondary role variables
These variables are used by the role internals and can be used to override the
2022-06-02 13:38:25 +02:00
defaults that correspond to each supported platform. They are not tested and
generally are not needed as the role will determine them from the OS type.
2018-09-07 01:31:02 +02:00
2023-08-15 15:43:21 +02:00
#### sshd_packages
2018-09-07 01:31:02 +02:00
Use this variable to override the default list of packages to install.
2023-08-15 15:43:21 +02:00
#### sshd_binary
2018-09-07 01:31:02 +02:00
The path to the openssh executable
2023-08-15 15:43:21 +02:00
#### sshd_service
2018-09-07 01:31:02 +02:00
The name of the openssh service. By default, this variable contains the name of
the ssh service that the target platform uses. But it can also be used to set
the name of the custom ssh service when the `sshd_install_service` variable is
used.
2023-08-15 15:43:21 +02:00
#### sshd_sftp_server
2020-11-04 16:00:51 +01:00
Default path to the sftp server binary.
2021-01-28 13:40:24 +01:00
### Variables Exported by the Role
2023-08-15 15:43:21 +02:00
#### sshd_has_run
2021-01-28 13:40:24 +01:00
This variable is set to *true* after the role was successfully executed.
2023-09-11 15:39:03 +02:00
## Configure SSH certificate authentication
To configure SSH certificate authentication on your SSH server, you need to provide at least the trusted user CA key, which will be used to validate client certificates against.
This is done with the `sshd_trusted_user_ca_keys_list` variable.
If you need to map some of the authorized principals to system users, you can do that using the `sshd_principals` variable.
### Additional variables
#### sshd_trusted_user_ca_keys_list
List of the trusted user CA public keys in OpenSSH (one-line) format (mandatory).
#### sshd_trustedusercakeys_directory_owner, shsd_trustedusercakeys_directory_group, sshd_trustedusercakeys_directory_mode
Use these variables to set the ownership and permissions for the Trusted User CA Keys directory. Defaults are respectively *root* , *root* and *0755* .
#### sshd_trustedusercakeys_file_owner, shsd_trustedusercakeys_file_group, sshd_trustedusercakeys_file_mode
Use these variables to set the ownership and permissions for the Trusted User CA Keys file. Defaults are respectively *root* , *root* and *0640* .
#### sshd_principals
A dict containing principals for users in the os (optional). e.g.
```yaml
sshd_principals:
admin:
- frontend-admin
- backend-admin
somelinuxuser:
- some-principal-defined-in-certificate
```
#### sshd_authorizedprincipals_directory_owner, shsd_authorizedprincipals_directory_group, sshd_authorizedprincipals_directory_mode
Use these variables to set the ownership and permissions for the Authorized Principals directory. Defaults are respectively *root* , *root* and *0755* .
#### sshd_authorizedprincipals_file_owner, shsd_authorizedprincipals_file_group, sshd_authorizedprincipals_file_mode
Use these variables to set the ownership and permissions for the Authorized Principals file. Defaults are respectively *root* , *root* and *0644* .
### Additional configuration
The SSH server needs this information stored in files so in addition to the above variables, respective configuration options `TrustedUserCAKeys` (mandatory) and `AuthorizedPrincipalsFile` (optional) need to be present the `sshd` dictionary when invoking the role. For example:
```yaml
sshd:
TrustedUserCAKeys: /etc/ssh/path-to-trusted-user-ca-keys/trusted-user-ca-keys.pub
AuthorizedPrincipalsFile: "/etc/ssh/path-to-auth-principals/auth_principals/%u"
```
To learn more about SSH Certificates, here is a [nice tutorial to pure SSH certificates, from wikibooks ](https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Certificate-based_Authentication ).
To understand principals and to set up SSH certificates with Vault, this is a [well-explained tutorial from Hashicorp ](https://www.hashicorp.com/blog/managing-ssh-access-at-scale-with-hashicorp-vault ).
2023-08-15 15:43:21 +02:00
## Dependencies
2015-01-14 13:53:16 +01:00
2015-06-29 14:36:39 +02:00
None
2015-01-14 13:53:16 +01:00
2023-08-15 15:43:21 +02:00
For tests, the `ansible.posix` collection is required for the `mount` role to
2022-04-11 13:53:06 +02:00
emulate FIPS mode.
2023-08-15 15:43:21 +02:00
## Example Playbook
2015-08-25 19:41:22 +02:00
2016-01-12 16:57:30 +01:00
**DANGER!** This example is to show the range of configuration this role
provides. Running it will likely break your SSH access to the server!
2014-12-25 13:13:34 +01:00
```yaml
---
2015-01-12 22:40:04 +01:00
- hosts: all
vars:
sshd_skip_defaults: true
sshd:
Compression: true
ListenAddress:
- "0.0.0.0"
- "::"
2023-04-10 22:19:29 +02:00
GSSAPIAuthentication: false
2015-01-12 22:40:04 +01:00
Match:
- Condition: "Group user"
2023-04-10 22:19:29 +02:00
GSSAPIAuthentication: true
sshd_UsePrivilegeSeparation: false
2015-01-12 22:40:04 +01:00
sshd_match:
- Condition: "Group xusers"
2023-04-10 22:19:29 +02:00
X11Forwarding: true
2015-01-12 22:40:04 +01:00
roles:
2017-03-20 12:03:19 +01:00
- role: willshersystems.sshd
2014-12-25 13:13:34 +01:00
```
Results in:
2023-08-15 15:43:21 +02:00
```text
2014-12-25 13:13:34 +01:00
# Ansible managed: ...
Compression yes
GSSAPIAuthentication no
2016-01-12 16:57:30 +01:00
UsePrivilegeSeparation no
2014-12-25 13:13:34 +01:00
Match Group user
GSSAPIAuthentication yes
Match Group xusers
X11Forwarding yes
```
2014-12-26 11:09:34 +01:00
2020-09-17 17:26:09 +02:00
Since Ansible 2.4, the role can be invoked using `include_role` keyword,
for example:
```yaml
---
- hosts: all
become: true
tasks:
- name: "Configure sshd"
include_role:
name: willshersystems.sshd
vars:
sshd_skip_defaults: true
sshd:
Compression: true
ListenAddress:
- "0.0.0.0"
- "::"
2023-04-10 22:19:29 +02:00
GSSAPIAuthentication: false
2020-09-17 17:26:09 +02:00
Match:
- Condition: "Group user"
2023-04-10 22:19:29 +02:00
GSSAPIAuthentication: true
sshd_UsePrivilegeSeparation: false
2020-09-17 17:26:09 +02:00
sshd_match:
- Condition: "Group xusers"
2023-04-10 22:19:29 +02:00
X11Forwarding: true
2020-09-24 10:55:54 +02:00
```
2020-09-17 17:26:09 +02:00
2021-06-10 21:46:06 +02:00
You can just add a configuration snippet with the `sshd_config_namespace`
2021-05-27 15:26:59 +02:00
option:
2023-08-15 15:43:21 +02:00
```yaml
2021-05-27 15:26:59 +02:00
---
- hosts: all
tasks:
- name: Configure sshd to accept some useful environment variables
include_role:
2024-01-29 18:55:43 +01:00
name: willshersystems.sshd
2021-05-27 15:26:59 +02:00
vars:
2021-06-10 21:46:06 +02:00
sshd_config_namespace: accept-env
2021-05-27 15:26:59 +02:00
sshd:
# there are some handy environment variables to accept
AcceptEnv:
LANG
LS_COLORS
EDITOR
```
2023-08-15 15:43:21 +02:00
2021-06-10 21:46:06 +02:00
The following snippet will be added to the default configuration file
(if not yet present):
2023-08-15 15:43:21 +02:00
```text
2021-05-27 15:26:59 +02:00
# BEGIN sshd system role managed block: namespace accept-env
Match all
AcceptEnv LANG LS_COLORS EDITOR
# END sshd system role managed block: namespace accept-env
```
2020-12-15 15:54:10 +01:00
More example playbooks can be found in [`examples/` ](examples/ ) directory.
2023-08-15 15:43:21 +02:00
## Template Generation
2015-06-28 11:29:16 +02:00
2022-05-02 16:32:31 +02:00
The [`sshd_config.j2` ](templates/sshd_config.j2 ) and
[`sshd_config_snippet.j2` ](templates/sshd_config_snippet.j2 ) templates are
2024-01-29 18:55:43 +01:00
programmatically generated by the scripts in meta. New options should be added
2022-07-28 23:40:10 +02:00
to the `options_body` and/or `options_match` .
2015-06-28 11:29:16 +02:00
2022-07-28 23:40:10 +02:00
To regenerate the templates, from within the `meta/` directory run:
2021-05-20 16:52:29 +02:00
`./make_option_lists`
2015-06-28 11:29:16 +02:00
2023-11-17 14:44:54 +01:00
## rpm-ostree
See README-ostree.md
2023-08-15 15:43:21 +02:00
## License
2015-01-12 22:40:04 +01:00
LGPLv3
2023-08-15 15:43:21 +02:00
## Authors
2015-01-12 22:40:04 +01:00
Matt Willsher < matt @ willsher . systems >
2014-12-26 11:09:34 +01:00
2015-08-25 19:41:22 +02:00
© 2014,2015 Willsher Systems Ltd.
2022-04-11 13:53:06 +02:00
Jakub Jelen < jjelen @ redhat . com >
© 2020 - 2022 Red Hat, Inc.