Welcome Guest, Not a member yet? Register   Sign In
security of CI information with Docker Secrets
#1

In config/database.php my userid and password for mySQL is visable, unencryted.  I have some other things that I use in my app that are secrets such as my AWS userids. I need to secure these and since I am using Docker I am investigating using Docker Secrets. But how can I modify the $db array prior to bringing up my system with the userid and password kept in Docker Secrets. I am not sure yet but I presume that there is an api call I will make to get the secret. But where do I place that in the CI application?
proof that an old dog can learn new tricks
Reply
#2

(10-27-2020, 05:55 AM)richb201 Wrote: In config/database.php my userid and password for mySQL is visable, unencryted.  I have some other things that I use in my app that are secrets such as my AWS userids. I need to secure these and since I am using Docker I am investigating using Docker Secrets. But how can I modify the $db array prior to bringing up my system with the userid and password kept in Docker Secrets. I am not sure yet but I presume that there is an api call I will make to get the secret. But where do I place that in the CI application?
Haven't looked into Docker Secrets, but I run multiple CI projects in FARGATE and ECS and this is how I do it;

In the Config/Database.php I use the constructor to gather stuff from the running environment. My configuration is a mix of stuff from AWS CloudFormation inserted as ENV in the Docker tasks (database and redis host etc).
Static, secret stuff (username, API keys and passwords) I put in the .env file when building the Docker image and uploading to the private ECR.

PHP Code:
    public function __construct()
    {
        
parent::__construct();

        // Ensure that we always set the database group to 'tests' if
        // we are currently running an automated test suite, so that
        // we don't overwrite live data on accident.
        
if (ENVIRONMENT === 'testing')
        {
            
$this->defaultGroup 'tests';

            
// Under Travis-CI, we can set an ENV var named 'DB_GROUP'
            // so that we can test against multiple databases.
            
if ($group getenv('DB'))
            {
                if (
is_file(TESTPATH 'travis/Database.php')) {
                    require TESTPATH 'travis/Database.php';

                    if ( ! empty($dbconfig) && array_key_exists($group$dbconfig)) {
                        $this->tests $dbconfig[$group];
                    }
                }
            }
        } else {
            $this->default['hostname'] = getenv('CONFIG_RDS_RW');
            $this->default['password'] = getenv('CONFIG_RDS_PASSWORD');
            $this->default['username'] = getenv('CONFIG_RDS_USERNAME');
            $this->default['database'] = getenv('CONFIG_RDS_DATABASE');
        }
    
Reply
#3

Thanks. So you are directly modifying the $dbconfig? Where are you doing this? I think you are doing this when building the Docker image. I am trying to use pre-existing Docker images and not build them myself. Any idea what CI module runs prior to the $dbconfig being used?
proof that an old dog can learn new tricks
Reply
#4

(10-27-2020, 10:11 AM)richb201 Wrote: Thanks. So you are directly modifying the $dbconfig? Where are you doing this? I think you are doing this when building the Docker image. I am trying to use pre-existing Docker images and not build them myself. Any idea what CI module runs prior to the $dbconfig being used?
I am doing this in the constructor in app/Config/Database.php The getenv() command gets information from the $_ENV or .env file - see http://codeigniter.com/user_guide/genera...ments.html 
I am not 100% sure when this file is running, but it happens every time the application is executed (remember PHP is an interpreted language - we have been experimenting with bootstrapping this when the docker launches but found that fragile using FARGATE) 

I don't change the code when building the Docker image, the code base is the same for all customers and managed through git. We just add a specific .env file suitable for the production environment (we use Bamboo to manage multiple customers and staging/production) and then upload the built image to the Registry. The .env-file handles username, passwords and API keys.
The other part is the dynamic environment (databases hosts, filesystems, redis-caches etc) that we get from the docker task ENV.

We also use the stock pre-existing image, but have a short Dockerfile to configure extensions etc. This is basically the file we use:
Code:
# Use an official PHP runtime as a parent image
FROM php:7.3.23-apache-stretch

RUN pecl install -o -f redis \
&&  rm -rf /tmp/pear \
&&  docker-php-ext-enable redis

RUN apt-get update && apt-get install -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libzip-dev \
        libpng-dev \
        libicu-dev \
    && rm -rf /var/lib/apt/lists/* \
    && docker-php-source extract \
    && pecl install mcrypt-1.0.2 \
    && docker-php-ext-enable mcrypt \
    && docker-php-ext-install -j$(nproc) iconv mysqli zip mbstring \
    && docker-php-ext-configure opcache --enable-opcache \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd \
    && docker-php-ext-install opcache \
    && docker-php-ext-configure intl \
    && docker-php-ext-install intl \
    && docker-php-source delete

RUN a2enmod rewrite

# Configuration files for apache and PHP
COPY 000-default.conf /etc/apache2/sites-available/000-default.conf
COPY tangix.ini /usr/local/etc/php/conf.d

# git checkout directory containing the CI project
COPY deploy /var/www/deploy
# .env file for the specific customer created by BAMBOO in the build job
COPY env.bamboo /var/www/deploy/.env

# Setting build timestamp and other stuff
ENV VT_DOCKER_IMAGE="$bamboo_shortPlanName" \
VT_DOCKER_BUILD="$bamboo_buildResultKey" \
VT_DOCKER_TIME="$bamboo_buildTimeStamp"

# Make port 80 available to the world outside this container
EXPOSE 80

CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

HtH
/Mattias
Reply
#5

and I guess you assume that the .env file is secure? Is that an .htaccess setting thing?
proof that an old dog can learn new tricks
Reply
#6

(This post was last modified: 10-27-2020, 12:57 PM by tgix.)

(10-27-2020, 12:50 PM)richb201 Wrote: and I guess you assume that the .env file is secure? Is that an .htaccess setting thing?
As suggested strongly recommended in the CI docs - apache should only serve the /public directory, so everything else in the project directory should be safe (unless there is an apache bug). I set DocumentRoot to the public directory and .env is one level above and not accessible.

You should of course consider everything stored on a connected server as "unsafe" ;-)
Reply




Theme © iAndrew 2016 - Forum software by © MyBB