技术并艺术着

张华的技术Blog

OpenStack SSL (by joshua)

版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 (作者:张华 发表于:2018-02-07)

OpenStack Charm如何支持SSL

OpenStack Charm需为每个OpenStack服务配置证书(/var/lib/keystone/juju_ssl/, /usr/local/share/ca-certificates/)与https endpoint,同时也会生成/etc/apache2/ssl/keystone配置。

  1. 一种方式有证书就直接指定证书
juju config <openstack-charm> os-admin-hostname='X.xxx.com' os-public-hostname='X.xxx.com' os-internal-hostname='X.xxx.com' ssl_ca='$cat ~/ssl_ca.crt' ssl_cert='$cat ~/ssl_cert.crt' ssl_key=''$cat ~/ssl_key.key'
  1. 第二种方式是由charm来自动生成证书。如果用户没有指定ssl_cert与ssl_key,那么is_cert_provided_in_config=False,charm将自动生成证书。
def is_cert_provided_in_config():
    cert = config('ssl_cert')
    key = config('ssl_key')
    return bool(cert and key)

具体命令如下,也可参考:https://paste.ubuntu.com/26533565/

juju config keystone use-https=true
juju config keystone https-service-endpoints=true
tree /var/lib/keystone/juju_ssl/
grep -r 'ssl' /etc/keystone/
grep -r 'ssl' /etc/nova/  #on nova node
select * from endpoint;
juju run --unit keystone/0 "relation-ids identity-service"
juju run --unit keystone/0 "relation-list -r identity-service:13"
juju run --unit keystone/0 "relation-get -r identity-service:13 - nova-cloud-controller/0"

export OS_REGION_NAME=RegionOne
export OS_PROJECT_NAME=admin
export OS_PASSWORD=openstack
export OS_AUTH_URL=https://10.5.0.28:5000/v2.0
export OS_USERNAME=admin
openstack --insecure endpoint list
openstack --insecure server list
openstack --insecure --debug server list
openstack --insecure --debug volume list

OpenStack HA Charm如何支持SSL

如果如nova-cloud-controller服务前又运行了下列命令添加了HA服务时呢?

juju add-unit nova-cloud-controller -n 2  
juju deploy hacluster ncc-hacluster --series xenial  
juju add-relation nova-cloud-controller ncc-hacluster  
juju config nova-cloud-controller vip=10.5.104.1

corosync将通过下列配置将VIP=10.5.104.1创建在juju-2f3cc6-mitaka-10上。

root@juju-2f3cc6-mitaka-10:~# crm status
Last updated: Wed Feb  7 04:18:31 2018      Last change: Wed Feb  7 04:09:33 2018 by hacluster via crmd on juju-2f3cc6-mitaka-10
Stack: corosync
Current DC: juju-2f3cc6-mitaka-6 (version 1.1.14-70404b0) - partition with quorum
3 nodes and 4 resources configured
Online: [ juju-2f3cc6-mitaka-10 juju-2f3cc6-mitaka-11 juju-2f3cc6-mitaka-6 ]
Full list of resources:
 Resource Group: grp_nova_vips
     res_nova_ens3_vip  (ocf::heartbeat:IPaddr2):   Started juju-2f3cc6-mitaka-10
 Clone Set: cl_nova_haproxy [res_nova_haproxy]
     Started: [ juju-2f3cc6-mitaka-10 juju-2f3cc6-mitaka-11 juju-2f3cc6-mitaka-6 ]

root@juju-2f3cc6-mitaka-10:~# ip addr show ens3 |grep 10.5.104.1
    inet 10.5.104.1/16 brd 10.5.255.255 scope global secondary ens3

同时,三个HA节点上的haproxy的配置(/etc/haproxy/haproxy.cfg)将创建代理。

frontend tcp-in_nova-api-os-compute
    bind *:8774
    bind :::8774
    acl net_10.5.0.15 dst 10.5.0.15/255.255.0.0
    use_backend nova-api-os-compute_10.5.0.15 if net_10.5.0.15
    default_backend nova-api-os-compute_10.5.0.15
backend nova-api-os-compute_10.5.0.15
    balance leastconn
    server nova-cloud-controller-1 10.5.0.15:8764 check
    server nova-cloud-controller-0 10.5.0.37:8764 check
    server nova-cloud-controller-2 10.5.0.52:8764 check

最重要的是,三个HA节点上Apache都将设置代理“RequestHeader set X-Forwarded-Proto “https””,完整的配置如下:

root@juju-2f3cc6-mitaka-10:~# cat /etc/apache2/sites-available/openstack_https_frontend.conf 
Listen 8764
<VirtualHost 10.5.0.15:8764>
    ServerName 10.5.104.1
    SSLEngine on
    SSLProtocol +TLSv1 +TLSv1.1 +TLSv1.2
    SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!EXP:!LOW:!MEDIUM
    SSLCertificateFile /etc/apache2/ssl/nova/cert_10.5.104.1
    # See LP 1484489 - this is to support <= 2.4.7 and >= 2.4.8
    SSLCertificateChainFile /etc/apache2/ssl/nova/cert_10.5.104.1
    SSLCertificateKeyFile /etc/apache2/ssl/nova/key_10.5.104.1
    ProxyPass / http://localhost:8754/
    ProxyPassReverse / http://localhost:8754/
    ProxyPreserveHost on
    RequestHeader set X-Forwarded-Proto "https"
</VirtualHost>
<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>
<Location />
    Order allow,deny
    Allow from all
</Location>

OpenStack Horizon和Apache代理之间如何支持SSL

openstack horizon使用了Django框架,Django中有如下代码(https://github.com/django/django/blob/2.0.2/django/http/request.py#L191),

    @property
    def scheme(self):
        if settings.SECURE_PROXY_SSL_HEADER:
            try:
                header, value = settings.SECURE_PROXY_SSL_HEADER
            except ValueError:
                raise ImproperlyConfigured(
                    'The SECURE_PROXY_SSL_HEADER setting must be a tuple containing two values.'
                )
            if self.META.get(header) == value:
                return 'https'
        return self._get_scheme()

它会根据django中是否配置了SECURE_PROXY_SSL_HEADER,然后比较和header中传过来的SECURE_PROXY_SSL_HEADER(self.META.get(header))是否相等, 若相等才返回https给前端代理。所以这说明需要做两件事情:

  1. 一是在django的conf/global_settings.py模板中配置: SECURE_PROXY_SSL_HEADER = (‘HTTP_X_FORWARDED_PROTO’, ‘https’)
  2. 二是前端代理apache中的配置传过来名为X-Forwarded-Proto的header: RequestHeader set X-Forwarded-Proto “https”
    更多见: https://design.canonical.com/2015/08/django-behind-a-proxy-fixing-absolute-urls/

OpenStack其他工程和Apache代理之间如何支持SSL

至于其它openstack工程如nova则需要使用olso.middleware中的http_proxy_to_wsgi.py(https://github.com/openstack/oslo.middleware/blob/stable/ocata/oslo_middleware/http_proxy_to_wsgi.py)用于解析前端代理apache传过来的X-Forwarded-Proto

            # World before RFC7239
            forwarded_proto = req.environ.get("HTTP_X_FORWARDED_PROTO")
            if forwarded_proto:
                req.environ['wsgi.url_scheme'] = forwarded_proto

nova-api中再根据wsgi.url_scheme(https://github.com/openstack/nova/blob/stable/ocata/nova/api/openstack/urlmap.py)决定是使用80还是ssl的443

            if environ['wsgi.url_scheme'] == 'http':
                port = '80'
            else:
                port = '443'

配置http_proxy_to_wsgi的方法是在/etc/nova/api-paste.ini中添加http_proxy_to_wsgi( eg: https://bugs.launchpad.net/keystone/+bug/1590608)

[composite:openstack_compute_api_v21]
use = call:nova.api.auth:pipeline_factory_v21
noauth2 = cors http_proxy_to_wsgi compute_req_id faultwrap sizelimit noauth2 osapi_compute_app_v21
keystone = cors http_proxy_to_wsgi compute_req_id faultwrap sizelimit authtoken keystonecontext osapi_compute_app_v21
[filter:http_proxy_to_wsgi]
paste.filter_factory = oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory

附录 - 原生OpenStack配置SSL的方法

1, Create ssl certifate

$ sudo keystone-manage ssl_setup --keystone-user keystone --keystone-group keystone
$ chown -R keystone:keystone /etc/keystone/ssl
$ sudo ls /etc/keystone/ssl/certs
01.pem  ca.pem  index.txt  index.txt.attr  index.txt.old  keystone.pem  openssl.conf  req.pem  serial  serial.old
$ sudo ls /etc/keystone/ssl/private
cakey.pem  keystonekey.pem

openssl genrsa -out /etc/keystone/ssl/private/cakey.pem 1024
openssl req -new -x509 -extensions v3_ca -key /etc/keystone/ssl/private/cakey.pem -out /etc/keystone/ssl/certs/ca.pem -days 3650 -config /etc/keystone/ssl/certs/openssl.conf -subj /C=US/ST=Unset/L=Unset/O=Unset/CN=localhost
openssl genrsa -out /etc/keystone/ssl/private/keystonekey.pem 1024
openssl req -key /etc/keystone/ssl/private/keystonekey.pem -new -out /etc/keystone/ssl/certs/req.pem -config /etc/keystone/ssl/certs/openssl.conf -subj /C=US/ST=Unset/L=Unset/O=Unset/CN=localhost
openssl ca -batch -out /etc/keystone/ssl/certs/keystone.pem -config /etc/keystone/ssl/certs/openssl.conf -days 3650d -cert /etc/keystone/ssl/certs/ca.pem -keyfile /etc/keystone/ssl/private/cakey.pem -infiles /etc/keystone/ssl/certs/req.pem

2, Keystone ssl configuration

# vi /etc/keystone/keystone.conf
[signing]
certfile = /var/lib/keystone/juju_ssl/pki/certs/signing_cert.pem
keyfile = /var/lib/keystone/juju_ssl/pki/privates/signing_key.pem
ca_certs = /var/lib/keystone/juju_ssl/pki/certs/ca.pem
ca_key = /var/lib/keystone/juju_ssl/pki/certs/ca_key.pem

export OS_AUTH_URL=https://{keystoneHost}:5000/v2.0

# create new https endpoint
keystone endpoint-create
--service keystone --region RegionOne --publicurl
https://{keystoneHost}:5000/v2.0 --internalurl
https://{keystoneHost}:35357/v2.0 --adminurl
https://{keystoneHost}:35357/v2.0

# delete old http endpoint
keystone –-insecure endpoint-delete {old endpoint id}

3, Nova ssl configuration

# configure nova to use https to connect keystone
# vi /etc/nova/api-paste.ini
auth_uri = https://10.1.0.92:5000/v2.0
auth_protocol = https
insecure = True

service openstack-nova-api restart
service openstack-nova-compute restart
service openstack-nova-scheduler restart
service openstack-nova-cert restart
service openstack-nova-conductor restart
service openstack-nova-consoleauth restart


# vi /etc/nova/nova.conf [DEFAULT]
enabled_ssl_apis=osapi_compute
ssl_cert_file=/etc/nova/ssl/keystone.pem
ssl_key_file=/etc/nova/ssl/keystonekey.pem

# test it, at this time other component has not be configured to use https, so use --insecure
nova --insecure hypervisor-list

# copy ssl certifate for nova
# mkdir /etc/nova/ssl
# cp /etc/keystone/ssl/certs/keystone.pem /etc/nova/ssl/
# cp /etc/keystone/ssl/private/keystonekey.pem /etc/nova/ssl/
# chown -R nova:nova /etc/nova/ssl/


# create new https endpoint for nova
# keystone --insecure
endpoint-create --service nova --region RegionOne --publicurl
"https://{novaHost}:8774/v2/%(tenant_id)s" --internalurl
"https://{novaHost}:8774/v2/%(tenant_id)s" --adminurl
"https://{novaHost}:8774/v2/%(tenant_id)s"

备份网址

https://zhhuabj.github.io/2018/02/07/OpenStack-SSL/

阅读更多
版权声明:本文为博主原创文章,如需转载,请注明出处! https://blog.csdn.net/quqi99/article/details/79279060
文章标签: ssl charm
个人分类: OpenStack Non-Networking
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭