I reviewed ceph-iscsi 3.4-0ubuntu2 as checked into focal. This shouldn't be considered a full audit but rather a quick gauge of maintainability. ceph-iscsi is a set of tools for managing LIO gateways for Ceph. It consists of 2 services providing REST APIs - one for obtaining gateway node statistics and another for providing the gateway API, restoring gateway state and keeping gateway nodes in sync. Under the hood, it uses rtslib for configuring the gateway via the LIO interfaces, and Ceph backstores are implemented in userspace (in tcmu). A command line tool is provided for managing the gateway nodes, which communicates with the gateway node's API. - No CVE history. - All build-depends in main except for: python3-configshell-fb, python3-mock, python3-pytest, python3-rtslib-fb. Only python3-configshell-fb and python3-rtslib-fb are required at runtime (this MIR). - Depends on python3-openssl (crypto), python3-requests (HTTP) and python-flask (werkzeug based web framework). - Maintainer scripts just contain some debhelper snippets from dh_python3, dh_installinit and dh_installsystemd. - Provides 2 services: - rbd-target-gw: - This is a simple flask app that provides a REST API with 2 endpoints on port 9287 (configurable) to obtain gateway statistics. - The /metrics endpoint just provides a formatted summary of a bunch of properties from configfs (via rtslib). - rbd-target-api: - This is a flask app that provides a REST API on port 5000 (configurable) for configuring the gateways and restoring their state. - Some of the API is used by gwcli, and some of it is considered "internal" for the purposes of syncrhonizing configuration on gateway nodes. - Both services run as root. - The APIs are publicly available by default, although this is configurable. - The APIs are exported using HTTP by default. They can be configured to use HTTPS. - Contains 2 systemd units for starting the 2 REST services as part of multi-user.target. Both run as root, but do specify the PrivateDevices=yes, ProtectHome=true, ProtectSystem=full, PrivateTmp=true options. - No D-Bus services. - No setuid binaries. - 3 binaries in PATH: the 2 services (rbd-target-api, rbd-target-gw) and a CLI tool (gwcli) for managing the Ceph iSCSI gateway. - No sudo fragments. - No policykit. - No udev rules. - Some limited unit tests that test a few classes in the ceph_iscsi_config python package. These run as part of the build and all pass. No autopkgtests. - No cronjobs. - Build logs are clean - just some deprecation warnings that seem to come from pyudev. Only lintian warnings are a couple of binary-without-manpage warnings for the 2 services. - Spawns subprocesses using subprocess.check_output. - gwcli uses the default shell=False - rbd-target-api uses shell=True, but doesn't seem to be using it with arguments from untrusted sources. - There is a subprocess.check_output helper in ceph_iscsi_config/utils.py (shellcommand) that appears to be unused. - Opens files for reading in a few places using a mixture of hard-coded paths and paths specified in the config file (/etc/ceph/iscsi-gateway.cfg). - One API endpoint (/api/_targetinfo/), opens a file in configfs for reading and returns the contents using a path derived from the received target IQN. There is a check that the IQN corresponds to target in the gateway configuration though. - It's not reading from untrusted files (just /etc and configfs). - No files opened for writing. - Plenty of logging using python's logging module. Services log to syslog at level logging.INFO and a rotating file handler in /var/log at a custom level (configured in /etc/ceph/iscsi-gateway.cfg) which defaults to logging.DEBUG. - The default log level for gwcli seems to be logging.DEBUG, and it appears to log to ~/gwcli.log by default. I'm suspicious that it is logging passwords in a couple of places (gwcli/client.py:Client.set_auth and gwcli/gateway.py:Target.ui_command_auth). - Only use of environment is by gwcli to read PATH in order to determine if the ceph binary exists. - No evidence of privileged operations. - Makes use of python-cryptography using the default backend (openssl?) for encrypting target passwords with RSA-OAEP using SHA-256 hashing (see class CHAP in ceph_iscsi_config/client.py). - No tempfile usage. - Uses python-flask for providing 2 REST APIs. - Internal exceptions are caught by flask and result in a generic 500 response without exposing debug information by default. - All APIs that accept arguments require authentication as the gateway API user. - No paths are provided as arguments, although arguments are used to derive configfs paths in some API endpoints. - ceph_iscsi_config/target.py:GWTarget._exists tests if a configfs path exists and derives the path from an argument that looks like it can be provided via the /api/_targetauth/ endpoint. This may be susceptible to path traversal, despite the argument being sanitized via rtslib_fb.utils.normalize_wwn (as the regexp there won't reject an IQN that might start with a valid name but then contain other path components, such as "iqn.0123-12.foo.bar/../../../../../.."). However, I don't think there's a way to actually leak information here as the particular API endpoint always returns success and the lack of presence of a path doesn't appear to trigger any exceptions. Still, this could be a bit more defensive. - No webkit. - All gateway REST API endpoints other than /api require authentication as the gateway API user using HTTP basic auth. The username and password are specified in the gateway configuration file (/etc/ceph/iscsi-gateway.cfg). - Note that the password for the gateway API user is stored in plaintext. Is there a reason not to salt and hash this? - Some API endpoints also use source IP filtering on top of the basic auth. Security team ACK for promoting ceph-iscsi to main, although I'd like someone to confirm or not whether gwcli is writing passwords to a logfile and get that fixed if it is. (I don't have a setup in which I was able to test this).