Signal agent token is required
The agent needs to be able to understand if the agent token is supported and is a mandatory feature of the ironic deployment as that can alter some of the behavior of the agent itself. Also adds documentation on the subject for administrators. Story: 2007025 Task: 37821 Change-Id: Ic635e0ed6d378d6a34a4a82e66ca647eee33bc26
This commit is contained in:
parent
392f2a56bf
commit
deca07de3c
@ -479,6 +479,9 @@ IRONIC_DEPLOY_LOGS_LOCAL_PATH=${IRONIC_DEPLOY_LOGS_LOCAL_PATH:-$IRONIC_VM_LOG_DI
|
|||||||
# Fast track option
|
# Fast track option
|
||||||
IRONIC_DEPLOY_FAST_TRACK=${IRONIC_DEPLOY_FAST_TRACK:-False}
|
IRONIC_DEPLOY_FAST_TRACK=${IRONIC_DEPLOY_FAST_TRACK:-False}
|
||||||
|
|
||||||
|
# Agent Token requirement
|
||||||
|
IRONIC_REQUIRE_AGENT_TOKEN=${IRONIC_REQUIRE_AGENT_TOKEN:-True}
|
||||||
|
|
||||||
# Define baremetal min_microversion in tempest config. Default value None is picked from tempest.
|
# Define baremetal min_microversion in tempest config. Default value None is picked from tempest.
|
||||||
TEMPEST_BAREMETAL_MIN_MICROVERSION=${TEMPEST_BAREMETAL_MIN_MICROVERSION:-}
|
TEMPEST_BAREMETAL_MIN_MICROVERSION=${TEMPEST_BAREMETAL_MIN_MICROVERSION:-}
|
||||||
|
|
||||||
@ -1294,6 +1297,8 @@ function configure_ironic {
|
|||||||
# Set fast track options
|
# Set fast track options
|
||||||
iniset $IRONIC_CONF_FILE deploy fast_track $IRONIC_DEPLOY_FAST_TRACK
|
iniset $IRONIC_CONF_FILE deploy fast_track $IRONIC_DEPLOY_FAST_TRACK
|
||||||
|
|
||||||
|
# Set requirement for agent tokens
|
||||||
|
iniset $IRONIC_CONF_FILE DEFAULT require_agent_token $IRONIC_REQUIRE_AGENT_TOKEN
|
||||||
# No need to check if RabbitMQ is enabled, this call does it in a smart way
|
# No need to check if RabbitMQ is enabled, this call does it in a smart way
|
||||||
if [[ "$IRONIC_RPC_TRANSPORT" == "oslo" ]]; then
|
if [[ "$IRONIC_RPC_TRANSPORT" == "oslo" ]]; then
|
||||||
iniset_rpc_backend ironic $IRONIC_CONF_FILE
|
iniset_rpc_backend ironic $IRONIC_CONF_FILE
|
||||||
|
121
doc/source/admin/agent-token.rst
Normal file
121
doc/source/admin/agent-token.rst
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
.. _agent_token:
|
||||||
|
|
||||||
|
===========
|
||||||
|
Agent Token
|
||||||
|
===========
|
||||||
|
|
||||||
|
Purpose
|
||||||
|
=======
|
||||||
|
|
||||||
|
The concept of agent tokens is to provide a mechanism by which the
|
||||||
|
relationship between an operating deployment of the Bare Metal Service
|
||||||
|
and an instance of the ``ironic-python-agent`` is verified. In a sense,
|
||||||
|
this token can be viewed as a session identifier or authentication token.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
This functionality does not remove the risk of a man-in-the-middle attack
|
||||||
|
that could occur from connection intercept or when TLS is not used for
|
||||||
|
all communication.
|
||||||
|
|
||||||
|
This becomes useful in the case of deploying an "edge" node where intermediate
|
||||||
|
networks are not trustworthy.
|
||||||
|
|
||||||
|
How it works
|
||||||
|
============
|
||||||
|
|
||||||
|
These tokens are provided in one of two ways to the running agent.
|
||||||
|
|
||||||
|
1. A pre-generated token which is embedded into virtual media ISOs.
|
||||||
|
2. A one-time generated token that are provided upon the first "lookup"
|
||||||
|
of the node.
|
||||||
|
|
||||||
|
In both cases, the tokens are a randomly generated length of 128 characters.
|
||||||
|
|
||||||
|
Once the token has been provided, the token cannot be retrieved or accessed.
|
||||||
|
It remains available to the conductors, and is stored in memory of the
|
||||||
|
``ironic-python-agent``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
In the case of the token being embedded with virtual media, it is read
|
||||||
|
from a configuration file with-in the image. Ideally this should be paired
|
||||||
|
with Swift temporary URLs.
|
||||||
|
|
||||||
|
With the token is available in memory in the agent, the token is embedded with
|
||||||
|
``heartbeat`` operations to the ironic API endpoint. This enables the API to
|
||||||
|
authenticate the heartbeat request, and refuse "heartbeat" requests from the
|
||||||
|
``ironic-python-agent``. With the ``Ussuri`` release, the confiuration option
|
||||||
|
``[DEFAULT]require_agent_token`` can be set ``True`` to explicitly require
|
||||||
|
token use.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
If the Bare Metal Service is updated, and the version of
|
||||||
|
``ironic-python-agent`` should be updated to enable this feature.
|
||||||
|
|
||||||
|
In addition to heartbeats being verified, commands from the
|
||||||
|
``ironic-conductor`` service to the ``ironic-python-agent`` also include the
|
||||||
|
token, allowing the agent to authenticate the caller.
|
||||||
|
|
||||||
|
|
||||||
|
With Virtual Media
|
||||||
|
------------------
|
||||||
|
|
||||||
|
.. seqdiag::
|
||||||
|
:scale: 80
|
||||||
|
|
||||||
|
diagram {
|
||||||
|
API; Conductor; Baremetal; Swift; IPA;
|
||||||
|
activation = none;
|
||||||
|
span_height = 1;
|
||||||
|
edge_length = 250;
|
||||||
|
default_note_color = white;
|
||||||
|
default_fontsize = 14;
|
||||||
|
|
||||||
|
Conductor -> Conductor [label = "Generates a random token"];
|
||||||
|
Conductor -> Conductor [label = "Generates configuration for IPA ramdisk"];
|
||||||
|
Conductor -> Swift [label = "IPA image, with configuration is uploaded"];
|
||||||
|
Conductor -> Baremetal [label = "Attach IPA virtual media in Swift as virtual CD"];
|
||||||
|
Conductor -> Baremetal [label = "Conductor turns power on"];
|
||||||
|
Baremetal -> Swift [label = "Baremetal reads virtual media"];
|
||||||
|
Baremetal -> Baremetal [label = "Boots IPA virtual media image"];
|
||||||
|
Baremetal -> Baremetal [label = "IPA is started"];
|
||||||
|
IPA -> Baremetal [label = "IPA loads configuration and agent token into memory"];
|
||||||
|
IPA -> API [label = "Lookup node"];
|
||||||
|
API -> IPA [label = "API responds with node UUID and token value of '******'"];
|
||||||
|
IPA -> API [label = "Heartbeat with agent token"];
|
||||||
|
}
|
||||||
|
|
||||||
|
With PXE/iPXE/etc.
|
||||||
|
------------------
|
||||||
|
|
||||||
|
.. seqdiag::
|
||||||
|
:scale: 80
|
||||||
|
|
||||||
|
diagram {
|
||||||
|
API; Conductor; Baremetal; iPXE; IPA;
|
||||||
|
activation = none;
|
||||||
|
span_height = 1;
|
||||||
|
edge_length = 250;
|
||||||
|
default_note_color = white;
|
||||||
|
default_fontsize = 14;
|
||||||
|
|
||||||
|
Conductor -> Baremetal [label = "Conductor turns power on"];
|
||||||
|
Baremetal -> iPXE [label = "Baremetal reads kernel/ramdisk and starts boot"];
|
||||||
|
Baremetal -> Baremetal [label = "Boots IPA virtual media image"];
|
||||||
|
Baremetal -> Baremetal [label = "IPA is started"];
|
||||||
|
IPA -> Baremetal [label = "IPA loads configuration"];
|
||||||
|
IPA -> API [label = "Lookup node"];
|
||||||
|
API -> Conductor [label = "API requests conductor to generates a random token"];
|
||||||
|
API -> IPA [label = "API responds with node UUID and token value"];
|
||||||
|
IPA -> API [label = "Heartbeat with agent token"];
|
||||||
|
}
|
||||||
|
|
||||||
|
Agent Configuration
|
||||||
|
===================
|
||||||
|
|
||||||
|
An additional setting which may be leveraged with the ``ironic-python-agent``
|
||||||
|
is a ``agent_token_required`` setting. Under normal circumstances, this
|
||||||
|
setting can be asserted via the configuration supplied from the Bare Metal
|
||||||
|
service deployment upon the ``lookup`` action, but can be asserted via the
|
||||||
|
embedded configuration for the agent in the ramdisk. This setting is also
|
||||||
|
available via kernel command line as ``ipa-agent-token-required``.
|
||||||
|
|
@ -32,6 +32,7 @@ the services.
|
|||||||
Windows Images <building-windows-images>
|
Windows Images <building-windows-images>
|
||||||
Troubleshooting FAQ <troubleshooting>
|
Troubleshooting FAQ <troubleshooting>
|
||||||
Power Sync with the Compute Service <power-sync>
|
Power Sync with the Compute Service <power-sync>
|
||||||
|
Agent Token <agent-token>
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:hidden:
|
:hidden:
|
||||||
|
@ -53,7 +53,10 @@ def config(token):
|
|||||||
'statsd_port': CONF.metrics_statsd.agent_statsd_port
|
'statsd_port': CONF.metrics_statsd.agent_statsd_port
|
||||||
},
|
},
|
||||||
'heartbeat_timeout': CONF.api.ramdisk_heartbeat_timeout,
|
'heartbeat_timeout': CONF.api.ramdisk_heartbeat_timeout,
|
||||||
'agent_token': token
|
'agent_token': token,
|
||||||
|
# Not an API version based indicator, passing as configuration
|
||||||
|
# as the signifigants indicates support should also be present.
|
||||||
|
'agent_token_required': CONF.require_agent_token,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ class TestLookup(test_api_base.BaseApiTest):
|
|||||||
self.mock_get_node_with_token.return_value = node
|
self.mock_get_node_with_token.return_value = node
|
||||||
|
|
||||||
def _check_config(self, data):
|
def _check_config(self, data):
|
||||||
expected_metrics = {
|
expected_config = {
|
||||||
'metrics': {
|
'metrics': {
|
||||||
'backend': 'statsd',
|
'backend': 'statsd',
|
||||||
'prepend_host': CONF.metrics.agent_prepend_host,
|
'prepend_host': CONF.metrics.agent_prepend_host,
|
||||||
@ -76,9 +76,10 @@ class TestLookup(test_api_base.BaseApiTest):
|
|||||||
'statsd_port': CONF.metrics_statsd.agent_statsd_port
|
'statsd_port': CONF.metrics_statsd.agent_statsd_port
|
||||||
},
|
},
|
||||||
'heartbeat_timeout': CONF.api.ramdisk_heartbeat_timeout,
|
'heartbeat_timeout': CONF.api.ramdisk_heartbeat_timeout,
|
||||||
'agent_token': mock.ANY
|
'agent_token': mock.ANY,
|
||||||
|
'agent_token_required': False,
|
||||||
}
|
}
|
||||||
self.assertEqual(expected_metrics, data['config'])
|
self.assertEqual(expected_config, data['config'])
|
||||||
self.assertIsNotNone(data['config']['agent_token'])
|
self.assertIsNotNone(data['config']['agent_token'])
|
||||||
self.assertNotEqual('******', data['config']['agent_token'])
|
self.assertNotEqual('******', data['config']['agent_token'])
|
||||||
|
|
||||||
|
@ -151,6 +151,8 @@
|
|||||||
|
|
||||||
export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_VM_COUNT=7"
|
export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_VM_COUNT=7"
|
||||||
|
|
||||||
|
export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_REQUIRE_AGENT_TOKEN=False"
|
||||||
|
|
||||||
# Ensure the ironic-vars-EARLY file exists
|
# Ensure the ironic-vars-EARLY file exists
|
||||||
touch ironic-vars-early
|
touch ironic-vars-early
|
||||||
# Pull in the EARLY variables injected by the optional builders
|
# Pull in the EARLY variables injected by the optional builders
|
||||||
|
@ -97,6 +97,8 @@
|
|||||||
|
|
||||||
export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_VM_COUNT=7"
|
export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_VM_COUNT=7"
|
||||||
|
|
||||||
|
export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_REQUIRE_AGENT_TOKEN=False"
|
||||||
|
|
||||||
# Ensure the ironic-vars-EARLY file exists
|
# Ensure the ironic-vars-EARLY file exists
|
||||||
touch ironic-vars-early
|
touch ironic-vars-early
|
||||||
# Pull in the EARLY variables injected by the optional builders
|
# Pull in the EARLY variables injected by the optional builders
|
||||||
|
19
releasenotes/notes/agent-token-support-0a5b5aa1585dfbb5.yaml
Normal file
19
releasenotes/notes/agent-token-support-0a5b5aa1585dfbb5.yaml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds support of ``agent token`` which serves as a mechanism to secure
|
||||||
|
the normally unauthenticated API endpoints in ironic which are used in
|
||||||
|
the mechanics of baremetal provisioning. This feature is optional, however
|
||||||
|
operators may require this feature by changing the
|
||||||
|
``[DEFAULT]require_agent_token`` setting to ``True``.
|
||||||
|
upgrades:
|
||||||
|
- |
|
||||||
|
In order to use the new Agent Token support, all ramdisk settings should
|
||||||
|
be updated for all nodes in ironic. If token use is required by ironic's
|
||||||
|
configuration, and the ramdisks have not been updated, then all
|
||||||
|
deployment, cleaning, and rescue operations will fail until the version of
|
||||||
|
the ironic-python-agent ramdisk has been updated.
|
||||||
|
issues:
|
||||||
|
- |
|
||||||
|
The ``ansible`` deployment interface does not support use of an
|
||||||
|
``agent token`` at this time.
|
Loading…
x
Reference in New Issue
Block a user