]> ruderich.org/simon Gitweb - safcm/safcm.git/blobdiff - README.adoc
Use SPDX license identifiers
[safcm/safcm.git] / README.adoc
index f120694f97abdfe5adbc728996efccee8d7be8b0..fe6a4482e7bdf2323399df70f0ec91f1cf4a24ef 100644 (file)
@@ -8,7 +8,7 @@ under GPLv3+. It is:
 - *configuration management*: sync files, packages, services and run commands
   on remote hosts
 
-The goal is that even unexperienced users (with safcm or configuration
+The goal is that even inexperienced users (with safcm or configuration
 management in general) should be able to apply configuration with safcm
 quickly. This means all key concepts of safcm must be easy to grasp and for
 each task there should be one obvious way.
@@ -17,15 +17,18 @@ It can also be read as "saf(e) configuration management" as it combines
 simplicity and safety in the following principles:
 
 - *fail fast*: catch (user) errors as soon as possible; host configuration
-  (including templates) evaluated locally to prevent partial configuration;
+  (including templates) is evaluated locally to prevent partial configuration;
   errors immediately abort the synchronization
-- *remote hosts untrusted*: clear security boundary between local and remote
-  host; data used from remote hosts is marked (detected groups); all output
-  from remote hosts is escaped to prevent terminal injection attacks; each
-  host only receives its configuration and no data from other hosts
+- *remote hosts are untrusted*: clear security boundary between local and
+  remote host; data used from remote hosts is marked tainted (detected
+  groups); all output from remote hosts is escaped to prevent terminal
+  injection attacks; each host only receives its own configuration and no data
+  from other hosts
 - *safety and security*: create files with "write to temporary file", "sync",
-  "rename", "sync directory" for atomicity and durability; guard against
-  symlink and other TOCTOU attacks; extensive test suite
+  "rename", "sync directory" for atomicity and durability; implemented in a
+  memory safe language and using a simple synchronization protocol to prevent
+  attacks on the local host; guard against symlink and other TOCTOU attacks;
+  extensive test suite
 
 
 == Overview
@@ -38,37 +41,39 @@ _hosts_. All hosts are explicitly configured. Hosts can be put into _groups_
 to apply the same configuration to multiple hosts. The host itself is also
 considered a group for host-specific configuration. In addition to manual
 group assignment _detected groups_ assign hosts to groups depending on the
-output of custom commands on the remote host. The configuration for a group
+output of custom commands on the remote host. The _configuration_ for a group
 contains the files, packages, services and commands which should be applied to
 all hosts which are members of this group.
 
 The configuration of all managed hosts is stored in a directory on the local
-host. Safcm uses https://yaml.org/[YAML] for all configuration files. However,
-tasks like copying a file require no explicit configuration (see the
-documentation for details).
-
-Files consist of a tree of files (regular files and symbolic links) and
-directories with permissions, user/group and content. Files can use
-_templates_ for dynamic content depending on the host or its groups. Each path
-can have _trigger_ commands which are executed when the path itself or any
-sub-paths are modified during synchronization. Packages are package names of
-the remote operating system. Services are service names of the remote
-operating system. Commands are shell commands passed to `/bin/sh`.
-
-When files with the same path are present in multiple groups of a host an
-explicit _group order_ must be configured to resolve the conflict. Conflicts
-do not apply to packages and services which are simply merged from all groups.
-Commands are appended so that the same command can be executed multiple times.
-
-To sync the configuration to a remote host the local `safcm` binary connects
+host. Safcm uses https://yaml.org/[YAML] for all configuration files. Strict
+type checks prevent potential pitfalls due to the complex YAML syntax. Tasks
+like copying a file require no explicit configuration.
+
+Files (regular files and symbolic links) and directories, including
+permissions, user/group and content are kept in a regular filesystem tree on
+the local host. Files can use _templates_ for dynamic content depending on the
+host or its groups. Each path can have _trigger_ commands which are executed
+when the path itself or any sub-paths are modified during synchronization.
+Packages are package names of the remote operating system. Services are
+service names of the remote operating system. Commands are shell commands
+passed to `/bin/sh`.
+
+When files with the same path are present in multiple groups of a host, an
+explicit _group priority_ must be configured to resolve the conflict.
+Conflicts do not apply to packages and services which are simply merged from
+all groups. Commands are appended so that the same command can be executed
+multiple times.
+
+To sync the configuration to a remote host, the local `safcm` binary connects
 to it via `ssh`. It then copies a _remote helper_ binary to `/tmp` on the
-remote host to later perform the actual sync. If the remote helper is already
-present, has the proper checksum, permissions and user then the copy is
-skipped. `safcm` then queries the remote host for information, including
-operating system, architecture and detected groups. With all relevant data
-collected it assigns the host its groups, evaluates the configuration
-including templates and finally sends it to the remote helper which then
-applies it to the remote host.
+remote host to perform the actual sync later. If the remote helper is already
+present, has the proper checksum, permissions and user/group then the copying
+step is skipped. `safcm` then queries the remote host for information,
+including operating system, architecture and detected groups. With all
+relevant data collected, it assigns the host to its groups, evaluates the
+configuration including templates and finally sends the new configuration to
+the remote helper which then applies it to the remote host.
 
 The synchronization happens in the following order which cannot be changed:
 
@@ -93,19 +98,19 @@ future, others are due to the design of safcm.
 
 - Commands are executed with `/bin/sh -c` on the remote host which might leak
   sensitive information to other users via the command line (unless `/proc` is
-  mounted with `hidepid=`). Store sensitive data in a file and execute or
-  source it as a workaround.
+  mounted with `hidepid=` on GNU/Linux systems). Store sensitive data in a
+  file and execute or source it as a workaround.
 
 - Permissions of existing files and directories will be overwritten with the
-  default (root/root, 0644 for files, 0755 for directories) unless manually
-  configured via `permissions.yaml`. This includes important paths like
-  `/root` which often have strict permissions by default, so carefully check
-  the diff output for unwanted changes.
+  default (root/root or root/wheel, 0644 for files, 0755 for directories)
+  unless manually configured via `permissions.yaml`. This includes important
+  paths like `/root` which often have strict permissions by default, so
+  carefully check the output for unwanted changes.
 
-- Full file content of all files is sent to the remote during synchronization.
-  This makes it impractical to synchronize large files with safcm. As most
-  configuration files are small this shouldn't be an issue for common
-  scenarios.
+- The full file content of all files is sent to the remote during
+  synchronization. This makes it impractical to synchronize large files with
+  safcm. Since most configuration files are small this shouldn't be an issue
+  for common scenarios.
 
 - Quoted strings in the output are quoted using Go's `%q` format string. The
   result is similar -- but not identical -- to quoted strings in regular shell
@@ -120,8 +125,8 @@ future, others are due to the design of safcm.
 
 == Requirements
 
-- build the `safcm` binary and remote helper:
-  * Go >= 1.16
+- to build the `safcm` binary and remote helper:
+  * Go >= 1.16 (for `go:embed`, `io/fs`)
   * GNU make
 
 - local host:
@@ -135,6 +140,7 @@ future, others are due to the design of safcm.
     ** GNU/Linux with common commands (`uname`, `id`, `stat`, `sha512sum`,
        `cat`, `mktemp`, `rm`, `ln`, `chmod`)
     ** FreeBSD (same commands, but uses `sha512`)
+    ** OpenBSD (same commands, but uses `sha512`)
   * SSH server
   * to install packages:
     ** `apt-get` (Debian or derivative)
@@ -144,6 +150,14 @@ future, others are due to the design of safcm.
 Adding support for other operating systems (e.g. BSDs) or distributions
 including package managers (e.g. Arch, Gentoo) is easy. Please send patches.
 
+At the moment the remote helper is built for the following operating systems
+($GOOS) and architectures ($GOARCH). To add more architectures simply edit
+`cmd/safcm-remote/build.sh`.
+
+    - freebsd: amd64
+    - linux: amd64, armv7
+    - openbsd: amd64
+
 
 == Authors
 
@@ -154,7 +168,7 @@ Written by Simon Ruderich <simon@ruderich.org>.
 
 This program is licensed under GPL version 3 or later.
 
-Copyright (C) 2021  Simon Ruderich
+Copyright (C) 2021-2024  Simon Ruderich
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by