Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

usage with docker? #17

Closed
jeffwillette opened this issue Apr 19, 2018 · 5 comments
Closed

usage with docker? #17

jeffwillette opened this issue Apr 19, 2018 · 5 comments

Comments

@jeffwillette
Copy link

jeffwillette commented Apr 19, 2018

cool project! Thanks for making it. I am using gatsbyjs which uses devcert and I was wondering if you had a suggested usage flow with docker?

Right now I am running the project in docker which works on https but it still gives me the ugly browser warnings since the container is like a separate machine. Can you see an easy way around this to get the certificate trusted on the host machine and used in a container?

Thanks

@davewasmer
Copy link
Owner

Hmm, that's a great question.

Short version: kinda.

Because Docker isolates the container from the host, there's no way for devcert to run inside the container, and get the host outside the container to trust it's certs.

However, if you installed devcert on the host machine, and then as part of your build step ran a script that did something like this before the actual docker build:

let { key, cert } = await devcert.certificateFor('my-app.test');
fs.writeFileSync('./ssl.key', key);
fs.writeFileSync('./ssl.cert', cert);

Then the certificates would be available inside the container. Those certificates wouldn't be trusted by the container OS though, so that might get tricky in a microservice style architecture if you have multiple containers communicating with each other over HTTPS, since none of them would trust each other's certs. But if you're just accessing the container processes from your host browser, that should work.

I would love to make devcert work better in this case, but I think there are just some fundamental limitations that are difficult to work around. But if anyone else has ideas / suggestions, I'm more than happy to listen!

@jeffwillette
Copy link
Author

hmm yeah I was kind of thinking something like that might work... I'm a bit confused as to where that JS code would actually be run though...

Do you mean that if I run that one time (just to get and write the files in the Gatsby root dir) it should work? or did I misunderstand it?

@davewasmer
Copy link
Owner

Yep, exactly right. Devcert doesn't use that approach normally for a few reasons:

  1. It encourages devs to commit those certs, which they should not do, because those certs will only work on their machine and no one else's.

  2. Devcert installs itself on first-run, so asking devcert for the certificates every time ensures that if someone else clones the repo and runs it, they will go through the install process for devcert - no separate "oh and run devcert install" step.

  3. It allows devcert to potentially update/replace the root certificate authority in the future and regenerate all the certificates transparently. If you copied the certificate files out, and we replace the root certificate authority, those might stop working suddenly.

With all that said though, it should work if you just save the certificate files, but it comes with those longer-term drawbacks mentioned above.

@jeffwillette
Copy link
Author

unfortunately in gatsby, there is currently no way to pass a custom ssl cert, so putting it in the home dir doesn't work, but as long as the server reads a custom ssl cert, this script should take care of generating the certs to be mounted in the docker container...

#!/bin/bash

# external to this script:
# 1. yarn global add devcert
# 2. brew install nss
# 3. cd ~/.config/yarn/global/node_modules/devcert (or wherever your globals are)
# 4. yarn link devcert
# 5. I put this script in my project root that uses devcert

yarn link devcert

cat > ./devcert.tmp.js <<EOL
const devcert = require('devcert');
const fs = require('fs');

const pkg = require('./package.json');

const writeCerts = async () => {
  let { key, cert } = await devcert.certificateFor(pkg.name);
  fs.writeFileSync('./ssl.key', key);
  fs.writeFileSync('./ssl.cert', cert);
};

writeCerts();
EOL

node ./devcert.tmp.js

rm devcert.tmp.js

yarn unlink devcert

I don't know enough about the internals of the lib to think of a way to make a PR so I will just leave this here for anyone who may find it...

@jeffwillette
Copy link
Author

@davewasmer I noticed some differences in the files when I use the method you gave me...Gatsby seems to use devcert-san which gives three files when they call this function...

const getDevelopmentCertificate = require(`devcert-san`).default

it gives three files to my global config which have the extensions .crt, .csr, and .key

all of them look like regular cert files in the form of

-----BEGIN CERTIFICATE REQUEST-----
...
-----END CERTIFICATE REQUEST-----

On the other hand when I require devcert like you recommended, I get a certfile that looks like this...

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 2 (0x2)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=devcert
        Validity
            Not Before: Apr 20 04:25:55 2018 GMT
            Not After : Jun 19 04:25:55 2037 GMT
        Subject: CN=gatsby-starter-default
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:d6:6f:51:f8:24:12:7c:cd:ed:ae:d4:73:dd:88:
                    d8:b7:ff:ff:82:74:26:22:0c:3f:bd:e2:97:4d:fd:
                    97:69:23:ca:57:59:f0:2b:59:32:cd:0f:a3:66:56:
                    ef:78:c1:b7:b4:01:be:09:ac:c2:b4:73:eb:cf:fe:
                    7d:1e:ec:68:89:16:1e:8a:63:a5:4c:5c:c6:9a:7b:
                    ab:25:ff:d0:36:fa:a7:68:c6:94:3d:59:3f:c4:81:
                    e7:69:6a:ca:c7:a4:99:0d:ac:5e:5e:33:53:6b:28:
                    9b:fa:e2:61:8c:1a:9b:9a:cb:5c:a0:5f:03:a4:1b:
                    ff:33:18:24:b6:b4:36:5b:e7:59:26:02:0e:84:cd:
                    0b:c2:58:15:58:3c:f5:ab:8e:d8:85:94:22:e9:7e:
                    8c:d8:1a:96:e5:03:70:57:fb:44:d4:26:17:b4:5c:
                    01:f4:1e:70:84:81:d1:e9:c9:14:63:61:09:76:2d:
                    3f:a8:eb:1d:5c:b7:69:04:da:22:32:26:c6:50:a3:
                    9e:ea:eb:f1:dc:24:a3:e4:e8:ff:08:ff:05:c1:05:
                    a4:4c:a0:53:f8:74:5d:b0:34:f3:d3:12:9c:07:c4:
                    71:a7:4b:e9:60:05:9d:df:fa:c8:e4:3c:7b:96:b6:
                    e5:aa:8d:96:ef:b4:78:14:1d:fc:04:a2:1f:bf:78:
                    08:a9
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                44:63:83:C6:4C:B1:10:38:25:4A:F1:3E:C5:15:E8:83:A7:8B:FB:9F
            X509v3 Authority Key Identifier:
                keyid:51:22:04:0F:A5:5F:76:17:AF:D5:FE:13:A1:F0:DF:24:62:86:1E:F1
                DirName:/CN=devcert
                serial:BA:84:5A:F7:AB:77:07:F5

            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:*.gatsby-starter-default, DNS:gatsby-starter-default
    Signature Algorithm: sha256WithRSAEncryption
         8c:a2:4c:9a:a2:6f:40:fd:0f:5c:f3:3b:6e:0e:7c:7f:4f:48:
         19:69:d5:17:d5:c2:e5:1f:6d:ec:4b:15:0d:f3:66:75:56:d8:
         b9:e7:10:8a:48:79:f3:a3:ea:a0:92:2d:33:af:d6:97:36:37:
         7c:c5:9f:bd:ee:bd:5c:71:e1:a8:b6:ab:a3:cc:57:3e:80:02:
         28:3e:83:46:08:e7:ae:9b:ae:e3:79:ee:5c:3d:1a:6c:61:66:
         af:b7:e0:44:53:38:3c:5a:73:8a:81:73:d7:a9:a9:39:21:95:
         b6:13:fb:45:8b:97:44:66:59:3a:3e:86:a9:2a:10:be:df:36:
         d0:85:31:41:69:39:02:15:2d:31:46:7c:b8:56:70:85:89:c5:
         89:02:8d:03:78:bb:45:b1:30:df:3b:a5:64:ac:f9:a8:7c:67:
         45:8a:92:9d:73:b6:6a:db:be:89:94:ad:aa:24:22:be:8e:c5:
         20:e9:05:e0:54:68:88:db:58:fb:7e:6c:2a:3f:ee:66:66:9b:
         b6:ed:af:25:b4:ad:ee:4b:2c:6a:8e:ce:61:b6:c9:bc:f0:35:
         a1:f7:2f:14:bd:dd:0f:ac:46:21:ed:53:bd:a2:3d:a6:4f:1a:
         ba:9a:7f:f6:44:87:16:0e:22:4d:44:27:c5:ec:47:74:1e:2d:
         3a:de:62:84
-----BEGIN CERTIFICATE-----
MIIDhTCCAm2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdkZXZj
ZXJ0MB4XDTE4MDQyMDA0MjU1NVoXDTM3MDYxOTA0MjU1NVowITEfMB0GA1UEAwwW
Z2F0c2J5LXN0YXJ0ZXItZGVmYXVsdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBANZvUfgkEnzN7a7Uc92I2Lf//4J0JiIMP73il039l2kjyldZ8CtZMs0P
o2ZW73jBt7QBvgmswrRz68/+fR7saIkWHopjpUxcxpp7qyX/0Db6p2jGlD1ZP8SB
52lqysekmQ2sXl4zU2som/riYYwam5rLXKBfA6Qb/zMYJLa0NlvnWSYCDoTNC8JY
FVg89auO2IWUIul+jNgaluUDcFf7RNQmF7RcAfQecISB0enJFGNhCXYtP6jrHVy3
aQTaIjImxlCjnurr8dwko+To/wj/BcEFpEygU/h0XbA089MSnAfEcadL6WAFnd/6
yOQ8e5a25aqNlu+0eBQd/ASiH794CKkCAwEAAaOB1jCB0zAMBgNVHRMBAf8EAjAA
MB0GA1UdDgQWBBREY4PGTLEQOCVK8T7FFeiDp4v7nzBCBgNVHSMEOzA5gBRRIgQP
pV92F6/V/hOh8N8kYoYe8aEWpBQwEjEQMA4GA1UEAwwHZGV2Y2VydIIJALqEWver
dwf1MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATA7BgNVHREE
NDAyghgqLmdhdHNieS1zdGFydGVyLWRlZmF1bHSCFmdhdHNieS1zdGFydGVyLWRl
ZmF1bHQwDQYJKoZIhvcNAQELBQADggEBAIyiTJqib0D9D1zzO24OfH9PSBlp1RfV
wuUfbexLFQ3zZnVW2LnnEIpIefOj6qCSLTOv1pc2N3zFn73uvVxx4ai2q6PMVz6A
Aig+g0YI566bruN57lw9GmxhZq+34ERTODxac4qBc9epqTkhlbYT+0WLl0RmWTo+
hqkqEL7fNtCFMUFpOQIVLTFGfLhWcIWJxYkCjQN4u0WxMN87pWSs+ah8Z0WKkp1z
tmrbvomUraokIr6OxSDpBeBUaIjbWPt+bCo/7mZmm7btryW0re5LLGqOzmG2ybzw
NaH3LxS93Q+sRiHtU72iPaZPGrqaf/ZEhxYOIk1EJ8XsR3QeLTreYoQ=
-----END CERTIFICATE-----

Should I only be taking the ----BEGIN CERTIFICATE---- section of that file and passing it to the server or should I be passing the whole file?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants