BrowserSync / browser-sync

Keep multiple browsers & devices in sync when building websites. https://browsersync.io
https://discord.gg/2d2xUThp
Apache License 2.0
12.18k stars 756 forks source link

Add HTTPS/TLS support #193

Closed PaulKinlan closed 10 years ago

PaulKinlan commented 10 years ago

On the web-starter-kit project, we are very keen to make it as easy as possible for developers to get their sites working with TLS from the start. To do this though we need browser-sync to support TLS connections.

Looking at the project, it doesn't seem like it would be "too" much work to start to land https support. I am certainly up for helping out if needed.

My preferences (feel free to ignore):

shakyShane commented 10 years ago

Hi.

I've been meaning to add this for the longest time, so this is motivation to get it done now!

It will be easy to implement - I just didn't realise you could provide dummy certs for localhost.

I would suggest an https option, that will default to localhost certs & also accept others.

// default to localhost certs
var config = {
    server: {
        baseDir: "./app"
    },
    https: true
};

// Provide custom 
var config = {
    server: {
        baseDir: "./app"
    },
    https: {
        key: "keys/agent2-key.pem",
        cert: "keys/agent2-cert.pem"
    }
};

What do think to that?

shakyShane commented 10 years ago

If you do help out with this, you can follow this style of e2e test https://github.com/shakyShane/browser-sync/blob/master/test/specs/e2e/e2e.server.js

shakyShane commented 10 years ago

Also, any advice on generating "Default key and cert provided for localhost" or where to get them would be great.

PaulKinlan commented 10 years ago

We should just be able to create a self signed certificate along the lines of openssl req -new -days 365 -x509 -nodes -out /somedir/server.crt -keyout /somedir/server.key and then in theory stream them in...

I'll have play.

PaulKinlan commented 10 years ago

One thing to note: If we choose to go down the self certified route (the most likely) then we will likely have to get the developer to install a cert as a root CA to avoid getting warnings.

PaulKinlan commented 10 years ago

Just got a first version working https://github.com/PaulKinlan/browser-sync/commit/a4fa0aebac738727f6a2c690bfa9c948012c4f70

screen shot 2014-07-08 at 9 28 50 pm

shakyShane commented 10 years ago

Wow! great work.

If you pull my latest changes from master the test suit will run correctly.

PaulKinlan commented 10 years ago

Pulled in.. Tests pass now, but I need to add some more and check the custom cert code.

shakyShane commented 10 years ago

Awesome!

PaulKinlan commented 10 years ago

I owe the final PR for this.

re: #182 I would need to do more research for this.

shakyShane commented 10 years ago

re #182 - it should be just as easy as we're using https://github.com/nodejitsu/node-http-proxy under the hood of foxy

PaulKinlan commented 10 years ago

It looks like my tests passed due to a failure of my configurations, which is where we hit on a bit of a problem... supertest doesn't support creating an https server (https://github.com/visionmedia/supertest/blob/master/index.js#L8) so I would need to fix that first if we create the server via the standard route. I am going to have to work around it.

NOTE: Ignore me, we pass in our own server but it is still failing.

shakyShane commented 10 years ago

If it's simply the use of supertest that's causing the issue, I'm more than happy to have some manual assertions on response bodies retrieved with http.get or whatever. :)

PaulKinlan commented 10 years ago

Cool, I will work on that assumption. I have just tested it with an https client and it works as expected, I am going to dig a little further as I suspect it is an security issue with a non-CA based cert.

PaulKinlan commented 10 years ago

Sorted. Will push PR shortly.

markwoon commented 9 years ago

Is there a way to provide our own key/cert to test with?

markwoon commented 9 years ago

Nevermind. Checked the source and figured it out. I sent a PR to update the docs.

lindleywhite commented 9 years ago

Great work on the HTTPS support. However, the certificate is now expired. @PaulKinlan. I'll see if I can get a PR against a new one.

marcelo-mason commented 9 years ago

@lindleywhite Give it something like 10 years.

shakyShane commented 9 years ago

@lindleywhite - I'm on it

shakyShane commented 9 years ago

@PaulKinlan - could I ask you for a little assistance?

So as you may of noticed from @lindleywhite 's comment, the certs you provided in your original PR have expired. I re-created some myself with the following https://github.com/BrowserSync/browser-sync/blob/master/lib/server/certs/gen.sh

Could you explain how exactly you created them in the original case, as mine are currently producing errors on websocket connections net::ERR_INSECURE_RESPONSE

jonricaurte commented 9 years ago

@shakyShane I'm getting the same issue in regards to the net::ERR_INSECURE_RESPONSE. Is there a workaround for this?

Thanks.

jonricaurte commented 9 years ago

Nevermind. Just saw the PR.

anthonyabraira commented 6 years ago

Did an implementation ever get deciphered? I should mention that I am using this in conjunction with the FoundationPress git

macbookandrew commented 6 years ago

@anthonyabraira Here’s what I’ve been doing:

  1. Generate my own self-signed cert for my local dev domains and mark it as trusted in my Keychain app
  2. Add these options to the gruntfile browserSync options to use my trusted self-signed cert for local dev:
                proxy: "https://my-local-site.wordpress.dev",
                open: "external",
                host: "my-computer.local",
                https: {
                    key: "path-to/local-dev.key",
                    cert: "path-to/local-dev.crt",
                }
anthonyabraira commented 6 years ago

Thanks for the response. I am looking to get these setting put in the right place. In FoundationPress there is a gulpfile.babel.js which has settings listed out like this:

// Start BrowserSync to preview the site in
function server(done) {
  browser.init({
    proxy: BROWSERSYNC.url,

    ui: {
      port: 8080
    },

  });
  done();
}

Not sure if goes here or if it goes in the config-default.yml file:

# Browsersync config
BROWSERSYNC:
  # URL of local development server goes here (ex. http://localsite.dev)
  url: ""

# Autoprefixer will make sure your CSS works with these browsers
COMPATIBILITY:
  - "last 2 versions"
  - "ie >= 9"
  - "ios >= 7"

I should say that I tried copying and pasting the settings onto config-default.yml producing this error:

YAMLException: bad indentation of a mapping entry at line 4, column 10:
      url: "",
             ^
macbookandrew commented 6 years ago

@anthonyabraira Try adding this to gulpfile.babel.js:

// Start BrowserSync to preview the site in
function server(done) {
  browser.init({
    proxy: BROWSERSYNC.url,
    open: 'external',
    host: BROWSERSYNC.host,
    https: {
      key: BROWSERSYNC.certkey,
      cert: BROWSERSYNC.cert,
    },
    ui: {
      port: 8080
    },
  });
  done();
}

and then update the BrowserSync section in config.yml (not config-default.yml):

url: "your-machine-name.local", // needs to be included in the cert’s main name or alternate names
certkey: "path-to-key.key",
cert: "path-to-cert.crt",
anthonyabraira commented 6 years ago

Alright I applied your updates to gulpfile.babel.js It looks like this:

// Start BrowserSync to preview the site in
function server(done) {
  browser.init({
    proxy: BROWSERSYNC.url,

    /**/
    open: 'external',
    host: BROWSERSYNC.host,
    https: {
      key: BROWSERSYNC.certkey,
      cert: BROWSERSYNC.cert,
    },    
    /**/

    ui: {
      port: 8080
    },

  });
  done();
}

I added the comments so that I can keep track of the difference between the original setup. Now the problem still resides in config-default.yml I understand that you had mentioned using config.yml but this file didn't exist before. The npm start sequence also indicates that, in fact, I am using the config-default.yml for my settings:

foundationpress@2.10.4 start /Users/Shared/htdocs/xoavl.com/wp-content/themes/fp_2.10.4 gulp

[08:45:39] Requiring external module babel-register
[08:45:40] Loading config file...
[08:45:40] config.yml does not exist, loading config-default.yml

Now the error that is being coughed up is roughly the same as before. Occurring within the js-yaml loader:

htdocs/xoavl.com/wp-content/themes/fp_2.10.4/node_modules/js-yaml/lib/js-yaml/loader.js:171
  throw generateError(state, message);
  ^
YAMLException: can not read a block mapping entry; a multiline key may not be an implicit key at line 6, column 9:
        certkey: "../../xo-xoavl.com.key"
            ^
    at generateError (/Users/Shared/htdocs/xoavl.com/wp-content/themes/fp_2.10.4/node_modules/js-yaml/lib/js-yaml/loader.js:165:10)
    at throwError (/Users/Shared/htdocs/xoavl.com/wp-content/themes/fp_2.10.4/node_modules/js-yaml/lib/js-yaml/loader.js:171:9)
    at readBlockMapping (/Users/Shared/htdocs/xoavl.com/wp-content/themes/fp_2.10.4/node_modules/js-yaml/lib/js-yaml/loader.js:1046:9)
    at composeNode (/Users/Shared/htdocs/xoavl.com/wp-content/themes/fp_2.10.4/node_modules/js-yaml/lib/js-yaml/loader.js:1332:12)
    at readDocument (/Users/Shared/htdocs/xoavl.com/wp-content/themes/fp_2.10.4/node_modules/js-yaml/lib/js-yaml/loader.js:1492:3)
    at loadDocuments (/Users/Shared/htdocs/xoavl.com/wp-content/themes/fp_2.10.4/node_modules/js-yaml/lib/js-yaml/loader.js:1548:5)
    at Object.load (/Users/Shared/htdocs/xoavl.com/wp-content/themes/fp_2.10.4/node_modules/js-yaml/lib/js-yaml/loader.js:1569:19)
    at loadConfig (/Users/Shared/htdocs/xoavl.com/wp-content/themes/fp_2.10.4/gulpfile.babel.js:54:17)
    at Object.<anonymous> (/Users/Shared/htdocs/xoavl.com/wp-content/themes/fp_2.10.4/gulpfile.babel.js:27:60)
    at Module._compile (module.js:662:30)

This is what the config-default.yml looks like after your updates.

# Browsersync config
BROWSERSYNC:
# URL of local development server goes here (ex. http://localsite.dev)
    url: "https://xo-xoavl.com",
    certkey: "../../xo-xoavl.com.key",
    cert: "../../xo-xoavl.com.crt"

I wasn't sure about the certkey and cert so I just figured they were relative paths ... back tracking to the root folder where the MAMP Pro software defaults the certificate and key files. I also tried the url: as my computer name under the System Preferences > Sharing options and also reviewed the certificate to see that it was registered as the xo-xoavl.com ... since the comments on the config-default.yml indicate to put the full https:// address to the localsite dev, that's what I did.

macbookandrew commented 6 years ago

@anthonyabraira Try a full path instead: /Users/anthony/MAMP/xo-xoavl.com.key, etc.

You might want to put secrets in a config.yml file and make sure it’s ignored by git for security reasons.