]> ruderich.org/simon Gitweb - nsscash/nsscash.git/blobdiff - README.adoc
README: rename to README.adoc
[nsscash/nsscash.git] / README.adoc
diff --git a/README.adoc b/README.adoc
new file mode 100644 (file)
index 0000000..d2578ae
--- /dev/null
@@ -0,0 +1,189 @@
+= README
+
+Nsscash (a pun on cache) is a simple file-based cache for NSS similar to
+nsscache [1]. The goal is to distribute users/groups/etc. to multiple systems
+without having to rely on a (single) stable server. Traditional systems like
+LDAP or NIS require a stable server or users/groups cannot be resolved. By
+distributing the data to all systems, temporary outages of the server cause no
+issues on the clients. In addition the local storage is much faster than
+remote network access. To update the local caches polling via HTTP is
+performed, for example every minute, only downloading new data if anything has
+changed.
+
+Nsscash consists of two parts: `nsscash`, written in Go, which downloads files
+via HTTP or HTTPS, parses them, creates indices and writes the result to a
+local file. The second part is the NSS module (`libnss_cash.so.2`), written in
+C, which provides integration via `/etc/nsswitch.conf`. It's specifically
+designed to be very simple and uses the data prepared by `nsscash` for
+lookups. To support quick lookups, in O(log n), the files utilize indices.
+
+Nsscash is very careful when deploying the changes:
+- All files are updated using the standard "write to temporary file", "sync",
+  "rename" steps which is atomic on UNIX file systems. The indices are stored
+  in the same file preventing stale data during the update.
+- All errors cause an immediate abort ("fail fast") with a proper error
+  message and a non-zero exit status. This prevents hiding possibly important
+  errors. In addition all files are fetched first and then deployed to try to
+  prevent inconsistent state if only one file can be downloaded. The state
+  file (containing last file modification and content hash) is only updated
+  when all operations were successful.
+- To prevent unexpected permissions, `nsscash` does not create new files. The
+  user must create them first and `nsscash` will then re-use the permissions
+  (without the write bits to discourage manual modifications) and owner/group
+  when updating the file (see examples below).
+- To prevent misconfigurations, empty files (no users/groups) are not
+  permitted and will not be written to disk. This is designed to prevent the
+  accidental loss of all users/groups on a system.
+
+The passwd/group files have the following size restrictions:
+- maximum number of entries: '2^64-1' (uint64_t)
+- maximum passwd entry size: 65543 bytes (including newline)
+- maximum group entry size: 65535 bytes (including newline, only one member)
+- maximum members per group: depends on the user name length,
+                             with 9 bytes per user: 5460 users
+- `nsscash` checks for these restrictions and aborts with an error if they are
+  violated
+
+nsscash has an extensive test suite for both the Go and C part testing general
+requirements and various corner cases.
+
+nsscash is licensed under AGPL version 3 or later.
+
+[1] https://github.com/google/nsscache
+
+
+== REQUIREMENTS
+
+- Go, for `nsscash`
+  - github.com/pkg/errors
+  - github.com/BurntSushi/toml
+- C compiler, for `libnss_cash.so.2`
+
+- HTTP(S) server to provide the passwd/group/etc. files
+
+Tested on Debian Buster, but should work on any GNU/Linux system. With
+adaptations to the NSS module it should work on any UNIX-like system which
+uses NSS.
+
+
+== USAGE
+
+Install `libnss_cash.so.2` somewhere in your library search path (see
+`/etc/ld.so.conf`), e.g. `/usr/lib/x86_64-linux-gnu/`.
+
+Update `/etc/nsswitch.conf` to include the cash module; `passwd` and `group`
+are currently supported. For example:
+
+    passwd:         files cash
+    group:          files cash
+    [...]
+
+Create the cache files with the proper permissions (`nsscash fetch` won't
+create new files to prevent using incorrect permissions):
+
+    touch /etc/passwd.nsscash
+    touch /etc/group.nsscash
+    chmod 0644 /etc/passwd.nsscash
+    chmod 0644 /etc/group.nsscash
+
+Configure the `nsscash` configuration file `nsscash.toml`, see below.
+
+Then start `nsscash`:
+
+    nsscash fetch /path/to/config/nsscash.toml
+
+This will fetch the configured files and update the local caches. The files
+are atomically overwritten (via temporary file, sync, and rename).
+
+Verify the users/groups are available, e.g. with `getent`. If everything
+works, remember to reboot the host as changes to `nsswitch.conf` don't affect
+running processes!
+
+Now configure `nsscash` to run regularly, for example via cron or a systemd
+timer.
+
+To monitor `nsscash` for errors one can use the last modification time of the
+state file (see below). It's written on each successful run and not modified
+if an error occurs.
+
+=== CONFIGURATION
+
+Nsscash is configured through a simple configuration file written in TOML. A
+typical configuration looks like this:
+
+    statepath = "/var/lib/nsscash/state.json"
+
+    [[file]]
+    type = "passwd"
+    url = "https://example.org/passwd"
+    path = "/etc/passwd.nsscash"
+
+    [[file]]
+    type = "group"
+    url = "https://example.org/group"
+    path = "/etc/group.nsscash"
+
+    # Optional, but useful to deploy files which are not supported by the
+    # nsscash NSS module, but by libc's "files" NSS module. nsscash takes care
+    # of the atomic replacement and updates; an "netgroup: files" entry in
+    # "/etc/nsswitch.conf" makes the netgroups available.
+    [[file]]
+    type = "plain"
+    url = "https://example.org/netgroup"
+    path = "/etc/netgroup"
+
+The following global keys are available:
+
+- `statepath`: Path to a JSON file which stores the last modification time and
+  hash of each file; automatically updated by `nsscash`. Used to fetch data
+  only when something has changed to reduce the required traffic, via
+  `If-Modified-Since`. When the hash of a file has changed the download is
+  forced.
+
+Each `file` block describes a single file to download/write. The following
+keys are available:
+
+- `type`: Type of this file; can be either `passwd` (for files in
+  `/etc/passwd` format), `group` (for files in `/etc/group` format), or
+  `plain` (arbitrary format). Only `passwd` and `group` files are supported by
+  the nsscash NSS module. But, as explained above, `plain` can be used to
+  distribute arbitrary files. The type is required as the `.nsscash` files are
+  pre processed for faster lookups and simpler C code which requires a known
+  format.
+
+- `url`: URL to fetch the file from; HTTP and HTTPS are supported
+
+- `ca`: Path to a custom CA in PEM format. Restricts HTTPS requests to accept
+  only certificates signed by this CA. Defaults to the system's certificate
+  store when omitted. (optional)
+
+- `username`/`password`: Username and password sent via HTTP Basic-Auth to the
+  webserver. The configuration file must not be readable by other users when
+  this is used. (optional)
+
+- `path`: Path to store the retrieved file
+
+
+== AUTHORS
+
+Written by Simon Ruderich <simon@ruderich.org>.
+
+
+== LICENSE
+
+This program is licensed under AGPL version 3 or later.
+
+Copyright (C) 2019  Simon Ruderich
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program.  If not, see <https://www.gnu.org/licenses/>.