diff --git a/DEMO.md b/DEMO.md
index 2b279d3..9c99e0f 100644
--- a/DEMO.md
+++ b/DEMO.md
@@ -31,8 +31,8 @@ kubernetes, respectively.
```
sudo snap install microstack --beta --devmode
-sudo snap install --classic juju
-sudo snap install --classic kubectl
+sudo snap install juju --classic
+sudo snap install kubectl --classic
```
To make sure that you can use the snaps we've installed, add /snap/bin
@@ -158,11 +158,11 @@ Answer the questions as follows:
cloud type: | openstack |
- endpoint: | http://10.20.20.1:5000/v3 |
+ endpoint: | https://10.20.20.1:5000/v3 |
cert path: | none |
auth type: | userpass |
region: | microstack |
- region endpoint: | http://10.20.20.1:5000/v3 |
+ region endpoint: | https://10.20.20.1:5000/v3 |
add another region?: | N |
@@ -182,7 +182,7 @@ images in your microstack cloud. Here's how to set that up.
```
mkdir simplestreams
-juju metadata generate-image -d ~/simplestreams -i $IMAGE -s bionic -r microstack -u http://10.20.20.1:5000/v3
+juju metadata generate-image -d ~/simplestreams -i $IMAGE -s bionic -r microstack -u https://10.20.20.1:5000/v3
```
(If you don't still have an `IMAGE` variable in your env, you can find
diff --git a/snap-overlay/bin/set-default-config.py b/snap-overlay/bin/set-default-config.py
index e3c195a..a36a02f 100755
--- a/snap-overlay/bin/set-default-config.py
+++ b/snap-overlay/bin/set-default-config.py
@@ -35,7 +35,7 @@ def _get_default_config():
'config.network.ext-cidr': '10.20.20.1/24',
'config.network.security-rules': True,
'config.network.dashboard-allowed-hosts': '*',
- 'config.network.ports.dashboard': 80,
+ 'config.network.ports.dashboard': 443,
'config.network.ports.mysql': 3306,
'config.network.ports.rabbit': 5672,
'config.network.external-bridge-name': 'br-ex',
@@ -75,6 +75,14 @@ def _get_default_config():
'config.nova.cpu-mode': 'host-model',
# Do not override cpu-models by default.
'config.nova.cpu-models': '',
+
+ 'config.tls.generate-self-signed': True,
+ 'config.tls.cacert-path':
+ f'{snap_common}/etc/ssl/certs/cacert.pem',
+ 'config.tls.cert-path':
+ f'{snap_common}/etc/ssl/certs/cert.pem',
+ 'config.tls.key-path':
+ f'{snap_common}/etc/ssl/private/key.pem',
}
diff --git a/snap-overlay/snap-openstack.yaml b/snap-overlay/snap-openstack.yaml
index 1d3a4f5..2c879dc 100644
--- a/snap-overlay/snap-openstack.yaml
+++ b/snap-overlay/snap-openstack.yaml
@@ -8,7 +8,6 @@ setup:
- "{snap_common}/etc/neutron/policy.d"
- "{snap_common}/etc/neutron/rootwrap.d"
- "{snap_common}/etc/nginx/sites-enabled"
- - "{snap_common}/etc/nginx/snap/sites-enabled"
- "{snap_common}/etc/glance/glance.conf.d"
- "{snap_common}/etc/placement/placement.conf.d"
- "{snap_common}/etc/horizon/horizon.conf.d"
@@ -22,6 +21,8 @@ setup:
- "{snap_common}/etc/cluster/tls"
- "{snap_common}/etc/cluster/uwsgi/snap"
- "{snap_common}/etc/rabbitmq"
+ - "{snap_common}/etc/ssl/certs"
+ - "{snap_common}/etc/ssl/private"
- "{snap_common}/fernet-keys"
- "{snap_common}/lib"
- "{snap_common}/lib/images"
@@ -33,24 +34,25 @@ setup:
- "{snap_common}/etc/iscsi"
- "{snap_common}/etc/target"
templates:
- cluster-nginx.conf.j2: "{snap_common}/etc/nginx/snap/sites-enabled/cluster.conf"
- keystone-nginx.conf.j2: "{snap_common}/etc/nginx/snap/sites-enabled/keystone.conf"
+ cluster-nginx.conf.j2: "{snap_common}/etc/nginx/sites-enabled/cluster.conf"
+ keystone-nginx.conf.j2: "{snap_common}/etc/nginx/sites-enabled/keystone.conf"
keystone-snap.conf.j2: "{snap_common}/etc/keystone/keystone.conf.d/keystone-snap.conf"
neutron-snap.conf.j2: "{snap_common}/etc/neutron/neutron.conf.d/neutron-snap.conf"
nginx.conf.j2: "{snap_common}/etc/nginx/snap/nginx.conf"
nova-snap.conf.j2: "{snap_common}/etc/nova/nova.conf.d/nova-snap.conf"
- nova-nginx.conf.j2: "{snap_common}/etc/nginx/snap/sites-enabled/nova.conf"
+ nova-nginx.conf.j2: "{snap_common}/etc/nginx/sites-enabled/nova.conf"
glance-snap.conf.j2: "{snap_common}/etc/glance/glance.conf.d/glance-snap.conf"
- placement-nginx.conf.j2: "{snap_common}/etc/nginx/snap/sites-enabled/placement.conf"
+ glance-nginx.conf.j2: "{snap_common}/etc/nginx/sites-enabled/glance.conf"
+ placement-nginx.conf.j2: "{snap_common}/etc/nginx/sites-enabled/placement.conf"
placement-snap.conf.j2: "{snap_common}/etc/placement/placement.conf.d/placement-snap.conf"
- cinder-nginx.conf.j2: "{snap_common}/etc/nginx/snap/sites-enabled/cinder.conf"
+ cinder-nginx.conf.j2: "{snap_common}/etc/nginx/sites-enabled/cinder.conf"
cinder-snap.conf.j2: "{snap_common}/etc/cinder/cinder.conf.d/cinder-snap.conf"
cinder.database.conf.j2: "{snap_common}/etc/cinder/cinder.conf.d/database.conf"
cinder.rabbitmq.conf.j2: "{snap_common}/etc/cinder/cinder.conf.d/rabbitmq.conf"
cinder.keystone.conf.j2: "{snap_common}/etc/cinder/cinder.conf.d/keystone.conf"
cinder-rootwrap.conf.j2: "{snap_common}/etc/cinder/rootwrap.conf"
horizon-snap.conf.j2: "{snap_common}/etc/horizon/horizon.conf.d/horizon-snap.conf"
- horizon-nginx.conf.j2: "{snap_common}/etc/nginx/snap/sites-enabled/horizon.conf"
+ horizon-nginx.conf.j2: "{snap_common}/etc/nginx/sites-enabled/horizon.conf"
05_snap_tweaks.j2: "{snap_common}/etc/horizon/local_settings.d/_05_snap_tweaks.py"
libvirtd.conf.j2: "{snap_common}/etc/libvirt/libvirtd.conf"
qemu.conf.j2: "{snap_common}/etc/libvirt/qemu.conf"
@@ -62,10 +64,12 @@ setup:
nova.conf.d.keystone.conf.j2: "{snap_common}/etc/nova/nova.conf.d/keystone.conf"
nova.conf.d.database.conf.j2: "{snap_common}/etc/nova/nova.conf.d/database.conf"
nova.conf.d.rabbitmq.conf.j2: "{snap_common}/etc/nova/nova.conf.d/rabbitmq.conf"
+ nova.conf.d.cinder.conf.j2: "{snap_common}/etc/nova/nova.conf.d/cinder.conf"
nova.conf.d.glance.conf.j2: "{snap_common}/etc/nova/nova.conf.d/glance.conf"
nova.conf.d.neutron.conf.j2: "{snap_common}/etc/nova/nova.conf.d/neutron.conf"
nova.conf.d.placement.conf.j2: "{snap_common}/etc/nova/nova.conf.d/placement.conf"
nova.conf.d.console.conf.j2: "{snap_common}/etc/nova/nova.conf.d/console.conf"
+ nova-nginx.conf.j2: "{snap_common}/etc/nginx/sites-enabled/nova.conf"
keystone.database.conf.j2: "{snap_common}/etc/keystone/keystone.conf.d/database.conf"
glance.database.conf.j2: "{snap_common}/etc/glance/glance.conf.d/database.conf"
placement.conf.d.database.conf.j2: "{snap_common}/etc/placement/placement.conf.d/database.conf"
@@ -75,6 +79,7 @@ setup:
neutron.database.conf.j2: "{snap_common}/etc/neutron/neutron.conf.d/database.conf"
neutron.conf.d.rabbitmq.conf.j2: "{snap_common}/etc/neutron/neutron.conf.d/rabbitmq.conf"
neutron_ovn_metadata_agent.ini.j2: "{snap_common}/etc/neutron/neutron_ovn_metadata_agent.ini"
+ neutron-nginx.conf.j2: "{snap_common}/etc/nginx/sites-enabled/neutron.conf"
rabbitmq.conf.j2: "{snap_common}/etc/rabbitmq/rabbitmq.config"
iscsid.conf.j2: "{snap_common}/etc/iscsi/iscsid.conf"
lvm.conf.j2: "{snap_common}/etc/lvm/lvm.conf"
@@ -84,6 +89,9 @@ setup:
nrpe.cfg.j2: "{snap_common}/etc/nrpe/nrpe-microstack.cfg"
filebeat.yaml.j2: "{snap_common}/etc/filebeat/filebeat-microstack.yaml"
chmod:
+ "{snap_common}/etc/ssl": 0755
+ "{snap_common}/etc/ssl/certs": 0755
+ "{snap_common}/etc/ssl/private": 0700
"{snap_common}/instances": 0755
"{snap_common}/etc/microstack.rc": 0644
"{snap_common}/etc/microstack.json": 0644
@@ -124,6 +132,10 @@ setup:
virt_type: 'config.nova.virt-type'
cpu_mode: 'config.nova.cpu-mode'
cpu_models: 'config.nova.cpu-models'
+ tls_generate_self_signed: 'config.tls.generate-self-signed'
+ tls_cacert_path: 'config.tls.cacert-path'
+ tls_cert_path: 'config.tls.cert-path'
+ tls_key_path: 'config.tls.key-path'
entry_points:
keystone-manage:
binary: "{snap}/bin/keystone-manage"
diff --git a/snap-overlay/templates/05_snap_tweaks.j2 b/snap-overlay/templates/05_snap_tweaks.j2
index 6a2149b..6c59d07 100644
--- a/snap-overlay/templates/05_snap_tweaks.j2
+++ b/snap-overlay/templates/05_snap_tweaks.j2
@@ -23,7 +23,7 @@ AVAILABLE_THEMES = [
# Point us at keystone.
OPENSTACK_HOST = "10.20.20.1"
-OPENSTACK_KEYSTONE_URL = "http://%s:5000/v3" % OPENSTACK_HOST
+OPENSTACK_KEYSTONE_URL = "https://%s:5000/v3" % OPENSTACK_HOST
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "_member_"
# Turn off external access for now. (This should be turned on once we
@@ -40,4 +40,11 @@ CACHES = {
}
SESSION_ENGINE='django.contrib.sessions.backends.cache'
-
+# SSL config
+CSRF_COOKIE_SECURE = True
+SESSION_COOKIE_SECURE = True
+{% if tls_generate_self_signed|lower == "false" %}
+OPENSTACK_SSL_CACERT = "{{ tls_cacert_path }}"
+{% else %}
+OPENSTACK_SSL_NO_VERIFY = True
+{% endif %}
diff --git a/snap-overlay/templates/cinder-nginx.conf.j2 b/snap-overlay/templates/cinder-nginx.conf.j2
index 47e6c7f..5134741 100644
--- a/snap-overlay/templates/cinder-nginx.conf.j2
+++ b/snap-overlay/templates/cinder-nginx.conf.j2
@@ -1,5 +1,9 @@
server {
- listen 8776;
+ listen 8776 ssl;
+ ssl_certificate {{ tls_cert_path }};
+ ssl_certificate_key {{ tls_key_path }};
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
access_log {{ snap_common }}/log/nginx-access.log;
error_log {{ snap_common }}/log/nginx-error.log;
location / {
diff --git a/snap-overlay/templates/cinder.keystone.conf.j2 b/snap-overlay/templates/cinder.keystone.conf.j2
index e4144f5..5c56735 100644
--- a/snap-overlay/templates/cinder.keystone.conf.j2
+++ b/snap-overlay/templates/cinder.keystone.conf.j2
@@ -2,8 +2,8 @@
auth_strategy = keystone
[keystone_authtoken]
-auth_uri = http://{{ control_ip }}:5000
-auth_url = http://{{ control_ip }}:5000
+auth_uri = https://{{ control_ip }}:5000/v3
+auth_url = https://{{ control_ip }}:5000/v3
memcached_servers = {{ compute_ip }}:11211
auth_type = password
project_domain_name = default
@@ -11,3 +11,4 @@ user_domain_name = default
project_name = service
username = cinder
password = {{ cinder_password }}
+cafile = {{ tls_cacert_path }}
diff --git a/snap-overlay/templates/glance-nginx.conf.j2 b/snap-overlay/templates/glance-nginx.conf.j2
new file mode 100644
index 0000000..05c9457
--- /dev/null
+++ b/snap-overlay/templates/glance-nginx.conf.j2
@@ -0,0 +1,18 @@
+server {
+ listen 9292 ssl;
+ ssl_certificate {{ tls_cert_path }};
+ ssl_certificate_key {{ tls_key_path }};
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
+ access_log {{ snap_common }}/log/nginx-access.log;
+ error_log {{ snap_common }}/log/nginx-error.log;
+ # Disabled for glance image uploads. The maximum size will be
+ # determined by glance settings.
+ client_max_body_size 0;
+ location / {
+ proxy_set_header X-Forwarded-Host $host:$server_port;
+ proxy_set_header X-Forwarded-Server $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_pass http://127.0.0.1:9282;
+ }
+}
diff --git a/snap-overlay/templates/glance-snap.conf.j2 b/snap-overlay/templates/glance-snap.conf.j2
index 1e1c610..0802727 100644
--- a/snap-overlay/templates/glance-snap.conf.j2
+++ b/snap-overlay/templates/glance-snap.conf.j2
@@ -3,6 +3,7 @@
state_path = {{ snap_common }}/lib
# Log to systemd journal
use_journal = True
+bind_port = 9282
log_file = {{ snap_common }}/log/glance.log
debug = {{ logging_debug }}
diff --git a/snap-overlay/templates/glance.conf.d.keystone.conf.j2 b/snap-overlay/templates/glance.conf.d.keystone.conf.j2
index 9857898..f593dff 100644
--- a/snap-overlay/templates/glance.conf.d.keystone.conf.j2
+++ b/snap-overlay/templates/glance.conf.d.keystone.conf.j2
@@ -1,6 +1,6 @@
[keystone_authtoken]
-auth_uri = http://{{ control_ip }}:5000
-auth_url = http://{{ control_ip }}:5000
+auth_uri = https://{{ control_ip }}:5000/v3
+auth_url = https://{{ control_ip }}:5000/v3
memcached_servers = {{ compute_ip }}:11211
auth_type = password
project_domain_name = default
@@ -8,6 +8,7 @@ user_domain_name = default
project_name = service
username = glance
password = {{ glance_password }}
+cafile = {{ tls_cacert_path }}
[paste_deploy]
flavor = keystone
diff --git a/snap-overlay/templates/horizon-nginx.conf.j2 b/snap-overlay/templates/horizon-nginx.conf.j2
index 394e4e9..3f9b36d 100644
--- a/snap-overlay/templates/horizon-nginx.conf.j2
+++ b/snap-overlay/templates/horizon-nginx.conf.j2
@@ -1,10 +1,11 @@
-# If the OpenStack service has an API that runs behind uwsgi+nginx, you'll need
-# to define this template. Be sure to update "listen" with the port number and
-# also update "api-name" for the socket.
server {
- listen {{ dashboard_port }};
- error_log syslog:server=unix:/dev/log;
- access_log syslog:server=unix:/dev/log;
+ listen {{ dashboard_port }} ssl;
+ ssl_certificate {{ tls_cert_path }};
+ ssl_certificate_key {{ tls_key_path }};
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
+ access_log {{ snap_common }}/log/nginx-access.log;
+ error_log {{ snap_common }}/log/nginx-error.log;
location / {
include {{ snap }}/usr/conf/uwsgi_params;
uwsgi_param SCRIPT_NAME '';
diff --git a/snap-overlay/templates/keystone-nginx.conf.j2 b/snap-overlay/templates/keystone-nginx.conf.j2
index 413e923..62f6e1a 100644
--- a/snap-overlay/templates/keystone-nginx.conf.j2
+++ b/snap-overlay/templates/keystone-nginx.conf.j2
@@ -1,7 +1,11 @@
server {
- listen 5000;
- error_log syslog:server=unix:/dev/log;
- access_log syslog:server=unix:/dev/log;
+ listen 5000 ssl;
+ ssl_certificate {{ tls_cert_path }};
+ ssl_certificate_key {{ tls_key_path }};
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
+ access_log {{ snap_common }}/log/nginx-access.log;
+ error_log {{ snap_common }}/log/nginx-error.log;
location / {
include {{ snap }}/usr/conf/uwsgi_params;
uwsgi_param SCRIPT_NAME '';
diff --git a/snap-overlay/templates/microstack.json.j2 b/snap-overlay/templates/microstack.json.j2
index 587d62d..c3df4fd 100644
--- a/snap-overlay/templates/microstack.json.j2
+++ b/snap-overlay/templates/microstack.json.j2
@@ -13,12 +13,19 @@
"version": 3
}
},
- "auth_url": "http://{{ control_ip }}:5000",
+ "auth_url": "https://{{ control_ip }}:5000/v3",
"endpoint_type": null,
+{% if tls_generate_self_signed|lower == "false" %}
+ "https_cacert": "{{ tls_cacert_path }}",
+ "https_cert": "{{ tls_cert_path }}",
+ "https_key": "{{ tls_key_path }}",
+ "https_insecure": false,
+{% else %}
"https_cacert": "",
"https_cert": "",
- "https_insecure": false,
"https_key": "",
+ "https_insecure": true,
+{% endif %}
"profiler_conn_str": null,
"profiler_hmac_key": null,
"region_name": ""
diff --git a/snap-overlay/templates/microstack.rc.j2 b/snap-overlay/templates/microstack.rc.j2
index 1545f2e..f1e9df8 100644
--- a/snap-overlay/templates/microstack.rc.j2
+++ b/snap-overlay/templates/microstack.rc.j2
@@ -3,7 +3,8 @@ export OS_USER_DOMAIN_NAME=default
export OS_PROJECT_NAME=admin
export OS_USERNAME=admin
export OS_PASSWORD={{ keystone_password }}
-export OS_AUTH_URL=http://{{ control_ip }}:5000
+export OS_AUTH_PROTOCOL=https
+export OS_AUTH_URL=https://{{ control_ip }}:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2
-
+export OS_CACERT={{ tls_cacert_path }}
diff --git a/snap-overlay/templates/neutron-nginx.conf.j2 b/snap-overlay/templates/neutron-nginx.conf.j2
new file mode 100644
index 0000000..af38190
--- /dev/null
+++ b/snap-overlay/templates/neutron-nginx.conf.j2
@@ -0,0 +1,15 @@
+server {
+ listen 9696 ssl;
+ ssl_certificate {{ tls_cert_path }};
+ ssl_certificate_key {{ tls_key_path }};
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
+ access_log {{ snap_common }}/log/nginx-access.log;
+ error_log {{ snap_common }}/log/nginx-error.log;
+ location / {
+ proxy_set_header X-Forwarded-Host $host:$server_port;
+ proxy_set_header X-Forwarded-Server $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_pass http://127.0.0.1:9686;
+ }
+}
diff --git a/snap-overlay/templates/neutron-snap.conf.j2 b/snap-overlay/templates/neutron-snap.conf.j2
index 3f72448..e2f9420 100644
--- a/snap-overlay/templates/neutron-snap.conf.j2
+++ b/snap-overlay/templates/neutron-snap.conf.j2
@@ -3,6 +3,7 @@
state_path = {{ snap_common }}/lib
# Log to systemd journal
use_journal = True
+bind_port = 9686
log_file = {{ snap_common }}/log/neutron.log
debug = {{ logging_debug }}
diff --git a/snap-overlay/templates/neutron.keystone.conf.j2 b/snap-overlay/templates/neutron.keystone.conf.j2
index fef46ab..5ae9e96 100644
--- a/snap-overlay/templates/neutron.keystone.conf.j2
+++ b/snap-overlay/templates/neutron.keystone.conf.j2
@@ -2,8 +2,8 @@
auth_strategy = keystone
[keystone_authtoken]
-auth_uri = http://{{ control_ip }}:5000
-auth_url = http://{{ control_ip }}:5000
+auth_uri = https://{{ control_ip }}:5000/v3
+auth_url = https://{{ control_ip }}:5000/v3
memcached_servers = {{ compute_ip }}:11211
auth_type = password
project_domain_name = default
@@ -11,3 +11,4 @@ user_domain_name = default
project_name = service
username = neutron
password = {{ neutron_password }}
+cafile = {{ tls_cacert_path }}
diff --git a/snap-overlay/templates/neutron.nova.conf.j2 b/snap-overlay/templates/neutron.nova.conf.j2
index 5cba31a..02d5ac5 100644
--- a/snap-overlay/templates/neutron.nova.conf.j2
+++ b/snap-overlay/templates/neutron.nova.conf.j2
@@ -3,7 +3,7 @@ notify_nova_on_port_status_changes = True
notify_nova_on_port_data_changes = True
[nova]
-auth_url = http://{{ control_ip }}:5000
+auth_url = https://{{ control_ip }}:5000/v3
auth_type = password
project_domain_name = default
user_domain_name = default
@@ -11,3 +11,4 @@ region_name = {{ region_name }}
project_name = service
username = nova
password = {{ nova_password }}
+cafile = {{ tls_cacert_path }}
diff --git a/snap-overlay/templates/neutron.placement.conf.j2 b/snap-overlay/templates/neutron.placement.conf.j2
index e1dff73..741355b 100644
--- a/snap-overlay/templates/neutron.placement.conf.j2
+++ b/snap-overlay/templates/neutron.placement.conf.j2
@@ -1,5 +1,5 @@
[placement]
-auth_url = http://{{ control_ip }}:5000
+auth_url = https://{{ control_ip }}:5000/v3
auth_type = password
project_domain_name = default
user_domain_name = default
@@ -7,3 +7,4 @@ region_name = {{ region_name }}
project_name = service
username = placement
password = {{ placement_password }}
+cafile = {{ tls_cacert_path }}
diff --git a/snap-overlay/templates/nginx.conf.j2 b/snap-overlay/templates/nginx.conf.j2
index 9c5762c..5c102cf 100644
--- a/snap-overlay/templates/nginx.conf.j2
+++ b/snap-overlay/templates/nginx.conf.j2
@@ -45,5 +45,5 @@ http {
gzip_disable "msie6";
include {{ snap_common }}/etc/nginx/conf.d/*.conf;
- include {{ snap_common }}/etc/nginx/snap/sites-enabled/*;
+ include {{ snap_common }}/etc/nginx/sites-enabled/*;
}
diff --git a/snap-overlay/templates/nova-nginx.conf.j2 b/snap-overlay/templates/nova-nginx.conf.j2
index 91c43a6..4263742 100644
--- a/snap-overlay/templates/nova-nginx.conf.j2
+++ b/snap-overlay/templates/nova-nginx.conf.j2
@@ -1,10 +1,15 @@
server {
- listen 8778;
+ listen 8774 ssl;
+ ssl_certificate {{ tls_cert_path }};
+ ssl_certificate_key {{ tls_key_path }};
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
access_log {{ snap_common }}/log/nginx-access.log;
error_log {{ snap_common }}/log/nginx-error.log;
location / {
- include {{ snap }}/usr/conf/uwsgi_params;
- uwsgi_param SCRIPT_NAME '';
- uwsgi_pass unix://{{ snap_common }}/run/placement-api.sock;
+ proxy_set_header X-Forwarded-Host $host:$server_port;
+ proxy_set_header X-Forwarded-Server $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_pass http://127.0.0.1:8764;
}
}
diff --git a/snap-overlay/templates/nova-snap.conf.j2 b/snap-overlay/templates/nova-snap.conf.j2
index d9ecde9..9d0db12 100644
--- a/snap-overlay/templates/nova-snap.conf.j2
+++ b/snap-overlay/templates/nova-snap.conf.j2
@@ -7,6 +7,8 @@ state_path = {{ snap_common }}/lib
# Log to systemd journal
use_journal = True
+osapi_compute_listen_port = 8764
+
# Set a hostname to be an FQDN to avoid issues with port binding for
# which a hostname of a Nova node must match a hostname of an OVN chassis.
host = {{ node_fqdn }}
diff --git a/snap-overlay/templates/nova.conf.d.cinder.conf.j2 b/snap-overlay/templates/nova.conf.d.cinder.conf.j2
new file mode 100644
index 0000000..77bd1c1
--- /dev/null
+++ b/snap-overlay/templates/nova.conf.d.cinder.conf.j2
@@ -0,0 +1,5 @@
+[cinder]
+service_type = volume
+service_name = cinder
+region_name = {{ region_name }}
+cafile = {{ tls_cacert_path }}
diff --git a/snap-overlay/templates/nova.conf.d.glance.conf.j2 b/snap-overlay/templates/nova.conf.d.glance.conf.j2
index 973442d..99abdaa 100644
--- a/snap-overlay/templates/nova.conf.d.glance.conf.j2
+++ b/snap-overlay/templates/nova.conf.d.glance.conf.j2
@@ -2,3 +2,4 @@
service_type = image
service_name = glance
region_name = {{ region_name }}
+cafile = {{ tls_cacert_path }}
diff --git a/snap-overlay/templates/nova.conf.d.keystone.conf.j2 b/snap-overlay/templates/nova.conf.d.keystone.conf.j2
index c259341..93ab25d 100644
--- a/snap-overlay/templates/nova.conf.d.keystone.conf.j2
+++ b/snap-overlay/templates/nova.conf.d.keystone.conf.j2
@@ -1,6 +1,6 @@
[keystone_authtoken]
-auth_uri = http://{{ control_ip }}:5000
-auth_url = http://{{ control_ip }}:5000
+auth_uri = https://{{ control_ip }}:5000/v3
+auth_url = https://{{ control_ip }}:5000/v3
memcached_servers = {{ compute_ip }}:11211
auth_type = password
project_domain_name = default
@@ -8,6 +8,7 @@ user_domain_name = default
project_name = service
username = nova
password = {{ nova_password }}
+cafile = {{ tls_cacert_path }}
[paste_deploy]
flavor = keystone
diff --git a/snap-overlay/templates/nova.conf.d.neutron.conf.j2 b/snap-overlay/templates/nova.conf.d.neutron.conf.j2
index 1a717cb..41c65f4 100644
--- a/snap-overlay/templates/nova.conf.d.neutron.conf.j2
+++ b/snap-overlay/templates/nova.conf.d.neutron.conf.j2
@@ -1,6 +1,6 @@
[neutron]
-url = http://{{ control_ip }}:9696
-auth_url = http://{{ control_ip }}:5000
+url = https://{{ control_ip }}:9696
+auth_url = https://{{ control_ip }}:5000/v3
memcached_servers = {{ compute_ip }}:11211
auth_type = password
project_domain_name = default
@@ -11,3 +11,4 @@ username = neutron
password = {{ neutron_password }}
service_metadata_proxy = True
metadata_proxy_shared_secret = {{ ovn_metadata_proxy_shared_secret }}
+cafile = {{ tls_cacert_path }}
diff --git a/snap-overlay/templates/nova.conf.d.placement.conf.j2 b/snap-overlay/templates/nova.conf.d.placement.conf.j2
index 065d21c..b749277 100644
--- a/snap-overlay/templates/nova.conf.d.placement.conf.j2
+++ b/snap-overlay/templates/nova.conf.d.placement.conf.j2
@@ -1,6 +1,6 @@
[placement]
-auth_uri = http://{{ control_ip }}:5000
-auth_url = http://{{ control_ip }}:5000
+auth_uri = https://{{ control_ip }}:5000/v3
+auth_url = https://{{ control_ip }}:5000/v3
memcached_servers = {{ compute_ip }}:11211
auth_type = password
project_domain_name = default
@@ -9,3 +9,4 @@ project_name = service
username = nova
password = {{ nova_password }}
region_name = {{ region_name }}
+cafile = {{ tls_cacert_path }}
diff --git a/snap-overlay/templates/placement-nginx.conf.j2 b/snap-overlay/templates/placement-nginx.conf.j2
index c60dc9d..d84daaa 100644
--- a/snap-overlay/templates/placement-nginx.conf.j2
+++ b/snap-overlay/templates/placement-nginx.conf.j2
@@ -1,7 +1,11 @@
server {
- listen 8778;
- error_log syslog:server=unix:/dev/log;
- access_log syslog:server=unix:/dev/log;
+ listen 8778 ssl;
+ ssl_certificate {{ tls_cert_path }};
+ ssl_certificate_key {{ tls_key_path }};
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
+ access_log {{ snap_common }}/log/nginx-access.log;
+ error_log {{ snap_common }}/log/nginx-error.log;
location / {
include {{ snap }}/usr/conf/uwsgi_params;
uwsgi_param SCRIPT_NAME '';
diff --git a/snap-overlay/templates/placement.conf.d.keystone.conf.j2 b/snap-overlay/templates/placement.conf.d.keystone.conf.j2
index ed05bee..dfd1438 100644
--- a/snap-overlay/templates/placement.conf.d.keystone.conf.j2
+++ b/snap-overlay/templates/placement.conf.d.keystone.conf.j2
@@ -1,6 +1,6 @@
[keystone_authtoken]
-auth_uri = http://{{ control_ip }}:5000
-auth_url = http://{{ control_ip }}:5000
+auth_uri = https://{{ control_ip }}:5000/v3
+auth_url = https://{{ control_ip }}:5000/v3
memcached_servers = {{ compute_ip }}:11211
auth_type = password
project_domain_name = default
@@ -8,6 +8,7 @@ user_domain_name = default
project_name = service
username = placement
password = {{ placement_password }}
+cafile = {{ tls_cacert_path }}
[paste_deploy]
flavor = keystone
diff --git a/snap/hooks/post-refresh b/snap/hooks/post-refresh
index 327a9bd..ff75d4a 100755
--- a/snap/hooks/post-refresh
+++ b/snap/hooks/post-refresh
@@ -22,7 +22,7 @@ fi
# Add default ports for mysql, rabbit and dashboard services.
# [2019-11-21] build 171 (beta) -> master
if [ -z "$(snapctl get config.network.ports.dashboard)" ]; then
- snapctl set config.network.ports.dashboard=80
+ snapctl set config.network.ports.dashboard=443
fi
if [ -z "$(snapctl get config.network.ports.mysql)" ]; then
diff --git a/tests/basic-test.sh b/tests/basic-test.sh
index d4099f5..19a9971 100755
--- a/tests/basic-test.sh
+++ b/tests/basic-test.sh
@@ -190,7 +190,7 @@ echo "++++++++++++++++++++++++++++++++++++++++++++++++++"
export HORIZON_IP
if [[ $PREFIX == *"multipass"* ]]; then
- echo "Opening $HORIZON_IP:80 up to the outside world."
+ echo "Opening $HORIZON_IP:443 up to the outside world."
cat< /tmp/_10_hosts.py
# Allow all hosts to connect to this machine
ALLOWED_HOSTS = ['*',]
diff --git a/tests/configure-the-things.sh b/tests/configure-the-things.sh
index 7ffe635..36dc616 100644
--- a/tests/configure-the-things.sh
+++ b/tests/configure-the-things.sh
@@ -26,9 +26,9 @@ sudo systemctl restart snap.microstack.*
microstack.openstack user show admin || {
sudo microstack.keystone-manage bootstrap \
--bootstrap-password $OS_PASSWORD \
- --bootstrap-admin-url http://10.20.20.1:5000/v3/ \
- --bootstrap-internal-url http://10.20.20.1:5000/v3/ \
- --bootstrap-public-url http://10.20.20.1:5000/v3/ \
+ --bootstrap-admin-url https://10.20.20.1:5000/v3/ \
+ --bootstrap-internal-url https://10.20.20.1:5000/v3/ \
+ --bootstrap-public-url https://10.20.20.1:5000/v3/ \
--bootstrap-region-id microstack
}
diff --git a/tests/framework.py b/tests/framework.py
index 17241c2..a893dad 100644
--- a/tests/framework.py
+++ b/tests/framework.py
@@ -434,7 +434,7 @@ class Framework(unittest.TestCase):
'microstack',
'config.credentials.keystone-password'
]).decode('utf-8')
- self.driver.get(f'http://{control_ip}:{dashboard_port}/')
+ self.driver.get(f'https://{control_ip}:{dashboard_port}/')
# Login to horizon!
self.driver.find_element(By.ID, "id_username").click()
self.driver.find_element(By.ID, "id_username").send_keys("admin")
diff --git a/tools/cluster/cluster/add_compute.py b/tools/cluster/cluster/add_compute.py
index e88e09c..8c6f22f 100644
--- a/tools/cluster/cluster/add_compute.py
+++ b/tools/cluster/cluster/add_compute.py
@@ -29,14 +29,23 @@ def _create_credential():
domain_name = 'default'
# TODO: add support for TLS-terminated Keystone once this is supported.
auth = v3.password.Password(
- auth_url="http://localhost:5000/v3",
+ auth_url="https://localhost:5000/v3",
username='nova',
password=config_get('config.credentials.nova-password'),
user_domain_name=domain_name,
project_domain_name=domain_name,
project_name=project_name
)
- sess = session.Session(auth=auth)
+ if config_get('config.tls.generate-self-signed'):
+ sess = session.Session(
+ auth=auth,
+ verify=False,
+ )
+ else:
+ sess = session.Session(
+ auth=auth,
+ verify=config_get('config.tls.cacert-path'),
+ )
keystone_client = client.Client(session=sess)
# Only allow this credential to list the Keystone catalog. After it
diff --git a/tools/cluster/cluster/client.py b/tools/cluster/cluster/client.py
index 249a8f0..7378767 100755
--- a/tools/cluster/cluster/client.py
+++ b/tools/cluster/cluster/client.py
@@ -98,6 +98,20 @@ def join():
control_ip = response_dict['config']['network']['control-ip']
shell.config_set(**{'config.network.control-ip': control_ip})
+ # Write controller's TLS certificate data to compute node
+ config = json.loads(shell.check_output('snapctl', 'get', 'config'))
+ tls_path_map = {
+ 'cacert-path': 'tls_cacert',
+ 'cert-path': 'tls_cert',
+ 'key-path': 'tls_key',
+ }
+ for tls_config, tls_file in tls_path_map.items():
+ tls_path = response_dict['config']['tls'][tls_config]
+ shell.config_set(**{'config.tls.{}'.format(tls_config): tls_path})
+ with open(tls_path, "w") as f:
+ f.write(response_dict[tls_file])
+ shell.config_set(**{'config.tls.generate-self-signed': False})
+
if __name__ == '__main__':
join()
diff --git a/tools/cluster/cluster/daemon.py b/tools/cluster/cluster/daemon.py
index b462f6c..9f903cb 100644
--- a/tools/cluster/cluster/daemon.py
+++ b/tools/cluster/cluster/daemon.py
@@ -10,6 +10,7 @@ from werkzeug.exceptions import BadRequest
from cluster.shell import check_output
+from cluster.shell import config_get
from keystoneauth1.identity import v3
from keystoneauth1 import session
@@ -153,8 +154,20 @@ def handle_unexpected_error(error):
def join_info():
"""Generate the configuration information to return to a client."""
# TODO: be selective about what we return. For now, we just get everything.
+ info = {}
config = json.loads(check_output('snapctl', 'get', 'config'))
- info = {'config': config}
+ info['config'] = config
+
+ # Add the controller's TLS certificate data
+ tls_path_map = {
+ 'cacert-path': 'tls_cacert',
+ 'cert-path': 'tls_cert',
+ 'key-path': 'tls_key',
+ }
+ for tls_config, tls_file in tls_path_map.items():
+ with open(config_get('config.tls.{}'.format(tls_config)), "r") as f:
+ info[tls_file] = f.read()
+
return info
@@ -210,8 +223,7 @@ def join():
' authentication data in the request.')
return MissingAuthDataInRequest()
- # TODO: handle https here when TLS termination support is added.
- keystone_base_url = 'http://localhost:5000/v3'
+ keystone_base_url = 'https://localhost:5000/v3'
# In an unlikely event of failing to construct an auth object
# treat it as if invalid data got passed in terms of responding
@@ -231,7 +243,16 @@ def join():
try:
# Use the auth object with the app credential to create a session
# which the Keystone client will use.
- sess = session.Session(auth=auth)
+ if config_get('config.tls.generate-self-signed'):
+ sess = session.Session(
+ auth=auth,
+ verify=False,
+ )
+ else:
+ sess = session.Session(
+ auth=auth,
+ verify=config_get('config.tls.cacert-path'),
+ )
except Exception:
logger.exception('An exception has occurred while trying to build'
' a Session object with auth data'
diff --git a/tools/init/init/main.py b/tools/init/init/main.py
index fa175b9..1658bb2 100644
--- a/tools/init/init/main.py
+++ b/tools/init/init/main.py
@@ -182,6 +182,7 @@ def init() -> None:
# The following are not yet implemented:
# questions.VmSwappiness(),
# questions.FileHandleLimits(),
+ questions.TlsCertificates(),
questions.DashboardAccess(),
questions.RabbitMq(),
questions.DatabaseSetup(),
diff --git a/tools/init/init/questions/__init__.py b/tools/init/init/questions/__init__.py
index 7b2555d..a227f89 100644
--- a/tools/init/init/questions/__init__.py
+++ b/tools/init/init/questions/__init__.py
@@ -26,14 +26,16 @@ limitations under the License.
import json
from time import sleep
from os import path
+from pathlib import Path
+from shutil import copyfile
from init import shell
from init.shell import (check, call, check_output, sql, nc_wait, log_wait,
restart, download, disable, enable)
from init.config import Env, log
-from init import cluster_tls
+from init import tls
from init.questions.question import Question
-from init.questions import clustering, network, uninstall # noqa F401
+from init.questions import clustering, network, tls, uninstall # noqa F401
_env = Env().get_env()
@@ -102,7 +104,13 @@ class Clustering(Question):
'config.services.hypervisor': 'true',
})
# Generate a self-signed certificate for the clustering service.
- cluster_tls.generate_selfsigned()
+ cert_path, key_path = (
+ Path(shell.config_get('config.cluster.tls-cert-path')),
+ Path(shell.config_get('config.cluster.tls-key-path')),
+ )
+ tls.generate_self_signed(
+ cert_path, key_path,
+ fingerprint_config='config.cluster.fingerprint')
# Write templates
check('snap-openstack', 'setup')
@@ -288,6 +296,36 @@ class DashboardAccess(ConfigQuestion):
hosts=answer))
+class TlsCertificates(Question):
+
+ _type = 'boolean'
+ _question = 'Do you wish to generate a self-signed certificate for TLS?'
+ config_key = 'config.tls.generate-self-signed'
+
+ def yes(self, answer: str) -> None:
+ role = shell.config_get('config.cluster.role')
+
+ if role == 'control':
+ log.info('Generating TLS Certificate and Key')
+ cert_path, key_path = (
+ Path(shell.config_get('config.tls.cert-path')),
+ Path(shell.config_get('config.tls.key-path')),
+ )
+ tls.generate_self_signed(cert_path, key_path, ip=_env['control_ip'])
+ copyfile(Path(shell.config_get('config.tls.cert-path')),
+ Path(shell.config_get('config.tls.cacert-path')))
+ restart('nginx')
+
+ elif role == 'compute':
+ log.warning('TLS certificate generation can only be performed on '
+ 'control node')
+
+ def no(self, answer: str):
+ log.info('TLS certificates must be provided: config.tls.cacert-path, '
+ 'config.tls.cert-path, and config.tls.key-path.')
+ restart('nginx')
+
+
class RabbitMq(Question):
"""Wait for Rabbit to start, then setup permissions."""
@@ -362,7 +400,7 @@ class DatabaseSetup(Question):
if call('openstack', 'user', 'show', 'admin'):
return
- bootstrap_url = 'http://{control_ip}:5000/v3/'.format(**_env)
+ bootstrap_url = 'https://{control_ip}:5000/v3/'.format(**_env)
check('snap-openstack', 'launch', 'keystone-manage', 'bootstrap',
'--bootstrap-password', _env['keystone_password'],
@@ -401,7 +439,7 @@ class DatabaseSetup(Question):
log.info('Creating service project ...')
if not call('openstack', 'project', 'show', 'service'):
check('openstack', 'project', 'create', '--domain',
- 'default', '--description', 'Service Project',
+ 'default', '--description', '"Service Project"',
'service')
log.info('Keystone configured!')
@@ -536,7 +574,7 @@ class PlacementSetup(Question):
for endpoint in ['public', 'internal', 'admin']:
call('openstack', 'endpoint', 'create', '--region',
'microstack', 'placement', endpoint,
- 'http://{control_ip}:8778'.format(**_env))
+ 'https://{control_ip}:8778'.format(**_env))
log.info('Running Placement DB migrations...')
check('snap-openstack', 'launch', 'placement-manage', 'db', 'sync')
@@ -612,6 +650,7 @@ class NovaControlPlane(Question):
enable('nova-api')
restart('nova-compute')
+ restart('nginx')
for service in [
'nova-api-metadata',
@@ -630,7 +669,7 @@ class NovaControlPlane(Question):
for endpoint in ['public', 'internal', 'admin']:
call('openstack', 'endpoint', 'create', '--region',
'microstack', 'compute', endpoint,
- 'http://{control_ip}:8774/v2.1'.format(**_env))
+ 'https://{control_ip}:8774/v2.1'.format(**_env))
log.info('Creating default flavors...')
@@ -682,7 +721,7 @@ class CinderSetup(Question):
check(
'openstack', 'endpoint', 'create', '--region',
'microstack', f'volume{api_version}', endpoint,
- f'http://{control_ip}:8776/{api_version}/'
+ f'https://{control_ip}:8776/{api_version}/'
'$(project_id)s'
)
log.info('Running Cinder DB migrations...')
@@ -754,12 +793,13 @@ class NeutronControlPlane(Question):
for endpoint in ['public', 'internal', 'admin']:
call('openstack', 'endpoint', 'create', '--region',
'microstack', 'network', endpoint,
- 'http://{control_ip}:9696'.format(**_env))
+ 'https://{control_ip}:9696'.format(**_env))
check('snap-openstack', 'launch', 'neutron-db-manage', 'upgrade',
'head')
enable('neutron-api')
enable('neutron-ovn-metadata-agent')
+ restart('nginx')
nc_wait(_env['control_ip'], '9696')
@@ -864,10 +904,11 @@ class GlanceSetup(Question):
for endpoint in ['internal', 'admin', 'public']:
check('openstack', 'endpoint', 'create', '--region',
'microstack', 'image', endpoint,
- 'http://{compute_ip}:9292'.format(**_env))
+ 'https://{compute_ip}:9292'.format(**_env))
check('snap-openstack', 'launch', 'glance-manage', 'db_sync')
enable('glance-api')
+ restart('nginx')
nc_wait(_env['compute_ip'], '9292')
diff --git a/tools/init/init/cluster_tls.py b/tools/init/init/tls.py
similarity index 79%
rename from tools/init/init/cluster_tls.py
rename to tools/init/init/tls.py
index 95e4c98..3724f7c 100644
--- a/tools/init/init/cluster_tls.py
+++ b/tools/init/init/tls.py
@@ -1,9 +1,12 @@
#!/usr/bin/env python3
-from pathlib import Path
+
+from init.shell import check
from datetime import datetime
from dateutil.relativedelta import relativedelta
+import ipaddress
+import socket
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
@@ -15,7 +18,7 @@ from cryptography.x509.oid import NameOID
from init import shell
-def generate_selfsigned():
+def generate_self_signed(cert_path, key_path, ip=None, fingerprint_config=None):
"""Generate a self-signed certificate with associated keys.
The certificate will have a fake CNAME and subjAltName since
@@ -28,26 +31,29 @@ def generate_selfsigned():
via a secure channel.
https://owasp.org/www-community/controls/Certificate_and_Public_Key_Pinning
"""
- cert_path, key_path = (
- Path(shell.config_get('config.cluster.tls-cert-path')),
- Path(shell.config_get('config.cluster.tls-key-path')),
- )
# Do not generate a new certificate and key if there is already an existing
# pair. TODO: improve this check and allow renewal.
if cert_path.exists() and key_path.exists():
return
- dummy_cn = 'microstack.run'
key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend(),
)
+ cn = socket.gethostname()
common_name = x509.Name([
- x509.NameAttribute(NameOID.COMMON_NAME, dummy_cn)
+ x509.NameAttribute(NameOID.COMMON_NAME, cn)
])
- san = x509.SubjectAlternativeName([x509.DNSName(dummy_cn)])
+ if ip:
+ san = x509.SubjectAlternativeName(
+ [x509.DNSName(cn), x509.IPAddress(ipaddress.ip_address(ip))]
+ )
+ else:
+ san = x509.SubjectAlternativeName([x509.DNSName(cn)])
+
basic_contraints = x509.BasicConstraints(ca=True, path_length=0)
+
now = datetime.utcnow()
cert = (
x509.CertificateBuilder()
@@ -63,7 +69,8 @@ def generate_selfsigned():
)
cert_fprint = cert.fingerprint(hashes.SHA256()).hex()
- shell.config_set(**{'config.cluster.fingerprint': cert_fprint})
+ if fingerprint_config:
+ shell.config_set(**{fingerprint_config: cert_fprint})
serialized_cert = cert.public_bytes(encoding=serialization.Encoding.PEM)
serialized_key = key.private_bytes(
@@ -73,3 +80,5 @@ def generate_selfsigned():
)
cert_path.write_bytes(serialized_cert)
key_path.write_bytes(serialized_key)
+ check('chmod', '644', str(cert_path))
+ check('chmod', '600', str(key_path))
diff --git a/tools/launch/launch/main.py b/tools/launch/launch/main.py
index c60fcc1..47a067c 100644
--- a/tools/launch/launch/main.py
+++ b/tools/launch/launch/main.py
@@ -207,8 +207,8 @@ Access it with `ssh -i {key_path} {username}@{ip}`\
gate = check_output('snapctl', 'get', 'config.network.ext-gateway')
port = check_output('snapctl', 'get', 'config.network.ports.dashboard')
- print('You can also visit the OpenStack dashboard at http://{}:{}'.format(
- gate, port))
+ print('You can also visit the OpenStack dashboard at https://{}:{}'.format(
+ gate, port))
def main():