Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot get SSL to work in Docker container

Let me start off by saying that I am no server administrator and there are a great many things I do not know. Because of this I am sure that I have made a mistake somewhere setting up my Docker container, because SSL does not work.

The container is running Apache 2.4 with PHP 5.6 on Ubuntu 14.04 and is linked to a MySQL 5.6 Docker container.

I started with this basic setup from Docker - Official PHP Repo. Here are the relevant files:

Dockefile

FROM php:5.6-apache

RUN apt-get update
RUN apt-get install -y net-tools
RUN docker-php-ext-install pdo pdo_mysql
RUN docker-php-ext-install sockets

RUN a2enmod rewrite
RUN a2enmod ssl

ADD 000-default.conf /etc/apache2/sites-enabled/
ADD default-ssl.conf /etc/apache2/sites-anabled/
ADD apache2.conf /etc/apache2/
ADD www-server/ www-server/

EXPOSE 443

000-default.conf

<VirtualHost *:80>

    ServerAdmin webmaster@localhost
    DocumentRoot /www-server/

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

<Directory /home/www-server/>
    # allow .htaccess overrides to work
    AllowOverride All
    DirectoryIndex login.html index.html index.php
</Directory>

<Directory /home/www-server/client>
    DirectoryIndex home.html
    Options All
    AllowOverride All
    Require all granted
</Directory>

default-ssl.conf

<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        ServerAdmin webmaster@localhost
        DocumentRoot /home/www-server

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # Enable/Disable SSL for this virtual host.
        SSLEngine on

        SSLCertificateFile /etc/ssl/certs/site.crt
        SSLCertificateKeyFile /etc/ssl/certs/site.key
        SSLCACertificatePath /etc/ssl/certs/digicert/

     </VirtualHost>
</IfModule>

apache2.conf

Mutex file:/var/lock/apache2 default
PidFile /var/run/apache2/apache2.pid
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
User www-data
Group www-data
HostnameLookups Off
ErrorLog /proc/self/fd/2
LogLevel warn

IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf

# ports.conf
Listen 80
<IfModule ssl_module>
        Listen 443
</IfModule>
<IfModule mod_gnutls.c>
        Listen 443
</IfModule>

<Directory />
        Options FollowSymLinks
        AllowOverride None
        Require all denied
</Directory>

<Directory /home/www-server/>
    Options Indexes FollowSymLinks Includes ExecCGI
    AllowOverride All
    Require all granted
</Directory>

DocumentRoot /home/www-server

AccessFileName .htaccess
<FilesMatch "^\.ht">
        Require all denied
</FilesMatch>

LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

CustomLog /proc/self/fd/1 combined

<FilesMatch \.php$>
        SetHandler application/x-httpd-php
</FilesMatch>

# Multiple DirectoryIndex directives within the same context will add
# to the list of resources to look for rather than replace
# https://httpd.apache.org/docs/current/mod/mod_dir.html#directoryindex
DirectoryIndex disabled
DirectoryIndex index.php index.html

IncludeOptional conf-enabled/*.conf
IncludeOptional sites-enabled/*.conf

NOTE: I have removed non-relevant parts of these files.

To run the Docker container I use this:

sudo docker run -v /home/src/ssl-cert:/etc/ssl/certs --name app-gateway --link mysql56:mysql -p 80:80 -p 443:443 -d  app-image

Here is a section of the log files:

::1 - - [10/Nov/2015:19:26:19 +0000] "OPTIONS * HTTP/1.0" 200 152 "-" "Apache/2.4.10 (Debian) PHP/5.6.15 OpenSSL/1.0.1k (internal dummy connection)"
::1 - - [10/Nov/2015:19:26:20 +0000] "OPTIONS * HTTP/1.0" 200 152 "-" "Apache/2.4.10 (Debian) PHP/5.6.15 OpenSSL/1.0.1k (internal dummy connection)"
72.5.190.136 - - [10/Nov/2015:19:26:21 +0000] "\x16\x03\x01" 400 0 "-" "-"
72.5.190.136 - - [10/Nov/2015:19:26:21 +0000] "\x16\x03\x01" 400 0 "-" "-"
72.5.190.136 - - [10/Nov/2015:19:26:21 +0000] "\x16\x03\x01" 400 0 "-" "-"

With this error in the browser:

ERR_SSL_PROTOCOL_ERROR

TL;DR I have followed all of the steps that I have found online to install and use my SSL certificates in a Docker container but I have had no success in making it work. Is there anything obvious I've overlooked to make SSL work in a Docker container?

like image 323
Jay Blanchard Avatar asked Nov 10 '15 19:11

Jay Blanchard


Video Answer


2 Answers

Sometimes, especially when you have been trying to solve a problem for a long time and you're coding in a console window on the command line, you miss the simplest things. Have a look at these two lines in the Dockerfile:

ADD 000-default.conf /etc/apache2/sites-enabled/ ADD default-ssl.conf /etc/apache2/sites-anabled/ 

The a is nearly indistinguishable from an e, making the misspelling hard to find. The Dockerfile builds the image correctly and adds the new directory in the container, then places the configuration file within that directory.

drwxr-xr-x  2 www www  4096 Nov 11 15:56 sites-anabled drwxr-xr-x  2 www www  4096 Oct 23 20:19 sites-available drwxr-xr-x  2 www www  4096 Nov 11 15:56 sites-enabled 

Since no error is thrown for an unknown directory and the image builds successfully it will run, but in this case the SSL will not work appropriately.

like image 186
Jay Blanchard Avatar answered Sep 20 '22 03:09

Jay Blanchard


I didn't want to 'add' files as other answers had done. and the HTML files would be installed via a mount to /var/www. All I needed was the apache server to accept HTTPS (SSL), redirect HTTP (non-SSL) to HTTPS, and some minor PHP configuration.

Here is what I did in my DockerFile...

# Install PHP Apache as the base image
FROM "php:7.3-apache"

# Install ssl-cert (snakeoil) package
RUN set -eux; \
    apt-get update && apt-get install -y ssl-cert; \
    : "Clean Apt system" ;\
    apt-get clean; \
    rm -rf /var/lib/apt/lists/*; \
    rm -rf /tmp/* /var/tmp/* /var/log/lastlog /var/log/faillog; \
    rm -f /var/log/{apt/*,alternatives.log,dpkg.log}; \
    :;

# Set up apache with HTTPS redirect
RUN set -eux; \
    : "Time Zone"; \
    ln -sf /usr/share/zoneinfo/Australia/Sydney /etc/localtime; \
    : "Apache Changes" ;\
    # enable SSL \
    a2enmod rewrite ssl; \
    a2ensite default-ssl; \
    cd /etc/apache2/sites-enabled/; \
    sed -i '/<\/VirtualHost>/d'                          000-default.conf; \
    echo 'RewriteEngine On'                           >> 000-default.conf; \
    echo 'RewriteRule . https://%{SERVER_NAME} [R,L]' >> 000-default.conf; \
    echo '</VirtualHost>'                             >> 000-default.conf; \
    :;

# PHP Configuration
RUN set -eux; \
    cd $PHP_INI_DIR; \
    cp php.ini-production php.ini; \
    cd conf.d ;\
    echo "date.timezone=Australia/Sydney"      > date_timezone.ini; \
    echo "session.gc_probability=1"            > session.ini; \
    echo "session.gc_divisor=100"             >> session.ini; \
    echo "session.gc_maxlifetime=1440"        >> session.ini; \
    echo "session.cookie=1440"                >> session.ini; \
    :;

Hope you find this helpful

like image 21
anthony Avatar answered Sep 18 '22 03:09

anthony