Remove appliance's hard-coded password in favor of ssh pub key
This removes the hard-coded password from the appliance VM's user-data and replaces it with a SSH public key, which is read from a file whos path is configured in rug.ini. It also disables password logins for the user. Another patch to akanda-appliance-builder will allow developers to include a specified debug user to allow debugging in dev environments. Change-Id: I7db92bc7fd3743d89d73ab2a0b8da14685c30c69
This commit is contained in:
parent
55666d9f15
commit
a06dbe7ab3
@ -19,9 +19,19 @@ import logging
|
||||
|
||||
from novaclient.v1_1 import client
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
OPTIONS = [
|
||||
cfg.StrOpt(
|
||||
'router_ssh_public_key',
|
||||
help="Path to the SSH public key for the 'akanda' user within "
|
||||
"router appliance VMs",
|
||||
default='/etc/akanda-rug/akanda.pub')
|
||||
]
|
||||
cfg.CONF.register_opts(OPTIONS)
|
||||
|
||||
|
||||
class InstanceInfo(object):
|
||||
def __init__(self, instance_id, name, management_port=None, ports=(),
|
||||
@ -181,7 +191,7 @@ debug:
|
||||
- verbose: true
|
||||
|
||||
bootcmd:
|
||||
- /usr/local/bin/akanda-configure-management %s %s/64
|
||||
- /usr/local/bin/akanda-configure-management %(mac_address)s %(ip_address)s/64
|
||||
|
||||
users:
|
||||
- name: akanda
|
||||
@ -189,12 +199,30 @@ users:
|
||||
groups: users
|
||||
shell: /bin/bash
|
||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||
passwd: $6$rounds=4096$zxaBh6omTayBSA$rI1.FNliuUl7R2SMdkj7zWv.FBhqGVd1lLYDatJd6MiE9WqEQx0M.o7bLyp5nA0CxV6ahoDb0m8Y5OQMDHx1V/
|
||||
lock-passwd: false
|
||||
lock-passwd: true
|
||||
ssh-authorized-keys:
|
||||
- %(ssh_public_key)s
|
||||
|
||||
final_message: "Akanda appliance is running"
|
||||
""" # noqa
|
||||
|
||||
|
||||
def _router_ssh_key():
|
||||
key = cfg.CONF.router_ssh_public_key
|
||||
if not key:
|
||||
return ''
|
||||
try:
|
||||
with open(key) as out:
|
||||
return out.read()
|
||||
except IOError:
|
||||
LOG.warning('Could not load router ssh public key from %s' % key)
|
||||
return ''
|
||||
|
||||
|
||||
def _format_userdata(mgt_port):
|
||||
return TEMPLATE % (mgt_port.mac_address, mgt_port.fixed_ips[0].ip_address)
|
||||
ctxt = {
|
||||
'ssh_public_key': _router_ssh_key(),
|
||||
'mac_address': mgt_port.mac_address,
|
||||
'ip_address': mgt_port.fixed_ips[0].ip_address,
|
||||
}
|
||||
return TEMPLATE % ctxt
|
||||
|
@ -18,7 +18,7 @@
|
||||
import datetime
|
||||
import mock
|
||||
import unittest2 as unittest
|
||||
|
||||
from six.moves import builtins as __builtins__
|
||||
from akanda.rug.api import nova
|
||||
|
||||
|
||||
@ -65,6 +65,40 @@ class FakeConf:
|
||||
router_instance_flavor = 1
|
||||
|
||||
|
||||
EXPECTED_USERDATA = """
|
||||
#cloud-config
|
||||
|
||||
cloud_config_modules:
|
||||
- emit_upstart
|
||||
- set_hostname
|
||||
- locale
|
||||
- set-passwords
|
||||
- timezone
|
||||
- disable-ec2-metadata
|
||||
- runcmd
|
||||
|
||||
output: {all: '| tee -a /var/log/cloud-init-output.log'}
|
||||
|
||||
debug:
|
||||
- verbose: true
|
||||
|
||||
bootcmd:
|
||||
- /usr/local/bin/akanda-configure-management aa:aa:aa:aa:aa:aa 192.168.1.1/64
|
||||
|
||||
users:
|
||||
- name: akanda
|
||||
gecos: Akanda
|
||||
groups: users
|
||||
shell: /bin/bash
|
||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||
lock-passwd: true
|
||||
ssh-authorized-keys:
|
||||
- fake_key
|
||||
|
||||
final_message: "Akanda appliance is running"
|
||||
"""
|
||||
|
||||
|
||||
def fake_make_ports_callback():
|
||||
return (fake_mgt_port, [fake_ext_port, fake_int_port])
|
||||
|
||||
@ -149,3 +183,26 @@ class TestNovaWrapper(unittest.TestCase):
|
||||
def test_destroy_router_instance(self):
|
||||
self.nova.destroy_instance(self.INSTANCE_INFO)
|
||||
self.client.servers.delete.assert_called_with(self.INSTANCE_INFO.id_)
|
||||
|
||||
@mock.patch.object(nova, '_router_ssh_key')
|
||||
def test_format_userdata(self, fake_ssh_key):
|
||||
fake_ssh_key.return_value = 'fake_key'
|
||||
result = nova._format_userdata(fake_int_port)
|
||||
self.assertEqual(result.strip(), EXPECTED_USERDATA.strip())
|
||||
|
||||
@mock.patch.object(__builtins__, 'open', autospec=True)
|
||||
def test_router_ssh_key(self, fake_open):
|
||||
mock_key_file = mock.MagicMock(spec=file)
|
||||
mock_key_file.read.return_value = 'fake-key'
|
||||
mock_key_file.__enter__.return_value = mock_key_file
|
||||
fake_open.return_value = mock_key_file
|
||||
result = nova._router_ssh_key()
|
||||
self.assertEqual(result, 'fake-key')
|
||||
|
||||
@mock.patch.object(nova, 'LOG', autospec=True)
|
||||
@mock.patch.object(__builtins__, 'open', autospec=True)
|
||||
def test_router_ssh_key_not_found(self, fake_open, fake_log):
|
||||
fake_open.side_effect = IOError
|
||||
result = nova._router_ssh_key()
|
||||
self.assertEqual(result, '')
|
||||
self.assertTrue(fake_log.warning.called)
|
||||
|
@ -32,6 +32,10 @@ AKANDA_RUG_MANAGEMENT_PORT=${AKANDA_RUG_MANAGEMENT_PORT:-5000}
|
||||
|
||||
HORIZON_LOCAL_SETTINGS=$HORIZON_DIR/openstack_dashboard/local/local_settings.py
|
||||
|
||||
# Path to public ssh key that will be added to the 'akanda' users authorized_keys
|
||||
# within the appliance VM.
|
||||
AKANDA_APPLIANCE_SSH_PUBLIC_KEY=${AKANDA_APPLIANCE_SSH_PUBLIC_KEY:-/home/$STACK_USER/.ssh/id_rsa.pub}
|
||||
|
||||
function configure_akanda() {
|
||||
if [[ ! -d $AKANDA_CONF_DIR ]]; then
|
||||
sudo mkdir -p $AKANDA_CONF_DIR
|
||||
@ -59,6 +63,8 @@ function configure_akanda() {
|
||||
if [[ "$Q_AGENT" == "linuxbridge" ]]; then
|
||||
iniset $AKANDA_RUG_CONF DEFAULT interface_driver "akanda.rug.common.linux.interface.BridgeInterfaceDriver"
|
||||
fi
|
||||
|
||||
iniset $AKANDA_RUG_CONF DEFAULT router_ssh_public_key $AKANDA_APPLIANCE_SSH_PUBLIC_KEY
|
||||
}
|
||||
|
||||
function configure_akanda_nova() {
|
||||
@ -172,9 +178,11 @@ function pre_start_akanda() {
|
||||
# Point DIB at the devstack checkout of the akanda-appliance repo
|
||||
DIB_REPOLOCATION_akanda=$AKANDA_APPLIANCE_DIR \
|
||||
DIB_REPOREF_akanda="$(cd $AKANDA_APPLIANCE_DIR && git rev-parse HEAD)" \
|
||||
DIB_AKANDA_APPLIANCE_DEBUG_USER=$ADMIN_USERNAME \
|
||||
DIB_AKANDA_APPLIANCE_DEBUG_PASSWORD=$ADMIN_PASSWORD \
|
||||
http_proxy=$AKANDA_DEV_APPLIANCE_BUILD_PROXY \
|
||||
ELEMENTS_PATH=$AKANDA_APPLIANCE_BUILDER_DIR/diskimage-builder/elements \
|
||||
DIB_RELEASE=wheezy DIB_EXTLINUX=1 disk-image-create debian vm akanda \
|
||||
DIB_RELEASE=wheezy DIB_EXTLINUX=1 disk-image-create debian vm akanda debug-user \
|
||||
-o $TOP_DIR/files/akanda
|
||||
akanda_dev_image_src=$AKANDA_DEV_APPLIANCE_FILE
|
||||
else
|
||||
@ -250,11 +258,20 @@ function set_demo_tenant_sec_group_dhcp_rules() {
|
||||
}
|
||||
|
||||
|
||||
function check_prereqs() {
|
||||
# Fail devstack as early as possible if system does not satisfy some known
|
||||
# prerequisites
|
||||
if [ ! -e "$AKANDA_APPLIANCE_SSH_PUBLIC_KEY" ]; then
|
||||
die $LINENO "Public SSH key not found at $AKANDA_APPLIANCE_SSH_PUBLIC_KEY. Please copy one there or " \
|
||||
"set AKANDA_APPLIANCE_SSH_PUBLIC_KEY accordingly."
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if is_service_enabled ak-rug; then
|
||||
if [[ "$1" == "source" ]]; then
|
||||
# no-op
|
||||
:
|
||||
check_prereqs
|
||||
|
||||
elif [[ "$1" == "stack" && "$2" == "install" ]]; then
|
||||
echo_summary "Installing Akanda"
|
||||
|
@ -20,6 +20,7 @@ plug_external_port=True
|
||||
|
||||
router_image_uuid=1e9c16f3-e070-47b7-b49c-ffcf38df5f9a
|
||||
router_instance_flavor=1
|
||||
router_ssh_public_key=/etc/akanda/akanda.pub
|
||||
|
||||
# to plug in rug interface
|
||||
interface_driver=akanda.rug.common.linux.interface.OVSInterfaceDriver
|
||||
|
@ -8,3 +8,4 @@ iso8601
|
||||
mox==0.5.3
|
||||
testtools
|
||||
fixtures
|
||||
six>=1.9.0
|
||||
|
Loading…
Reference in New Issue
Block a user