ARTICLES

DOCKER

 

Creating a Dockerfile to configure an CentOS Apache Server to be security hardened with proper digital certificates:

You can create a file which you name Dockerfile which allows you to download and deploy and image and then configure it to the way you want it, with all the commands you would run and files you would copy so you can deploy a fully fledged, in this case, Apache Server, with PHP 5.6, security hardened and with your own CA approved certificates. Obviously this technique can be used for any Docker Container, not just Apache but I thought I would show you an example.

It seems a particularly elegant and clean solution and completely consistent. An Apache web server that may have taken me 45 minutes of installation and configuration can be deployed in about 2 minutes.

 

This is an excellent article on getting started with Dockerfiles and all the basic commands:

https://www.digitalocean.com/community/tutorials/docker-explained-using-dockerfiles-to-automate-building-of-images

 

This is the Dockerfile I created:

 

#################################################################

#  Dockerfile to build Apache container Images

#  Based on CentOS

#################################################################

 

# Set the base image to Ubuntu

FROM centos

 

# File Author / Maintainer

MAINTAINER Alastair Ferguson

 

# Update the repository sources list

RUN yum upgrade -y

################## BEGIN INSTALLATION ###########################

# Begin installation of Apache packages

 

# Add the package verification key

RUN rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm

RUN rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm

RUN yum install httpd httpd-devel openssl mod_ssl php56w php56w-opcache php56w-bcmath php56w-xml php56w-tcpdf php56w-pear php56w-mysql php56w-pgsql php56w-php-gettext php56w-mcrypt php56w-mbstring php56w-devel php56w-gd -y

 

ADD ./star_example_com.* /etc/ssl/

ADD ./DigiCertCA.crt /etc/ssl/

RUN rm -f /etc/httpd/conf.d/ssl.conf

ADD ./ssl.conf /etc/httpd/conf.d/

 

 

# Update the repository sources list again

RUN yum upgrade -y

 

 

 

##################### INSTALLATION END #####################

 

# Expose the default port

EXPOSE 80

EXPOSE 443

 

# Set default container command

 

ENTRYPOINT ["/usr/sbin/httpd", "-D", "FOREGROUND"]

 

Pretty simple right?

OK so as you can see, first we specify the Docker repository image to base our Dockerfile on, in this case centos. It should be noted it will always assume imagename:latest if you don't explicitly state it. If you want to specify an older image you would have to search for it and then state the name explicitly.

 

Then we specify myself as the Maintainer, and do a yum upgrade -y to upgrade to the latest packages before deploying.

We then add Epel and Webtatic repos and then install Apache, Openssl, mod_ssl and the php 5.6 rpms, then copy the digital certificates to /etc/ssl, and then my custom ssl.conf file to the correct location (after deleting the original).

The custom ssl.conf files has some hardened cipher and protocol options and the location of the certificates in /etc/ssl.

These new commands are:

 

SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder On
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
# Requires Apache >= 2.4
SSLCompression off
# Requires Apache >= 2.4.11
SSLSessionTickets Off

SSLCertificateFile /etc/ssl/star_example_com.crt

SSLCertificateKeyFile /etc/ssl/star_example_com.key

SSLCACertificateFile /etc/ssl/DigiCertCA.crt

 

It should be noted that all of the certificates and the ssl.conf need to be in the same directory that the Dockerfile is in or it won't work, hence the ./ before each of these file names.

I then do another yum upgrade -y then expose ports 80 and 443 on the container only, then start Apache.

 

Building the Image

docker build -t httpd .

Again you need to be in the same directory as the Dockerfile for this to work ( hence the .). The

 

Deploying the Container from the Image 

docker run --name example_httpd -p 80:80 -p 443:443 -d -t httpd

In this example I am deploying a container from the image translating ports 80 and 443 from the container to the host. 

A fully fledged CentOS Apache Web Server in production in 2 minutes. 

 

However, this is only part of the story as if you turn off or exit this server then any changes made to the Docker container AFTER this point will be lost.

 

Post deployment tasks to save Container state and changes

Once you have run the previous command you can check what containers are running or not with the command:

docker ps -a

In my case:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                      NAMES

 

57d52d0e8034        httpd               "/usr/sbin/httpd -D F"   11 minutes ago      Up 8 minutes        0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   example_httpd

 

Container ID is what you need to know and also that the service is currently running (up 8 minutes).

At present if you ran the command:

docker stop 57d52d0e8034

This would stop the container and any updates would be lost.

In order to preserve container state including logs etc, use:

 

docker commit 57d52d0e8034

 

You can check it works by connecting to the running container via bash like so:

 

 

docker exec -it 57d52d0e8034 bash

 

Creating some files, exiting without shutting down, committing and then stop the container from running.

 

To exit the Bash shell use the following commands:

CTRL + P then CTRL + Q

 

You can now stop the Docker container with this command:

 

docker stop 57d52d0e8034

 

and check it is no longer running by running docker ps -a - it should look like this:

 

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES

57d52d0e8034        httpd               "/usr/sbin/httpd -D F"   About an hour ago   Exited (0) 1 seconds ago                       example_httpd

 

Now start the container and check that the created files are still there:

 

docker start 57d52d0e8034

 

 

You now have a fully working, saveable Docker container that will continue to function after stops and starts.

 

 

 

Further reading:

Install Docker on CentOS: 

 

Easy Getting started / Basics Guide:

 

 

Using Docker on the command line:

 
 
 

Install Docker LAMP stack:

 

 

Removing Docker Images and Containers:

 

https://www.digitalocean.com/community/tutorials/how-to-remove-docker-images-containers-and-volumes

 

 

Useful Commands:

 

 

https://medium.com/@gchudnov/copying-data-between-docker-containers-26890935da3f