From 358b6eac404d0bab09290fbb9334f1a93e992e01 Mon Sep 17 00:00:00 2001 From: Dmitry Tantsur Date: Wed, 9 Feb 2022 10:41:13 +0100 Subject: [PATCH] Support listening on a Unix socket When using nginx to terminate TLS (like it's done in Bifrost), it's more secure to use a Unix socket for communication, so that local users cannot access plain text communication. Copies Inspector change I37b762cca035b5855deb92635c29e8eb97a87c20. Change-Id: If00e5a3537b8fbaae3fa01f71bd515399464da36 --- ironic/common/wsgi_service.py | 21 +++++++++++++++---- ironic/conf/api.py | 16 ++++++++++++++ .../notes/unix-socket-48e8f1caf4cb19f9.yaml | 5 +++++ 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 releasenotes/notes/unix-socket-48e8f1caf4cb19f9.yaml diff --git a/ironic/common/wsgi_service.py b/ironic/common/wsgi_service.py index e7bbe9dcd2..abfe4b1f2c 100644 --- a/ironic/common/wsgi_service.py +++ b/ironic/common/wsgi_service.py @@ -10,6 +10,9 @@ # License for the specific language governing permissions and limitations # under the License. +import socket + +from ironic_lib import utils as il_utils from oslo_concurrency import processutils from oslo_service import service from oslo_service import wsgi @@ -46,10 +49,18 @@ class WSGIService(service.ServiceBase): _("api_workers value of %d is invalid, " "must be greater than 0.") % self.workers) - self.server = wsgi.Server(CONF, name, self.app, - host=CONF.api.host_ip, - port=CONF.api.port, - use_ssl=use_ssl) + if CONF.api.unix_socket: + il_utils.unlink_without_raise(CONF.api.unix_socket) + self.server = wsgi.Server(CONF, name, self.app, + socket_family=socket.AF_UNIX, + socket_file=CONF.api.unix_socket, + socket_mode=CONF.api.unix_socket_mode, + use_ssl=use_ssl) + else: + self.server = wsgi.Server(CONF, name, self.app, + host=CONF.api.host_ip, + port=CONF.api.port, + use_ssl=use_ssl) def start(self): """Start serving this service using loaded configuration. @@ -64,6 +75,8 @@ class WSGIService(service.ServiceBase): :returns: None """ self.server.stop() + if CONF.api.unix_socket: + il_utils.unlink_without_raise(CONF.unix_socket) def wait(self): """Wait for the service to stop serving this API. diff --git a/ironic/conf/api.py b/ironic/conf/api.py index dcf235eddc..2b0e9a824c 100644 --- a/ironic/conf/api.py +++ b/ironic/conf/api.py @@ -15,9 +15,20 @@ # under the License. from oslo_config import cfg +from oslo_config import types as cfg_types from ironic.common.i18n import _ + +class Octal(cfg_types.Integer): + + def __call__(self, value): + if isinstance(value, int): + return value + else: + return int(str(value), 8) + + opts = [ cfg.HostAddressOpt('host_ip', default='0.0.0.0', @@ -26,6 +37,11 @@ opts = [ cfg.PortOpt('port', default=6385, help=_('The TCP port on which ironic-api listens.')), + cfg.StrOpt('unix_socket', + help=_('Unix socket to listen on. Disables host_ip and port.')), + cfg.Opt('unix_socket_mode', type=Octal(), + help=_('File mode (an octal number) of the unix socket to ' + 'listen on. Ignored if unix_socket is not set.')), cfg.IntOpt('max_limit', default=1000, mutable=True, diff --git a/releasenotes/notes/unix-socket-48e8f1caf4cb19f9.yaml b/releasenotes/notes/unix-socket-48e8f1caf4cb19f9.yaml new file mode 100644 index 0000000000..14fefaf73b --- /dev/null +++ b/releasenotes/notes/unix-socket-48e8f1caf4cb19f9.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Supports listening on a Unix socket instead of a normal TCP socket. + This is useful with an HTTP server such as nginx in proxy mode.