{"id":2734,"date":"2018-11-12T15:39:51","date_gmt":"2018-11-12T13:39:51","guid":{"rendered":"http:\/\/hasselba.ch\/blog\/?p=2734"},"modified":"2018-11-12T15:57:27","modified_gmt":"2018-11-12T13:57:27","slug":"node-js-domino-db-docker-10-protecting-proton-keys","status":"publish","type":"post","link":"https:\/\/hasselba.ch\/blog\/?p=2734","title":{"rendered":"node.js, domino-db &#038; Docker (10): Protecting Proton Keys"},"content":{"rendered":"<p>Before we are looking into the details how to setup a non-anynomous connection to Domino&#8217;s Proton server, I have an advice for protecting the key files required for the connection.<\/p>\n<p>The keys are not password protected, and this is a high risk which should be avoided: First, if you make a mistake or if there is a bug in the software, the keys could be accessed from &#8222;outside&#8220;. And second, if you check in your code in a repository, the IT security should roast you. It&#8217;s clear that the keys are still unprotected if someone hacks the application, but this is a different topic.<\/p>\n<p>First thing to to is to encrypt the keys with AES. To achive this, we are using <em>openssl<\/em>:<\/p>\n<pre><code>openssl enc -aes-256-cbc -k \"0123456789\" -in domino-express.key -out domino-express.key.enc<\/code><\/pre>\n<p>The parameter <em>-k<\/em> is the key to use for encryption. The path to the unencrypted file is passed with <em>-in<\/em>, and <em>-out<\/em> is the path of the encrypted file.<\/p>\n<p>I also encryted the <em>.crt<\/em> files, which is not required, but <span id=\"result_box\" class=\"short_text\" lang=\"en\"><span class=\"\">it does not hurt either<\/span><\/span>.<\/p>\n<p>The <em>config.js<\/em> file must now be changed to the follwing (a new method for reading and decrypting the files with <em>openssl<\/em> is added):<\/p>\n<pre><code>const exec = require('child_process').execSync;\r\n\r\nconst path = require('path');\r\n\r\n\/**\r\n * reads an aes-256-cbc encrypted file &amp; decrypts it\r\n * \r\n * @param {*} fileName \r\n *  the encrpyted file \r\n * @param {*} key \r\n *  the decryption key\r\n *\/\r\nconst readFileEncrypted = (fileName, key) =&gt; {\r\n  try {\r\n    \/\/ resolve the filepath\r\n    const filePath = path.resolve(fileName);\r\n\r\n    \/\/ use openssl to decrypt the keys\r\n    return exec(`openssl enc -d -aes-256-cbc -k \"${key}\" -in \"${filePath}\"`, \r\n    (error, stdout) =&gt; {\r\n      if (error) {\r\n        console.error(`exec error: ${error}`);\r\n      }\r\n      return stdout;\r\n    });\r\n  } catch (error) {\r\n    console.error(error);\r\n    return undefined;\r\n  }\r\n};\r\n\r\n\/\/ the password (stored in environment)\r\nconst password = process.env.PASSWORD_KEYFILES;\r\nif (!password) {\r\n  console.error('Environment Variable \"PASSWORD_KEYFILES\" is not set.');\r\n  process.exit(1);\r\n}\r\n\r\n\/\/ load the keys &amp; certificates\r\nconst rootCertificate = readFileEncrypted('.\/app\/certs\/ca.crt.enc', password);\r\nconst clientCertificate = readFileEncrypted('.\/app\/certs\/domino-express.crt.enc', password);\r\nconst clientKey = readFileEncrypted('.\/app\/certs\/domino-express.key.enc', password);\r\n\r\n\/\/ check if the keys are ok \r\nif (!rootCertificate || !clientCertificate || !clientKey) {\r\n  console.error('Unable to load certificates and\/or key.');\r\n  process.exit(1);\r\n}\r\n\r\nconst Config = {\r\n    serverConfig: {\r\n        hostName: process.env.NODE_ENV === 'development' ? 'dev.example.com' : 'example.com', \/\/ Host name of your server\r\n        connection: {\r\n          port: '3002', \/\/ Proton port on your server\r\n          secure: true,\r\n        }, \r\n        credentials: {\r\n            rootCertificate,\r\n            clientCertificate,\r\n            clientKey,\r\n          },\r\n      },\r\n      databaseConfig: {\r\n        filePath: 'testnode.nsf', \/\/ The database file name\r\n      }\r\n};\r\n\r\nmodule.exports = Config;\r\n<\/code><\/pre>\n<p>But where to store the key? Nowhere, the key is stored in an evironmental variable.<\/p>\n<p>This line reads the value from the variable <em>PASSWORD_KEYFILES<\/em>.<\/p>\n<pre><code>const password = process.env.PASSWORD_KEYFILES;<\/code><\/pre>\n<p>When running your application in a docker container, just start the container with the following command including the variable:<\/p>\n<pre><code>docker run <strong>-e \"PASSWORD_KEYFILES=0123456789\"<\/strong> --name dominoexpress -p 3000:3000 -d -it shasselba\/domino-express<\/code><\/pre>\n<p>To use it in a IDE like Visual Studio Code, you have to add it to the debugging configuration:<\/p>\n<pre><code>{\r\n    \"version\": \"0.2.0\",\r\n    \"configurations\": [\r\n        {\r\n            \"type\": \"node\",\r\n            \"request\": \"launch\",\r\n            \"name\": \"Programm starten\",\r\n            \"program\": \"${workspaceFolder}\/app\/bin\/www\",\r\n            <strong>\"env\": {\"PASSWORD_KEYFILES\": \"0123456789\"}<\/strong>\r\n        },\r\n    ]\r\n}<\/code><\/pre>\n<p>Now you can add the <em>.enc<\/em> files to your application in folder <em>\/app\/certs<\/em> without worrying about it. If the variable is not set, the application terminates with error code 1.<\/p>\n<p>P.S. Don&#8217;t forget to remove the original key files from your project!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Before we are looking into the details how to setup a non-anynomous connection to Domino&#8217;s Proton server, I have an advice for protecting the key files required for the connection. The keys are not password protected, and this is a &hellip; <a href=\"https:\/\/hasselba.ch\/blog\/?p=2734\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[141,139,9,131,35],"tags":[142,138,140,4,132,90],"class_list":["post-2734","post","type-post","status-publish","format-standard","hentry","category-docker","category-es6","category-javascript","category-node-js","category-security","tag-docker","tag-domino-db","tag-es6","tag-js","tag-node-js","tag-security"],"_links":{"self":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2734","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2734"}],"version-history":[{"count":4,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2734\/revisions"}],"predecessor-version":[{"id":2738,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2734\/revisions\/2738"}],"wp:attachment":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2734"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2734"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2734"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}