<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    
    <title>Andrew's blog (Entries tagged as openstack)</title>
    <link>https://blog.etc.gen.nz/</link>
    <description>This is a blog, it is it is.</description>
    <dc:language>en</dc:language>
    <admin:errorReportsTo rdf:resource="mailto:blog@etc.gen.nz" />
    <generator>Serendipity 2.4.0 - http://www.s9y.org/</generator>
    <pubDate>Sun, 03 Aug 2025 09:20:18 GMT</pubDate>

    <image>
    <url>https://blog.etc.gen.nz/templates/2k11/img/s9y_banner_small.png</url>
    <title>RSS: Andrew's blog - This is a blog, it is it is.</title>
    <link>https://blog.etc.gen.nz/</link>
    <width>100</width>
    <height>21</height>
</image>

<item>
    <title>Let's Encrypt with Octavia in OpenStack</title>
    <link>https://blog.etc.gen.nz/archives/135-Lets-Encrypt-with-Octavia-in-OpenStack.html</link>
    
    <comments>https://blog.etc.gen.nz/archives/135-Lets-Encrypt-with-Octavia-in-OpenStack.html#comments</comments>
    <wfw:comment>https://blog.etc.gen.nz/wfwcomment.php?cid=135</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://blog.etc.gen.nz/rss.php?version=2.0&amp;type=comments&amp;cid=135</wfw:commentRss>
    

    <author>andrew@etc.gen.nz (Andrew Ruthven)</author>
    <content:encoded>
    &lt;p&gt;I like using &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/catalystcloud.nz&#039;]);&quot;  href=&quot;https://catalystcloud.nz&quot;&gt;Catalyst Cloud&lt;/a&gt; to host some of my personal sites. In the past I used to use &lt;a href=&quot;https://blog.etc.gen.nz/index.php?/plugin/tag/cacert&quot;&gt;CAcert&lt;/a&gt; for my TLS certificates, but more recently I&#039;ve been using &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/letsencrypt.org/&#039;]);&quot;  href=&quot;https://letsencrypt.org/&quot;&gt;Let&#039;s Encrypt&lt;/a&gt; for my TLS certificates as they&#039;re trusted in all browsers. Currently the LoadBalancer as a Service (LBaaS) in Catalyst Cloud doesn&#039;t have built in support for Let&#039;s Encrypt. I could use an apache2/nginx proxy and handle the TLS termination there and have that manage the Let&#039;s Encrypt lifecycle, but really, I&#039;d rather use LBaaS.&lt;/p&gt;

&lt;p&gt;So I thought I&#039;d set about working out how to get Dehydrated (the Let&#039;s Encrypt client I&#039;ve been using) to drive LBaaS (known as Octavia). I figured this would be of interest to other people using Octavia with OpenStack in general, not just Catalyst Cloud.&lt;/p&gt;

&lt;p&gt;There&#039;s a few things you need to do. These instructions are specific to Debian:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Install and configure Dehydrated to create the certificates for the domain(s) you want.
    &lt;ul&gt;&lt;li&gt;&lt;tt&gt;apt install barbican&lt;/tt&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/docs.catalystcloud.nz/load-balancer/layer-4.html&#039;]);&quot;  href=&quot;https://docs.catalystcloud.nz/load-balancer/layer-4.html&quot;&gt;Create the LoadBalancer&lt;/a&gt; (use the API, ClickOps, whatever), just forward port 80 for now (see sample Apache configs below).&lt;/li&gt;
  &lt;li&gt;Save the sample hook.sh below to &lt;tt&gt;/etc/dehydrated/hook.sh&lt;/tt&gt;, you&#039;ll probably need to customise it, mine is a bit more complicated!&lt;/li&gt;
  &lt;li&gt;Insert the UUID of your LoadBalancer in hook.sh where LB_LISTENER is set.&lt;/li&gt;
  &lt;li&gt;Create &lt;tt&gt;/etc/dehydrated/catalystcloud/password&lt;/tt&gt; as described in hook.sh&lt;/li&gt;
  &lt;li&gt;Save OpenRC file from the Catalyst Cloud dashboard as &lt;tt&gt;/etc/dehydrated/catalystcloud/openrc.sh&lt;/tt&gt;&lt;/li&gt;
  &lt;li&gt;Install jq, openssl and the openstack tools, on Debian this is:
    &lt;ul&gt;&lt;li&gt;&lt;tt&gt;apt install jq openssl python3-openstackclient python3-barbicanclient python3-octaviaclient&lt;/tt&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Add &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/docs.catalystcloud.nz/load-balancer/tls-termination.html&#039;]);&quot;  href=&quot;https://docs.catalystcloud.nz/load-balancer/tls-termination.html&quot;&gt;TLS termination to your LoadBalancer&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;You should be able to rename the latest certs &lt;tt&gt;/var/lib/dehydrated/certs/$DOMAIN&lt;/tt&gt; and then run &lt;tt&gt;dehydrated -c&lt;/tt&gt; to have it reissue and then deploy a cert.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As we&#039;re using &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/letsencrypt.org/docs/challenge-types/#http-01-challenge&#039;]);&quot;  href=&quot;https://letsencrypt.org/docs/challenge-types/#http-01-challenge&quot;&gt;HTTP-01 Challenge Type&lt;/a&gt; here, you need to have the LoadBalancer forwarding port 80 to your website to allow for the challenge response. It is good practice to have a redirect to HTTPS, here&#039;s an example virtual host for Apache:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;VirtualHost *:80&amp;gt;
    ServerName www.example.com
    ServerAlias example.com

    RewriteEngine On
    RewriteRule ^/.well-known/ - [L]
    RewriteRule ^/(.*)$ https://www.example.com/$1 [R=301,L]

    &amp;lt;Location /&amp;gt;
        Require all granted
    &amp;lt;/Location&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/pre&gt;

You all also need this in &lt;tt&gt;/etc/apache2/conf-enabled/letsencrypt.conf&lt;/tt&gt;:

&lt;pre&gt;
Alias /.well-known/acme-challenge /var/lib/dehydrated/acme-challenges

&amp;lt;Directory /var/lib/dehydrated/acme-challenges&amp;gt;
        Options None
        AllowOverride None

        # Apache 2.x
        &amp;lt;IfModule !mod_authz_core.c&amp;gt;
                Order allow,deny
                Allow from all
        &amp;lt;/IfModule&amp;gt;

        # Apache 2.4
        &amp;lt;IfModule mod_authz_core.c&amp;gt;
                Require all granted
        &amp;lt;/IfModule&amp;gt;
&amp;lt;/Directory&amp;gt;
&lt;/pre&gt;

&lt;p&gt;And that should be all that you need to do. Now, when Dehydrated updates your certificate, it should update your LoadBalancer as well!&lt;/p&gt;

Sample &lt;tt&gt;hook.sh&lt;/tt&gt;:

&lt;pre&gt;
deploy_cert() {
    local DOMAIN=&quot;${1}&quot; KEYFILE=&quot;${2}&quot; CERTFILE=&quot;${3}&quot; FULLCHAINFILE=&quot;${4}&quot; \
          CHAINFILE=&quot;${5}&quot; TIMESTAMP=&quot;${6}&quot;
    shift 6

    # File contents should be:
    #   export OS_PASSWORD=&#039;your password in here&#039;
    . /etc/dehydrated/catalystcloud/password

    # OpenRC file from the Catalyst Cloud dashboard
    . /etc/dehydrated/catalystcloud/openrc.sh --no-token

    # UUID of the LoadBalancer to be managed
    LB_LISTENER=&#039;xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&#039;

    # Barbican uses P12 files, we need to make one.
    P12=$(readlink -f $KEYFILE \
        | sed -E &#039;s/privkey-([0-9]+)\.pem/barbican-\1.p12/&#039;)
    openssl pkcs12 -export -inkey $KEYFILE -in $CERTFILE -certfile \
        $FULLCHAINFILE -passout pass: -out $P12

    # Keep track of existing certs for this domain (hopefully no more than 100)
    EXISTING_URIS=$(openstack secret list --limit 100 \
        -c Name -c &#039;Secret href&#039; -f json \
        | jq -r &quot;.[]|select(.Name | startswith(\&quot;$DOMAIN\&quot;))|.\&quot;Secret href\&quot;&quot;)

    # Upload the new cert
    NOW=$(date +&quot;%s&quot;)
    openstack secret store --name $DOMAIN-$TIMESTAMP-$NOW -e base64 \
        -t &quot;application/octet-stream&quot; --payload=&quot;$(base64 &lt; $P12)&quot;

    NEW_URI=$(openstack secret list --name $DOMAIN-$TIMESTAMP-$NOW \
        -c &#039;Secret href&#039; -f value) \
        || unset NEW_URI

    # Change LoadBalancer to use new cert - if the old one was the default,
    # change the default. If the old one was in the SNI list, update the
    # SNI list.
    if [ -n &quot;$EXISTING_URIS&quot; ]; then
        DEFAULT_CONTAINER=$(openstack loadbalancer listener show $LB_LISTENER \
            -c default_tls_container_ref -f value)

        for URI in $EXISTING_URIS; do
            if [ &quot;x$URI&quot; = &quot;x$DEFAULT_CONTAINER&quot; ]; then
                openstack loadbalancer listener set $LB_LISTENER \
                    --default-tls-container-ref $NEW_URI
            fi
        done

        SNI_CONTAINERS=$(openstack loadbalancer listener show $LB_LISTENER \
            -c sni_container_refs -f value | sed &quot;s/&#039;//g&quot; | sed &#039;s/^\[//&#039; \
            | sed &#039;s/\]$//&#039; | sed &quot;s/,//g&quot;)

        for URI in $EXISTING_URIS; do
            if echo $SNI_CONTAINERS | grep -q $URI; then
                SNI_CONTAINERS=$(echo $SNI_CONTAINERS | sed &quot;s,$URI,$NEW_URI,&quot;)
                openstack loadbalancer listener set $LB_LISTENER \
                    --sni-container-refs $SNI_CONTAINERS
            fi
        done

        # Remove old certs
        for URI in $EXISTING_URIS; do
            openstack secret delete $URI
        done
    fi
}

HANDLER=&quot;$1&quot;; shift
#if [[ &quot;${HANDLER}&quot; =~ ^(deploy_challenge|clean_challenge|sync_cert|deploy_cert|deploy_ocsp|unchanged_cert|invalid_challenge|request_failure|generate_csr|startup_hook|exit_hook)$ ]]; then
if [[ &quot;${HANDLER}&quot; =~ ^(deploy_cert)$ ]]; then
    &quot;$HANDLER&quot; &quot;$@&quot;
fi
&lt;/pre&gt; 
    </content:encoded>

    <pubDate>Sun, 23 Oct 2022 05:09:00 +0000</pubDate>
    <guid isPermaLink="false">https://blog.etc.gen.nz/archives/135-guid.html</guid>
    <category>catalystcloud</category>
<category>geek</category>
<category>linux</category>
<category>openstack</category>

</item>
<item>
    <title>Cloud - in New Zealand!</title>
    <link>https://blog.etc.gen.nz/archives/126-Cloud-in-New-Zealand!.html</link>
            <category>catalyst</category>
    
    <comments>https://blog.etc.gen.nz/archives/126-Cloud-in-New-Zealand!.html#comments</comments>
    <wfw:comment>https://blog.etc.gen.nz/wfwcomment.php?cid=126</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://blog.etc.gen.nz/rss.php?version=2.0&amp;type=comments&amp;cid=126</wfw:commentRss>
    

    <author>andrew@etc.gen.nz (Andrew Ruthven)</author>
    <content:encoded>
    I&#039;ve spent a reasonable chunk of the past year working on a project we launched last month, &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.catalyst.net.nz/what-we-offer/cloud-services&#039;]);&quot;  href=&quot;http://www.catalyst.net.nz/what-we-offer/cloud-services&quot;&gt;Catalyst Cloud&lt;/a&gt;! It is using &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.openstack.org/&#039;]);&quot;  href=&quot;http://www.openstack.org/&quot;&gt;OpenStack&lt;/a&gt; with &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/ceph.com/&#039;]);&quot;  href=&quot;http://ceph.com/&quot;&gt;Ceph&lt;/a&gt; as the object store. It has taken a lot of work, and it is now very exciting seeing the level of interest there we&#039;re receiving about this new service!&lt;br /&gt;
&lt;br /&gt;
The great part of this is that we can now offer private cloud services to our customers which provides all the flexibility that we&#039;ve come to expect with the &quot;cloud&quot;, but hosted in New Zealand by a New Zealand owned company so no concerns about jurisdiction of your data! Not only are we able to offer private cloud services on our OpenStack cluster(s), but we can also deploy OpenStack onto our customers own hardware using our &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.catalyst.net.nz/what-we-offer/cloud-services/on-premises-openstack-cloud&#039;]);&quot;  href=&quot;http://www.catalyst.net.nz/what-we-offer/cloud-services/on-premises-openstack-cloud&quot;&gt;ProdStack&lt;/a&gt; solution (I get to look directly at the Dashboard shown on that page, which is pretty cool).&lt;br /&gt;
&lt;br /&gt;
Next up is deploying another OpenStack cluster in our new data centre (which is another project I&#039;m working on). In the near future we also hope to start using &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.opencompute.org/&#039;]);&quot;  href=&quot;http://www.opencompute.org/&quot;&gt;Open Compute Project&lt;/a&gt; hardware for our clusters. 
    </content:encoded>

    <pubDate>Thu, 10 Jul 2014 22:19:05 +0000</pubDate>
    <guid isPermaLink="false">https://blog.etc.gen.nz/archives/126-guid.html</guid>
    <category>catalyst</category>
<category>geek</category>
<category>openstack</category>

</item>

</channel>
</rss>
