3

I have an application running properly with docker-compose up. That application connects using SSH to my host machine and executes some commands. Right now I provide the SSH credentials by writing them in the source code like this:

const pass = 'mypassword';
let username = 'myusername';
let host = '172.17.0.1';

I 'm trying to follow this guide in order to provide the credentials in a better way. I cannot understand how this line works privateKey: require('fs').readFileSync('/here/is/my/key') Is it a relative path, is the "key" a file with the password as plain text? Is there something I should provide from my host machine? How can I give the credentials in a docker container?

Jabster28
  • 177
  • 11

1 Answers1

2

In general, to pass in parameters into a container to be read by your Node.js script, you can:

For secret data such as SSH credentials, I would advise against using arguments or environment variables because they can be inspected from various sources. This article explains well why: https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/

Instead, I would create a simple configuration file that your Node.js script can read.

{
   "username": "myuser",
   "password": "pass",
   "host": "172.17.0.1",
   ...
}

You can put this file a directory on your host system and mount it under /myvolume to the container when you start your container:

docker run -it -v host-directory:/myvolume myimage

Your Node.js script now can read the JSON file:

const configFilePath = "/myvolume/secret-config.json"
const config = JSON.parse(fs.readFileSync(configFilePath));

// now you can use config.host, config.username and config.password

As a side note: I recommend setting up your remote SSH server to use private/public key authentication since passwords generally less secure. Once you have set up private/public key authentication, you can put the private key file in the same volume and load it from your Node.js script in a similar way :)

mitchkman
  • 6,201
  • 8
  • 39
  • 67
  • so if I want to pass username, password, host-ip, as I already did with a .env file, I should use 3 secret-config.json files? – Stavros Droutsas Jun 13 '19 at 21:53
  • You can also work with an```.env``` file using ```dotenv``` instead of a JSON file. In either case, you would pass all three parameters in one file, not three files. – mitchkman Jun 13 '19 at 22:02
  • Although .env files are great, I personally would not use it in this specific case. It would enable other developers (who might maintain the code after me) to use it less securely (with environment variables). – mitchkman Jun 13 '19 at 22:04
  • so the concept is to use a volume to keep the file in the host machine right? For security reasons? – Stavros Droutsas Jun 13 '19 at 22:05
  • Yes, the idea is to keep private data like hostname, username, password away from command outputs like ```ps```. You can learn about this more here: https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/ – mitchkman Jun 13 '19 at 22:11
  • This also assumes that you keep the file itself safe, such as not running any processes inside the container as root and set proper file permissions. – mitchkman Jun 13 '19 at 22:14
  • I just realized you didn't try to connect using a private key but want to use username and password instead. While it it generally more secure to use a private/public key pair to authenticate with an SSH server, I updated my answer to fit your question better. – mitchkman Jun 13 '19 at 22:18
  • It's working! is it possible to run it with docker compose up? – Stavros Droutsas Jun 13 '19 at 23:15
  • Yes, very similar! Instead of passing the volume definition via the command line you need to pass it via the docker-compose.yaml file. See here: https://docs.docker.com/compose/compose-file/#volume-configuration-reference – mitchkman Jun 14 '19 at 03:32
  • Fine. I did it. Thank you. – Stavros Droutsas Jun 14 '19 at 06:05