Deploy to GitHub pages

This commit is contained in:
github-actions[bot] 2024-09-17 12:46:21 +00:00 committed by GitHub
commit 4317b3a529
305 changed files with 62455 additions and 0 deletions

4
.buildinfo Normal file
View file

@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 219f4083df119dbc63e42c5077c45e34
tags: 645f666f9bcd5a90fca523b33c5a78b7

0
.nojekyll Normal file
View file

BIN
_images/group_roles.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
_images/groups.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

BIN
_images/locked_session.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
_images/putty1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
_images/putty10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
_images/putty2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
_images/putty3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
_images/putty4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
_images/putty5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
_images/putty6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
_images/putty7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
_images/putty8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
_images/putty9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,36 @@
===================
Configuration files
===================
Main configuration files
========================
These config files should be reviewed and adapted for the environment in which
you're deploying The Bastion. The doc:`bastion_conf` is the only one that is
mandatory to get you started. You should however review the other ones before
going into production.
.. toctree::
:maxdepth: 1
bastion_conf
osh-backup-acl-keys_conf
osh-encrypt-rsync_conf
osh-sync-watcher_sh
osh-http-proxy_conf
Configuration files for satellite scripts
=========================================
These config files govern the behavior of satellite scripts that handle
background tasks of The Bastion. Most of the time, there is no need to alter
the configuration as sane defaults are already built in.
.. toctree::
:maxdepth: 1
osh-piv-grace-reaper_conf
osh-remove-empty-folders_conf
osh-cleanup-guest-key-access_conf
osh-lingering-sessions-reaper_conf
osh-orphaned-homedir_conf

View file

@ -0,0 +1,183 @@
========================
osh-backup-acl-keys.conf
========================
.. note::
This script is called by cron and is responsible
for backing up the bastion configuration, users & groups lists,
credentials, and everything needed to be able to restore a functioning
bastion from scratch.
.. warning::
If left unconfigured, this script won't do anything,
and you won't have backups, unless this task is handled by
some other external system.
Option List
===========
Logging & activation options
----------------------------
Script logging configuration and script activation
- `LOGFILE`_
- `LOG_FACILITY`_
- `ENABLED`_
Backup policy options
---------------------
These options configure the backup policy to apply
- `DESTDIR`_
- `DAYSTOKEEP`_
Encryption and signing options
------------------------------
These options configure how the script uses GPG to encrypt and sign the ttyrec files
- `GPGKEYS`_
- `SIGNING_KEY`_
- `SIGNING_KEY_PASSPHRASE`_
Remote backup options
---------------------
These options configure how the script should push the encrypted backups to a remote system
- `PUSH_REMOTE`_
- `PUSH_OPTIONS`_
Option Reference
================
Logging & activation
--------------------
LOGFILE
*******
:Type: ``string, path to a file``
:Default: ``""``
File where the logs will be written to (don't forget to configure ``logrotate``!).
Note that using this configuration option, the script will directly write to the file, without using syslog.
If empty, won't log directly to any file.
LOG_FACILITY
************
:Type: ``string``
:Default: ``"local6"``
The syslog facility to use for logging the script output.
If set to the empty string, we'll not log through syslog at all.
If this configuration option is missing from your config file altogether,
the default value will be used (local6), which means that we'll log to syslog.
ENABLED
*******
:Type: ``0 or 1``
:Default: ``1``
If set to 1, the script is enabled and will run when started by crond.
Backup policy
-------------
DESTDIR
*******
:Type: ``path to a folder``
:Default: ``""``
:Example: ``"/root/backups"``
Folder where to put the backup artefacts (``.tar.gz`` files).
This folder will be created if needed. If empty or omitted,
the script won't run: this option is mandatory.
DAYSTOKEEP
**********
:Type: ``int > 0``
:Default: ``90``
Number of days to keep the old backups on the filesystem before deleting them.
Encryption and signing
----------------------
GPGKEYS
*******
:Type: ``string, space-separated list of GPG keys IDs``
:Default: ``""``
:Example: ``"41FDB9C7 DA97EFD1 339483FF"``
List of public GPG keys to encrypt to (see ``gpg --list-keys``), these must be separated by spaces.
Note that if this option is empty or omitted, backup artefacts will NOT be encrypted!
SIGNING_KEY
***********
:Type: ``string, GPG key ID in short or long format``
:Default: ``(none)``
ID of the GPG key used to sign the ttyrec files.
The key must be in the local root keyring, check it with ``gpg --list-secret-keys``.
If empty, the archives will not be signed, but encrypted only (using the GPGKEYS configuration above).
SIGNING_KEY_PASSPHRASE
**********************
:Type: ``string``
:Default: ``(none)``
This passphrase should be able to unlock the SIGNING_KEY defined above.
Please ensure this configuration file only readable by root (0640), to protect this passphrase.
As a security measure, the script will refuse to read the configuration otherwise.
Remote backup
-------------
PUSH_REMOTE
***********
:Type: ``string``
:Default: ``""``
:Example: ``"push@192.0.2.4:~/backup/"``
The ``scp`` remote host push backups to. If empty or missing, won't push backups.
This will also be the case if the ``GPGKEYS`` option above is empty or missing,
because we will never push unencrypted backups.
Don't forget to put a trailing ``/`` (except if you want to push to the remote ``$HOME``,
in which case ending with a simple ``:`` works, as per standard ``scp``).
PUSH_OPTIONS
************
:Type: ``string``
:Default: ``""``
:Example: ``"-i $HOME/.ssh/id_backup"``
Additional options to pass to ``scp``, if needed.

View file

@ -0,0 +1,51 @@
=================================
osh-cleanup-guest-key-access.conf
=================================
.. note::
This script is called by cron and is responsible for cleaning up dangling
accesses to group keys for group guests that no longer have access to any
server of the group. This happens when the last access a guest have on a
group has a TTL, and this TTL expires.
This is a basic background task of The Bastion, hence there is not much
to configure. You can still disable this script below, if needs be.
Option List
===========
Logging & activation options
----------------------------
Script logging configuration and script activation
- `syslog_facility`_
- `enabled`_
Option Reference
================
Logging & activation
--------------------
syslog_facility
***************
:Type: ``string``
:Default: ``local6``
The syslog facility to use for logging the script output.
If set to the empty string, we'll not log through syslog at all.
If this configuration option is missing from your config file altogether,
the default value will be used (local6), which means that we'll log to syslog.
enabled
*******
:Type: ``bool``
:Default: ``true``
If not set to `true` (or a true value), the script will not run.

View file

@ -0,0 +1,243 @@
======================
osh-encrypt-rsync.conf
======================
.. note::
The osh-encrypt-rsync script is called by cron and is responsible for encrypting
and optionally pushing the recorded ``ttyrec`` files to a distant server, along
with the user logs (``/home/*/*.log``) and user sqlite files (``/home/*/*.sqlite``).
The global log and sqlite files are also handled (located in ``/home/logkeeper/``).
Note that logs sent through syslog are NOT managed by this script.
.. warning::
If left unconfigured, this script won't do anything, and the recorded ``ttyrec`` files,
along with the log and sqlite files won't be encrypted or moved out from the server.
This might not be a problem for low-traffic bastions or if you have plenty of storage available, though.
Option List
===========
Logging options
---------------
These options configure the way the script logs its actions
- `logfile`_
- `syslog_facility`_
- `verbose`_
Encryption and signing options
------------------------------
These options configure how the script uses GPG to encrypt and sign the ttyrec files
- `signing_key`_
- `signing_key_passphrase`_
- `recipients`_
- `encrypt_and_move_to_directory`_
- `encrypt_and_move_ttyrec_delay_days`_
- `encrypt_and_move_user_logs_delay_days`_
- `encrypt_and_move_user_sqlites_delay_days`_
Push files to a remote destination options
------------------------------------------
These options configure the way the script uses rsync to optionally push the encrypted files out of the server
- `rsync_destination`_
- `rsync_rsh`_
- `rsync_delay_before_remove_days`_
Option Reference
================
Logging
-------
logfile
*******
:Type: ``string, path to a file``
:Default: ``""``
File where the logs will be written to (don't forget to configure ``logrotate``!).
Note that using this configuration option, the script will directly write to the file, without using syslog.
If empty, won't log directly to any file.
syslog_facility
***************
:Type: ``string``
:Default: ``"local6"``
The syslog facility to use for logging the script output.
If set to the empty string, we'll not log through syslog at all.
If this configuration option is missing from your config file altogether,
the default value will be used (local6), which means that we'll log to syslog.
verbose
*******
:Type: ``int >= 0``
:Default: ``0``
The verbosity level of the logs produced by the script
0: normal (default)
1: log more information about what is happening
2: log debug-level information
Encryption and signing
----------------------
signing_key
***********
:Type: ``string, GPG key ID in short or long format``
:Default: ``(none), setting a value is mandatory``
ID of the GPG key used to sign the ttyrec files.
The key must be in the local root keyring, check it with ``gpg --list-secret-keys``
signing_key_passphrase
**********************
:Type: ``string``
:Default: ``(none), setting a value is mandatory``
This passphrase should be able to unlock the ``signing_key`` defined above.
As a side note, please ensure this configuration file only readable by root (0640),
to protect this passphrase. As a security measure,
the script will refuse to read the configuration otherwise.
recipients
**********
:Type: ``array of array of strings, a string being a GPG key ID in short or long format``
:Default: ``(none), setting a value is mandatory``
The ttyrecs will be encrypted with those GPG keys, possibly using multi-layer GPG encryption.
Each sub-array is a layer, the first sub-array being the first encryption layer (which is also the last one for decryption)
To completely decrypt a ttyrec, one would need at least one key of each layer.
To encrypt only to a single layer and to only one key, simply use [ [ "KEYID" ] ].
To encrypt to a single layer but with 3 keys being able to decrypt the ttyrec, use [ [ "KEY1", "KEY2", "KEY3" ] ], etc.
A common use of multi-layer encryption is to have the first layer composed of the auditors' GPG keys, and
the second layer composed of the sysadmins' GPG keys. During an audit, the sysadmins would get the ttyrec encrypted file,
decrypt the second encryption layer (the first for decryption), and handle the now only auditor-protected file to the auditors.
All public keys must be in the local root keyring (gpg --list-keys).
Don't forget to trust those keys "ultimately" in root's keyring, too (gpg --edit-key ID)
encrypt_and_move_to_directory
*****************************
:Type: ``string, a valid directory name``
:Default: ``"/home/.encrypt"``
After encryption (and compression), move ttyrec, user sqlite and user log files to subdirs of this directory.
It'll be created if it doesn't exist yet.
You may want this directory to be the mount point of a remote filer, if you wish.
If you change this, it's probably a good idea to ensure that the path is excluded from the
master/slave synchronization, in ``/etc/bastion/osh-sync-watcher.rsyncfilter``.
This is already the case for the default value.
encrypt_and_move_ttyrec_delay_days
**********************************
:Type: ``int > 0, or -1``
:Default: ``14``
Don't touch ttyrec files that have a modification time more recent than this amount of days.
The files won't be encrypted nor moved yet, and will still be readable by the ``selfPlaySession`` command.
You can set this to a (possibly) much higher value, the only limit is the amount of disk space you have.
If set to -1, the ttyrec files will never get encrypted or moved by this script.
The eligible files will be encrypted and moved to ``encrypt_and_move_to_directory``.
NOTE: The old name of this option is `encrypt_and_move_delay_days`.
If it is found in your configuration file and `encrypt_and_move_ttyrec_delay_days` is not,
then the value of `encrypt_and_move_delay_days` will be used instead of the default.
encrypt_and_move_user_logs_delay_days
*************************************
:Type: ``int >= 31, or -1``
:Default: ``31``
Don't touch user log files (``/home/*/*.log``) that have been modified more recently than this amount of days.
The bare minimum is 31 days, to ensure we're not moving a current-month file.
You can set this to a (possibly) much higher value, the only limit is the amount of disk space you have.
If set to -1, the user log files will never get encrypted or moved by this script.
The eligible files will be encrypted and moved to ``encrypt_and_move_to_directory``.
encrypt_and_move_user_sqlites_delay_days
****************************************
:Type: ``int >= 31, or -1``
:Default: ``31``
Don't touch user sqlite files (``/home/*/*.sqlite``) that have been modified more recently than this amount of days.
The files won't be encrypted nor moved yet, and will still be usable by the ``selfListSessions`` command.
The bare minimum is 31 days, to ensure we're not moving a current-month file.
You can set this to a (possibly) much higher value, the only limit is the amount of disk space you have.
If set to -1, the user sqlite files will never get encrypted or moved by this script.
The eligible files will be encrypted and moved to ``encrypt_and_move_to_directory``.
Push files to a remote destination
----------------------------------
rsync_destination
*****************
:Type: ``string``
:Default: ``""``
:Example: ``"user@remotebackup.example.org:/remote/dir"``
The value of this option will be passed to ``rsync`` as the destination.
Note that the source of the rsync is already configured above, as the ``encrypt_and_move_to_directory``.
We only rsync the files that have already been encrypted and moved there.
If this option is empty, this will **disable** ``rsync``, meaning that the ttyrec files will be encrypted,
but not moved out of the server. In other words, the files will pile up in ``encrypt_and_move_to_directory``,
which can be pretty okay in you have enough disk space.
rsync_rsh
*********
:Type: ``string``
:Default: ``""``
:Example: ``"ssh -p 222 -i /root/.ssh/id_ed25519_backup"``
The value of this option will be passed to ``rsync``'s ``--rsh`` option.
This is useful to specify an SSH key or an alternate SSH port for example.
This option is ignored when ``rsync`` is disabled (i.e. when ``rsync_destination`` is empty).
rsync_delay_before_remove_days
******************************
:Type: ``int >= 0, or -1``
:Default: ``0``
After encryption/compression, and successful rsync of ``encrypt_and_move_to_directory`` to remote,
wait for this amount of days before removing the encrypted/compressed files locally.
Specify 0 to remove the files as soon as they're transferred.
This option is ignored when ``rsync`` is disabled (i.e. when ``rsync_destination`` is empty).
Note that if rsync is enabled (see ``rsync_destination`` above), we'll always sync the files present in
``encrypt_and_move_to_directory`` as soon as we can, to ensure limitation of logs data loss in case of
catastrophic failure of the server. The ``rsync_delay_before_remove_days`` option configures the number
of days after we remove the files locally, but note that these have already been transferred remotely
as soon as they were present in ``encrypt_and_move_to_directory``.
To rsync the files remotely but never delete them locally, set this to -1.

View file

@ -0,0 +1,178 @@
===================
osh-http-proxy.conf
===================
.. note::
This module is optional, and disabled by default.
To know more about the HTTP Proxy feature of The Bastion,
please check the :doc:`/using/http_proxy` section
Option List
===========
HTTP Proxy configuration options
--------------------------------
These options modify the behavior of the HTTP Proxy, an optional module of The Bastion
- `enabled`_
- `port`_
- `ssl_certificate`_
- `ssl_key`_
- `ciphers`_
- `insecure`_
- `min_servers`_
- `max_servers`_
- `min_spare_servers`_
- `max_spare_servers`_
- `timeout`_
- `log_request_response`_
- `log_request_response_max_size`_
Option Reference
================
HTTP Proxy configuration
------------------------
enabled
*******
:Type: ``bool``
:Default: ``false``
Whether the HTTP proxy daemon daemon is enabled or not. If it's not enabled, it'll exit when started.
Of course, if you want to enable this daemon, you should **also** configure your init system to start it
for you. Both sysV-style scripts and systemd unit files are provided.
For systemd, using `systemctl enable osh-http-proxy.service` should be enough.
For sysV-style inits, it depends on the scripts provided for your distro,
but usually `update-rc.d osh-http-proxy defaults` then `update-rc.d osh-http-proxy enable` should
do the trick.
port
****
:Type: ``int, 1 to 65535``
:Default: ``8443``
The port to listen to. You can use ports < 1024, in which case privileges will be dropped after binding,
but please ensure your systemd unit file starts the daemon as root in that case.
ssl_certificate
***************
:Type: ``string``
:Default: ``/etc/ssl/certs/ssl-cert-snakeoil.pem``
The file that contains the server SSL certificate in PEM format.
For tests, install the ``ssl-cert`` package and point this configuration item
to the snakeoil certs (which is the default).
ssl_key
*******
:Type: ``string``
:Default: ``/etc/ssl/private/ssl-cert-snakeoil.key``
The file that contains the server SSL key in PEM format.
For tests, install the ``ssl-cert`` package and point this configuration item
to the snakeoil certs (which is the default).
ciphers
*******
:Type: ``string``
:Default: ``""``
:Example: ``"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"``
The ordered list the TLS server ciphers, in ``openssl`` classic format. Use ``openssl ciphers``
to see what your system supports, an empty list leaves the choice to your openssl libraries default
values (system-dependent)
insecure
********
:Type: ``bool``
:Default: ``false``
Whether to ignore SSL certificate verification for the connection between the bastion and the devices
min_servers
***********
:Type: ``int, 1 to 512``
:Default: ``8``
Number of child processes to start at launch
max_servers
***********
:Type: ``int, 1 to 512``
:Default: ``32``
Hard maximum number of child processes that can be active at any given time no matter what
min_spare_servers
*****************
:Type: ``int, 1 to 512``
:Default: ``8``
The daemon will ensure that there is at least this number of children idle & ready to accept
new connections (as long as max_servers is not reached)
max_spare_servers
*****************
:Type: ``int, 1 to 512``
:Default: ``16``
The daemon will kill *idle* children to keep their number below this maximum when traffic is low
timeout
*******
:Type: ``int, 1 to 3600``
:Default: ``120``
Timeout delay (in seconds) for the connection between the bastion and the devices
log_request_response
********************
:Type: ``bool``
:Default: ``true``
When enabled, the complete response of the device to the request we forwarded will be logged,
otherwise we'll only log the response headers
log_request_response_max_size
*****************************
:Type: ``int, 0 to 2^30 (1 GiB)``
:Default: ``65536``
This option only applies when `log_request_response` is true (see above).
When set to zero, the complete response will be logged in the account's home log directory,
including the body, regardless of its size. If set to a positive integer,
the query response will only be partially logged, with full status and headers but the body only up
to the specified size. This is a way to avoid turning off request response logging completely on
very busy bastions, by ensuring logs growth don't get out of hand, as some responses to queries can
take megabytes, with possibly limited added value to traceability.

View file

@ -0,0 +1,81 @@
==================================
osh-lingering-sessions-reaper.conf
==================================
.. note::
This script is called by cron and is responsible for terminating
lingering sessions that no longer have any tty attached nor parent PID,
and have been running for some time.
Option List
===========
Logging & activation options
----------------------------
Script logging configuration and script activation
- `LOGFILE`_
- `LOG_FACILITY`_
- `ENABLED`_
Main options
------------
These options govern the behavior of the script
- `MAX_AGE`_
Option Reference
================
Logging & activation
--------------------
LOGFILE
*******
:Type: ``string, path to a file``
:Default: ``""``
File where the logs will be written to (don't forget to configure ``logrotate``!).
Note that using this configuration option, the script will directly write to the file, without using syslog.
If empty, won't log directly to any file.
LOG_FACILITY
************
:Type: ``string``
:Default: ``"local6"``
The syslog facility to use for logging the script output.
If set to the empty string, we'll not log through syslog at all.
If this configuration option is missing from your config file altogether,
the default value will be used (local6), which means that we'll log to syslog.
ENABLED
*******
:Type: ``0 or 1``
:Default: ``1``
If set to 1, the script is enabled and will run when started by crond.
Main
----
MAX_AGE
*******
:Type: ``int >= 0``
:Default: ``86400``
The minimum number of seconds a session must have been opened before
being considered as possibly a lingering orphan session.
Still alive sessions, even older than MAX_AGE seconds, will be kept.

View file

@ -0,0 +1,62 @@
=========================
osh-orphaned-homedir.conf
=========================
.. note::
This script is called by cron and is responsible for clearing up
orphaned home directories on secondary bastions.
Indeed, once the user has been deleted, a few files may remain,
such as logs, so this script handles the proper archiving
of these sparse files, before removing the orphaned home directory.
Option List
===========
Logging & activation options
----------------------------
Script logging configuration and script activation
- `LOGFILE`_
- `LOG_FACILITY`_
- `ENABLED`_
Option Reference
================
Logging & activation
--------------------
LOGFILE
*******
:Type: ``string, path to a file``
:Default: ``""``
File where the logs will be written to (don't forget to configure ``logrotate``!).
Note that using this configuration option, the script will directly write to the file, without using syslog.
If empty, won't log directly to any file.
LOG_FACILITY
************
:Type: ``string``
:Default: ``"local6"``
The syslog facility to use for logging the script output.
If set to the empty string, we'll not log through syslog at all.
If this configuration option is missing from your config file altogether,
the default value will be used (local6), which means that we'll log to syslog.
ENABLED
*******
:Type: ``0 or 1``
:Default: ``1``
If set to 1, the script is enabled and will run when started by crond.

View file

@ -0,0 +1,48 @@
=========================
osh-piv-grace-reaper.conf
=========================
.. note::
This script is called by cron and is responsible for removing temporary
grace periods on PIV policies, once they expire. If you don't use PIV keys,
this script won't do anything (see :doc:`/using/piv`).
Option List
===========
Logging & activation options
----------------------------
Script logging configuration and script activation
- `syslog_facility`_
- `enabled`_
Option Reference
================
Logging & activation
--------------------
syslog_facility
***************
:Type: ``string``
:Default: ``local6``
The syslog facility to use for logging the script output.
If set to the empty string, we'll not log through syslog at all.
If this configuration option is missing from your config file altogether,
the default value will be used (local6), which means that we'll log to syslog.
enabled
*******
:Type: ``bool``
:Default: ``true``
If not set to `true` (or a true value), the script will not run.

View file

@ -0,0 +1,84 @@
=============================
osh-remove-empty-folders.conf
=============================
.. note::
This script is called by cron and is responsible for getting rid of empty
folders in the ``ttyrec/`` directory of users homes, which may contain a
high amount of empty folders for busy users connecting to a lot of
different servers, as we create one folder per destination IP.
Of course, this script will only remove empty folders, never actual files.
Option List
===========
Logging & activation options
----------------------------
Script logging configuration and script activation
- `LOGFILE`_
- `LOG_FACILITY`_
Behavior options
----------------
These options govern the behavior of the script
- `ENABLED`_
- `MTIME_DAYS`_
Option Reference
================
Logging & activation
--------------------
LOGFILE
*******
:Type: ``string, path to a file``
:Default: ``""``
File where the logs will be written to (don't forget to configure ``logrotate``!).
Note that using this configuration option, the script will directly write to the file, without using syslog.
If empty, won't log directly to any file.
LOG_FACILITY
************
:Type: ``string``
:Default: ``"local6"``
The syslog facility to use for logging the script output.
If set to the empty string, we'll not log through syslog at all.
If this configuration option is missing from your config file altogether,
the default value will be used (local6), which means that we'll log to syslog.
Behavior
--------
ENABLED
*******
:Type: ``0 or 1``
:Default: ``1``
If set to 1, the script is enabled and will attempt to garbage-collect empty directories located
in ``/home/*/ttyrec``. If set to anything else, the script is considered disabled and will not run.
MTIME_DAYS
**********
:Type: ``int, >= 0``
:Default: ``1``
The amount of days the empty folder must have been empty before considering a removal. You probably
don't need to change the default value, unless you want to ensure that a given folder has not been
used since some time before removing it (this has no impact as folders are re-created as needed).

View file

@ -0,0 +1,119 @@
===================
osh-sync-watcher.sh
===================
.. note::
This daemon is responsible for ensuring secondary bastions
are synced up to their primary at all times.
If you don't have such HA setup, you can ignore this config file.
For more information, refer to
:ref:`installation/advanced:clustering (high availability)`.
Option List
===========
Logging options
---------------
These options configure the way the script logs its actions
- `logdir`_
- `syslog`_
Daemon setup options
--------------------
These options configure whether the synchronization daemon is enabled
- `enabled`_
- `timeout`_
Remote synchronization options
------------------------------
These options configure how the primary bastion should push its configuration to the secondaries
- `rshcmd`_
- `remoteuser`_
- `remotehostlist`_
Option Reference
================
Logging
-------
logdir
******
:Type: ``string``
:Default: ``""``
Directory where the logs will be written to. Note that using this configuration option, the script will directly write to a file, without using syslog. If empty, won't log directly to a file.
syslog
******
:Type: ``string``
:Default: ``"local6"``
The syslog facility to use for logging the script output. If set to the empty string, we'll not log through syslog at all. If this configuration option is missing from your config file altogether, the default value will be used (local6), which means that we'll log to syslog.
Daemon setup
------------
enabled
*******
:Type: ``int``
:Default: ``0``
If set to anything else than ``1``, the daemon will refuse to start (e.g. you don't have secondary bastions). You can set this to ``1`` when you've configured and tested the primary/secondaries setup.
timeout
*******
:Type: ``int > 0``
:Default: ``120``
The maximum delay, in seconds, after which we'll forcefully synchronize our data to the secondaries, even if no change was detected.
Remote synchronization
----------------------
rshcmd
******
:Type: ``string``
:Default: ``""``
:Example: ``"ssh -q -i /root/.ssh/id_master2slave -o StrictHostKeyChecking=accept-new"``
This value will be passed as the ``--rsh`` parameter of ``rsync`` (don't use ``-p`` to specify the port here, use the ``remotehostlist`` config below instead), this can be used to specify which SSH key to use, for example. NOTE THAT THIS OPTION IS MANDATORY (if you don't have anything to specify here, you can just say ``ssh``). If you followed the standard installation procedure, the "example" value specified below will work.
remoteuser
**********
:Type: ``string``
:Default: ``"bastionsync"``
The remote user to connect as, using ``ssh`` while rsyncing to secondaries. You probably don't need to change this.
remotehostlist
**************
:Type: ``space-separated list of strings, each string being either 'ip' or 'ip:port'``
:Default: ``""``
:Example: ``"192.0.2.17 192.0.2.12:2244"``
The list of the secondary bastions to push our data to. If this list is empty, the daemon won't do anything.

View file

@ -0,0 +1,599 @@
====
Logs
====
.. note::
The Bastion comes with a lot of traceability features, you have to ensure that you've done your configuration
correctly so that those logs are kept in a safe place when you need them. It is warmly advised to enable at least
the syslog option, and push your logs to a remote syslog server.
.. contents::
:depth: 5
Message types
=============
The Bastion has several configurable ways of logging events, but before detailing those,
let's see the different message types that can be logged.
The Bastion currently has 12 different message types, listed below:
- :ref:`log_open`
- :ref:`log_close`
- :ref:`log_warn`
- :ref:`log_warninfo`
- :ref:`log_codewarn`
- :ref:`log_acl`
- :ref:`log_membership`
- :ref:`log_security`
- :ref:`log_group`
- :ref:`log_account`
First, let's list the fields that are common to all the message types:
uniqid
This is the unique connection ID, you can find all the logs relevant to the same connection
by filtering on the ``uniqid``. This ID is also, by default, part of the filename given to the ``ttyrec`` files,
for easier correlation. The same ID is also used in the sqlite logs, if you enabled those. In some rare cases,
the value can be "-", for example if a satellite script has something to log,
not linked to an actual connection or session.
version
This indicates the version of The Bastion software that is writing the log
pid, ppid
This is the system PID (resp. system parent PID) of the process writing the log,
for easier correlation with system audit logs if you have them
sysuser
This is the system user under which the process writing the log is currently running on,
can be useful to detect abnormalities
sudo_user
When the value is present, it contains the system user name that has launched the ``sudo`` command the code is
currently running under (this will be the case if a so-called "bastion helper" is pushing a log, for example).
However this field will often have an empty value, it means that the code that is writing the log
is not running under ``sudo``
uid, gid
This is the system user ID aka UID (resp. group ID aka GID) under which
the process writing the log is currently running
account
This is the name of the bastion account that launched the command that produced the log
The other fields depend on the message type, as detailed in the next sections.
.. _log_open:
open
****
This log is produced when a user established a session with the bastion.
Example::
Dec 28 11:12:26 myhostname bastion: open uniqid="e9e4baf6873b" version="3.01.03" pid="18721" ppid="18720"
sysuser="gthreepw" sudo_user="" uid="99998" gid="99998" account="gthreepw" cmdtype="ssh" allowed="true"
ip_from="172.17.0.1" port_from="39696" host_from="172.17.0.1" ip_bastion="172.17.0.2" port_bastion="22"
host_bastion="myhostname.example.org" user="foo" ip_to="172.17.0.123" port_to="22" host_to="srv123.example.org"
plugin="" globalsql="ok" accountsql="ok" comment="" params="ttyrec -f
/home/gthreepw/ttyrec/172.17.0.123/2020-12-28.11-12-26.074894.e9e4baf6873b.gthreepw.foo.172.17.0.123.22.ttyrec -F
/home/gthreepw/ttyrec/172.17.0.123/%Y--%d.%H-%M-%S.#usec#.e9e4baf6873b.gthreepw.foo.172.17.0.123.22.ttyrec --
/usr/bin/ssh 172.17.0.123 -l foo -p 22 -i /home/gthreepw/.ssh/id_rsa4096_private.1594384739 -i
/home/keykeeper/keyagroup/id_ed25519_agroup.1607524914 -o PreferredAuthentications=publickey"
Fields:
cmdtype
Indicates which category of command has been requested by the user:
- ssh: the user is trying to establish an SSH egress connection to a remote server
- telnet: the user is trying to establish a telnet egress connection to a remote server
- abort: the action requested by the user has been aborted early, possibly because of permission issues
or impossibility to understand the request, more information is available in the **bastion_comment** field
- osh: the user is trying to execute a bastion plugin with the ``--osh`` command
- interactive: the user just entered interactive mode. Note that all the commands launched through
the interactive mode will still have their own log.
- sshas: an administrator is currently establishing a connection on behalf of another user.
This connection will also have its own log.
- proxyhttp_daemon: the HTTPS proxy daemon received a request
- proxyhttp_worker: the HTTPS proxy worker specifically spawned for the user by the daemon is handling the request
allowed
Indicates whether the requested action was allowed or not by the bastion, after executing the authorization phase.
Will be either "true" or "false".
ip_from, port_from, host_from
These are the IP and source port as seen by the bastion, from which the ingress connection originates.
If the bastion can resolve the reverse of the IP to a hostname, it'll be indicated in host_from,
otherwise the IP will be repeated there.
ip_bastion, port_bastion, host_bastion
These are the IP and port of the bastion to which the ingress connection terminates.
If your bastion has several IPs and/or interfaces, this can be useful.
If the bastion can resolve the reverse of the IP to a hostname, it'll be indicated in host_bastion,
otherwise the IP will be repeated there.
ip_to, port_to, host_to
These are the IP and destination port to which the bastion will connect on the egress side,
on behalf of the requesting user. If the bastion can resolve the reverse of the IP to a hostname,
it'll be indicated in host_to, otherwise the IP will be repeated there.
plugin
When ``cmdtype`` is ``osh``, the name of the command (or *plugin*) will appear in this field.
Otherwise it'll be blank.
accountsql
This field will contain either:
- ok: when :ref:`enableAccountSqlLog` is enabled, and we successfully inserted a new row for the log
- no: when :ref:`enableAccountSqlLog` is disabled
- error: when we couldn't insert a new row, **error** followed by a detailed error message,
for example "error SQL error [global] err 8 while doing [inserting data (execute)]:
attempt to write a readonly database".
globalsql
This field can contain the same values than **accountsql** above,
but for ``enableGlobalSqlLog`` instead of ``enableAccountSqlLog``
comment
Some more information about the current event, depending on the ``cmdtype`` value.
params
This is the fully expanded command line that will be launched under the currently running user rights,
to establish the egress connection, if applicable.
.. _log_close:
close
*****
This log is produced when a user terminates a currently running session with The Bastion.
It is always matched (through the ``uniqid``) to another log with the ``open`` message type.
Example::
Dec 28 11:12:26 myhostname bastion: open uniqid="e9e4baf6873b" version="3.01.03" pid="18721" ppid="18720"
sysuser="gthreepw" sudo_user="" uid="99998" gid="99998" account="gthreepw" cmdtype="ssh" allowed="true"
ip_from="172.17.0.1" port_from="39696" host_from="172.17.0.1" ip_bastion="172.17.0.2" port_bastion="22"
host_bastion="myhostname.example.org" user="foo" ip_to="172.17.0.123" port_to="22"
host_to="srv123.example.org" plugin="" globalsql="ok" accountsql="ok" comment="" params="ttyrec -f
/home/gthreepw/ttyrec/172.17.0.123/2020-12-28.11-12-26.074894.e9e4baf6873b.gthreepw.foo.172.17.0.123.22.ttyrec -F
/home/gthreepw/ttyrec/172.17.0.123/%Y--%d.%H-%M-%S.#usec#.e9e4baf6873b.gthreepw.foo.172.17.0.123.22.ttyrec --
/usr/bin/ssh 172.17.0.123 -l foo -p 22 -i /home/gthreepw/.ssh/id_rsa4096_private.1594384739 -i
/home/keykeeper/keyagroup/id_ed25519_agroup.1607524914 -o PreferredAuthentications=publickey" sysret="0"
signal="" comment_close="hostkey_changed passauth_disabled" duration="43.692"
All the fields from the corresponding ``open`` log are repeated in this log line, in addition to the following fields:
sysret
Return code of the launched system command (that established the egress connection)
or the plugin (if an ``--osh`` command was passed).
If we don't have a return code, for example because we were interrupted by a signal, the value will be empty.
signal
Name of the UNIX signal that terminated the command, if any. For example "HUP" or "SEGV".
If we got no signal, the value will be empty.
comment_close
A space-separated list of messages giving some hints gathered at the end of a session.
For example `hostkey_changed passauth_disabled` means that we detected that our egress ssh client
emitted a warning telling us that the remote keys changed, and also that password authentication has been disabled.
duration
Amount of seconds (with a millisecond precision) between the session open and the session close.
.. _log_warn:
warn, die
*********
These logs are produced when Perl emits a warning (using the ``warn()`` call),
or respectively when Perl halts abruptly due to a ``die()`` call.
This should not happen during nominal use. You might want to keep a look on those messages if they're produced.
Example::
Dec 28 11:12:26 myhostname bastion: warn uniqid="a46e51b5dce4" version="3.01.02" pid="3308212" ppid="3308206"
sysuser="lechuck" sudo_user="" uid="99994" gid="99994" msg="Cannot find termcap: TERM not set at
/usr/share/perl/5.28/Term/ReadLine.pm line 379. " program="/opt/bastion/bin/shell/osh.pl" cmdline="-c^-i ssh
root@172.17.0.222 id" trace=" at /opt/bastion/bin/shell/../../lib/perl/OVH/Bastion.pm
line 41. OVH::Bastion::__ANON__(\"Cannot find termcap: TERM not set at /usr/share/perl/5.28/Ter\"...)
called at /usr/share/perl/5.28/Term/ReadLine.pm line
391 Term::ReadLine::TermCap::ornaments(Term::ReadLine::Stub=ARRAY(0x5575da36b690), 1) called at
/opt/bastion/lib/perl/OVH/Bastion/interactive.inc line 77 OVH::Bastion::interactive(\"realOptions\", \"-i ssh
root\\@172.17.0.222 id\"..., \"timeoutHandler\", CODE(0x5575da15aa78), \"self\", \"lechuck\")
called at /opt/bastion/bin/shell/osh.pl line 485 "
Fields:
msg
This is the message used as a parameter to the ``warn()`` or ``die()`` call
program
Contains the name of the currently running program (first parameter of ``execve()``)
cmdline
Contains the full command line passed to the currently running program (remaining parameters of ``execve()``).
The command-line fields are separated by ``^``'s.
trace
The call trace leading to this ``warn()`` or ``die()``
.. _log_warninfo:
warn-info, die-info
*******************
These logs are produced when some known portion of code (including libraries) called ``warn()`` or ``die()``
but in a known case that can happen during nominal use.
Don't use these logs to directly trigger an alert, but you can keep an eye on those, as e.g. an unusually
high number of occurences in a short time may be a weak signal that somebody or something is misbehaving.
The fields are the same than the ones specified above for **warn** and **die**.
.. _log_codeinfo:
code-info
*********
These logs are produced when some portion of the code encounters an minor issue that is worth logging,
to e.g. help debugging an issue or understanding what happened in a specific use-case,
for example if a user-session ended abruptly.
These logs are not the result of an error on the bastion configuration and don't mandate immediate admin attention.
Example::
Dec 25 14:56:11 myhostname bastion: code-info uniqid="98d2f32b1a2d" version="3.07.00" pid="3708843"
ppid="3708842" sysuser="lechuck" sudo_user="" uid="8423" gid="8423" msg="execute():
error while syswriting(Broken pipe) on stderr, aborting this cycle"
Fields:
msg
A human-readable text describing the error
.. _log_codewarn:
code-warning
************
These logs are produced when some portion of the code encounters an unexpected issue or abnormality
that is worth logging. They'll usually not be emitted due to a bad user interaction, but rather if the bastion
is misconfigured, or for anything that might need some attention or fixing from the admins.
Example::
Dec 28 11:12:26 myhostname bastion: code-warning uniqid="ffee33abd1ba" version="3.01.03" pid="3709643"
ppid="3709642" sysuser="lechuck" sudo_user="" uid="8423" gid="8423" msg="Configuration error
for plugin selfGenerateEgressKey on the 'disabled' key: expected a boolean, casted 'no' into false"
Fields:
msg
A human-readable text describing the error
.. _log_acl:
acl
***
This log is produced when an access control list is modified,
either personal accesses of an account, or a group servers list.
Example::
Dec 28 11:12:26 myhostname bastion: acl uniqid="f25fe71c6635" version="3.01.02" pid="3116604"
ppid="3116603" sysuser="keysomegroup" sudo_user="lechuck" uid="10006" gid="10057" action="add"
type="group" group="somegroup" account="" user="root" ip="172.16.2.2" port="22" ttl="" force_key="" comment=""
Fields:
action
Will be either *add* if an access is added, or *del* if an access is removed
type
Will be either *group* if we're modifying a group server list, in which case the *group* field will be filled,
or *account* if we're modifying personal accesses of an account, in which case the *account* field will be filled
group
If **type** is *group*, indicates which group servers list has been modified
account
If **type** is *account*, indicates which account personal accesses have been modified
user
The remote user part of the access we're adding/removing
ip
The IP or IP block of the access we're adding/removing
port
The port of the access we're adding/removing
ttl
If set, represents the TTL after which the access will automatically be removed
force_key
If set, this contains the fingerprint of the key that'll be used for this access
comment
Any comment set by the user adding/removing the access
.. _log_membership:
membership
**********
This log is produced when one of a group's role list is modified:
either an owner, member, guest, aclkeeper or gatekeeper.
Example::
Dec 28 11:12:26 myhostname bastion: membership uniqid="a00993ec6767" version="3.01.02"
pid="1072528" ppid="1072497" sysuser="lechuck" sudo_user="" uid="2070" gid="2070" action="add"
type="member" group="monkeys" account="stan" self="lechuck" user="" host="" port="" ttl=""
Fields:
action
Either *add* when an account is added to a group role list, or *del* when an account is removed
type
Type of the role list we're modifying, either *member*, *aclkeeper*, *gatekeeper*, *guest* or *owner*
group
Group whose one of the role list is being modified
account
Account being added/removed to/from the group role list
self
Account performing the change
user
When **type** is *guest*, the remote user part of the access we're adding/removing
host
When **type** is *guest*, the IP or IP block part of the access we're adding/removing
port
When **type** is *guest*, the port of the access we're adding/removing
ttl
When **type** is *guest* and **action** is *add*, if a TTL has been specified for the access, it appears here
.. _log_security:
security
********
This log is produced when an important security event has occurred, such as when an admin impersonates another user,
or when a super owner uses his implicit global ownership to modify a group. You might want to watch those closely.
Example::
Dec 28 11:12:26 myhostname bastion: security uniqid="601a17b5e5ba" version="3.01.03" pid="20519"
ppid="20518" sysuser="lechuck" sudo_user="" uid="2604" gid="2604" type="admin-ssh-as" account="lechuck"
sudo-as="gthreepw" plugin="ssh" params="--user root --host supersecretserver.example.org --port 22"
Fields:
type
Type of the security event that occurred. Can be:
- admin-ssh-as: an admin impersonated another user to establish an egress connection
- admin-sudo: an admin impersonated another user and launched an osh plugin on their behalf
- superowner-override: a super owner used his implicit ownership on all groups to modify a group
account
Account that emitted the security event
sudo-as
When **type** is *admin-ssh-as* or *admin-sudo*, name of the account that was impersonated
plugin
Name of the osh plugin that was launched
params
Parameters passed to the plugin, or command line used to establish the egress connection
.. _log_group:
group
*****
This log is produced when a group is created or deleted.
Note that membership modifications are referenced with the **membership** type instead, see above.
Example::
Dec 28 11:12:26 myhostname bastion: group uniqid="56f321fb3e58" version="3.01.03" pid="1325901"
ppid="1325900" sysuser="root" sudo_user="lechuck" uid="0" gid="0" action="create" group="themonkeys"
owner="stan" egress_ssh_key_algorithm="ed25519" egress_ssh_key_size="256" egress_ssh_key_encrypted="false"
Fields:
action
Either *create* or *delete*, indicating whether the group has just been created or deleted
group
The group name being created or deleted
owner
When **action** is *create*, the name of the owner of the new group we're creating
egress_ssh_key_algorithm, egress_ssh_key_size
When **action** is *create*, the algorithm (and size) used to generate the first pair of SSH keys,
can be empty if ``--no-key`` was specified
egress_ssh_key_encrypted
When **action** is *create*, if a key was generated,
will be *true* if ``--encrypted`` has been used, *false* otherwise
.. _log_account:
account
*******
This log is produced when an account is created or deleted.
Example::
Dec 21 14:30:26 myhostname bastion: account uniqid="ee4c91000b75" version="3.01.02" pid="537253" ppid="537252"
sysuser="root" sudo_user="lechuck" uid="0" gid="0" action="create" account="stan" account_uid="8431"
public_key="ssh-rsa AAAAB[...]" always_active="false" uid_auto="false" osh_only="false" immutable_key="false"
comment="CREATED_BY=lechuck BASTION_VERSION=3.01.02 CREATION_TIME=Mon Dec 21 14:30:26 2020
CREATION_TIMESTAMP=1608561026 COMMENT=requested_by_the_sword_master_of_melee_island_see_ticket_no_1337"
Fields:
action
Either *create* or *delete*, indicating whether the account has just been created or deleted
account
The account name being created or deleted
account_uid
When **action** is *create*, the UID associated corresponding to the account we're creating
public_key
When **action** is *create*, the public key we've generated for the new account
always_active, uid_auto, osh_only, immutable_key
When **action** is *create*, *true* if the corresponding option was specified (``--always-active``,
``--uid-auto``, ``--osh-only`` or ``--immutable-key``), *false* otherwise
comment
When **action** is *create*, the comment specified at creation if any, with some metadata that'll be stored in
the account properties (*created_by*, *bastion_version*, *creation_time*, *creation_timestamp*)
tty_group
When **action** is *delete*, the name of the tty group specific to this account that was deleted at the same time
.. _syslog:
Syslog
======
Files location
**************
If you use ``syslog-ng`` and installed the provided templates (which is the default if you used
the ``--new-install`` option to the install script), you'll have 4 files in your system log directory:
/var/log/bastion/bastion.log
This is where all the bastion usage logs will be written. All the above message types can be found in this file.
/var/log/bastion/bastion-die.log
This is where Perl crashes will be logged, with the message type ``die``.
On a production bastion, this file should normally be empty.
/var/log/bastion/bastion-warn.log
This is where Perl warnings will be logged, with the message type ``warning``.
On a production bastion, this file should mostly be empty.
/var/log/bastion/bastion-scripts.log
This is where all the satellite scripts (mostly found in the ``bin/cron/`` directory) will log their output.
Log format
**********
A syslog message will always match the following generic format::
SYSLOG_TIME SYSLOG_HOST bastion: MSGTYPE field1="value1" field2="second value" ...
Where SYSLOG_TIME is the usual datetime field added by your local syslog daemon,
and SYSLOG_HOST the hostname of the local machine.
The MSGTYPE indicates the message type of the log line (the list of types is further below).
Then, a possibly long list of fields with quoted values, depending on the MSGTYPE.
An example follows::
Dec 28 11:14:23 myhostname bastion: code-warning uniqid="e192fce7553a" version="3.01.03"
pid="18803" ppid="18802" sysuser="gthreepw" sudo_user="" uid="99998" gid="99998"
msg="Configuration error: specified adminAccounts 'joe' is not a valid account, ignoring"
In that case, the MSGTYPE is ``code-warning``, and we have a few field/value couples with some metadata of interest,
followed by a human-readable message, indicated by the ``msg`` field.
Only satellite scripts will miss the field/value construction, which will just be replaced by a plain text message.
These logs are stored in :file:`/var/log/bastion/bastion-scripts.log` by default.
Access logs
===========
If you don't or can't use :ref:`syslog`, the bastion can create and use access log files on its own,
without relying on a syslog daemon. Note that you can enable both syslog and these access logs, if you want.
These access logs will only contain :ref:`log_open` and :ref:`log_close` log types, which can be seen as "access logs".
All the other log types, such as :ref:`log_warn`, :ref:`log_membership`, etc. are only logged through syslog.
These logs are enabled through the :ref:`enableGlobalAccessLog` and :ref:`enableAccountAccessLog` options.
enableGlobalAccessLog
When enabled, a single log file will be used, located in :file:`/home/logkeeper/global-log-YYYYMM.log`.
There will be one file per month. Note that it can grow quite large if you have a busy bastion.
enableAccountAccessLog
When enabled, one log file per account will be used, located in :file:`/home/USER/USER-log-YYYYMM.log`.
There will be one file per month.
If both options are enabled, it means that every access log will be logged twice, to two different locations.
If you also enabled syslog, it's even three times!
SQLite logs
===========
If you want to store access logs into local sqlite databases, you can enable either :ref:`enableGlobalSqlLog`,
:ref:`enableAccountSqlLog`, or both.
enableGlobalSqlLog
When enabled, a global sqlite database will be created in :file:`/home/logkeeper/global-log-YYYYMM.sqlite`.
It'll contain one row per access (created at the same time the :ref:`log_open` log is emitted).
The following columns exist: id, timestamp, account, cmdtype, allowed, ipfrom, ipto, portto, user, plugin, uniqid.
Refer to the :ref:`log_open` log description to get the meaning of each column.
enableAccountSqlLog
When enabled, an sqlite database per account will be created in :file:`/home/USER/USER-log-YYYYMM.sqlite`.
It'll contain one row per access (created at the same time the :ref:`log_open` log is emitted),
and the same row will be updated by the :ref:`log_close` event when it is emitted. The following columns exist:
id, timestamp, timestampusec, account, cmdtype, allowed, hostfrom, ipfrom, bastionip, bastionport, hostto,
ipto, portto, user, plugin, ttyrecfilee, params, timestampend, timestampendusec, returnvalue, comment, uniqid.
Refer to the :ref:`log_open` log and :ref:`log_close` log descriptions to get the meaning of each column.
Note that the :ref:`enableAccountSqlLog` option is required if you want the :doc:`/plugins/open/selfListSessions`
and :doc:`/plugins/open/selfPlaySession` plugins to work, as they use this database.
Note that enabling these on a very busy bastion (several new connections per second) can create lock contention,
especially on the global log: ensure you have a fast storage. In any case, if a connection can't get the lock after
a few seconds, it'll proceed anyway, and skip writing the sql log. In that case, if you enabled syslog or
local access logs, the **globalsql** and/or the **accountsql** field will contain the error detail.
Terminal recordings (*ttyrec*)
==============================
Every egress connection is started under ``ttyrec``, which means that everything appearing on the console is recorded.
If a password is asked by some program, for example, and typing the password prints '*' or doesn't print
anything at all, this won't be recorded. This is by design. In other words, the keystrokes are not recorded,
except if they produce something on the screen.
The ttyrec files location is always :file:`/home/USER/ttyrec/REMOTEIP/file.ttyrec`, where the actual `file.ttyrec`
name can be configured by the :ref:`ttyrecFilenameFormat` option.
By default, it'll contain the date, time, account, remote ip, port and user used to start the egress connection,
as well as the uniqid, for easier correlation between all the logs produced by the same connection.
Note that for long connections, or connections producing a lot of output, ttyrec files will be transparently rotated,
without interrupting the connection.
This is to avoid ending up with ttyrec files of several gigabytes that would still be opened, written to,
hence impossible to compress, encrypt, and push to an escrow filer.
The uniqid will be the same for all the ttyrec files corresponding to the same connection.
To play ttyrec files, you can either use :doc:`/plugins/open/selfPlaySession` for yourself, or,
for admins having local access to the bastion machine, the ``ttyplay`` program can be used.
Another software, perhaps more powerful than ttyplay, can also be used:
`IPBT <https://www.chiark.greenend.org.uk/~sgtatham/ipbt/>`_ (`wiki <https://nethackwiki.com/wiki/IPBT>`_),
aka "It's PlayBack Time", by the PuTTY author.
It can do more advanced things such as look for words appearing on any frame recorded in the ttyrec file,
play files using a logarithmic speed, or display an OSD with the exact time output you're seeing has appeared.
As ttyrec is a well-known format that has been around for a while,
there are a bunch of other programs you can use to read or convert these files.

View file

@ -0,0 +1,441 @@
===========================
Multi-Factor Authentication
===========================
.. contents::
Introduction
============
Flavors
*******
The Bastion supports two flavors of Multi-Factor Authentication (MFA, sometimes called 2FA):
- `Immediate MFA`, mandatory on a per-account basis during the SSH authentication phase on the ingress side,
done by the system even before executing the bastion code, regardless of which actions (plugin calls,
remote connection, ...) are to be done by the account currently being authenticated
- `JIT MFA`, done after the authentication phase, by the bastion code, conditionally (*just-in-time*), when
an action that is about to be done requires it by (configurable) policy
Each of these methods and their differences are detailed below, so you can choose the one that fits your environment.
Supported additional factors
****************************
The first factor is always the SSH publickey. Two additional factors are supported:
- `password`, in which case a password is attached to the account. This password's policy is configurable through
:ref:`administration/configuration/bastion_conf:mfapasswordmindays`,
:ref:`administration/configuration/bastion_conf:mfapasswordmaxdays`,
:ref:`administration/configuration/bastion_conf:mfapasswordwarndays`,
:ref:`administration/configuration/bastion_conf:mfapasswordinactivedays`.
- `TOTP`, aka "Time-based One-Time Password", which requires a smartphone app and generates a new pin-code every
60 seconds.
Immediate MFA
=============
This method implements MFA directly using PAM during the initial SSH authentication phase, on the ingress
side, e.g. when accounts are connecting to the bastion. This entirely resides on SSH/PAM and doesn't even depend
on The Bastion code (appart from the setup side of the additional factor for each account).
.. note::
Use this method if you want to enable MFA for some or all accounts unconditionally, regardless of which action
they're about to conduct on The Bastion (i.e. use an ``--osh`` command, or attempt to connect somewhere,
or just display the help). If you want to enable MFA only for some precise ``--osh`` commands or some remote hosts,
you'll want to use :ref:`jit_mfa` instead.
This method requires proper configuration of both the SSH server, and PAM. The included templates of
:file:`/etc/ssh/sshd_config` and :file:`/etc/pam.d/ssh` files do support it out of the box.
Detailed explanation of the SSH server and PAM configuration
************************************************************
This works by modifying the ``AuthenticationMethods`` in :file:`sshd_config` to add ``keyboard-interactive:pam``,
which instructs the SSH server to rely on PAM for part of the authentication phase. Then, the PAM file defines
several authentications methods, which include several factors that can be configured per-account.
.. note::
You can skip this subsection if you're not interested in how this works exactly, but mainly want to know how
to setup MFA. If you're using the included :file:`sshd_config` and :file:`pam.d/ssh` templates unmodified,
which you are if you've followed the installation section, this will just work out of the box so you may skip
over the details and jump to :ref:`immediate_mfa_howto`.
sshd_config snippet
-------------------
Let's take the last few lines of the :file:`ssh_config` file and explain them step by step. These are where the
MFA logic is implemented. We've left the comments that can be found in the template, for clarity.
.. code-block:: shell
# If 2FA has been configured for root, we force pubkey+PAM for it. If this is the case
# on your system, uncomment the next two lines (see
# https://ovh.github.io/the-bastion/installation/advanced.html#fa-root-authentication)
#Match User root
# AuthenticationMethods publickey,keyboard-interactive:pam
As explained in the comments within the file, this section (commented by default) refers to the MFA that can be
configured on the ``root`` account to protect The Bastion's own system. This is out of the scope of this documenation
section, as we're focusing on the users MFA here, so refer to the :ref:`installation/advanced:2fa root authentication`
section if that's what you want to achieve.
.. code-block:: shell
# Unconditionally skip PAM auth for members of the bastion-nopam group
Match Group bastion-nopam
AuthenticationMethods publickey
The snipper above tells the SSH server to NOT rely on PAM (hence disable MFA) for accounts that are part of the
``bastion-nopam`` group. This is an internal group that is used for accounts whose MFA setup has been set to
bypass PAM authentication, with the following command:
.. code-block:: none
:emphasize-lines: 1
bssh --osh accountModify --account robot-sync --pam-auth-bypass yes
╭──ac777d06bec9───────────────────────────────────────────the-bastion-3.12.00───
│ ▶ modify the configuration of an account
├───────────────────────────────────────────────────────────────────────────────
│ Bypassing sshd PAM auth usage for this account...
│ ... done, this account will no longer use PAM for authentication
╰────────────────────────────────────────────────────────────</accountModify>───
This way, the account ``robot-sync`` will fall into the above configuration section ``Match`` case and end up
only using classic ``publickey`` authentication, hence no MFA. As MFA is only meaningful for humans, use this setting
for accounts that are used by any automated process you might have that interact with the bastion (for example using
its :doc:`/using/api`).
.. code-block:: shell
# if in one of the mfa groups AND the osh-pubkey-auth-optional group, use publickey+pam OR pam
Match Group mfa-totp-configd,mfa-password-configd Group osh-pubkey-auth-optional
AuthenticationMethods publickey,keyboard-interactive:pam keyboard-interactive:pam
The snippet above tells SSH that for accounts having an authentication factor configured, namely either a TOTP or
a password, and having the "public key is optional" flag, set by ``--osh accountModify --pubkey-auth-optional``,
implies that those accounts can either authenticate through public key and an additional factor (through PAM),
or through PAM only. In essence these accounts may use only a password, or a TOTP, or both, without having a
public key in addition to the other factors. Hence, this is not MFA per-se, but is an additional functionaly available
should you need this in your environment. You may remove (or comment) the two lines above if you're confident you'll
never require the `pubkey-auth-optional` feature.
.. code-block:: shell
# if in one of the mfa groups, use publickey AND pam
Match Group mfa-totp-configd,mfa-password-configd
AuthenticationMethods publickey,keyboard-interactive:pam
The snippet above is the core of the mandatory MFA configuration of the SSH server: it instructs the SSH server to
authenticate accounts that have at least one MFA factor configured with their public key first, then hand over the
authentication phase to PAM to check the additional factors.
.. code-block:: shell
# by default, always ask the publickey (no PAM)
Match All
AuthenticationMethods publickey
Finally, the snippet above is for the general case, i.e. accounts not having MFA configured, in which case they're
authenticated using their public key only.
PAM ssh snippet
---------------
The template is `heavily commented<https://github.com/ovh/the-bastion/blob/master/etc/pam.d/sshd.debian12>`, line by line, please have a look at it if you want to know more.
.. _immediate_mfa_howto:
How to use Immediate MFA
************************
If you want to setup immediate MFA, you'll need to setup the SSH server and PAM configurations correctly, as explained
above. If you installed the provided templates for both (which is the default), you're good to go.
You may want either to enable MFA for *all* the accounts existing on your bastion, or only a subset of these users,
read on the proper section below for each case.
Requiring all users to setup their MFA
--------------------------------------
To ensure no user can use their account without configuring their MFA first, you have to set the ``accountMFAPolicy``
option of :file:`bastion.conf` to either ``any-required``, ``totp-required`` or ``password-required``. Detailed
information about this configuration setting is available
:ref:`here <administration/configuration/bastion_conf:accountmfapolicy>`.
When this setting is configured to any of the 3 above values, no interaction will be allowed on the bastion (such as
using plugins or connecting to a remote asset) as long as the user didn't set up their MFA:
.. code-block:: none
bssh --osh selfListAccesses
│ ⛔ Sorry johndoe, but you need to setup the Multi-Factor Authentication before using this bastion, please use either the `--osh selfMFASetupPassword' or the `--osh selfMFASetupTOTP' option, at your discretion, to do so
The only allowed ``--osh`` commands allowed in such a case are ``help``, ``info`` and the two ones referenced in the
above error message, precisely to be able to setup the MFA on the account.
In this mode, if you want to exclude a few accounts from requiring MFA (if you have accounts that are used by
automation or any other M2M workflow), you can do so using ``accountModify --pam-auth-bypass yes``.
.. _immediate_mfa_subset_users:
Requiring only a subset of users to setup their MFA
---------------------------------------------------
If instead of forcing all users to require MFA, you want to require a precise subset of users to have MFA, you should
leave the ``accountMFAPolicy`` to ``enabled``, and set the requirement flag on a per-account basis. This can be
done using ``accountModify --mfa-password-required yes`` and/or ``accountModify --mfa-totp-required yes``. If you
set both flags on the same account, the bastion will require both factors to be set and provided on authentication,
in addition to publickey authentication. In this case, 3 authentication factors would be required. This is why we
call it *MFA* instead of *2FA*: the number of additional factors you want is configurable.
.. _jit_mfa:
JIT MFA
=======
This method implements MFA checking right before an action is allowed, depending on the bastion policy, instead of
requiring it at the ingress authentication stage.
.. note::
Use this method if you want to enable MFA on a per-action basis. In this case, The Bastion will decide whether
providing additional authentication factors is required right before a specific action is requested (such as
connection to a given remote asset, or execution of a subset of ``--osh`` commands).
You may also want to use this method if for some reason you can't setup the :file:`sshd_config` file
as required by the *Immediate MFA* method
Note that the different ways detailed below can be cumulated: you might want to enable MFA for a few plugins, along
with enabling it for sensitive remote hosts present in specific bastion groups, in addition to a few sensitive
accounts that would require it no matter what.
.. _jit_mfa_sshd_config:
Proper setup of sshd_config
***************************
To use `JIT MFA`, your first have to disable `Immediate MFA`, as is the default if you're using the provided
configuration template for your SSH server (which you are if you followed the default installation steps).
You'll need to comment out two lines within the :file:`/etc/ssh/sshd_config` file, these are located near the
end of the file:
.. code-block:: shell
# if in one of the mfa groups, use publickey AND pam
#Match Group mfa-totp-configd,mfa-password-configd
# AuthenticationMethods publickey,keyboard-interactive:pam
You'll need to reload the SSH daemon for this to be taken into account. The next subsections explain how to setup
policies depending on the actions you want to protect through `JIT MFA`.
On a per-plugin basis
*********************
First ensure you've followed the :ref:`jit_mfa_sshd_config`.
To force MFA for a plugin, you may add the ``mfa_required`` option to its configuration. This configuration parameter
allows 4 values:
- `any`, in which case MFA is required with any supported factor (currently either password or TOTP)
- `password`, in which case a password is required in addition to publickey authentication
- `totp`, in which case a TOTP is required in addition to publickey authentication
- `none`, in which case no MFA is required (which is the default if the ``mfa_required`` setting is omitted)
To enable MFA for the ``adminSudo`` plugin, for example, you may add:
.. code-block:: shell
{
"mfa_required": "any"
}
to the :file:`/etc/bastion/plugin.adminSudo.conf` file. Please ensure that this file is readable by the
``bastion-users`` system group (as all :file:`/etc/bastion/plugin.*.conf` files should be), so that the code running
under the bastion users permissions can read it.
When configured like this, usage of the adminSudo plugin, in our example, will trigger the validation of additional
authentication factors.
Note that for this to work, you must have the :file:`/etc/pam.d/ssh` file set up correctly,
as we're using PAM for this. The provided template is advised, and you're already using it if you followed the
default installation steps.
If you are not sure you're using the provided template, you may compare your current :file:`/etc/pam.d/ssh` file
with the proper template for your distro, which can be found in :file:`/opt/bastion/etc/pam.d/sshd.*`.
As you see, the MFA phase will be fired up for this plugin, but not for the ``info`` plugin for example:
.. code-block:: none
:emphasize-lines: 1,7
bssh --osh adminSudo
As this is required to run this plugin, entering MFA phase for johndoe.
Your account has Multi-Factor Authentication enabled, an additional authentication factor is required (password).
Your password expires on 2023/10/31, in 89 days
Password: ^C
bssh --osh info
╭──ac777d06bec9───────────────────────────────────────────the-bastion-3.12.00───
│ ▶ information
├───────────────────────────────────────────────────────────────────────────────
│ You are johndoe
[...]
On a per-group basis
********************
First ensure you've followed the :ref:`jit_mfa_sshd_config`.
If you want to ensure that MFA is required to connect to a remote host through a bastion group,
you should tag this group to require MFA. To do this, use the ``groupModify`` command:
.. code-block:: none
:emphasize-lines: 1,9,18
guybrush@bastion1(master)> groupModify --group securegroup --mfa-required any
╭──ac777d06bec9───────────────────────────────────────────the-bastion-3.12.00───
│ ▶ modify the configuration of a group
├───────────────────────────────────────────────────────────────────────────────
│ Modifying mfa-required policy of group...
│ ... done, policy is now: any
╰──────────────────────────────────────────────────────────────</groupModify>───
guybrush@bastion1(master)> groupInfo --group securegroup
╭──ac777d06bec9───────────────────────────────────────────the-bastion-3.12.00───
│ ▶ group info
├───────────────────────────────────────────────────────────────────────────────
│ Group securegroup's Owners are: guybrush
[...]
│ ❗ MFA Required: when connecting to servers of this group, users will be asked for an additional authentication factor
[...]
guybrush@bastion1(master)> ssh root@127.1.2.3
│ Welcome to bastion1, guybrush, your last login was 00:00:27 ago (Wed 2023-08-02 15:36:03 UTC) from 172.17.0.1(172.17.0.1)
[...]
will try the following accesses you have:
- group-member of securegroup with ED25519-256 key SHA256:94yETEnnWUy9yTG1dgAdXgunq6zzJPjlddFXjUH0Czw [2023/03/03] (MFA REQUIRED: ANY)
As this is required for this host, entering MFA phase for guybrush.
Your account has Multi-Factor Authentication enabled, an additional authentication factor is required (password).
Your password expires on 2023/10/31, in 89 days
Password:
As you see, after setting the flag on the group, attempting to access an asset that is part of the group (see
``groupListServers``) will require MFA.
.. note::
If an account has access to an asset via several groups, MFA will be required if at least one group requires it.
Hence, a good way to ensure that all connections to an asset will require MFA would be to list the
SSH keys on the remote server, match those to groups on the bastion, and ensure they all have ``--mfa-required`` enabled.
On a per-account basis
**********************
You may also use this method to enable MFA on a per-account basis (as is possible with the `Immediate MFA` method).
To do this, you should follow the same steps than are outlined in the :ref:`immediate_mfa_subset_users` subsection of the `Immediate MFA` setup.
The only difference will be in your :file:`sshd_config` file, as for `JIT MFA` your should ensure you've followed the :ref:`jit_mfa_sshd_config`.
In the case of `Immediate MFA`, the uncommented :file:`sshd_config` file block asks the SSH server to hand over authentication to PAM, hereby
requiring MFA at the authentication phase. For the `JIT MFA` on a per-account basis, this configuration is disabled, but the bastion code, after the
authentication phase is over, verifies whether the account requires to provide additional authentication factors, and triggers a PAM call if this
is the case.
Bypassing MFA for automated workflows
*************************************
If you have accounts that are used for automation, you'll want to exclude them from requiring MFA.
To do this, use ``--osh accountModify --mfa-password-required bypass --mfa-totp-required bypass``. Accounts
with this setting will no longer require to enter additional credentials even when the policy of `JIT MFA` would
require them to.
Additional information
======================
MFA and interactive mode
************************
When using the interactive mode, and `JIT MFA`, attempting to conduct an action that requires MFA will trigger the MFA authentication phase, as expected.
However, when multiple MFA-required operations are to be done back to back, as is often the case when interactive mode
is used, the MFA authentication phase will be triggered for each and every action, which can be cumbersome.
As long as :ref:`administration/configuration/bastion_conf:interactivemodeproactivemfaenabled` is true, users can use the **mfa** command in interactive
mode, to trigger the MFA authentication phase proactively, and enter an elevated session that will not require to enter MFA again. This elevated session
will expire after :ref:`administration/configuration/bastion_conf:interactivemodeproactivemfaexpiration` seconds (15 minutes by default). Users can exit
the elevated session manually by typing **nomfa**.
Here is how it looks like:
.. code-block:: none
:emphasize-lines: 1,8,12,18,24,27
bssh -i
Welcome to bastion1 interactive mode, type `help' for available commands.
You can use <tab> and <tab><tab> for autocompletion.
You'll be disconnected after 60 seconds of inactivity.
Loading... 90 commands and 0 autocompletion rules loaded.
guybrush@bastion1(master)> mfa
As proactive MFA validation has been requested, entering MFA phase.
Your account has Multi-Factor Authentication enabled, an additional authentication factor is required (password).
Your password expires on 2023/10/31, in 88 days
Password:
pamtester: successfully authenticated
Proactive MFA enabled, any command requiring MFA from now on will not ask you again.
This mode will expire in 00:15:00 (Thu 2023-08-03 12:35:08 UTC)
To exit this mode manually, type 'nomfa'.
guybrush@bastion1(master)[MFA-OK]> groupAddServer
╭──ac777d06bec9───────────────────────────────────────────the-bastion-3.12.00───
│ ▶ adding a server to a group
├───────────────────────────────────────────────────────────────────────────────
[...]
guybrush@bastion1(master)[MFA-OK]> nomfa
Your proactive MFA validation has been forgotten.
guybrush@bastion1(master)>
As you seen, once ``mfa`` has been entered and the MFA validated, the prompt changes to ``[MFA-OK]`` implying that
any command usually requiring MFA will not ask for it again (such as ``groupAddServer`` in the above example, as
we've configured it to). We then explicitely exit the MFA elevated session by entering ``nomfa``.
MFA and --osh batch
*******************
The :doc:`/plugins/open/batch` plugin is useful to enter several ``--osh`` commands in a batch way. However, if
any of those commands require MFA, it would ask us repeatedly for our MFA, which can be cumbersome.
To avoid this behavior, and if you know that some of the commands you want to use in batch more will require MFA,
you may use the ``--proactive-mfa`` option to the bastion, which will ask for your MFA *before* executing the
:doc:`/plugins/open/batch` plugin, and any command requiring MFA will not ask for it again:
.. code-block:: none
:emphasize-lines: 1,6
bssh --proactive-mfa --osh batch
As proactive MFA has been requested, entering MFA phase for guybrush.
Your account has Multi-Factor Authentication enabled, an additional authentication factor is required (password).
Your password expires on 2023/11/01, in 89 days
Password:
pamtester: successfully authenticated
╭──ac777d06bec9───────────────────────────────────────────the-bastion-3.12.00───
│ ▶ batch
├───────────────────────────────────────────────────────────────────────────────
│ Feed me osh commands line by line on stdin, I'll execute them sequentially.
│ Use 'exit', 'quit' or ^D to stop.
│ --- waiting for input
[...]

View file

@ -0,0 +1,13 @@
Security Advisories
===================
This section contains all the security advisories since The Bastion has been published.
If you find any behavior or bug that you suspect might have a security impact, please
`report it here <https://github.com/ovh/the-bastion/security>`_.
.. toctree::
:maxdepth: 1
:caption: CVE List
security_advisories/cve_2023_45140.rst

View file

@ -0,0 +1,79 @@
==============
CVE-2023-45140
==============
- ``Severity``: **4.8** (CVSS V3)
- ``Vector: CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N``
- ``Affected versions``: from 3.0.0 included to 3.14.15 excluded
- ``Patched versions``: 3.14.15 and up
`This advisory is also available online <https://github.com/ovh/the-bastion/security/advisories/GHSA-pr4q-w883-pf5x>`_.
Summary
=======
SCP and SFTP plugins don't honor group-based and account-based JIT MFA.
Details
=======
Establishing a SCP/SFTP connection through The Bastion via a group access where MFA is enforced does not ask for additional factor. This abnormal behavior only applies to `per-group-based JIT MFA <https://ovh.github.io/the-bastion/administration/mfa.html#on-a-per-group-basis>`_ and `JIT MFA on a per-account basis <https://ovh.github.io/the-bastion/administration/mfa.ht↪·ml#on-a-per-account-basis>`_.
Other MFA setup types, such as `Immediate MFA <https://ovh.github.io/the-bastion/administration/mfa.html#immediate-mfa>`_ and `JIT MFA on a per-plugin basis <https://ovh.github.io/the-bastion/administration/mfa.html#on-a-per-plugin-basis>`_ are not affected.
Normal SSH access (i.e. not SCP nor SFTP) is not affected.
How to reproduce for group-based JIT MFA
========================================
- Create a group
- Apply ``groupModify --mfa-required any`` to this group
- Grant SSH access to someone via this group on a given IP
- Grant ``scp`` download right (or ``sftp`` right) to the same person via this group on the same IP
- This group should now force MFA for any connection of the person allowed through the group's rights set. This is the case for SSH, but not for SCP or SFTP as would be expected.
How to reproduce for account-based JIT MFA
==========================================
- Create an account
- Apply ``accountModify --personal-egress-mfa-required any`` to this account
- Grant a personal SSH access to this account on a given IP
- Grant ``scp`` download right (or ``sftp`` right) to the same account via their personal access on the same IP
- This account should now have forced MFA for any egress connection allowed through their personal rights set. This is the case for SSH, but not for SCP or SFTP as would be expected.
Impact for group-based JIT MFA
==============================
For an actor to be able to bypass MFA for scp/sftp to a given remote server, ALL the following conditions must apply:
- The target server must be part of a group (and have the egress group's public key trusted in its :file:`authorized_keys` file)
- The group must have JIT MFA enabled on it (through ``groupModify --mfa-required any``)
- The actor must have an account on the bastion
- The actor must be a member of the group (granted by the groups's gatekeepers)
- scp and/or sftp must be globally enabled on the bastion (this is the default)
- scp and/or sftp must be explicitly allowed to the given remote server through the group (granted by the groups's aclkeepers)
When all conditions above apply, the actor would be able to use scp or sftp on the target server without requiring to provide an additional factor where it should.
Impact for account-based JIT MFA
================================
For an actor to be able to bypass MFA for scp/sftp to a given remote server, ALL the following conditions must apply:
- The target server must be part of the actor's account personal accesses (and have the account's egress public key trusted in its :file:`authorized_keys` file)
- The account must have JIT MFA enabled on it (through ``accountModify --personal-egress-mfa-required any``)
- scp and/or sftp must be globally enabled on the bastion (this is the default)
- scp and/or sftp must be explicitly allowed to the given remote server through this account's personal accesses (granted by either ``selfAddPersonalAccess`` or ``accountAddPersonalAccess``)
When all conditions above apply, the actor would be able to use scp or sftp on the target server without requiring to provide an additional factor where it should.
Mitigation
==========
If you don't use the `per-group-based JIT MFA <https://ovh.github.io/the-bastion/administration/mfa.html#on-a-per-group-basis>`_ on any of your groups (through ``groupModify --mfa-required``), and don't use the `JIT MFA on a per-account basis <https://ovh.gi↪·thub.io/the-bastion/administration/mfa.ht↪·ml#on-a-per-account-basis>`_ (through ``accountModify --personal-egress-mfa-required``), you don't need to mitigate the issue as you don't use the impacted feature (see above for impact details).
Otherwise, if you can't immediately upgrade to v3.14.15 or more recent, and you feel that the aforementioned impacts are important enough in your environment, you may choose to temporarily disable the ``scp`` and ``sftp`` plugins globally on the bastion, by setting ``"disabled": true`` in these plugins configuration files, which can be found in :file:`/etc/bastion/plugin.scp.conf` and :file:`/etc/bastion/plugin.sftp.conf` respectively. If these files don't exist, create them with the contents as ``{ "disabled": true }``. They should be readable by anyone but modifiable only by root (i.e. ``chmod 664; chown root:root``)
Timeline
========
- 2023-10-06: security bug report filed on GitHub
- 2023-10-06: bug report accepted and confirmed as having a security impact
- 2023-10-11: CVE ID requested
- 2023-10-11: CVE ID assigned
- 2023-11-07: fix pushed to a private fork for review
- 2023-11-08: v3.14.15 released with the fix

View file

@ -0,0 +1,190 @@
Environment setup
=================
.. contents::
This documentation section outlines the few steps needed to build a development environment for The Bastion,
easing code modification, tests, checks, and ultimately, pull requests.
Available tools
***************
The provided :file:`docker/devenv/run-tool.sh` script will build a development docker for you, under which it'll
run several tools. Your local git folder will be mounted as a volume inside this docker so that it can
access the files, and potentially modify them (such as for ``perltidy``).
The supported tools are as follows:
.. code-block:: none
:emphasize-lines: 1
Usage: ./docker/devenv/run-tool.sh COMMAND [OPTIONS]
COMMAND may be one of the following:
tidy [FILES..] runs perltidy on several or all the Perl source files, modifying them if needed
tidycheck [FILES..] runs perltidy in dry-run mode, and returns an error if files are not tidy
perlcritic runs perlcritic on all the Perl source files
shellcheck [FILES..] runs shellcheck on all the shell source files
lint runs tidy, perlcritic and shellcheck on all files in one command
doc generates the documentation
sphinx-view-objects shows the named objects of the Sphinx documentation that can be referenced
rebuild forces the rebuild of the devenv docker image that is needed to run all the above commands
run <COMMAND> spawn an interactive shell to run any arbitrary command in the devenv docker
doc-serve <PORT> starts a local HTTP python server on PORT to view generated documentation
Before submitting a pull request, you'll need at minimum to run ``lint``. It might be a good idea to setup a
git pre-commit hook to do this on modified files, see below.
Git pre-commit hook
*******************
Some lint checks are enforced through GitHub Actions, but it'll save you a lot of back-and-forth if you ensure that
these checks are passing locally on your development environment.
To this effect, you'll need to setup pre-commit hooks on your local copy of the git repository, so that your code
is automatically checked by ``perlcritic``, ``perltidy`` and ``shellcheck`` each time you commit.
If you previously cloned the repository with such a command:
.. code-block:: none
:emphasize-lines: 1
git clone https://github.com/ovh/the-bastion
Then you can copy the provided :file:`pre-commit` script into your local :file:`.git` folder:
.. code-block:: none
:emphasize-lines: 1
cp contrib/git/pre-commit .git/hooks/pre-commit
To verify that it works checkout a new test branch and add two dummy files like this:
.. code-block:: none
:emphasize-lines: 1-5
git checkout -B mybranch
printf "%b" "#! /usr/bin/env bash\nunused=1\n" > bin/shell/dummy.sh
printf "%b" "#! /usr/bin/env perl\nsub dummy { 1; };\n" > lib/perl/dummy.pm
git add bin/shell/dummy.sh lib/perl/dummy.pm
git commit -m dummy
*** Checking shell files syntax using system shellcheck
`-> bin/shell/dummy.sh
In bin/shell/dummy.sh line 2:
unused=1
^----^ SC2034: unused appears unused. Verify use (or export if used externally).
`-> [ERR.]
ERROR: shell-check failed on bin/shell/dummy.sh
*** Checking perl tidiness
`-> lib/perl/dummy.pm
./lib/perl/dummy.pm ./lib/perl/dummy.pm.tdy differ: char 38, line 2
--- ./lib/perl/dummy.pm 2023-10-03 08:19:55.605950307 +0000
+++ ./lib/perl/dummy.pm.tdy 2023-10-03 08:20:43.618577295 +0000
@@ -1,2 +1,2 @@
#! /usr/bin/env perl
-sub dummy { 1; };
+sub dummy { 1; }
ERROR: perl tidy failed on lib/perl/dummy.pm
!!! COMMIT ABORTED !!!
If you want to commit nevertheless, use -n.
As you see, the checks are running before the commit is validated and abort it should any check fail.
Running integration tests
*************************
Using Docker
------------
Functional tests use ``Docker`` to spawn an environment matching a bastion install.
One of the docker instances will be used as client, which will connect to the other instance
which is used as the bastion server. The client instance sends commands to the server instance
and tests the return values against expected output.
To test the current code, use the following script, which will run ``docker build`` and launch the tests:
.. code-block:: none
:emphasize-lines: 1
tests/functional/docker/docker_build_and_run_tests.sh <TARGET>
Where target is one of the supported OSes. Currently only Linux targets are supported.
You'll get a list of the supported targets by calling the command without argument.
For example, if you want to test it under Debian (which is a good default OS if you don't have any preference):
.. code-block:: none
:emphasize-lines: 1
tests/functional/docker/docker_build_and_run_tests.sh debian12
The full tests usually take 25 to 50 minutes to run, depending on your hardware specs.
If you want to launch only a subset of the integration tests, you may specify it:
.. code-block:: none
:emphasize-lines: 1
tests/functional/docker/docker_build_and_run_tests.sh debian12 --module=320-base.sh
Other options are supported, and passed through as-is to the underlying test script, use ``--help`` as below to
get the list (the output in this documentation might not be up to date, please actually launch it yourself
to get up-to-date information):
.. code-block:: none
:emphasize-lines: 1
tests/functional/launch_tests_on_instance.sh --help
Usage: /home/user/bastion/tests/functional/launch_tests_on_instance.sh [OPTIONS] <IP> <SSH_Port> <HTTP_Proxy_Port_or_Zero> <Remote_Admin_User_Name> <Admin_User_SSH_Key_Path> <Root_SSH_Key_Path>
Test Options:
--skip-consistency-check Speed up tests by skipping the consistency check between every test
--no-pause-on-fail Don't pause when a test fails
--log-prefix=X Prefix all logs by this name
--module=X Only test this module (specify a filename found in `functional/tests.d/`), can be specified multiple times
Remote OS directory locations:
--remote-etc-bastion=X Override the default remote bastion configuration directory (default: /etc/bastion)
--remote-basedir=X Override the default remote basedir location (default: /home/user/bastion)
Specifying features support of the underlying OS of the tested bastion:
--has-ed25519=[0|1] Ed25519 keys are supported (default: 1)
--has-mfa=[0|1] PAM is usable to check passwords and TOTP (default: 1)
--has-mfa-password=[0|1] PAM is usable to check passwords (default: 0)
--has-pamtester=[0|1] The `pamtester` binary is available, and PAM is usable (default: 1)
--has-piv=[0|1] The `yubico-piv-tool` binary is available (default: 1)
--has-sk=[0|1] The openssh-server supports Secure Keys (FIDO2) (default: 0)
Without Docker
--------------
.. note::
This method is discouraged, prefer using the Docker method above when possible
You can test the code against a BSD (or any other OS) without using Docker, by spawning a server
under the target OS (for example, on a VM), and installing the bastion on it.
Then, from another machine, run:
.. code-block:: none
:emphasize-lines: 1
test/functional/launch_tests_on_instance.sh <IP> <port> <remote_user_name> <ssh_key_path> [outdir]
Where ``IP`` and ``port`` are the information needed to connect to the remote server to test,
``remote_user_name`` is the name of the account created on the remote bastion to use for the tests,
and ``ssh_key_path`` is the private SSH key path used to connect to the account.
The ``outdir`` parameter is optional, if you want to keep the raw output of each test.
This script is also the script used by the Docker client instance,
so you're sure to get the proper results even without using Docker.
Please do **NOT** run any of those tests on a production bastion!

View file

@ -0,0 +1,180 @@
Writing tests
=============
.. contents::
When modifying code, adding features or fixing bugs, you're expected to write one or more tests to ensure that
the feature your adding works correctly, or that the bug you've fixed doesn't come back.
Integration tests modules live in the :file:`tests/functional/tests.d` folder.
You may either add a new file to test your feature, or modify an existing file.
These modules are shell scripts, and are sourced by the main integration test engine. Having a look at one of
these modules will help you understand how they work, the :file:`tests/functional/tests.d/320-base.sh` is a good
example you might want to look at.
Example
-------
Here is a simple test taken from :file:`320-base.sh`:
.. code-block:: none
:caption: a simple test
success help2 $a0 --osh help
contain "OSH help"
json .error_code OK .command help .value null
A complete reference of such commands can be found below, but let's explain this example in a few words:
The command ``success`` implies that we're running a new test command, and that we expect it to work (we might
also want to test invalid commands and ensure they fail as they should).
The tester docker will connect to the target docker (that is running the bastion code) as a bastion user, and
run the ``--osh help`` command there. This is expected to exit with a code indicating success (0),
otherwise this test fails.
The output of the command, once run on the bastion, should contain the text ``OSH help``, or the test will fail.
In the JSON output (see :doc:`/using/api`) of this command, we expect to find the ``error_code`` field set to ``OK``,
the ``command`` field set to ``help``, and the ``value`` field set to ``null``, or the test will fail.
Running just this test will yield the following output:
.. code-block:: none
:caption: a simple test output
00m04 [--] *** [0010/0021] 320-base::help2 (timeout --foreground 30 ssh -F /tmp/bastiontest.pgoA5h/ssh_config -i /tmp/bastiontest.pgoA5h/account0key1file user.5000@bastion_debian10_target -p 22 -- --json-greppable --osh help)
00m05 [--] [ OK ] RETURN VALUE (0)
00m05 [--] [ OK ] MUST CONTAIN (OSH help)
00m05 [--] [ OK ] JSON VALUE (.error_code => OK) [ ]
00m05 [--] [ OK ] JSON VALUE (.command => help) [ ]
00m05 [--] [ OK ] JSON VALUE (.value => null) [ ]
As you can see, this simple test actually checked 5 things: the return value, whether the output text contained
a given string, and 3 fields of the JSON output.
Reference
---------
These are functions that are defined by the integration test engine and should be used in the test modules.
Launch a test
*************
run
+++
.. admonition:: syntax
:class: cmdusage
- run <name> <command>
This function runs a new test named ``<name>``, which will execute ``<command>`` on the tester docker.
Usually ``<command>`` will connect to the target docker (running the bastion code) using one of the test accounts,
and run a command there.
A few accounts are preconfigured:
- The main account ("account 0"): this one is guaranteed to always exist at all times, and is a bastion admin.
There are a few variables that can be referenced to use this account:
- ``$a0`` is the ssh command-line to connect to the remote bastion as this account
- ``$account0`` is the account name, to be used in parameters of ``--osh`` commands where needed
- A few secondary accounts that are created, deleted, modified during the tests:
- ``$a1``, ``$a2`` and ``$a3`` are the ssh command-lines to connect to the remote bastion as these accounts
- ``$account1``, ``$account2`` and ``$account3`` are the accounts names
- Another special non-bastion-account command exists:
- ``$r0`` is the required command-line to directly connect to the remote docker on which the bastion code is running,
as root, with a bash shell. Only use this to modify the remote bastion files, such as config files, between tests
A few examples follow:
.. code-block:: none
:caption: running a few test commands
run test1 $a0 --osh info
run test2 $a0 --osh accountInfo --account $account1
run test3 $a1 --osh accountDelete --account $account2
Note that the ``run`` function just runs the given command, but doesn't check whether it exited normally, you'll
need other functions to verify this, see below.
success
+++++++
.. admonition:: syntax
:class: cmdusage
- success <name> <command>
This function is exactly the same as the ``run`` command above, except that it expects the given ``<command>`` to
return a valid error code (zero). Most of the time, you should be using this instead of ``run``, except if you're
expecting the command to fail, in which case you should use ``run`` + ``retvalshouldbe``, see below.
plgfail
+++++++
.. admonition:: syntax
:class: cmdusage
- plgfail <name> <command>
This function is exactly the same as the ``run`` command above, except that it expects the given ``<command>`` to
return an error code of 100, which is the standard exit value when an osh command fails.
This function is equivalent to using ``run`` followed by ``retvalshouldbe 100`` (see below).
Verify a test validity
**********************
retvalshouldbe
++++++++++++++
.. admonition:: syntax
:class: cmdusage
- retvalshouldbe <value>
Verify that the return value of a test launched right before with the ``run`` function is ``<value>``.
You should use this if you expect the previous test to return a non-zero value.
Note that the ``success`` function is equivalent to using ``run`` followed by ``retvalshouldbe 0``.
contain
+++++++
.. admonition:: syntax
:class: cmdusage
- contain <text>
- contain REGEX <regex>
This function verifies that the output of the test contains a given ``<text>``. If you need to use a regex
to match the output, you can use the ``contain REGEX`` construction, followed by the regex.
nocontain
+++++++++
.. admonition:: syntax
:class: cmdusage
- nocontain <text>
- nocontain REGEX <regex>
This function does the exact opposite of the ``contain`` function just above, and ensure that a given text
or regex is NOT present in the output.
json
++++
.. admonition:: syntax
:class: cmdusage
- json <field1> <value1> [<field2> <value2> ...]
This function checks the JSON API output of the test, and validates that it contains the correct value for each
specified field. The ``<fieldX>`` entries must be valid `jq` filters.

172
_sources/faq.rst.txt Normal file
View file

@ -0,0 +1,172 @@
===
FAQ
===
"The Bastion", really?
======================
We've been using this software for quite a while at OVHcloud, and there it has always been known as "the bastion":
nobody ever bothered to find a fancy name for it.
So, when we decided to release it in opensource, the naming problem arose.
After going through some possible names, we realized that nothing would work, as everybody would keep
naming it "the bastion" anyway, so, we decided to call it just *The Bastion*.
Why using common::sense?
========================
Because it's usually a good idea to ensure you use common::sense before writing code!
On a more serious note, this is almost like using ``strict`` and ``warnings``,
but with a very reduced memory footprint.
When you run a bastion with thousands of simultaneous active sessions with that many users, it starts to matter.
Why Perl?
=========
There is probably and endless list of why it's the perfect language for this,
and another similarly endless list of why Perl is completely irrelevant and other $COOL_LANGUAGE would be a better fit,
but some "why" reasons include:
- It works everywhere, and most OSes have it installed by default
- Perl has this cool "taint" mode that adds security to untrusted program inputs, we use this on sensitive code
- One of the design choice of The Bastion has always been to be very close to the system,
leveraging some low-level Operating System functions, which are easier to interact with using a scripting language
- The Bastion has a loose origin from an old script written at OVHcloud in the early days,
back when the de-facto usual language used internally was Perl
Why not using a PKI?
====================
Well, you can, of course! However this is a very centralized way of managing your accesses,
with all the power in the hands of whoever controls your CA.
It can be a highly successful if done very carefully, with a lot of security and processes around the
certificates delivery workflows. Managing a CA correctly is no joke and can bite you quite hard if done improperly.
This also happens to be a somewhat recent addition to OpenSSH, and if you have a lot of heterogeneous
systems to handle, this might be a no-go.
You can read more about this topic here: https://blog.ovhcloud.com/the-ovhcloud-bastion-part-1/
What does `osh` mean in ``--osh``?
==================================
This has long been forgotten. Some people say it used to mean "Ovh SHell" at some point,
but nobody knows whether it's true or just a legend.
What are the recommended hardware specifications?
=================================================
They're actually quite low. Down to its basics, the bastion is merely a fancy wrapper around ``ssh``,
so if you have a device that handles ``ssh`` well, it'll handle the bastion just fine.
Now to give you some data points, we've observed that 250 concurrent users take up 2.5 Gb of RAM (including
the operating system's own footprint, and the usual daemons such as auditd, syslog, etc.).
So a rule of thumb would be 1 Gb per 100 simultaneous sessions.
If you expect to get a lot of new connections per minute (not necessarily long-lived),
it's advised to use SSD drives however, as the bastion workload pattern for disk I/O is a lot of random seeks
to write logs and ttyrecs. Mechanical hard drives are very bad at this.
.. _faq_docker:
Can I run it under Docker in production?
========================================
Technically you can, but you have to think about what are the implications (this is true regardless
of the containerization technology). What's important to understand is that it adds another layer of abstraction,
and can give you a false sense of security.
If you either have the complete control of the host running Docker (and hardened it properly),
or you fully trust whoever is running the host for you, then this is fine.
Otherwise, *somebody* might have access to all your keys and you have no way to know or block it.
Note that the provided Dockerfiles are a good start, but no volumes are defined.
To ensure that all the accounts don't disappear on a ``docker rm``, you would at least need to ensure that
``/home``, ``/etc/passwd``, ``/etc/shadow``, ``/etc/group``, ``/etc/gshadow`` are stored in a volume,
in addition to ``/etc/bastion`` and ``/root/.gpg``.
You'll also need an SSH server, obviously, and probably a ``syslog-ng`` daemon.
.. _faq_existing_server:
Can I install it on my already existing server?
===============================================
This is discouraged if your server is already doing something else, such as hosting a website,
handling your e-mails or running a database.
From a security standpoint, it's a bad idea because if your server gets hacked due to one of
the other services you're hosting, the SSH keys could get compromised even if The Bastion itself has no security issue.
This is also discouraged due to the design of The Bastion: being deeply intertwined with the OS it's running on,
it might make changes that seem intrusive from the point of view of other running services.
Such as creating and deleting system accounts and groups from time to time, modifying the PAM configuration,
or hardening the SSH client and server configurations system-wide,
which could break other services or workflows that expect to be running on a default (non-hardened) SSH configuration.
.. _faq_jumphost:
How to use The Bastion with the SSH ``ProxyCommand`` option?
============================================================
**tl;dr**: you can't.
**Fast answer**: you can't, because The Bastion is not a proxy, nor what is often called an "ssh jumphost".
Granted, sometimes these are also called "bastions", hence the confusion.
Note that this also applies to the ``-J`` or ``JumpHost`` ssh option, which is just a simplified ``ProxyCommand``.
**Long answer**: The Bastion is acting as a trusted party between you (the admin or the robot) and the server
of the infrastructure you need to access. To achieve this, when you use the bastion to connect to the server,
there are two distinct ssh connections present at the same time:
- The ingress ssh connection, between you and the bastion.
For this connection your local private ssh key is used to authenticate yourself to the bastion
- The egress ssh connection, between the bastion and the remote server you need to access.
For this connection your bastion egress private ssh key (or a group egress private ssh key you're member of)
is used to authenticate the bastion to the remote server
Those two connections are distinct, and the bastion logic merges those two so that you're under the impression
that you're directly connected to the remote server. There is no dynamic port forwarding happening on the bastion
to enable access to the remote server from your desktop, network-wise (which is what ``JumpHost`` does).
Using ``ProxyCommand`` with the bastion doesn't make sense because with this option, your local ssh client expects
to talk the SSH dialect on the STDIN of the ProxyCommand you're giving, and it'll try to use your local SSH key
to authenticate you through it, which won't work as it's only used for the ingress connection.
However, when you use the usual bastion alias, in STDIN you have the remote server terminal directly,
all the SSH stuff has already been done.
Attempting to summarize this a bit would be: ``ProxyCommand`` and ``JumpHost`` are useful when the server
you're trying to connect to can't be accessed *network-wise* from where you stand, and needs to be accessed
through some kind of proxy instead, where The Bastion's logic is to use two distinct SSH connections,
and two distinct authentication phases, with two distinct SSH keys (yours for the ingress connection,
and your bastion egress key for the egress connection).
What is *session locking*?
==========================
Session locking can be enabled in the global configuration, through the :ref:`idleLockTimeout` option.
When enabled, the interactive SSH session will automatically lock itself after a defined amount of idle time.
Unlocking such a session can be done, but re-authentication is required, i.e. connecting to the bastion
from another console, and using the :doc:`/plugins/open/unlock` command.
Here, idle time is defined as keyboard input idle time, so even if a remote command might be running
(such as ``tail -f``), the connection will still be considered idle if no input is detected. This is by design.
Such as configuration can be required by policy or regulations, in some sensitive environments,
to ensure opened connections are automatically cut off when unused.
Locking such sessions can be an alternative to cutting (see the :ref:`idleKillTimeout` option) as it gives
a chance to unlock the session before tearing the connection down.
Both can also be used, such as locking first, then tearing down after more time has passed without the session
being unlocked. Note that while a session is locked, any potentially running remote command will still be running,
as locking the session will just hide the normal console output, and prevent any input to be registered.
Unlocking the session will simply resume display to the console.
Session locking can be seen as the equivalent of a desktop screensaver, but for SSH interactive sessions.
A locked session looks like this:
.. image:: /img/locked_session.png
Can I use Ansible over The Bastion?
===================================
Yes, you can, by using a wrapper available `here <https://github.com/ovh/the-bastion-ansible-wrapper>`_.
Please note however that some Ansible modules may not use the builtin SSH command of Ansible,
which we override with our wrapper, but some other mechanism we can't hook into.
This is for example the case of the `network_cli` module of Ansible, which underneath uses Paramiko,
a Python library to handle SSH connections, which prevents our wrapper to be used (see
`this GitHub issue <https://github.com/ovh/the-bastion/issues/254>`_ for more information).

107
_sources/index.rst.txt Normal file
View file

@ -0,0 +1,107 @@
=====================================
Welcome to The Bastion documentation!
=====================================
.. warning::
This documentation is in a WIP status, some edges might be rough!
Wait, what's a bastion exactly? (in 140-ish characters)
=======================================================
A so-called **bastion** is a machine used as a single entry point by operational teams (such as sysadmins, developers, devops, database admins, etc.) to securely connect to other machines of an infrastructure, usually using `ssh`.
The bastion provides mechanisms for *authentication*, *authorization*, *traceability* and *auditability* for the whole infrastructure.
Just yet another SSH relayhost/jumphost/gateway?
************************************************
No, The Bastion is an entirely different beast.
The key technical difference between those and The Bastion is that it strictly stands between you and the remote server, operating a protocol break in the process, which enables unique features such as tty recording, proper access auditability, builtin access and groups management commands, delegation of responsibilities all the way through, etc.
Advanced uses even include doing other things than just SSHing to a remote server.
Those wouldn't be possible with a "simple" jumphost. More technical details on the difference :ref:`here <faq_jumphost>`.
OK, tell me more!
=================
This documentation is organized in several sections. The first one is a **PRESENTATION** of the main functionalities, principles, and use cases of the bastion.
The second section explains the **INSTALLATION** procedure, including how to set up a quick playground using Docker if you want to get your hands dirty quickly.
The third section focuses on the **USAGE** of the bastion, from the perspective of the different roles, such as bastion users, group owners, bastion admins, etc.
The fourth section is about the proper **ADMINISTRATION** of the bastion itself. If you're about to be the person in charge of managing the bastion for your company, you want to read that one carefully!
The fifth section is about **DEVELOPMENT** and how to write code for the bastion. If you'd like to contribute, this is the section to read!
The sixth section is the complete reference of all the **PLUGINS** that are the commands used to interact with the bastion accounts, groups, accesses, credentials, and more.
The unavoidable and iconic FAQ is also available under the **PRESENTATION** section.
.. toctree::
:maxdepth: 2
:caption: Presentation
presentation/principles
presentation/features
presentation/security
faq
.. toctree::
:maxdepth: 2
:caption: Installation
installation/basic
installation/advanced
installation/upgrading
installation/docker
installation/restoring_from_backup
.. toctree::
:maxdepth: 2
:caption: Usage
using/basics/index
using/piv
using/sftp_scp_rsync
using/http_proxy
using/api
using/specific_ssh_clients_tutorials/index
.. toctree::
:maxdepth: 2
:caption: Administration
administration/configuration/index
administration/logs
administration/mfa
administration/security_advisories
.. toctree::
:maxdepth: 2
:caption: Development
development/setup
development/tests
.. _plugins:
.. toctree::
:maxdepth: 2
:caption: Plugins
plugins/admin/index.rst
plugins/group-aclkeeper/index.rst
plugins/group-gatekeeper/index.rst
plugins/group-owner/index.rst
plugins/open/index.rst
plugins/restricted/index.rst
Indices and tables
==================
* :ref:`genindex`
* :ref:`search`

View file

@ -0,0 +1,530 @@
=====================
Advanced Installation
=====================
This section goes further in explaining how to setup your bastion.
You should have completed the :doc:`basic installation<basic>` first.
.. _installadv_gpg:
Encryption & signature GPG keys
===============================
.. note::
This section is a prequisite to both the :ref:`installadv_encryptrsync` and the
:ref:`installadv_backup` steps further down this documentation
There are 2 pairs of GPG keys being used by the bastion:
- The *bastion GPG key*
* The **private** key is used by the **bastion** to **sign** the ttyrec files
* The **public** key is used by the **admins** to **verify** the signature and prove
non-repudiation and non-tampering of the ttyrec files
- The *admins GPG key*
* The **public** key is used by the **bastion** to **encrypt** the backups and the ttyrec files
* The **private** key is used by the **admins** to **decrypt** the backups when
a restore operation is needed, and the ttyrec files
Generating the bastion GPG key
******************************
Generate a GPG key that will be used by the bastion to sign files,
this might take a while especially if the server is idle:
.. code-block:: shell
:emphasize-lines: 1
/opt/bastion/bin/admin/setup-gpg.sh --generate
gpg: directory `/root/.gnupg' created
gpg: Generating GPG key, it'll take some time.
Not enough random bytes available. Please do some other work to give
the OS a chance to collect more entropy! (Need 39 more bytes)
..........+++++
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key A4480F26 marked as ultimately trusted
gpg: done
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
Configuration file /etc/bastion/osh-encrypt-rsync.conf.d/50-gpg-bastion-key.conf updated:
8<---8<---8<---8<---8<---8<--
# autogenerated with /opt/bastion/bin/admin/setup-gpg.sh at Wed Mar 21 10:03:08 CET 2018
{
"signing_key_passphrase": "************",
"signing_key": "5D3CFDFFA4480F26"
}
--->8--->8--->8--->8--->8--->8
Done.
While it's working, you can proceed to the section below.
Generating and importing the admins GPG key
*******************************************
You should import on the bastion one or more **public** GPG keys that'll be used for encryption.
If you don't already have a GPG key for this, you can generate one. As this is the admin GPG key,
don't generate it on the bastion itself, but on the desk of the administrator (you?) instead.
If you're running a reasonably recent GnuPG version (and the bastion does, too),
i.e. GnuPG >= 2.1.x, then you can generate an Ed25519 key by running:
.. code-block:: shell
:emphasize-lines: 1-8
myname='John Doe'
email='jd@example.org'
bastion='mybastion4.example.org'
pass=$(pwgen -sy 12 1)
echo "The passphrase for the key will be: $pass"
gpg --batch --pinentry-mode loopback --passphrase-fd 0 --quick-generate-key "$myname <$email>" ed25519 sign 0 <<< "$pass"
fpr=$(gpg --list-keys "$myname <$email>" | grep -Eo '[A-F0-9]{40}')
gpg --batch --pinentry-mode loopback --passphrase-fd 0 --quick-add-key "$fpr" cv25519 encr 0 <<< "$pass"
gpg: key 3F379CA7ECDF0537 marked as ultimately trusted
gpg: directory '/home/user/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/user/.gnupg/openpgp-revocs.d/3DFB21E3857F562A603BD4F83F379CA7ECDF0537.rev'
If you or the bastion is using an older version of GnuPG, or you are unsure and/or prefer compatibility
over speed or security, you can fallback to an RSA 4096 key:
.. code-block:: shell
:emphasize-lines: 1-9
myname='John Doe'
email='jd@example.org'
bastion='mybastion4.example.org'
pass=`pwgen -sy 12 1`
echo "The passphrase for the key will be: $pass"
printf "Key-Type: RSA\nKey-Length: 4096\nSubkey-Type: RSA\nSubkey-Length: 4096\n" \
"Name-Real: %s\nName-Comment: %s\nName-Email: %s\nExpire-Date: 0\n" \
"Passphrase: %s\n%%echo Generating GPG key\n%%commit\n%%echo done\n" \
"$myname ($bastion)" $(date +%Y) "$email" "$pass" | gpg --gen-key --batch
The passphrase for the key will be: ************
gpg: Generating GPG key
Not enough random bytes available. Please do some other work to give
the OS a chance to collect more entropy! (Need 119 more bytes)
.....+++++
gpg: key D2BDF9B5 marked as ultimately trusted
gpg: done
Of course, in both snippets above, adjust the ``myname``, ``email`` and ``bastion`` variables accordingly.
Write down the passphrase in a secure vault. All bastions admins will need it if they are to decrypt ttyrec files
later for inspection, and also decrypt the backup should a restore be needed.
When the key is done being generated, get the public key with:
.. code-block:: shell
:emphasize-lines: 1
gpg -a --export "$myname <$email>"
Copy it to your clipboard, then back to the bastion, paste it at the following prompt:
.. code-block:: shell
:emphasize-lines: 1
/opt/bastion/bin/admin/setup-gpg.sh --import
Also export the private admins GPG key to a secure vault (if you want the same key to be shared by the admins):
.. code-block:: shell
:emphasize-lines: 1
gpg --export-secret-keys --armor "$myname <$email>"
.. _installadv_encryptrsync:
Rotation, encryption & backup of ttyrec files
=============================================
.. note::
The above section :ref:`installadv_gpg` is a prerequisite to this one
The configuration file is located in ``/etc/bastion/osh-encrypt-rsync.conf``.
You can ignore the ``signing_key``, ``signing_key_passphrase`` and ``recipients`` options,
as these have been auto-filled when you generated the GPG keys, by dropping configuration files
in the ``/etc/bastion/osh-encrypt-rsync.conf.d`` directory.
Any file there takes precedence over the global configuration file.
Once you are done with your configuration, you might want to test it by running:
.. code-block:: shell
/opt/bastion/bin/cron/osh-encrypt-rsync.pl --config-test
Or even go further by starting the script in dry-run mode:
.. code-block:: shell
/opt/bastion/bin/cron/osh-encrypt-rsync.pl --dry-run
.. _installadv_backup:
Configuring keys, accounts & groups remote backup
=================================================
.. note::
The above section :ref:`installadv_gpg` is a prerequisite to this one, otherwise your backups will NOT
be automatically encrypted, which is something you probably want to avoid.
Everything that is needed to restore a bastion from backup (keys, accounts, groups, etc.) is backed up daily
in ``/root/backups`` by default.
If you want to push these backups to a remote location, which is warmly advised,
you have to specify the remote location to ``scp`` the backup archives to.
The configuration file is ``/etc/bastion/osh-backup-acl-keys.conf``,
and you should specify the ``PUSH_REMOTE`` and ``PUSH_OPTIONS``.
To verify that the script is correctly able to connect remotely (and also validate the remote hostkey),
start the script manually:
.. code-block:: shell
:emphasize-lines: 1
/opt/bastion/bin/cron/osh-backup-acl-keys.sh
Pushing backup file (/root/backups/backup-2020-05-25.tar.gz.gpg) remotely...
backup-2020-05-25.tar.gz.gpg
100% 21MB 20.8MB/s 00:00
Also verify that the extension is ``.gpg``, as seen above,
which indicates that the script successfully encrypted the backup.
Logs/Syslog
===========
It is advised to use syslog for The Bastion application logs.
This can be configured in ``/etc/bastion/bastion.conf`` with the parameter ``enableSyslog``.
There is a default ``syslog-ng`` configuration provided, if you happen to use it.
The file can be found as ``etc/syslog-ng/conf.d/20-bastion.conf.dist`` in the repository.
Please read the comments in the file to know how to integrate it properly in your system.
.. _installadv_ha:
Clustering (High Availability)
==============================
The bastions can work in a cluster, with N instances. In that case, there is one *master* instance,
where any modification command can be used (creating accounts, deleting groups, granting accesses),
and N-1 *slave* instances, where only *readonly* actions are permitted. Any of these instances may be
promoted, should the need arise.
Note that any instance can be used to connect to infrastructures, so in effect all instances can always be used
at the same time. You may set up a DNS round-robin hostname, with all the instances IPs declared,
so that clients automatically choose a random instance, without having to rely on another external component
such as a load-balancer. Note that if you do this, you'll need all the instances to share the same SSH host keys.
Before setting up the slave instance, you should have the two bastions up and running
(follow the normal installation documentation). Then, to set up the synchronization between the
instances, proceed as explained below.
Allowing the master to connect to the slave
*******************************************
On the slave, set the ``readOnlySlaveMode`` option in the ``/etc/bastion/bastion.conf`` file to ``true``:
.. code-block:: shell
:caption: run this on the SLAVE:
:emphasize-lines: 1
vim /etc/bastion/bastion.conf
This will instruct this bastion instance to deny any modification plugin,
so that changes can only be done through the master.
Then, append the master bastion synchronization public SSH keyfile,
found in :file:`~root/.ssh/id_master2slave.pub` on the master instance,
to :file:`~bastionsync/.ssh/authorized_keys` on the slave,
with the following prefix: ``from="IP.OF.THE.MASTER",restrict``
Hence the file should look like this:
.. code-block:: shell
:caption: run this on the SLAVE:
:emphasize-lines: 1
cat ~bastionsync/.ssh/authorized_keys
from="198.51.100.42",restrict ssh-ed25519 AAA[...]
Pushing the accounts and groups files to the slave
**************************************************
Check that the key setup has been done correctly by launching the following command under the ``root`` account:
.. code-block:: shell
:caption: run this on the MASTER:
:emphasize-lines: 1
rsync -v --rsh "ssh -i /root/.ssh/id_master2slave" /etc/passwd /etc/group bastionsync@IP.OF.THE.SLAVE:/root/
group
passwd
sent 105,512 bytes received 8,046 bytes 75,705.33 bytes/sec
total size is 1,071,566 speedup is 9.44
If this works correctly, you'll have two new files in the :file:`/root` directory of the slave instance.
We'll need those for the next step, which is verifying that the UIDs/GIDs of the slave instance are matching
the master instance's ones. Indeed, the sync of the ``/etc/passwd`` and ``/etc/group`` files can have adverse effects
on a newly installed machine where the packages were not installed in the same order than on the master, hence having
possibly mismatching UIDs/GIDs for the same users/groups.
The next step ensures these are matching between the master and the slave before actually enabling the synchronization.
.. _installadv_ha_uidgidsync:
Ensuring the UIDs/GIDs are in sync
**********************************
Now that we have the master's :file:`/etc/passwd` and :file:`/etc/group` files in the slave's :file:`/root` folder,
we can use a helper script to check for the UIDs/GIDs matches between the master and the slave.
This script's job is to check whether there is any discrepancy, and if this is the case, generate another script,
tailored to your case, to fix them:
.. code-block:: none
:caption: run this on the SLAVE:
:emphasize-lines: 1
/opt/bastion/bin/admin/check_uid_gid_collisions.pl --master-passwd /root/passwd --master-group /root/group --output /root/syncids.sh
WARN: local orphan group: local group 50 (with name 'staff') is only present locally, if you want to keep it, create it on the master first or it'll be erased
There is at least one warning, see above.
If you want to handle them, you may still abort now.
Type 'YES' to proceed regardless.
In the example above, the script warns us that some accounts or groups are only existing on the slave instance,
and not at all on the master. In this case, it's up to you to know what you want to do. If you choose to ignore it,
these accounts and groups will be erased on the first synchronization, as the master will push its own accounts and
groups to the slave instance. Such a discrepancy shouldn't happen as long as you're using the same OS and distro
on both sides. It may happen if you have installed more packages on the slave instance than on the master, as some
packages also create system groups or accounts. A possible fix is to install the same packages on the master, and/or
simply adding the account(s) and/or group(s) on the master, so that they're synchronized everywhere.
If you type 'YES' or simply don't have any warnings, you should see something like this:
.. code-block:: none
:caption: (output continued)
Name collision on UID: master UID 38 exists on local but with a different name (master=gnats local=list)
-> okay, offsetting local UID 38 to 50000038
Differing name attached to same UID: master UID 38 doesn't exist on local, but its corresponding name 'gnats' does, with local UID 41
Name collision on UID: master UID 39 exists on local but with a different name (master=list local=irc)
-> okay, offsetting local UID 39 to 50000039
[...]
You may now review the generated script (/root/syncids.sh) and launch it when you're ready.
Note that you'll have to reboot once the script has completed.
The generated script is found at the location you've specified, which is :file:`/root/syncids.sh` if you used
the command-line we suggested above. Reviewing this script is important, as this is the one that will be making
UIDs/GIDs modification to your slave instance, as to sync them to the master's ones, including propagating these
changes on your filesystem, using ``chmod`` and ``chgrp`` commands.
Once you're ready (note that you'll have to reboot the slave right after), you may run the generated script:
.. code-block:: none
:caption: run this on the SLAVE:
:emphasize-lines: 1
bash /root/syncids.sh
We'll change the UIDs/GIDs of files, when needed, in the following mountpoints: / /home /run /run/lock /run/snapd/ns /run/user/1001 /run/user/1001/doc /run/user/1001/gvfs
If you'd like to change this list, please edit this script and change the 'fslist' variable in the header.
Otherwise, if this sounds reasonable (e.g. there is no remotely mounted filesystem that you don't want us to touch), say 'YES' below:
Please review the listed mountpoints (obviously, they'll be different than the ones above). As stated you may
edit the script to adjust them if needed. If any UID/GID needs to be changed to be in sync with the master,
the script will ensure the changes are propagated to the specified filesystems. You might want to exclude
network-mounted filesystems and such, if any. The script does its best to do this for you, but you should ensure
that it has got it right.
Then, the script may list the daemons and running processes that it'll need to kill before doing the changes,
as Linux forbids changing UIDs/GIDs when they're used by a process. This is why a reboot is needed at the end.
.. code-block:: shell
:caption: (output continued)
The following processes/daemons will need to be killed before swapping the UIDs/GIDs:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
kernoops 2484 0.0 0.0 11264 440 ? Ss Apr11 0:04 /usr/sbin/kerneloops
whoopsie 2467 0.0 0.0 253440 11860 ? Ssl Apr11 0:00 /usr/bin/whoopsie -f
colord 2227 0.0 0.0 249220 13180 ? Ssl Apr11 0:00 /usr/libexec/colord
geoclue 2091 0.0 0.1 905392 20268 ? Ssl Apr11 1:09 /usr/libexec/geoclue
rtkit 1789 0.0 0.0 153156 2644 ? SNsl Apr11 0:00 /usr/libexec/rtkit-daemon
syslog 1445 0.0 0.0 224548 4572 ? Ssl Apr11 0:02 /usr/sbin/rsyslogd -n -iNONE
systemd+ 1305 0.0 0.0 91016 4088 ? Ssl Apr11 0:00 /lib/systemd/systemd-timesyncd
If you want to stop them manually, you may abort now (CTRL+C) and do so.
Press ENTER to continue.
As stated, ensure that it's alright that these daemons are killed. You may want to terminate them manually
if needed, otherwise the script will simply send a ``SIGTERM`` to these processes.
.. code-block:: shell
:caption: (output continued)
[...]
Restoring SUID/SGID flags where needed...
[...]
UID/GID swapping done, please reboot now.
As instructed, you may now reboot.
.. note::
If you're currently restoring from a backup, you may stop here and resume
the :doc:`/installation/restoring_from_backup` procedure.
Enabling the synchronization
****************************
Now that the master and the slave UIDs/GIDs are matching, we may enable the synchronization daemon:
.. code-block:: shell
:caption: run this on the MASTER:
:emphasize-lines: 1
vim /etc/bastion/osh-sync-watcher.sh
You may review the configuration, but the two main items to review are:
- ``enabled``, which should be set to ``1``
- ``remotehostlist``, which should contain the hosts/IPs list of the slave instances, separated by spaces
If the synchronization daemon was not already enabled and started (i.e. this is the first slave instance
you're setting up for this master), then you should configure it to start it on boot, and you may also
start it manually right now:
.. code-block:: shell
:caption: run this on the MASTER:
:emphasize-lines: 1-2
systemctl enable osh-sync-watcher
systemctl start osh-sync-watcher
Otherwise, if the daemon is already enabled and active, you can just restart it so it picks up the new configuration:
.. code-block:: shell
:caption: run this on the MASTER:
:emphasize-lines: 1
systemctl restart osh-sync-watcher
Now, you can check the logs (if you configured ``syslog`` instead, which is encouraged,
then the logfile depends on your syslog daemon configuration. If you're using our bundled ``syslog-ng``
configuration, the output is logged in :file:`/var/log/bastion/bastion-scripts.log`)
.. code-block:: shell
:caption: run this on the MASTER:
:emphasize-lines: 1
tail -F /var/log/bastion/osh-sync-watcher.log
Apr 12 18:11:25 bastion1.example.org osh-sync-watcher.sh[3346532]: Starting sync!
Apr 12 18:11:25 bastion1.example.org osh-sync-watcher.sh[3346532]: 192.0.2.42: [Server 1/1 - Step 1/3] syncing needed data...
Apr 12 18:11:27 bastion1.example.org osh-sync-watcher.sh[3346532]: 192.0.2.42: [Server 1/1 - Step 1/3] sync ended with return value 0
Apr 12 18:11:27 bastion1.example.org osh-sync-watcher.sh[3346532]: 192.0.2.42: [Server 1/1 - Step 2/3] syncing lastlog files from master to slave, only if master version is newer...
Apr 12 18:11:28 bastion1.example.org osh-sync-watcher.sh[3346532]: 192.0.2.42: [Server 1/1 - Step 2/3] sync ended with return value 0
Apr 12 18:11:28 bastion1.example.org osh-sync-watcher.sh[3346532]: 192.0.2.42: [Server 1/1 - Step 3/3] syncing lastlog files from slave to master, only if slave version is newer...
Apr 12 18:11:30 bastion1.example.org osh-sync-watcher.sh[3346532]: 192.0.2.42: [Server 1/1 - Step 3/3] sync ended with return value 0
Apr 12 18:11:39 bastion1.example.org osh-sync-watcher.sh[3346532]: All secondaries have been synchronized successfully
Apr 12 18:11:39 bastion1.example.org osh-sync-watcher.sh[3346532]: Watching for changes (timeout: 120)...
Your new slave instance is now ready!
Creating SSHFP DNS records
==========================
If you want to use ``SSHFP`` to help authenticating your bastion public keys by publishing their checksum
in your DNS, here is now to generate the correct records:
.. code-block:: shell
awk 'tolower($1)~/^hostkey$/ {system("ssh-keygen -r bastion.name -f "$2)}' /etc/ssh/sshd_config
You shall then publish them in your DNS. It is also a good idea to secure your DNS zone with DNSSEC,
but this is out of the scope of this manual.
Hardening the SSH configuration
===============================
Using our SSH templates is a good start in any case. If you want to go further, there are a lot of online resources
to help you harden your SSH configuration, and audit a running SSHd server.
As the field evolves continuously, we don't want to recommend one particularly here,
as it might get out of date rapidly, but looking for `ssh audit <https://github.com/search?q=ssh+audit>`_ on GitHub
is probably a good start. Of course, this also depends on your environment, and you might not be able to harden
your SSHd configuration as much as you would like.
Note that for The Bastion, both sides can be independently hardened:
the ingress part is handled in ``sshd_config``, and the egress part is handled in ``ssh_config``.
2FA root authentication
=======================
The bastion supports TOTP (Time-based One Time Password), to further secure high profile accesses.
This section covers the configuration of 2FA root authentication on the bastion itself.
TOTP can also be enabled for regular bastion users, but this is covered in another section.
To enable 2FA root authentication, run on the bastion:
.. code-block:: shell
script -c "google-authenticator -t -Q UTF8 -r 3 -R 15 -s /var/otp/root -w 2 -e 4 -D" /root/qrcode
Of course, you can check the ``--help`` and adjust the options accordingly.
The example given above has sane defaults, but you might want to adjust if needed.
Now, flash this QR code with your phone, using a TOTP application.
You might want to copy the QR code somewhere safe in case you need to flash it on some other phone,
by exporting the ``base64`` version of it:
.. code-block:: shell
gzip -c /root/qrcode | base64 -w150
Copy this in your password manager (for example). You can then delete the :file:`/root/qrcode` file.
You have then two configuration adjustments to do.
- First, ensure you have installed the provided :file:`/etc/pam.d/sshd` file, or at least the corresponding line
to enable the TOTP pam plugin in your configuration.
- Second, ensure that your :file:`/etc/ssh/sshd_config` file calls PAM for root authentication.
In the provided templates, there is a commented snippet to do it. The uncommented snippet looks like this:
.. code-block:: shell
# 2FA has been configured for root, so we force pubkey+PAM for it
Match User root
AuthenticationMethods publickey,keyboard-interactive:pam
Note that first, the usual publickey method will be used, then control will be passed to PAM.
This is where the :file:`/etc/pam.d/sshd` configuration will apply.
Now, you should be asked for the TOTP the next time you try to login through ssh as root.
In case something goes wrong with the new configuration, be sure to keep your already opened existing
connection to be able to fix the problem without falling back to console access.
Once this has been tested, you can (and probably should) also protect the direct root console access
to your machine with TOTP, including a snippet similar to this one:
.. code-block:: shell
# TOTP config
auth [success=1 default=ignore] pam_google_authenticator.so secret=/var/otp/${USER}
auth requisite pam_deny.so
# End of TOTP Config
inside your :file:`/etc/pam.d/login` file.
Of course, when using TOTP, this is paramount to ensure your server is properly synchronized through NTP.

View file

@ -0,0 +1,280 @@
==================
Basic Installation
==================
If you are just upgrading from a previous version, please read :doc:`upgrading<upgrading>` instead.
0. Got Puppet?
==============
We published a Puppet module to handle The Bastion configuration and prerequisites.
The GitHub repo is `here <https://github.com/ovh/puppet-thebastion>`_ and our module has been published to
`the Puppet forge <https://forge.puppet.com/modules/goldenkiwi/thebastion>`_.
Of course, its usage is completely optional, but if you choose to use it,
some of the below steps will be done by Puppet. Hence, you might want to only consider the following steps:
- :ref:`install-basic_operating-system`
- :ref:`install-basic_get-the-code`
- :ref:`install-basic_encrypt-home`
- (Run Puppet)
- :ref:`install-basic_first-account`
.. _install-basic_operating-system:
1. Operating system
===================
.. warning::
The Bastion expects to be the only main service running on the server,
please see :ref:`this FAQ entry <faq_existing_server>` for more information.
The following Linux distros are tested with each release, but as this is a security product,
you are *warmly* advised to run it on the latest up-to-date stable version of your favorite OS:
- Debian 12 (Bookworm), 11 (Bullseye), 10 (Buster)
- RockyLinux 8.x, 9.x
- Ubuntu LTS 24.04, 22.04, 20.04, 18.04
- OpenSUSE Leap 15.6\*
\*: Note that these versions have no out-of-the-box MFA support, as they lack packaged versions of ``pamtester``,
``pam-google-authenticator``, or both. Of course, you may compile those yourself.
Any other so-called `modern` Linux version are not tested with each release,
but should work with no or minor adjustments.
The following OS are also tested with each release:
- FreeBSD/HardenedBSD 13.2\*\*
\*\*: Note that these have partial MFA support, due to their reduced set of available ``pam`` plugins.
Support for either an additional password or TOTP factor can be configured, but not both at the same time.
The code is actually known to work on FreeBSD/HardenedBSD 10+, but it's only regularly tested under 13.2.
Other BSD variants, such as OpenBSD and NetBSD, are unsupported as they have a severe limitation over the maximum
number of supplementary groups, causing problems for group membership and restricted commands checks,
as well as no filesystem-level ACL support and missing PAM support (hence no MFA).
In any case, you are expected to install this on a properly secured machine (including, but not limited to:
``iptables``/``pf``, reduced-set of installed software and daemons, general system hardening, etc.).
If you use Debian, following the `CIS Hardening guidelines <https://www.cisecurity.org/benchmark/debian_linux/>`_ is
a good start. We have `a tool <https://github.com/ovh/debian-cis>`_ to check for compliance against these guidelines.
If you use Debian and don't yet have your own hardened template, this script should help you getting up to speed,
and ensuring your hardened host stays hardened over time, through a daily audit you might want to setup through cron.
Great care has been taken to write secure, tested code, but of course this is worthless if your machine
is a hacker highway. Ensuring that all the layers below the bastion code (the operating system
and the hardware it's running on) is your job.
2. Connect to your server as root
=================================
You'll need to be connected to your server as root to perform the installation. If you're using root password
authentication through SSH to do so, note that during the installation, as the SSH server configuration
will be hardened, the SSH password authentication will be disabled server-wide.
Hence, to access your server, please set up an SSH public key authentication instead of a password authentication,
and do so before proceeding with the next steps. Otherwise you might lose access to your own server once the
SSH hardening will be in effect, as password authentication will then be disabled.
.. _install-basic_get-the-code:
3. Get the code
===============
The bastion code usually lives under ``/opt/bastion``.
You can either use ``git clone`` directly, or get the tarball of the latest release.
- Using :command:`git`:
.. code-block:: shell
git clone https://github.com/ovh/the-bastion /opt/bastion
git -C /opt/bastion checkout $(git -C /opt/bastion tag | tail -1)
- Using the tarball:
Get the tarball of the latest release, which can be found
`there <https://github.com/ovh/the-bastion/releases/latest>`_, then untar it:
.. code-block:: shell
mkdir -p /opt/bastion
tar -C /opt/bastion -zxf v3.16.99-rc2.tar.gz
The code supports being hosted somewhere else on the filesystem hierarchy, but this is discouraged as you might
need to adjust a lot of configuration files (notably sudoers.d, cron.d, init.d) that needs an absolute path.
You should end up with directories such as ``bin``, ``lib``, etc. directly under ``/opt/bastion``.
.. _install-basic_install-packages:
4. Install the needed packages
==============================
For the supported Linux distros (see above), you can simply run:
.. code-block:: shell
/opt/bastion/bin/admin/packages-check.sh -i
You can add other parameters to install optional packages, depending on your environment:
- ``-s`` to install ``syslog-ng`` (advised, we have templates files for it)
- ``-d`` to install packages needed for developing the software (useless in production)
You'll also need our version of ttyrec, `ovh-ttyrec <https://github.com/ovh/ovh-ttyrec>`_.
To get and install the precompiled binary that will work for your OS and architecture, you can use this script:
.. code-block:: shell
/opt/bastion/bin/admin/install-ttyrec.sh -a
This will detect your distro, then download and either install the ``.deb`` or ``.rpm`` package
for `ovh-ttyrec <https://github.com/ovh/ovh-ttyrec>`_. If your distro doesn't handle those package types,
it'll fallback to installing precompiled static binaries.
Of course you can package it yourself and make it available to your own internal repositories instead of installing it this way.
If you plan to use the PIV functionalities of The Bastion,
you'll also need to install the ``yubico-piv-checker`` `helper tool <https://github.com/ovh/yubico-piv-checker>`_.
You may also want to install ``the-bastion-mkhash-helper`` `tool <https://github.com/ovh/the-bastion-mkhash-helper>`_
if you want to be able to generate so-called type 8 and type 9 password hashes.
.. code-block:: shell
/opt/bastion/bin/admin/install-yubico-piv-checker.sh -a
/opt/bastion/bin/admin/install-mkhash-helper.sh -a
.. _install-basic_encrypt-home:
5. Encrypt /home
================
Strictly speaking, this step is optional, but if you skip it, know that all the SSH private keys and session
recordings will be stored unencrypted on the ``/home`` partition.
Of course, if partition encryption is already handled by the OS template you use,
or if the storage layer of your OS is encrypted by some other mean, you may skip this section.
First, generate a secure password on your desk (but not too complicated so it can be typed
on a console over your hypervisor over a VDI over VPN over 4G in the dark at 3am on a Sunday)
and save it to a secure location: ``pwgen -s 10``.
Then you can use the helper script to do this, it'll guide you through the process.
When prompted for a passphrase, enter the one chosen just before:
.. code-block:: shell
/opt/bastion/bin/admin/setup-encryption.sh
If you get a cryptsetup error, you might need to add ``--type luks1`` to the ``cryptsetup luksFormat`` command
in the script. It can happen if your kernel doesn't have the necessary features enabled for LUKS2.
.. warning::
Once you have setup encryption, **do not forget** to ensure that the keys backup script has encryption enabled,
otherwise the backups will be stored unencrypted in ``/root/backups``,
which would make your ``/home`` encryption moot.
This is not covered here because you can do it later, just don't forget it:
it's in the :doc:`advanced installation<advanced>` section.
.. _install-basic_setup:
6. Setup bastion and system configuration
=========================================
The following script will do that for you. There are several possibilities here.
- If you're installing a new machine (nobody is using it as a bastion yet), then you can regenerate brand new
host keys and directly harden the ssh configuration without any side effect:
.. code-block:: shell
/opt/bastion/bin/admin/install --new-install
- If you're upgrading an existing machine (from a previous version of this software),
and there are already some people using it as a bastion, then if you change the host keys,
they'll have to acknowledge the change when connecting, i.e. this is not transparent at all.
To avoid doing that and not touching either the ssh config or the host keys, use this:
.. code-block:: shell
/opt/bastion/bin/admin/install --upgrade
If you used ``--upgrade``, then you are **warmly** advised to harden the configuration yourself,
using our templates as a basis. For example, if you're under Debian 11:
.. code-block:: shell
vimdiff /opt/bastion/etc/ssh/ssh_config.debian11 /etc/ssh/ssh_config
vimdiff /opt/bastion/etc/ssh/sshd_config.debian11 /etc/ssh/sshd_config
There are other templates available in the same directory, for the other supported distros.
- If you want to have a fine-grained control of what is managed by the installation script,
and what is managed by yourself (or any configuration automation system you may have), you can review all the fine-grained options:
.. code-block:: shell
/opt/bastion/bin/admin/install --help
.. _install-basic_review-config:
7. Review the configuration
===========================
Base configuration files have been copied, you should review the main configuration and modify it to your needs:
.. code-block:: shell
vim /etc/bastion/bastion.conf
.. _install-basic_perl-check:
8. Check that the code works on your machine
============================================
This script will verify that all required modules are installed:
.. code-block:: shell
/opt/bastion/bin/dev/perl-check.sh
.. note::
If you're installing this instance to restore a backup, you may stop here and resume the
standard :doc:`/installation/restoring_from_backup` procedure.
.. _install-basic_first-account:
9. Manually create our first bastion account
============================================
Just launch this script, replacing *USERNAME* by the username you want to use:
.. code-block:: shell
/opt/bastion/bin/admin/setup-first-admin-account.sh USERNAME auto
You'll just need to specify the public SSH key to add to this new account.
It'll be created as a bastion admin, and all the restricted commands will be granted.
.. note::
This command will also give you a so-called *bastion alias*, this is the command you'll routinely use to
connect to the bastion, and to your infrastructures through it, replacing in effect your previous usage
of the `ssh` command. The alias name advertised on account creation is configurable in ``bastion.conf``,
and of course the users can rename it as they see fit, but it's advised to keep this command short,
as people will use it a lot.
If you want to create other admin accounts, you can repeat the operation.
All the other accounts should be created by a bastion admin (or more precisely,
by somebody granted to the *accountCreate* command), using the bastion own commands.
But more about this in the section *Using the bastion*.
You may head over to the **USAGE** section on the left menu, but please read the warning below first.
.. warning::
Note that even if your bastion should now be functional, proper setup for a production-level environment
is not done yet: for example, you don't have any backup system in place! Please ensure you follow the
:doc:`advanced installation<advanced>` documentation and carely consider each step (by either completing it
or deciding that it's not mandatory for your use case), before considering your installation complete.

View file

@ -0,0 +1,78 @@
====================
Sandbox using Docker
====================
This is a good way to test The Bastion within seconds, but :ref:`read the FAQ <faq_docker>`
if you're serious about using containerization in production.
The sandbox image is available for the following architectures: ``linux/386``, ``linux/amd64``, ``linux/arm/v6``,
``linux/arm/v7``, ``linux/arm64``, ``linux/ppc64le``, ``linux/s390x``.
- Let's run the docker image:
.. code-block:: shell
docker run -d -p 22 --name bastiontest ovhcom/the-bastion:sandbox
- Or, if you prefer building the docker image yourself, you can: use the two commands below.
Of course, if you already typed the ``docker run`` command above, you can skip the following commands:
.. code-block:: shell
docker build -f docker/Dockerfile.debian10 -t bastion:debian10 .
docker run -d -p 22 --name bastiontest bastion:debian10
- Configure the first administrator account (get your public SSH key ready)
.. code-block:: shell
docker exec -it bastiontest /opt/bastion/bin/admin/setup-first-admin-account.sh poweruser auto
- We're now up and running with the default configuration!
Let's setup a handy bastion alias, and test the ``info`` command:
.. code-block:: shell
PORT=$(docker port bastiontest | cut -d: -f2)
alias bastion="ssh poweruser@127.0.0.1 -tp $PORT -- "
bastion --osh info
- It should greet you as being a bastion admin, which means you have access to all commands.
Let's enter interactive mode:
.. code-block:: shell
bastion -i
- This is useful to call several ``--osh`` plugins in a row. Now we can ask for help to see all plugins:
.. code-block:: shell
$> help
- If you have a remote machine you want to try to connect to through the bastion, fetch your egress key:
.. code-block:: shell
$> selfListEgressKeys
- Copy this public key to the remote machine's ``authorized_keys`` under the ``.ssh/`` folder
of the account you want to connect to, then:
.. code-block:: shell
$> selfAddPersonalAccess --host <remote_host> --user <remote_account_name> --port-any
$> ssh <remote_account_name>@<remote_host>
- Note that you can connect directly without using interactive mode, with:
.. code-block:: shell
bastion <remote_account_name>@<remote_machine_host_or_ip>
That's it! You can head over to the **USAGE** section on the left menu for more information.
Be sure to check the help of the bastion with ``bastion --help``,
along with the help of each osh plugin with ``bastion --osh command --help``.
Also don't forget to customize your ``bastion.conf`` file,
which can be found in ``/etc/bastion/bastion.conf`` (for Linux).

View file

@ -0,0 +1,149 @@
=====================
Restoring from backup
=====================
In this section, we'll detail how to restore a bastion's main data from a backup.
This can be useful in two main cases:
- When an account with high privileges has deleted or altered by mistake a great amount of accounts or groups, up
to a point where it's operationally easier to just restore the settings, accounts, groups and keys from the latest
available backup
- When you are not in an :ref:`HA setup <installadv_ha>` and your only
instance is down and can't be brought back up in a timely manner.
Note that if you are in a HA setup and you need to add a new node (regardless of the fact that you're replacing
a failed node or not), you don't need to restore from backup: you can simply follow the HA setup procedure so
that your new node is synced with your main node.
Prerequisites
=============
First, you obviously must have a backup at hand, which should be the case if you followed the
:ref:`installadv_backup` section when you first installed the instance you want to restore.
If the backup is encrypted with GPG (it should be), you must have access to the corresponding GPG private key and
its passphrase.
You must ensure that the new server you're setting up has the same OS release than the one the backup file
comes from, as we'll overwrite the new server's accounts and groups files with the backed up versions.
This could cause adverse effects if the distro or release differ, although the restore script won't stop
you from doing so (it'll even help you adjust the discrepancies if needed, but again, this is strongly discouraged).
Steps
=====
Installation
------------
On the new server you want to deploy the backup to, you must first follow the standard :doc:`/installation/basic`
procedure, up to and including the *Check that the code works on your machine* step.
Once done, you may proceed to the next steps below.
GPG key and backup archive import
---------------------------------
On the server you've just installed, you'll need to import the private GPG key that was used to encrypt the backup, and
you'll also need to fetch the backup archive itself. It's a good practice to NOT decrypt the backup archive prior to
transferring it to the new server. This way, you're sure that the credentials and keys contained in the backup have
not been compromised.
To import the GPG key, just run:
.. code-block:: shell
:emphasize-lines: 1
gpg --import
And paste the private GPG key corresponding to the backup so that it gets imported into root's keyring.
Alternatively, you can put the private GPG key in a temporary file, and import it this way:
.. code-block:: shell
:emphasize-lines: 1
gpg --import < /tmp/backupkey.asc
You may now import the backup archive, which usually has a name matching the :file:`backup-YYYY-MM-DD.tar.gz.gpg` format.
You can use ``scp``, ``sftp`` or any other method to get this file onto the server, at any location you see fit. We'll use
:file:`/root` as location for the rest of this documentation, as this is guaranteed to only be readable by root,
hence not compromising the keys and credentials.
Decrypt and extract accounts and groups
---------------------------------------
Now, you can decrypt the backup archive:
.. code-block:: shell
:emphasize-lines: 1
gpg -d /root/backup-YYYY-MM-DD.tar.gz.gpg > /root/backup-decrypted.tar.gz
gpg: encrypted with 4096-bit RSA key, ID F50BFFC49143C821, created 2021-03-27
"Bastion Administrators <bastions.admins@example.org>"
You'll have to input the GPG private key passphrase when asked to.
Then, check whether the archive seems okay:
.. code-block:: shell
:emphasize-lines: 1
tar tvzf /root/backup-decrypted.tar.gz
You should see a long list of files, most under the :file:`/home` hierarchy.
We now need to extract the backed up :file:`/etc/passwd` and :file:`/etc/group` files, to ensure the new
instance we're setting up has its UIDs/GIDs synced with the system we're restoring:
.. code-block:: shell
:emphasize-lines: 1
tar xvzf /root/backup-decrypted.tar.gz -C /root --strip-components=1 etc/passwd etc/group
etc/group
etc/passwd
We now have the two original accounts and groups lists in :file:`/root`, and we can proceed to check
whether the UIDs and GIDs are in sync.
Ensuring the UIDs/GIDs are in sync
----------------------------------
This procedure is the same than when setting up a slave instance bastion,
please follow the corresponding :ref:`step there<installadv_ha_uidgidsync>` and come
back to this documentation when it's done.
.. note::
The referenced step above asks you to reboot at the end, please ensure you've done it before
continuing with the rest of the procedure below.
Restoring
---------
Now that we know the UIDs/GIDs are synced, we can proceed with the full restore:
.. code-block:: shell
:emphasize-lines: 1
tar -C / --preserve-permissions --preserve-order --overwrite --acls --numeric-owner -xzvf /root/backup-decrypted.tar.gz
.. note::
If you're getting errors such as 'Warning: Cannot acl_from_text: Invalid argument', please ensure that your
filesystem supports ACLs and is mounted with ACL support, otherwise ``tar`` can't restore ACLs from the backup.
Back to production
------------------
As the configuration of the SSH daemon has also been restored, you might want to restart it so that it
picks up the new configuration:
.. code-block:: shell
:emphasize-lines: 1
service ssh restart
Once this is done, all the accounts that were present in the backup should be working. After ensuring this is the case,
you may put the server put back in production.

View file

@ -0,0 +1,554 @@
=========
Upgrading
=========
General upgrade instructions
============================
- First, check below if there are specific upgrade instructions for your version.
- When you're ready, update the code, if you're using ``git``, you can checkout the latest tag:
.. code-block:: shell
( umask 0022 && cd /opt/bastion && git fetch && git checkout $(git tag | tail -1) )
- Run the install script in upgrade mode, so it can make adjustments to the system needed for the new version:
.. code-block:: shell
/opt/bastion/bin/admin/install --upgrade
Note that if you're using an infrastructure automation tool such as Puppet, Ansible, Chef,
and don't want the update script to touch some files that you manage yourself,
you can use ``--managed-upgrade`` instead of ``--upgrade``.
See the ``--help`` for a more fine-grained upgrade path if needed.
Version-specific upgrade instructions
=====================================
v3.16.99-rc2 - 2024/09/17
*************************
This release drops support for Ubuntu 16.04 and CentOS 7. If you're still using these EOL OS releases (which is
obviously discouraged), proper functioning of The Bastion is no longer tested or guaranteed.
It also adds official support for Ubuntu 24.04 LTS and OpenSUSE Leap 15.6, these were already working but
are now part of the integration tests.
This release adds support of wildcards (also called "shell-style globbing characters"), namely ``?`` and ``*``,
when using the ``--user`` option for plugins such as ``groupAddServer``, ``groupDelServer``, ``groupAddGuestAccess``,
``groupDelGuestAccess``, ``accountAddPersonalAccess``, ``accountDelPersonalAccess``, ``selfAddPersonalAccess``,
``selfDelPersonalAccess``.
We also deprecate all the ``--sftp``, ``--scpdown``, ``--scpup`` options that are now replaced by a more generic
``--protocol`` option, which supports ``sftp``, ``scpdown ``, ``scpup`` and now also ``rsync`` as parameters.
The use of rsync is similar to sftp and scp, and is detailed here: :doc:`/plugins/open/rsync`.
Last but not least, the ``sntrup761x25519-sha512@openssh.com`` KEX algorithm is now enabled by default on shipped
versions of ``sshd_config`` and ``ssh_config``. If you're upgrading, these files won't be touched, so if you want to
add support, you'll need to modify them manually by prepending ``sntrup761x25519-sha512@openssh.com`` to the
``KexAlgorithms`` line. Verify that the OpenSSH version shipped by your OS does support it (run ``ssh -Q kex``).
v3.16.01 - 2024/04/17
*********************
No specific upgrade instructions.
v3.16.00 - 2024/04/10
*********************
This version adds support for Secure Keys (FIDO2) for ingress authentication. It requires at least OpenSSH 8.2
installed on the server hosting The Bastion, as support for FIDO2 was added in this version.
Of the currently supported OS versions, the following are known to have a recent-enough version:
- Debian 11
- Debian 12
- Ubuntu 20.04
- Ubuntu 22.04
- OpenSUSE Leap 15.5
- Rocky Linux 9
Note that if you are upgrading, you'll need to enable the new ingress algorithms in the ``/etc/bastion/bastion.conf``
file, under the ``allowedIngressSshAlgorithms`` option. You may want to add ``ecdsa-sk`` and ``ed25519-sk`` to the list
if you want to support the FIDO2-backed versions of these two algorithms.
You may also refer to the distributed default configuration file in ``etc/bastion/bastion.conf.dist``,
which enables them by default.
v3.15.00 - 2024/03/22
*********************
No specific upgrade instructions.
v3.14.16 - 2024/02/20
*********************
No specific upgrade instructions.
v3.14.15 - 2023/11/08
*********************
This release fixes the :doc:`/administration/security_advisories/cve_2023_45140` with severity 4.8 (CVSS V3).
Please refer to its page for impact and mitigation details.
The changes introduced to fix this vulnerability imply that if you're using the ``scp`` or ``sftp`` plugins,
you'll need to update your wrappers using the new versions provided by this release. The old helpers will still
work, but only for remote hosts that don't require MFA.
To get the new wrappers for your account on a given bastion, just call ``--osh scp`` or ``--osh sftp`` without
specifying any host, which will give you your script, and examples of use.
As you'll notice, the new scripts are no longer helpers (that were to be used through ``scp -S`` and
``sftp -S``), but wrappers, that will call ``scp`` and ``sftp`` themselves.
As outlined above, the old helpers will still work for the foreseeable future, but as they're not able to
request MFA when this is configured for a remote host, they'll simply fail for such hosts on an updated
version of the bastion.
If you have some accounts that use automated accesses through the bastion and use ``scp`` or ``sftp`` on
hosts that have JIT MFA configured through their group, you'll need to set these accounts as immune to JIT MFA,
which can be done through :doc:`/plugins/restricted/accountModify`'s ``--mfa-password-required bypass``
and/or ``accountModify --mfa-totp-required bypass``, as has always been the case for classic SSH access.
An HMAC shared secret is automatically generated when this release is deployed, this secret must be shared
by all the instances of the same cluster. Hence, you should start by deploying this release on the primary
node, which will generate the secret automatically during the standard upgrading procedure, so that this
node can push the shared-secret to the other nodes. The other nodes don't have to be upgraded beforehand,
they'll just not use the secret until they're upgraded to this version, and JIT MFA for ``scp`` and ``sftp``
will not work through them until this is the case.
Once the primary node is upgraded, you should ensure the new file containing the HMAC shared secret is part
of the synchronization list. If you did not customize your synchronization list, you can apply the new one
over the old one directly:
.. code-block:: shell
:emphasize-lines: 1
cat /opt/bastion/etc/bastion/osh-sync-watcher.rsyncfilter.dist > /etc/bastion/osh-sync-watcher.rsyncfilter
Then, you need to restart the synchronization daemon, so that it takes into consideration the new file
(containing the shared secret) to push to the other nodes. This is usually done this way:
.. code-block:: shell
:emphasize-lines: 1
systemctl restart osh-sync-watcher
You can verify on the other nodes that the ``/etc/bastion/mfa-token.conf`` file is now present.
v3.14.00 - 2023/09/19
*********************
A new helper is required to support the so-called "type 8" and "type 9" password hash types, used on some
network devices. This helper is optional, and these hashes types will simply not be generated if the helper is
missing. The plugins concerned by this change are ``selfGeneratePassword``, ``selfListPasswords``,
``accountGeneratePassword``, ``accountListPasswords``, ``groupGeneratePassword``, ``groupListPasswords``.
New installations will get this helper installed automatically. When upgrading, if you'd like to install
this helper, you'll need to install it by running the following command as ``root``:
.. code-block:: shell
/opt/bastion/bin/admin/install-mkhash-helper.sh -a
This will detect your OS and either install a ``.deb`` file, an ``.rpm`` file, or a static binary.
If you want to ensure that the helper has installed correctly, you can call it manually for testing purposes:
.. code-block:: shell
:emphasize-lines: 1
echo test | the-bastion-mkhash-helper
{"Type8":"$8$EpvF1cVVzoEQFE$L3ZBWzfH9MTPo4WLX29Jd8LTM5sKlfEjtRZ//XMys2U","Type9":"$9$yRlXzt0T7WBs3E$YdKk8WMvLvAVcbglx.bMZoRlwBa6l5EhwLhBh1o0u4g","PasswordLen":4}
If you're not generating passwords for use with network devices using type 8 or type 9 hash types, installation of this
helper is not required.
v3.13.01 - 2023/08/22
*********************
No specific upgrade instructions.
v3.13.00 - 2023/07/28
*********************
Plugins output is now recorded using ttyrec, as the connections are, instead of being stored in sqlite format
within the home folder of the account. This helps avoiding the sqlite databases growing too much in size when
accounts are using osh commands very intensively.
v3.12.00 - 2023/06/27
*********************
Support for Debian 9 has been dropped. This doesn't mean that the code will suddenly stop working under this version,
but that tests no longer include this OS. Please consider upgrading to a more recent OS, as ensuring the underlying
OS is up to date and still supported is paramount to the security of The Bastion (or any other software).
Support of Debian "Bookworm" 12 is now official, as this is now Debian stable.
v3.11.02 - 2023/04/18
*********************
No specific upgrade instructions.
v3.11.01 - 2023/03/27
*********************
No specific upgrade instructions.
v3.11.00 - 2023/03/23
*********************
The upgrade path from the preceding version is straightforward, however there is a change
that you might want to be aware of before hitting the upgrade button:
The previously implicitly assumed ``--port-any`` and ``--user-any`` options
to the ``(self|account)(Add|Del)PersonalAccess`` commands, when either ``--user`` or ``--port`` were omitted,
now require to be stated explicitly, to be consistent with the behaviour of ``group(Add|Del)Server``,
which always required it. Note that using this mechanism always emitted a deprecation warning,
since the first publicly released version, encouraging the explicit use of ``--user-any`` and/or ``--port-any``
when this was desired. Now, omitting these options will simply return an error,
as this has always been the case with ``group(Add|Del)Server``.
Example of previous behaviour::
$ bssh --osh selfAddPersonalAccess --host 127.0.0.5 --force
╭──ac777d06bec9───────────────────────────────────────────the-bastion-3.10.00───
│ ▶ adding personal access to a server on your account
├───────────────────────────────────────────────────────────────────────────────
│ ❗ You didn't specify --user or --user-any, defaulting to --user-any, this will no longer be implicit in future versions
│ ❗ You didn't specify --port or --port-any, defaulting to --port-any, this will no longer be implicit in future versions
│ Forcing add as asked, we didn't test the SSH connection, maybe it won't work!
│ Access to 127.0.0.5 was added to account jdoe
╰────────────────────────────────────────────────────</selfAddPersonalAccess>───
Example of new behaviour::
$ bssh --osh selfAddPersonalAccess --host 127.0.0.5 --force
╭──ac777d06bec9───────────────────────────────────────────the-bastion-3.11.00───
│ ▶ adding personal access to a server on your account
├───────────────────────────────────────────────────────────────────────────────
│ Add a personal server access on your account
│ Usage: --osh selfAddPersonalAccess --host HOST [OPTIONS]
│ --host IP|HOST|IP/MASK Server to add access to
│ --user USER Remote login to use, if you want to allow any login, use --user-any
│ --user-any Allow access with any remote login
│ --port PORT Remote SSH port to use, if you want to allow any port, use --port-any
│ --port-any Allow access to all remote ports
│ --scpup Allow SCP upload, you--bastion-->server (omit --user in this case)
│ --scpdown Allow SCP download, you<--bastion--server (omit --user in this case)
│ --sftp Allow usage of the SFTP subsystem, you<--bastion-->server (omit --user in this case)
│ --force Add the access without checking that the public SSH key is properly installed remotely
│ --force-key FINGERPRINT Only use the key with the specified fingerprint to connect to the server (cf selfListEgressKeys)
│ --force-password HASH Only use the password with the specified hash to connect to the server (cf selfListPasswords)
│ --ttl SECONDS|DURATION Specify a number of seconds (or a duration string, such as "1d7h8m") after which the access will automatically expire
│ --comment "'ANY TEXT'" Add a comment alongside this server. Quote it twice as shown if you're under a shell.
│ ⛔ No user specified, if you want to add this server with any user, use --user-any
╰────────────────────────────────────────────────────</selfAddPersonalAccess>───
v3.10.00 - 2023/02/17
*********************
No specific upgrade instructions.
v3.09.02 - 2022/11/15
*********************
No specific upgrade instructions.
v3.09.01 - 2022/10/10
*********************
No specific upgrade instructions.
v3.09.00 - 2022/09/21
*********************
This version has changes around the satellite system scripts that should be reviewed:
- The ``osh-encrypt-rsync.pl`` script now also handles the account's access log and sql logs,
in addition to the ttyrec files.
A number of new options have been added to this script's config file, these options have sane defaults but you
might still want to review those, namely `encrypt_and_move_user_logs_delay_days <https://ovh.github.io/the-bastion/administration/configuration/osh-encrypt-rsync_conf.html#encrypt-and-move-user-logs-delay-days>`_
and `encrypt_and_move_user_sqlites_delay_days <https://ovh.github.io/the-bastion/administration/configuration/osh-encrypt-rsync_conf.html#encrypt-and-move-user-sqlites-delay-days>`_.
- As a result of the previous feature, the ``compress-old-logs.sh`` script has been retired.
- A new script, ``osh-cleanup-guest-key-access.pl``, has been added. It is enabled by default, though it can
be disabled if you have a good reason to do so. Please refer to its `documentation <https://ovh.github.io/thge-bastion/administration/configuration/osh-cleanup-guest-key-access_conf.html>`_ for more
information.
- All scripts that are automatically run by cron and reside under the ``bin/cron`` subfolder now have their own
configuration file in ``/etc/bastion``, even for simple scripts that only have two configuration knobs: their
logging facility and whether they should be enabled or not. It is now recommended to use these configuration knobs
to disable the scripts you don't want to see running, instead of removing their corresponding file in the
``/etc/cron.d`` folder, as any future update of the bastion would install them back.
- The logging format has been standardized across these scripts, to ensure the newly included NRPE probes can detect
errors in the scripts more easily. By default the logs are going through syslog, using the ``local6`` facility,
which ends up in the ``/var/log/bastion/bastion-scripts.log`` folder if you're using our stock ``syslog-ng``
configuration. The NRPE probes are available in the ``contrib/nrpe`` directory.
Additionally, NRPE probes have been added, and should be used to monitor your bastion instances / clusters.
More information is available in the `NRPE probes readme file <https://github.com/ovh/the-bastion/blob/master/contrib/nrpe/README.md>`_.
Last but not least, CentOS 8 support has been dropped (whereas RockyLinux 8 will remain supported),
and Ubuntu 22.04 LTS support has been added.
v3.08.01 - 2022/01/19
*********************
The upgrade path from the preceding version is straightforward, however you might want to know that there is
a new satellite script: ``osh-remove-empty-folders.sh``, run by cron and enabled by default,
whose job is to garbage-collect empty folders that may be piling up in busy users' homes,
under their ``ttyrec`` folder.
You can find more information in `the documentation
<https://ovh.github.io/the-bastion/administration/configuration/osh-remove-empty-folders_conf.html>`_, the script
is enabled by default because it can do no harm.
v3.08.00 - 2022/01/04
*********************
This version replaces usage of GnuPG 1.x by GnuPG 2.x for the backup/encrypt/rsync satellite scripts, namely:
- ``bin/cron/osh-backup-acl-keys.sh``
- ``bin/cron/osh-encrypt-rsync.pl``
These are optionally used to help you backup your system, and encrypt/move out ttyrec files.
If you don't use these scripts and never configured them as seen in the :doc:`/installation/advanced` section,
then you have nothing to do.
The script ``setup-gpg.sh`` will now create an Ed25519 key by default, instead of a 4K RSA key.
This type of key is usually seen as more secure (elliptic curve cryptography), and faster than RSA keys.
If you have already configured your system, then the above scripts will continue using the previously generated
RSA key, unless you generate a new key and reference it in the scripts configuration files.
If you want to generate new Ed25519 keys instead of using your preexisting RSA keys, you may proceed
to the :ref:`Ed25519 section below <upgrading_ed25519>`.
Otherwise, on the first run, GnuPG 2.x should transparently import the 1.x keyring.
To verify that it worked correctly, you may want to try:
.. code-block:: shell
/opt/bastion/bin/cron/osh-encrypt-rsync.pl --config-test
If you see *Config test passed*, and you're okay using your preexisting 4K RSA key, then you may stop here.
If the test fails, and you know that before upgrading, this script worked correctly, then you might need to
manually import the GnuPG 1.x public keys:
.. code-block:: shell
gpg1 --armor --export | gpg --import
Then, try again:
.. code-block:: shell
/opt/bastion/bin/cron/osh-encrypt-rsync.pl --config-test
If you don't see any errors here, you're done.
If you still see errors, then you might need to manually import the private key:
.. code-block:: shell
gpg1 --armor --export-secret-keys | gpg --import
You may get asked for a password for the bastion secret key, which should be found in
``/etc/bastion/osh-encrypt-rsync.conf.d/50-gpg-bastion-key.conf`` if you previously used the script to generate it.
A last config test should now work:
.. code-block:: shell
/opt/bastion/bin/cron/osh-encrypt-rsync.pl --config-test
If you prefer to generate Ed25519 keys instead, then you can proceed to the next section.
.. _upgrading_ed25519:
Ed25519
-------
If you want to replace your RSA key by an Ed25519 one (which is optional), then you don't need to import the
GnuPG 1.x keys as outlined above but you may run instead:
.. code-block:: shell
/opt/bastion/bin/admin/setup-gpg.sh generate --overwrite
Once the key has been generated, you may also want to generate a new admin key, by following this
:ref:`section <installation/advanced:Generating and importing the admins GPG key>` of the Advanced Installation documentation.
Note that you'll need to use the ``--overwrite`` parameter when importing:
.. code-block:: shell
/opt/bastion/bin/admin/setup-gpg.sh import --overwrite
Once done, a config test should work:
.. code-block:: shell
/opt/bastion/bin/cron/osh-encrypt-rsync.pl --config-test
v3.07.00 - 2021/12/13
*********************
No specific upgrade instructions.
v3.06.00 - 2021/10/15
*********************
The ``sshd_config`` templates have been modified to reflect the changes needed to use
the new ``--pubkey-auth-optional`` parameter of :doc:`/plugins/restricted/accountModify`
(`#237 <https://github.com/ovh/the-bastion/pull/237>`_).
If you want to use it, don't forget to review your ``sshd_config`` and modify it accordingly:
the templates can be found in ``etc/ssh/``.
Note that misconfiguring `sshd` and `pam` together could at worst entirely disable sshd authentication.
If you have a custom configuration, different from the templates we provide, please double-check
that such corner case is not possible by design.
A good way to ensure this is to review the `pam` configuration and ensure that there is no execution
flow that pushes a `pam_success` value to the pam stack without requiring any form of authentication.
v3.05.01 - 2021/09/22
*********************
In the configuration of the ``osh-backup-acl-keys`` script, a signing key can now be specified so that the backups
are signed by the bastion key in addition to being encrypted to the admin(s) key(s).
By default, the behaviour is the same as before: encrypt but don't sign.
v3.05.00 - 2021/09/14
*********************
The maximum length of accounts is now 28 characters up from 18 characters previously.
If you have setup a HA cluster with several bastion instances synchronized together, note that accounts longer
than 18 characters will not be deemed as valid on not-yet upgraded instances of a cluster.
v3.04.00 - 2021/07/02
*********************
The upgrade path from the preceding version is straightforward, however there are a few changes
that you might want to be aware of before hitting the upgrade button:
- Some EOL OSes have been dropped: Debian 8, Ubuntu 14.04, OpenSUSE 15.0 and 15.1.
This means that while the software might still work, theses OSes are no longer part of the tests
and might break in any future upgrade.
- The default logging level of the :doc:`/using/http_proxy` has been decreased. If you want to keep full requests
and responses logging, check the :doc:`log_request_response and log_request_response_max_size
</administration/configuration/osh-http-proxy_conf>` configuration options.
v3.03.01 - 2021/03/25
*********************
No specific upgrade instructions.
v3.03.00 - 2021/02/22
*********************
No specific upgrade instructions.
v3.02.00 - 2021/02/01
*********************
The upgrade path from the preceding version is straightforward, however there are a few changes
that you might want to be aware of before hitting the upgrade button:
The main configuration file now supports proper booleans
--------------------------------------------------------
For a lot of configuration options, previously you would specify "1" to enable a feature, and "0" to disable it.
This has been changed to use proper *true* and *false* json values in :file:`/etc/bastion/bastion.conf`.
Of course, backward compatibility with "0" and "1" will always be kept, so no breakage is to be expected
for this version or future ones even if you keep your configuration untouched.
Logs have been enhanced
-----------------------
All connections and plugin executions emit two logs, an *open* and a *close* log.
We now add all the details of the connection to the *close* logs, those that were previously only available
in the corresponding *open* log. This way, it is no longer required to correlate both logs with their uniqid
to have all the data: the *close* log should suffice.
The *open* log is still there if for some reason the *close* log can't be emitted (kill -9, system crash, etc.),
or if the *open* and the *close* log are several hours, days or months appart.
An additional field **duration** has been added to the *close* logs,
this represents the number of seconds (with millisecond precision) the connection lasted.
Two new fields **globalsql** and **accountsql** have been added to the *open*-type logs.
These will contain either `ok` if we successfully logged to the corresponding log database,
`no` if it is disabled, or `error $aDetailedMessage` if we got an error trying to insert the row.
The *close*-type log also has the new **accountsql_close** field, but misses the **globalsql_close** field as
we never update the global database on this event.
On the *close* log, we can also have the value **missing**, indicating that we couldn't update the access log row
in the database, as the corresponding *open* log couldn't insert it.
The **ttyrecsize** log field for the *close*-type logs has been removed, as it was never completely implemented,
and contains bogus data if ttyrec log rotation occurs. It has also been removed from the sqlite log databases.
The *open* and *close* events are now pushed to our own log files, in addition to syslog, if logging to those files
is enabled (see :ref:`enableGlobalAccessLog` and :ref:`enableAccountAccessLog`),
previously the *close* events were only pushed to syslog.
The :file:`/home/osh.log` file is no longer used for :ref:`enableGlobalAccessLog`, the global log
is instead written to :file:`/home/logkeeper/global-log-YYYYMM.log`.
The global sql file, enabled with :ref:`enableGlobalSqlLog`, is now split by year-month instead of by year,
to :file:`/home/logkeeper/global-log-YYYYMM.sqlite`.
v3.01.03 - 2020/12/15
*********************
No specific upgrade instructions.
v3.01.02 - 2020/12/08
*********************
No specific upgrade instructions.
v3.01.01 - 2020/12/04
*********************
No specific upgrade instructions.
v3.01.00 - 2020/11/20
*********************
A new bastion.conf option was introduced: *interactiveModeByDefault*. If not present in your config file,
its value defaults to 1 (true), which changes the behavior of The Bastion when a user connects
without specifying any command.
When this happens, it'll now display the help then drop the user into interactive mode (if this mode is enabled),
instead of displaying the help and aborting with an error message.
Set it to 0 (false) if you want to keep the previous behavior.
An SELinux module has been added in this version, to ensure TOTP MFA works correctly under systems where SELinux
is on enforcing mode. This module will be installed automatically whenever SELinux is detected on the system.
If you don't want to use this module, specify `--no-install-selinux-module` on your `/opt/bastion/bin/admin/install`
upgrade call (please refer to the generic upgrade instructions for more details).
v3.00.02 - 2020/11/16
*********************
No specific upgrade instructions.
v3.00.01 - 2020/11/06
*********************
If you previously installed ``ttyrec`` using the now deprecated ``build-and-install-ttyrec.sh`` script,
you might want to know that since this version, the script has been replaced by ``install-ttyrec.sh``,
which no longer builds in-place, but prefers downloading and installing prebuild ``rpm`` or ``deb`` packages.
If you previously built and installed ``ttyrec`` manually, and want to use the new packages instead,
you might want to manually uninstall your previously built ttyrec program (remove the binaries that were installed
in ``/usr/local/bin``), and call ``install-ttyrec.sh -a`` to download and install the proper package instead.
This is not mandatory and doesn't change anything from the software point of view.
v3.00.00 - 2020/10/30
*********************
Initial public version, no specific upgrade instructions.

View file

@ -0,0 +1,28 @@
=================
adminMaintenance
=================
Manage the bastion maintenance mode
===================================
.. admonition:: usage
:class: cmdusage
--osh adminMaintenance <--lock [--message "'reason for maintenance'"]|--unlock>
.. program:: adminMaintenance
.. option:: --lock
Set maintenance mode: new logins will be disallowed
.. option:: --unlock
Unset maintenance mode: new logins are allowed and the bastion functions normally
.. option:: --message MESSAGE
Optionally set a maintenance reason, if you're in a shell, quote it twice.

View file

@ -0,0 +1,31 @@
==========
adminSudo
==========
Impersonate another user
========================
.. admonition:: usage
:class: cmdusage
--osh adminSudo -- --sudo-as ACCOUNT <--sudo-cmd PLUGIN -- [PLUGIN specific options...]>
.. program:: adminSudo
.. option:: --sudo-as ACCOUNT
Specify which bastion account we want to impersonate
.. option:: --sudo-cmd PLUGIN
--osh command we want to launch as the user (see --osh help)
Example::
--osh adminSudo -- --sudo-as user12 --sudo-cmd info -- --name somebodyelse
Don't forget the double-double-dash as seen in the example above: one after the plugin name,
and another one to separate adminSudo options from the options of the plugin to be called.

View file

@ -0,0 +1,8 @@
==============
admin plugins
==============
.. toctree::
adminMaintenance
adminSudo

View file

@ -0,0 +1,72 @@
===============
groupAddServer
===============
Add an IP or IP block to a group's servers list
===============================================
.. admonition:: usage
:class: cmdusage
--osh groupAddServer --group GROUP --host HOST --user USER|* --port PORT|* [OPTIONS]
.. program:: groupAddServer
.. option:: --group GROUP
Specify which group this machine should be added to
.. option:: --host HOST|IP|NET/CIDR
Host(s) to add access to, either a HOST which will be resolved to an IP immediately,
or an IP, or a whole network using the NET/CIDR notation
--user USER|PATTERN|* Specify which remote user should be allowed to connect as.
Globbing characters '*' and '?' are supported, so you can specify a pattern
that will be matched against the actual remote user name.
To allow any user, use '--user *' (you might need to escape '*' from your shell)
--port PORT|* Remote port allowed to connect to
To allow any port, use '--port *' (you might need to escape '*' from your shell)
.. option:: --protocol PROTO
Specify that a special protocol should be allowed for this HOST:PORT tuple, note that you
must not specify --user in that case. However, for this protocol to be usable under a given
remote user, access to the USER@HOST:PORT tuple must also be allowed.
PROTO must be one of:
scpup allow SCP upload, you--bastion-->server
scpdown allow SCP download, you<--bastion--server
sftp allow usage of the SFTP subsystem, through the bastion
rsync allow usage of rsync, through the bastion
.. option:: --force
Don't try the ssh connection, just add the host to the group blindly
.. option:: --force-key FINGERPRINT
Only use the key with the specified fingerprint to connect to the server (cf groupInfo)
.. option:: --force-password HASH
Only use the password with the specified hash to connect to the server (cf groupListPasswords)
.. option:: --ttl SECONDS|DURATION
Specify a number of seconds (or a duration string, such as "1d7h8m") after which the access will automatically expire
.. option:: --comment "'ANY TEXT'"
Add a comment alongside this server. Quote it twice as shown if you're under a shell.
Examples::
--osh groupAddServer --group grp1 --host 203.0.113.0/24 --user '*' --port '*' --force --ttl 1d12h --comment '"a whole network"'
--osh groupAddServer --group grp2 --host srv1.example.org --user data --port 22
--osh groupAddServer --group grp2 --host srv1.example.org --user file --port 22
Example to allow using sftp to srv1.example.org using remote user 'data' or 'file', in addition to the above commands::
--osh groupAddServer --group grp2 --host srv1.example.org --port 22 --protocol sftp

View file

@ -0,0 +1,50 @@
===============
groupDelServer
===============
Remove an IP or IP block from a group's server list
===================================================
.. admonition:: usage
:class: cmdusage
--osh groupDelServer --group GROUP --host HOST --user USER --port PORT [OPTIONS]
.. program:: groupDelServer
.. option:: --group GROUP
Specify which group this machine should be removed from
.. option:: --host HOST|IP|NET/CIDR
Host(s) to remove access from, either a HOST which will be resolved to an IP immediately,
or an IP, or a whole network using the NET/CIDR notation
--user USER|PATTERN|* Specify which remote user was allowed to connect as.
Globbing characters '*' and '?' are supported, so you can specify a pattern
that will be matched against the actual remote user name.
If any user was allowed, use '--user *' (you might need to escape '*' from your shell)
--port PORT|* Remote port that was allowed to connect to
If any port was allowed, use '--port *' (you might need to escape '*' from your shell)
.. option:: --protocol PROTO
Specify that a special protocol allowance should be removed from this HOST:PORT tuple, note that you
must not specify --user in that case.
PROTO must be one of:
scpup allow SCP upload, you--bastion-->server
scpdown allow SCP download, you<--bastion--server
sftp allow usage of the SFTP subsystem, through the bastion
rsync allow usage of rsync, through the bastion
This command adds, to an existing bastion account, access to a given server, using the
egress keys of the group. The list of eligible servers for a given group is given by ``groupListServers``
If you want to add member access to an account to all the present and future servers
of the group, using the group key, please use ``groupAddMember`` instead.
If you want to add access to an account to a group server but using their personal bastion
key instead of the group key, please use ``accountAddPersonalAccess`` instead.

View file

@ -0,0 +1,41 @@
================
groupSetServers
================
Replace a group's current ACL by a new list
===========================================
.. admonition:: usage
:class: cmdusage
--osh groupSetServers --group GROUP [OPTIONS]
.. program:: groupSetServers
.. option:: --group GROUP
Specify which group to modify the ACL of
.. option:: --dry-run
Don't actually modify the ACL, just report whether the input contains errors
.. option:: --skip-errors
Don't abort on STDIN parsing errors, just skip the non-parseable lines
The list of the assets to constitute the new ACL should then be given on ``STDIN``,
respecting the following format: ``[USER@]HOST[:PORT][ COMMENT]``, with ``USER`` and ``PORT`` being optional,
and ``HOST`` being either a hostname, an IP, or an IP block in CIDR notation. The ``COMMENT`` is also optional,
and may contain spaces.
Example of valid lines to be fed through ``STDIN``::
server12.example.org
logs@server
192.0.2.21
host1.example.net:2222 host1 on secondary sshd with alternate port
root@192.0.2.0/24 production database cluster

View file

@ -0,0 +1,9 @@
========================
group-aclkeeper plugins
========================
.. toctree::
groupAddServer
groupDelServer
groupSetServers

View file

@ -0,0 +1,68 @@
====================
groupAddGuestAccess
====================
Add a specific group server access to an account
================================================
.. admonition:: usage
:class: cmdusage
--osh groupAddGuestAccess --group GROUP --account ACCOUNT [OPTIONS]
.. program:: groupAddGuestAccess
.. option:: --account ACCOUNT
Name of the other bastion account to add access to, they'll be given access to the GROUP key
.. option:: --group GROUP
Group to add the guest access to, note that this group should already have access
to the USER/HOST/PORT tuple you'll specify with the options below.
.. option:: --host HOST|IP|NET/CIDR
Host(s) to add access to, either a HOST which will be resolved to an IP immediately,
or an IP, or a whole network using the NET/CIDR notation
--user USER|PATTERN|* Specify which remote user should be allowed to connect as.
Globbing characters '*' and '?' are supported, so you can specify a pattern
that will be matched against the actual remote user name.
To allow any user, use '--user *' (you might need to escape '*' from your shell)
--port PORT|* Remote port allowed to connect to
To allow any port, use '--port *' (you might need to escape '*' from your shell)
.. option:: --protocol PROTO
Specify that a special protocol should be allowed for this HOST:PORT tuple, note that you
must not specify --user in that case. However, for this protocol to be usable under a given
remote user, access to the USER@HOST:PORT tuple must also be allowed.
PROTO must be one of:
scpup allow SCP upload, you--bastion-->server
scpdown allow SCP download, you<--bastion--server
sftp allow usage of the SFTP subsystem, through the bastion
rsync allow usage of rsync, through the bastion
.. option:: --ttl SECONDS|DURATION
Specify a number of seconds after which the access will automatically expire
.. option:: --comment '"ANY TEXT"'
Add a comment alongside this access. Quote it twice as shown if you're under a shell.
If omitted, we'll use the closest preexisting group access' comment as seen in groupListServers
This command adds, to an existing bastion account, access to the egress keys of a group,
but only to accessing one or several given servers, instead of all the servers of this group.
If you want to add complete access to an account to all the present and future servers
of the group, using the group key, please use ``groupAddMember`` instead.
If you want to add access to an account to a group server but using his personal bastion
key instead of the group key, please use ``accountAddPersonalAccess`` instead (his public key
must be on the remote server).
This command is the opposite of ``groupDelGuestAccess``.

View file

@ -0,0 +1,29 @@
===============
groupAddMember
===============
Add an account to the member list
=================================
.. admonition:: usage
:class: cmdusage
--osh groupAddMember --group GROUP --account ACCOUNT
.. program:: groupAddMember
.. option:: --group GROUP
which group to set ACCOUNT as a member of
.. option:: --account ACCOUNT
which account to set as a member of GROUP
The specified account will be able to access all present and future servers
pertaining to this group.
If you need to give a specific and/or temporary access instead,
see ``groupAddGuestAccess``

View file

@ -0,0 +1,57 @@
====================
groupDelGuestAccess
====================
Remove a specific group server access from an account
=====================================================
.. admonition:: usage
:class: cmdusage
--osh groupDelGuestAccess --group GROUP --account ACCOUNT [OPTIONS]
.. program:: groupDelGuestAccess
.. option:: --account ACCOUNT
Bastion account remove the guest access from
.. option:: --group GROUP
Specify which group to remove the guest access to ACCOUNT from
.. option:: --host HOST|IP|NET/CIDR
Host(s) to remove access from, either a HOST which will be resolved to an IP immediately,
or an IP, or a whole network using the NET/CIDR notation
--user USER|PATTERN|* Specify which remote user was allowed to connect as.
Globbing characters '*' and '?' are supported, so you can specify a pattern
that will be matched against the actual remote user name.
If any user was allowed, use '--user *' (you might need to escape '*' from your shell)
--port PORT|* Remote port that was allowed to connect to
If any user was allowed, use '--port *' (you might need to escape '*' from your shell)
.. option:: --protocol PROTO
Specify that a special protocol was allowed for this HOST:PORT tuple, note that you
must not specify --user in that case. However, for this protocol to be usable under a given
remote user, access to the USER@HOST:PORT tuple must also be allowed.
PROTO must be one of:
scpup allow SCP upload, you--bastion-->server
scpdown allow SCP download, you<--bastion--server
sftp allow usage of the SFTP subsystem, through the bastion
rsync allow usage of rsync, through the bastion
This command removes, from an existing bastion account, access to a given server, using the
egress keys of the group. The list of such servers is given by ``groupListGuestAccesses``
If you want to remove member access from an account to all the present and future servers
of the group, using the group key, please use ``groupDelMember`` instead.
If you want to remove access from an account from a group server but using their personal bastion
key instead of the group key, please use ``accountDelPersonalAccess`` instead.
This command is the opposite of ``groupAddGuestAccess``.

View file

@ -0,0 +1,29 @@
===============
groupDelMember
===============
Remove an account from the members list
=======================================
.. admonition:: usage
:class: cmdusage
--osh groupDelMember --group GROUP --account ACCOUNT
.. program:: groupDelMember
.. option:: --group GROUP
which group to remove ACCOUNT as a member of
.. option:: --account ACCOUNT
which account to remove as a member of GROUP
The specified account will no longer be able to access all present and future servers
pertaining to this group.
Note that if this account also had specific guest accesses to this group, they may
still apply, see ``groupListGuestAccesses``

View file

@ -0,0 +1,43 @@
=======================
groupListGuestAccesses
=======================
List the guest accesses to servers of a group specifically granted to an account
================================================================================
.. admonition:: usage
:class: cmdusage
--osh groupListGuestAccesses --group GROUP --account ACCOUNT
.. program:: groupListGuestAccesses
.. option:: --group GROUP
Look for accesses to servers of this GROUP
.. option:: --account ACCOUNT
Which account to check
.. option:: --reverse-dns
Attempt to resolve the reverse hostnames (SLOW!)
.. option:: --include PATTERN
Only include servers matching the given PATTERN (see below)
This option can be used multiple times to refine results
.. option:: --exclude PATTERN
Omit servers matching the given PATTERN (see below)
This option can be used multiple times.
Note that --exclude takes precedence over --include
**Note:** PATTERN supports the ``*`` and ``?`` wildcards.
If PATTERN is a simple string without wildcards, then names containing this string will be considered.
The matching is done on the text output of the command.

View file

@ -0,0 +1,11 @@
=========================
group-gatekeeper plugins
=========================
.. toctree::
groupAddGuestAccess
groupAddMember
groupDelGuestAccess
groupDelMember
groupListGuestAccesses

View file

@ -0,0 +1,26 @@
==================
groupAddAclkeeper
==================
Add the group aclkeeper role to an account
==========================================
.. admonition:: usage
:class: cmdusage
--osh groupAddAclkeeper --group GROUP --account ACCOUNT
.. program:: groupAddAclkeeper
.. option:: --group GROUP
which group to set ACCOUNT as an aclkeeper of
.. option:: --account ACCOUNT
which account to set as an aclkeeper of GROUP
The specified account will be able to manage the server list of this group

View file

@ -0,0 +1,27 @@
===================
groupAddGatekeeper
===================
Add the group gatekeeper role to an account
===========================================
.. admonition:: usage
:class: cmdusage
--osh groupAddGatekeeper --group GROUP --account ACCOUNT
.. program:: groupAddGatekeeper
.. option:: --group GROUP
which group to set ACCOUNT as a gatekeeper of
.. option:: --account ACCOUNT
which account to set as a gatekeeper of GROUP
The specified account will be able to manage the members list of this group,
along with the guests list

View file

@ -0,0 +1,29 @@
==============
groupAddOwner
==============
Add the group owner role to an account
======================================
.. admonition:: usage
:class: cmdusage
--osh groupAddOwner --group GROUP --account ACCOUNT
.. program:: groupAddOwner
.. option:: --group GROUP
which group to set ACCOUNT as an owner of
.. option:: --account ACCOUNT
which account to set as an owner of GROUP
The specified account will be able to manage the owner, gatekeeper
and aclkeeper list of this group. In other words, this account will
have all possible rights to manage the group and delegate some or all
of the rights to other accounts

View file

@ -0,0 +1,26 @@
==================
groupDelAclkeeper
==================
Remove the group aclkeeper role from an account
===============================================
.. admonition:: usage
:class: cmdusage
--osh groupDelAclkeeper --group GROUP --account ACCOUNT
.. program:: groupDelAclkeeper
.. option:: --group GROUP
which group to remove ACCOUNT as an aclkeeper of
.. option:: --account ACCOUNT
which account to remove as an aclkeeper of GROUP
The specified account will no longer be able to manage the server list of this group

View file

@ -0,0 +1,24 @@
==================
groupDelEgressKey
==================
Remove a bastion group egress key
=================================
.. admonition:: usage
:class: cmdusage
--osh groupDelEgressKey <--group GROUP> <--id ID>
.. program:: groupDelEgressKey
.. option:: --group GROUP
Name of the group to delete the egress key from
.. option:: --id ID
Specify the key ID to delete, you can get it with groupInfo

View file

@ -0,0 +1,27 @@
===================
groupDelGatekeeper
===================
Remove the group gatekeeper role from an account
================================================
.. admonition:: usage
:class: cmdusage
--osh groupDelGatekeeper --group GROUP --account ACCOUNT
.. program:: groupDelGatekeeper
.. option:: --group GROUP
which group to remove ACCOUNT as a gatekeeper of
.. option:: --account ACCOUNT
which account to remove as a gatekeeper of GROUP
The specified account will no longer be able to manager the members nor
the guest list of this group

View file

@ -0,0 +1,27 @@
==============
groupDelOwner
==============
Remove the group owner role from an account
===========================================
.. admonition:: usage
:class: cmdusage
--osh groupDelOwner --group GROUP --account ACCOUNT
.. program:: groupDelOwner
.. option:: --group GROUP
which group to set ACCOUNT as an owner of
.. option:: --account ACCOUNT
which account to set as an owner of GROUP
The specified account will no longer be able to manage the owner,
gatekeeper and aclkeeper lists of this group

View file

@ -0,0 +1,27 @@
=============
groupDestroy
=============
Delete a group
==============
.. admonition:: usage
:class: cmdusage
--osh groupDestroy --group GROUP
.. program:: groupDestroy
.. option:: --group GROUP
Group name to delete
.. option:: --no-confirm
Skip group name confirmation, but blame yourself if you deleted the wrong group!
This command is able to delete any group you're an owner of.
Granted users to the sibling restricted command `groupDelete` can delete any group.

View file

@ -0,0 +1,50 @@
=======================
groupGenerateEgressKey
=======================
Create a new public + private key pair for a group
==================================================
.. admonition:: usage
:class: cmdusage
--osh groupGenerateEgressKey --group GROUP --algo ALGO --size SIZE [--encrypted]
.. program:: groupGenerateEgressKey
.. option:: --group GROUP
Group name to generate a new egress key for.
.. option:: --algo ALGO
Specifies the algo of the key, either rsa, ecdsa or ed25519.
.. option:: --size SIZE
Specifies the size of the key to be generated.
For RSA, choose between 2048 and 8192 (4096 is good).
For ECDSA, choose either 256, 384 or 521.
For Ed25519, size is always 256.
.. option:: --encrypted
If specified, a passphrase will be prompted for the new key
A quick overview of the different algorithms:
.. code-block:: none
Ed25519 : robustness[###] speed[###]
ECDSA : robustness[##.] speed[###]
RSA : robustness[#..] speed[#..]
This table is meant as a quick cheat-sheet, you're warmly advised to do
your own research, as other constraints may apply to your environment.

View file

@ -0,0 +1,40 @@
======================
groupGeneratePassword
======================
Generate a new egress password for the group
============================================
.. admonition:: usage
:class: cmdusage
--osh groupGeneratePassword --group GROUP [--size SIZE] --do-it
.. program:: groupGeneratePassword
.. option:: --group GROUP
Specify which group you want to generate a password for
.. option:: --size SIZE
Specify the number of characters of the password to generate
.. option:: --do-it
Required for the password to actually be generated, BEWARE: please read the note below
Generate a new egress password to be used for ssh or telnet
NOTE: this is only needed for devices that don't support key-based SSH,
in most cases you should ignore this command completely, unless you
know that devices you need to access only support telnet or password-based SSH.
BEWARE: once a new password is generated this way, it'll be set as the new
egress password to use right away for the group, for any access that requires it.
A fallback mechanism exists that will auto-try the previous password if this one
doesn't work, but please ensure that this new password is deployed on the remote
devices as soon as possible.

View file

@ -0,0 +1,41 @@
============
groupModify
============
Modify the configuration of a group
===================================
.. admonition:: usage
:class: cmdusage
--osh groupModify --group GROUP [--mfa-required password|totp|any|none] [--guest-ttl-limit DURATION]
.. program:: groupModify
.. option:: --group GROUP
Name of the group to modify
.. option:: --mfa-required password|totp|any|none
Enforce UNIX password requirement, or TOTP requirement, or any MFA requirement, when connecting to a server of the group
--idle-lock-timeout DURATION|0|-1 Overrides the global setting (`idleLockTimeout`), to the specified duration. If set to 0, disables `idleLockTimeout` for
this group. If set to -1, remove this group override and use the global setting instead.
--idle-kill-timeout DURATION|0|-1 Overrides the global setting (`idleKillTimeout`), to the specified duration. If set to 0, disables `idleKillTimeout` for
this group. If set to -1, remove this group override and use the global setting instead.
.. option:: --guest-ttl-limit DURATION
This group will enforce TTL setting, on guest access creation, to be set, and not to a higher value than DURATION,
set to zero to allow guest accesses creation without any TTL set (default)
Note that `--idle-lock-timeout` and `--idle-kill-timeout` will NOT be applied for catch-all groups (having 0.0.0.0/0 in their server list).
If a server is in exactly one group an account is a member of, then its values of `--idle-lock-timeout` and `--idle-kill-timeout`, if set,
will prevail over the global setting. The global setting can be seen with `--osh info`.
Otherwise, the most restrictive setting (i.e. the one with the lower strictly positive duration) between
all the considered groups and the global setting, will be used.

View file

@ -0,0 +1,27 @@
=======================
groupTransmitOwnership
=======================
Transmit your group ownership to somebody else
==============================================
.. admonition:: usage
:class: cmdusage
--osh groupTransmitOwnership --group GROUP --account ACCOUNT
.. program:: groupTransmitOwnership
.. option:: --group GROUP
which group to set ACCOUNT as an owner of
.. option:: --account ACCOUNT
which account to set as an owner of GROUP
Note that this command has the same net effect than using ``groupAddOwner``
to add ACCOUNT as an owner, then removing yourself with ``groupDelOwner``

View file

@ -0,0 +1,18 @@
====================
group-owner plugins
====================
.. toctree::
groupAddAclkeeper
groupAddGatekeeper
groupAddOwner
groupDelAclkeeper
groupDelEgressKey
groupDelGatekeeper
groupDelOwner
groupDestroy
groupGenerateEgressKey
groupGeneratePassword
groupModify
groupTransmitOwnership

View file

@ -0,0 +1,23 @@
======
alive
======
Ping a host and exit as soon as it answers
==========================================
This command can be used to monitor a host that is expected to go back online soon.
Note that if you want to ssh to it afterwards, you can simply use the ``--wait`` main option.
.. admonition:: usage
:class: cmdusage
--osh alive [--host] HOSTNAME
.. program:: alive
.. option:: --host HOSTNAME
hostname or IP to ping

View file

@ -0,0 +1,37 @@
======
batch
======
Run a batch of osh commands fed through STDIN
=============================================
.. admonition:: usage
:class: cmdusage
--osh batch
.. program:: batch
**Examples:**
(replace ``bssh`` by your bastion alias)
- run 3 simple commands in a oneliner:
::
printf "%b\n%b\n%b" info selfListIngressKeys selfListEgressKeys | bssh --osh batch
- run a lot of commands written out line by line in a file:
::
bssh --osh batch < cmdlist.txt
- add 3 users to a group:
::
for i in user1 user2 user3; do echo "groupAddMember --account $i --group grp4"; done | bssh --osh batch

View file

@ -0,0 +1,44 @@
======
clush
======
Launch a remote command on several machines sequentially (clush-like)
=====================================================================
.. admonition:: usage
:class: cmdusage
--osh clush [OPTIONS] --command '"remote command"'
.. program:: clush
.. option:: --list HOSTLIST
Comma-separated list of the hosts (hostname or IP) to run the command on
.. option:: --user USER
Specify which remote user should we use to connect (default: BASTION_ACCOUNT)
.. option:: --port PORT
Specify which port to connect to (default: 22)
.. option:: --step-by-step
Pause before running the command on each host
.. option:: --no-pause-on-failure
Don't pause if the remote command failed (returned exit code != 0)
.. option:: --no-confirm
Skip confirmation of the host list and command
.. option:: --command '"remote cmd"'
Command to be run on the remote hosts. If you're in a shell, quote it twice as shown.

View file

@ -0,0 +1,70 @@
==========
groupInfo
==========
Print some basic information about a group
==========================================
.. admonition:: usage
:class: cmdusage
--osh groupInfo <--group GROUP|--all> [OPTIONS]
.. program:: groupInfo
.. option:: --group GROUP
Specify the group to display the info of
.. option:: --all
Dump info for all groups (auditors only), use with ``--json``
.. option:: --with[out]-everything
Include or exclude all below options, including future ones
.. option:: --with[out]-keys
Whether to include the group keys list (slow-ish, default: yes)
Usage examples
==============
Show info about a specific group::
--osh groupInfo --group mygroup2
Gather info about all groups, with no extra data except their keys::
--osh groupInfo --all --without-everything --with-keys --json
Gather info about all groups, including all extra data (and possibly future options)::
--osh groupInfo --all --with-everything --json
Output example
==============
.. code-block: none
| Group mygroup's Owners are: user1
| Group mygroup's GateKeepers (managing the members/guests list) are: user2
| Group mygroup's ACLKeepers (managing the group servers list) are: user3
| Group mygroup's Members (with access to ALL the group servers) are: user4
| Group mygroup's Guests (with access to SOME of the group servers) are: user5
|
| The public key of this group is:
|
| fingerprint: SHA256:r/PQS4wLdSWqjYsDca8ReKjhq0l9EX+zQgiUR5qKdlc (ED25519-256) [2018/04/16]
| keyline follows, please copy the *whole* line:
from="203.0.113.4/32,192.0.2.0/26" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILdD60bA3NgaOpRLgcACWfKcAMRQQRyFMppwp5GpHLTB mygroup@testbastion:1523886640
The first paragraph of the output lists the different roles along with the people having these roles.
You can also see the public egress key of this group, i.e. the key that needs to be added to the remote servers' ``authorized_keys`` files, so that ``members`` of this group can access these servers.
Note that if you want to see the list of servers pertaining to this group, you can use the command ``groupListServers``.

View file

@ -0,0 +1,34 @@
==========
groupList
==========
List the groups available on this bastion
=========================================
.. admonition:: usage
:class: cmdusage
--osh groupList [--all] [--exclude|--include PATTERN [--exclude|--include PATTERN ..]]
.. program:: groupList
.. option:: --all
List all groups, even those to which you don't have access
.. option:: --include PATTERN
Only list groups that match the given PATTERN (see below)
This option can be used multiple times to refine results
.. option:: --exclude PATTERN
Omit groups that match the given PATTERN string (see below)
This option can be used multiple times.
Note that --exclude takes precedence over --include
**Note:** PATTERN supports the ``*`` and ``?`` wildcards.
If PATTERN is a simple string without wildcards, then names containing this string will be considered.

View file

@ -0,0 +1,22 @@
===================
groupListPasswords
===================
List the hashes and metadata of egress passwords of a group
===========================================================
.. admonition:: usage
:class: cmdusage
--osh groupListPasswords --group GROUP
.. program:: groupListPasswords
.. option:: --group GROUP
Show the data for this group
The passwords corresponding to these hashes are only needed for devices that don't support key-based SSH

View file

@ -0,0 +1,39 @@
=================
groupListServers
=================
List the servers (IPs and IP blocks) pertaining to a group
==========================================================
.. admonition:: usage
:class: cmdusage
--osh groupListServers --group GROUP [--reverse-dns]
.. program:: groupListServers
.. option:: --group GROUP
List the servers of this group
.. option:: --reverse-dns
Attempt to resolve the reverse hostnames (SLOW!)
.. option:: --include PATTERN
Only include servers matching the given PATTERN (see below)
This option can be used multiple times to refine results
.. option:: --exclude PATTERN
Omit servers matching the given PATTERN (see below)
This option can be used multiple times.
Note that --exclude takes precedence over --include
**Note:** PATTERN supports the ``*`` and ``?`` wildcards.
If PATTERN is a simple string without wildcards, then names containing this string will be considered.
The matching is done on the text output of the command.

View file

@ -0,0 +1,31 @@
=====
help
=====
I'm So Meta, Even This Acronym
==============================
.. admonition:: usage
:class: cmdusage
--osh help
.. program:: help
Displays help about the available plugins callable with ``--osh``.
If you need help on a specific plugin, you can use ``--osh PLUGIN --help``, replacing ``PLUGIN`` with the actual plugin name.
Note that if you want some help about the bastion (and not specifically about the plugins), you should use ``--help`` (without ``--osh``).
Colors
======
You'll notice that plugins are highlighted in different colors, these indicate the access level needed to run the plugin. Note that plugins you don't have access to are simply omitted.
- green (``open``): these plugins can be called by anybody
- blue (``restricted``): these plugins can only be called by users having the specific right to call them. This right is granted per plugin by the ``accountGrantCommand`` plugin
- orange (``group-gatekeeper`` and ``group-aclkeeper``): these plugins can either be called by group gatekeepers or group aclkeepers. For clarity, the same color has been used for both cases
- purple (``group-owner``): these plugins can only be called by group owners
- red (``admin``): these plugins can only be called by bastion admins

View file

@ -0,0 +1,39 @@
=============
open plugins
=============
.. toctree::
alive
batch
clush
groupInfo
groupList
groupListPasswords
groupListServers
help
info
lock
mtr
nc
ping
rsync
scp
selfAddIngressKey
selfDelIngressKey
selfForgetHostKey
selfGenerateEgressKey
selfGeneratePassword
selfGenerateProxyPassword
selfListAccesses
selfListEgressKeys
selfListIngressKeys
selfListPasswords
selfListSessions
selfMFAResetPassword
selfMFAResetTOTP
selfMFASetupPassword
selfMFASetupTOTP
selfPlaySession
sftp
unlock

View file

@ -0,0 +1,86 @@
=====
info
=====
Displays some information about this bastion instance
=====================================================
.. admonition:: usage
:class: cmdusage
--osh info
.. program:: info
Output example
==============
::
~ You are user1
~
~ Your alias to connect to this bastion is:
~ alias bastion='ssh user1@testbastion.example.org -p 22 -t -- '
~ Your alias to connect to this bastion with MOSH is:
~ alias bastionm='mosh --ssh="ssh -p 22 -t" user1@testbastion.example.org -- '
~
~ Multi-Factor Authentication (MFA) on your account:
~ - Additional password authentication is not required
~ - Additional password authentication bypass is disabled
~ - Additional password authentication is enabled and active
~ - Additional TOTP authentication is not required
~ - Additional TOTP authentication bypass is disabled
~ - Additional TOTP authentication is disabled
~
~ I am testbastion-a.example.org, aka bastion
~ I have 42 registered accounts and 46 groups
~ I am a MASTER, which means I accept modifications
~ The networks I'm able to connect you to on the egress side are: all
~ The networks that are explicitly forbidden on the egress side are: none
~ My egress connection IP to remote servers is 192.0.2.45/32
~ ...don't forget to whitelist me in your firewalls!
~
~ The following policy applies on this bastion:
~ - The interactive mode (-i) is ENABLED
~ - The support of mosh is ENABLED
~ - Account expiration is DISABLED
~ - Keyboard input idle time for session locking is DISABLED
~ - Keyboard input idle time for session killing is DISABLED
~ - The forced "from" prepend on ingress keys is DISABLED
~ - The following algorithms are allowed for ingress SSH keys: rsa, ecdsa, ed25519
~ - The RSA key size for ingress SSH keys must be between 2048 and 8192 bits
~ - The following algorithms are allowed for egress SSH keys: rsa, ecdsa, ed25519
~ - The RSA key size for egress SSH keys must be between 2048 and 8192 bits
~ - The Multi-Factor Authentication (MFA) policy is ENABLED
~
~ Here is your excuse for anything not working today:
~ BOFH excuse #444:
~ overflow error in /dev/null
Plugin configuration
====================
Options
-------
.. option:: admin_show_system_info (optional, boolean)
If enabled, bastion admins get more output regarding information of the
underlying OS. When omitted, this is enabled by default.
.. option:: show_fortune (optional, boolean)
If enabled, and if the ``fortune`` package is installed on your OS,
shows a fortune. When omitted, this is enabled by default.
Example
-------
Configuration, in JSON format, must be in :file:`/etc/bastion/plugin.info.conf`:
.. code-block:: json
:emphasize-lines: 1
{ "admin_show_system_info": false, "show_fortune": false }

View file

@ -0,0 +1,18 @@
=====
lock
=====
Manually lock all your current sessions
=======================================
.. admonition:: usage
:class: cmdusage
--osh lock
.. program:: lock
This command will lock all your current sessions on this bastion instance. Note that this only applies to the bastion instance you're launching this command on, not on the whole bastion cluster (if you happen to have one).
To undo this action, you can use ``--osh unlock`` on the same instance.

View file

@ -0,0 +1,20 @@
====
mtr
====
Runs the mtr tool to traceroute a host
======================================
.. admonition:: usage
:class: cmdusage
--osh mtr [--host] HOST [--report]
.. program:: mtr
.. option:: --report
Don't run mtr interactively, output a text report once done

View file

@ -0,0 +1,29 @@
===
nc
===
Check whether a remote TCP port is open
=======================================
.. admonition:: usage
:class: cmdusage
--osh nc [--host] HOST [--port] PORT [-w TIMEOUT]
.. program:: nc
.. option:: --host HOST
Host or IP to attempt to connect to
.. option:: --port PORT
TCP port to attempt to connect to
.. option:: -w SECONDS
Timeout in seconds (default: 3)
Note that this is not a full-featured ``netcat``, we just test whether a remote port is open. There is no way to exchange data using this command.

View file

@ -0,0 +1,36 @@
=====
ping
=====
Ping a remote host from the bastion
===================================
.. admonition:: usage
:class: cmdusage
--osh ping [--host HOST] [-c COUNT] [-s PKTSZ] [-t TTL] [-w TIMEOUT]
.. program:: ping
.. option:: --host HOST
Remote host to ping
.. option:: -c COUNT
Number of pings to send (default: infinite)
.. option:: -s SIZE
Specify the packet size to send
.. option:: -t TTL
TTL to set in the ICMP packet (default: OS dependent)
.. option:: -w TIMEOUT
Exit unconditionally after this amount of seconds (default & max: 86400)

View file

@ -0,0 +1,35 @@
======
rsync
======
Transfer files from/to remote servers using rsync through the bastion
=====================================================================
.. note::
This plugin should not be called manually, but passed as the --rsh option to rsync.
Usage examples
--------------
To transfer all files from ``/srcdir`` to the ``remotehost``'s ``/dest/`` directory:
.. code-block: none
rsync -va --rsh "ssh -T BASTION_USER@BASTION_HOST -p BASTION_PORT -- --osh rsync --" /srcdir remoteuser@remotehost:/dest/
The ``-va`` options are just examples, you can use any option of ``rsync`` that you see fit.
To transfer all remote files from ``/srcdir`` to the local ``/dest`` directory:
.. code-block: none
rsync -va --rsh "ssh -T BASTION_USER@BASTION_HOST -p BASTION_PORT -- --osh rsync --" remoteuser@remotehost:/srcdir /dest/
Please note that you need to be granted for uploading or downloading files
with ``rsync`` to/from the remote host, in addition to having the right to SSH to it.
For a group, the right should be added with ``--protocol rsync`` of the :doc:`/plugins/group-aclkeeper/groupAddServer` command.
For a personal access, the right should be added with ``--protocol rsync`` of the :doc:`/plugins/restricted/selfAddPersonalAccess` command.
:doc:`/plugins/open/selfListEgressKeys`
You'll find more information and examples in :doc:`/using/sftp_scp_rsync`.

View file

@ -0,0 +1,32 @@
====
scp
====
Transfer files from/to remote servers using scp through the bastion
===================================================================
.. note::
This plugin generates a valid helper script for you to use the bastion over scp, read below to learn how to use it.
To be able to use ``scp`` over the bastion, you need to have a helper script that is specific
to your account on the bastion. This plugin's job is to generate it for you.
You can simply run it, and follow the guidelines.
Once this is done, you'll be able to ``scp`` through the bastion by adding ``-S SCP_SCRIPT`` to your
regular ``scp`` command, where ``SCP_SCRIPT`` is the location of the script you've just generated.
For example, to upload a file::
scp -S ~/scp_bastion localfile login@server:/dest/folder/
Or to recursively download a folder contents::
scp -S ~/scp_bastion -r login@server:/src/folder/ /tmp/
Please note that you need to be granted for uploading or downloading files
with scp to/from the remote host, in addition to having the right to SSH to it.
For a group, the right should be added with ``--scpup``/``--scpdown`` of the :doc:`/plugins/group-aclkeeper/groupAddServer` command.
For a personal access, the right should be added with ``--scpup``/``--scpdown`` of the :doc:`/plugins/restricted/selfAddPersonalAccess` command.
You'll find more information and examples in :doc:`/using/sftp_scp_rsync`.

View file

@ -0,0 +1,30 @@
==================
selfAddIngressKey
==================
Add a new ingress public key to your account
============================================
.. admonition:: usage
:class: cmdusage
--osh selfAddIngressKey [--public-key '"ssh key text"'] [--piv]
.. program:: selfAddIngressKey
.. option:: --public-key KEY
Your new ingress public SSH key to deposit on the bastion, use double-quoting if your're under a shell.
If this option is not specified, you'll be prompted interactively for your public SSH key. Note that you
can also pass it through STDIN directly. If the policy of this bastion allows it, you may prefix the key
with a 'from="IP1,IP2,..."' snippet, a la authorized_keys. However the policy might force a configured
'from' prefix that will override yours, or be used if you don't specify it yourself.
.. option:: --piv
Add a public SSH key from a PIV-compatible hardware token, along with its attestation certificate and key
certificate, both in PEM format. If you specified --public-key, then the attestation and key certificate are
expected on STDIN only, otherwise the public SSH key, the attestation and key certificate are expected on STDIN.

View file

@ -0,0 +1,26 @@
==================
selfDelIngressKey
==================
Remove an ingress public key from your account
==============================================
.. admonition:: usage
:class: cmdusage
--osh selfDelIngressKey [--id-to-delete|-l ID] [--fingerprint-to-delete|-f FP]
.. program:: selfDelIngressKey
.. option:: -l, --id-to-delete ID
Directly specify key id to delete (CAUTION!), you can get id with selfListIngressKeys
.. option:: -f, --fingerprint-to-delete FP
Directly specify the fingerprint of the key to delete (CAUTION!)
If none of these options are specified, you'll be prompted interactively.

View file

@ -0,0 +1,28 @@
==================
selfForgetHostKey
==================
Forget a known host key from your bastion account
=================================================
.. admonition:: usage
:class: cmdusage
--osh selfForgetHostKey [--host HOST] [--port PORT]
.. program:: selfForgetHostKey
.. option:: --host HOST
Host to remove from the known_hosts file
.. option:: --port PORT
Port to look for in the known_hosts file (default: 22)
This command is useful to remove the man-in-the-middle warning when a key has changed,
however please verify that the host key change is legit before using this command.
The warning SSH gives is there for a reason.

View file

@ -0,0 +1,45 @@
======================
selfGenerateEgressKey
======================
Create a new public + private key pair on your bastion account
==============================================================
.. admonition:: usage
:class: cmdusage
--osh selfGenerateEgressKey --algo ALGO --size SIZE [--encrypted]
.. program:: selfGenerateEgressKey
.. option:: --algo ALGO
Specifies the algo of the key, either rsa, ecdsa or ed25519.
.. option:: --size SIZE
Specifies the size of the key to be generated.
For RSA, choose between 2048 and 8192 (4096 is good).
For ECDSA, choose either 256, 384 or 521.
For ED25519, size is always 256.
.. option:: --encrypted
if specified, a passphrase will be prompted for the new key
A quick overview of the different algorithms:
.. code-block:: none
Ed25519 : robustness[###] speed[###]
ECDSA : robustness[##.] speed[###]
RSA : robustness[#..] speed[#..]
This table is meant as a quick cheat-sheet, you're warmly advised to do
your own research, as other constraints may apply to your environment.

View file

@ -0,0 +1,36 @@
=====================
selfGeneratePassword
=====================
Generate a new egress password for your account
===============================================
.. admonition:: usage
:class: cmdusage
--osh selfGeneratePassword [--size SIZE] --do-it
.. program:: selfGeneratePassword
.. option:: --size SIZE
Specify the number of characters of the password to generate
.. option:: --do-it
Required for the password to actually be generated, BEWARE: please read the note below
This plugin generates a new egress password to be used for ssh or telnet
NOTE: this is only needed for devices that don't support key-based SSH,
in most cases you should ignore this command completely, unless you
know that devices you need to access only support telnet or password-based SSH.
BEWARE: once a new password is generated this way, it'll be set as the new
egress password to use right away for your account, for any access that requires it.
A fallback mechanism exists that will auto-try the previous password if this one
doesn't work, but please ensure that this new password is deployed on the remote
devices as soon as possible.

View file

@ -0,0 +1,29 @@
==========================
selfGenerateProxyPassword
==========================
Generate a new ingress password to use the bastion HTTPS proxy
==============================================================
.. admonition:: usage
:class: cmdusage
--osh selfGenerateProxyPassword --do-it
.. program:: selfGenerateProxyPassword
.. option:: --do-it
Required for the password to actually be generated, BEWARE: please read the note below
This plugin generates a new ingress password to use the bastion HTTPS proxy.
NOTE: this is only needed for devices that only support HTTPS API and not ssh,
in most cases you should ignore this command completely, unless you
know that devices you need to access are using an HTTPS API.
BEWARE: once a new password is generated this way, it'll be set as the new
HTTPS proxy ingress password to use right away for your account.

View file

@ -0,0 +1,40 @@
=================
selfListAccesses
=================
Show the list of servers you have access to
===========================================
.. admonition:: usage
:class: cmdusage
--osh selfListAccesses [--hide-groups] [--reverse-dns]
.. program:: selfListAccesses
.. option:: --hide-groups
Don't show the machines you have access to through group rights.
In other words, list only your personal accesses.
.. option:: --reverse-dns
Attempt to resolve the reverse hostnames (SLOW!)
.. option:: --include PATTERN
Only include accesses matching the given PATTERN (see below)
This option can be used multiple times to refine results
.. option:: --exclude PATTERN
Omit accesses matching the given PATTERN (see below)
This option can be used multiple times.
Note that --exclude takes precedence over --include
**Note:** PATTERN supports the ``*`` and ``?`` wildcards.
If PATTERN is a simple string without wildcards, then names containing this string will be considered.
The matching is done on the text output of the command.

View file

@ -0,0 +1,20 @@
===================
selfListEgressKeys
===================
List the public egress keys of your account
===========================================
.. admonition:: usage
:class: cmdusage
--osh selfListEgressKeys
.. program:: selfListEgressKeys
The keys listed are the public egress SSH keys tied to your account.
They can be used to gain access to another machine from this bastion,
by putting one of those keys in the remote machine's ``authorized_keys`` file,
and adding yourself access to this machine with ``selfAddPersonalAccess``.

View file

@ -0,0 +1,19 @@
====================
selfListIngressKeys
====================
List the public ingress keys of your account
============================================
.. admonition:: usage
:class: cmdusage
--osh selfListIngressKeys
.. program:: selfListIngressKeys
The keys listed are the public ingress SSH keys tied to your account.
Their private counterpart should be detained only by you, and used
to authenticate yourself to this bastion.

View file

@ -0,0 +1,17 @@
==================
selfListPasswords
==================
List the hashes and metadata of the egress passwords associated to your account
===============================================================================
.. admonition:: usage
:class: cmdusage
--osh selfListPasswords
.. program:: selfListPasswords
The passwords corresponding to these hashes are only needed for devices that don't support key-based SSH

View file

@ -0,0 +1,73 @@
=================
selfListSessions
=================
List the few past sessions of your account
==========================================
.. admonition:: usage
:class: cmdusage
--osh selfListSessions [OPTIONS]
.. program:: selfListSessions
.. option:: --detailed
Display more information about each session
.. option:: --limit LIMIT
Limit to LIMIT results
.. option:: --id ID
Only sessions having this ID
.. option:: --type TYPE
Only sessions of specified type (ssh, osh, ...)
.. option:: --allowed
Only sessions that have been allowed by the bastion
.. option:: --denied
Only sessions that have been denied by the bastion
.. option:: --after WHEN
Only sessions that started after WHEN,
WHEN can be a TIMESTAMP, or YYYY-MM-DD[@HH:MM:SS]
.. option:: --before WHEN
Only sessions that started before WHEN,
WHEN can be a TIMESTAMP, or YYYY-MM-DD[@HH:MM:SS]
.. option:: --host HOST
Only sessions connecting to remote HOST
.. option:: --to-port PORT
Only sessions connecting to remote PORT
.. option:: --user USER
Only sessions connecting using remote USER
.. option:: --via HOST
Only sessions that connected through bastion IP HOST
.. option:: --via-port PORT
Only sessions that connected through bastion PORT
Note that only the sessions that happened on this precise bastion instance will be shown,
not the sessions from its possible cluster siblings.

View file

@ -0,0 +1,18 @@
=====================
selfMFAResetPassword
=====================
Remove the UNIX password of your account
========================================
.. admonition:: usage
:class: cmdusage
--osh selfMFAResetPassword
.. program:: selfMFAResetPassword
Note that if your password is set, you'll be prompted for it.
Also note that this doesn't remove your UNIX password requirement, if set (see ``accountModify`` for this).

View file

@ -0,0 +1,18 @@
=================
selfMFAResetTOTP
=================
Remove the TOTP configuration of your account
=============================================
.. admonition:: usage
:class: cmdusage
--osh selfMFAResetTOTP
.. program:: selfMFAResetTOTP
Note that if your TOTP is set, you'll be prompted for it.
Also note that this doesn't remove your TOTP requirement, if set (see accountModify for this).

View file

@ -0,0 +1,20 @@
=====================
selfMFASetupPassword
=====================
Setup an additional credential (UNIX password) to access your account
=====================================================================
.. admonition:: usage
:class: cmdusage
--osh selfMFASetupPassword [--yes]
.. program:: selfMFASetupPassword
.. option:: --yes
Don't ask for confirmation

View file

@ -0,0 +1,20 @@
=================
selfMFASetupTOTP
=================
Setup an additional credential (TOTP) to access your account
============================================================
.. admonition:: usage
:class: cmdusage
--osh selfMFASetupTOTP [--no-confirm]
.. program:: selfMFASetupTOTP
.. option:: --no-confirm
Bypass the confirmation step for TOTP enrollment phase

View file

@ -0,0 +1,20 @@
================
selfPlaySession
================
Replay the ttyrec of a past session
===================================
.. admonition:: usage
:class: cmdusage
--osh selfPlaySession --id ID
.. program:: selfPlaySession
.. option:: --id ID
ID of the session to replay, use ``selfListSessions`` to find it.

View file

@ -0,0 +1,35 @@
=====
sftp
=====
Transfer files from/to remote servers using sftp through the bastion
====================================================================
.. note::
This plugin generates a valid helper script for you to use the bastion over scp, read below to learn how to use it.
To be able to use ``sftp`` over the bastion, you need to have a helper script that is specific
to your account on the bastion. This plugin's job is to generate it for you.
You can simply run it, and follow the guidelines.
Once this is done, you'll be able to ``sftp`` through the bastion by adding ``-S SFTP_SCRIPT`` to your
regular ``sftp`` command, where ``SFTP_SCRIPT`` is the location of the script you've just generated.
For example::
sftp -S ~/sftp_bastion login@server
.. note::
If you're getting the 'subsystem request failed on channel 0' error, it usually means that
sftp is not enabled on the remote server, as this is not always enabled by default, depending
on the distro you're using.
Please note that you need to be granted for uploading or downloading files
with SFTP to/from the remote host, in addition to having the right to SSH to it.
For a group, the right should be added with ``--sftp`` of the :doc:`/plugins/group-aclkeeper/groupAddServer` command.
For a personal access, the right should be added with ``--sftp`` of the :doc:`/plugins/restricted/selfAddPersonalAccess` command.
:doc:`/plugins/open/selfListEgressKeys`
You'll find more information and examples in :doc:`/using/sftp_scp_rsync`.

View file

@ -0,0 +1,20 @@
=======
unlock
=======
Unlock all your current sessions
================================
.. admonition:: usage
:class: cmdusage
--osh unlock
.. program:: unlock
This command will unlock all your current sessions on this bastion instance,
that were either locked for inactivity timeout or manually locked by you with ``lock``.
Note that this only applies to the bastion instance you're launching this
command on, not on the whole bastion cluster (if you happen to have one).

View file

@ -0,0 +1,93 @@
=========================
accountAddPersonalAccess
=========================
Add a personal server access to an account
==========================================
.. admonition:: usage
:class: cmdusage
--osh accountAddPersonalAccess --account ACCOUNT --host HOST --user USER --port PORT [OPTIONS]
.. program:: accountAddPersonalAccess
.. option:: --account
Bastion account to add the access to
.. option:: --host HOST|IP|NET/CIDR
Host(s) to add access to, either a HOST which will be resolved to an IP immediately,
or an IP, or a whole network using the NET/CIDR notation
--user USER|PATTERN|* Specify which remote user should be allowed to connect as.
Globbing characters '*' and '?' are supported, so you can specify a pattern
that will be matched against the actual remote user name.
To allow any user, use '--user *' (you might need to escape '*' from your shell)
--port PORT|* Remote port allowed to connect to
To allow any port, use '--port *' (you might need to escape '*' from your shell)
.. option:: --protocol PROTO
Specify that a special protocol should be allowed for this HOST:PORT tuple, note that you
must not specify --user in that case. However, for this protocol to be usable under a given
remote user, access to the USER@HOST:PORT tuple must also be allowed.
PROTO must be one of:
scpup allow SCP upload, you--bastion-->server
scpdown allow SCP download, you<--bastion--server
sftp allow usage of the SFTP subsystem, through the bastion
rsync allow usage of rsync, through the bastion
.. option:: --force-key FINGERPRINT
Only use the key with the specified fingerprint to connect to the server (cf accountListEgressKeys)
.. option:: --force-password HASH
Only use the password with the specified hash to connect to the server (cf accountListPasswords)
.. option:: --ttl SECONDS|DURATION
Specify a number of seconds (or a duration string, such as "1d7h8m") after which the access will automatically expire
.. option:: --comment "'ANY TEXT'"
Add a comment alongside this server. Quote it twice as shown if you're under a shell.
The access will work only if one of the account's personal egress public key has been copied to the remote server.
To get the list of an account's personal egress public keys, see ``accountListEgressKeyss`` and ``selfListEgressKeys``.
Plugin configuration
====================
Options
-------
.. option:: widest_v4_prefix (optional, integer, between 0 and 32)
When specified, this limits the size of prefixes that can be added to an
ACL, e.g. 24 would not allow prefixes wider than /24 (such as /20 or
/16).
Note that this doesn't prevent users from adding thousands of ACLs to
cover a wide range of networks, but this helps ensuring ACLs such as
0.0.0.0/0 can't be added in a single command.
.. option:: self_remote_user_only (optional, boolean)
When true, this only allows to add ACLs with the remote user being the
same than the account name, i.e. adding an access to a bastion account
named "johndoe" can only be done specifying this very account name as
the remote user name, with ``accountAddPersonalAccess --user johndoe``.
Example
-------
Configuration, in JSON format, must be in :file:`/etc/bastion/plugin.accountAddPersonalAccess.conf`:
.. code-block:: json
:emphasize-lines: 1
{ "widest_v4_prefix": 24, "self_remote_user_only": true }

Some files were not shown because too many files have changed in this diff Show more