isaacs / github

Just a place to track issues and feature requests that I have for github
2.21k stars 129 forks source link

Add HTTPS support to Github Pages including custom domains #156

Closed konklone closed 6 years ago

konklone commented 10 years ago

NOTE to anyone stumbling on this thread - there are many people subscribed, so please do not comment here unless you have something new to add that is not already discussed above in this long, detailed (and I hope helpful!) discussion thread.


Update: GitHub *[announced official support of HTTPS for .github.io domains](https://github.com/blog/2186-https-for-github-pages), which is awesome**, and a clear first step. They clearly intend to move GitHub Pages in a secure direction, and this will help GitHub find and fix bugs as they (hopefully) figure out how to do custom domains.

However, this issue is not resolved yet, as custom domain support is a core issue affecting thousands of websites, including the homepages of many prominent software projects (not to mention GitHub's own conference, CodeConf). GitHub Pages doesn't offer complete HTTPS support until custom domains are supported.

To enable HTTPS for your *.github.io subdomain, flip the switch in your settings as described in GitHub's official documentation. 🎉


Github obviously takes HTTPS very seriously. It was early to switch to HTTPS everywhere in the site, and @dbussink has already made some great strides in shoring it up for Github.

Recently, Github has given Pages a proper home and place in the Github suite of offerings. I was extremely happy to see that, because Github Pages is one of my favorite things on the Internet and has amazing potential. It's being used for more than simple project pages, and that's only going to continue as Github's reach and accessibility improves.

Given all that, Github should figure out how to support HTTPS on Pages. Encryption is becoming the standard for the entire web, for many obvious reasons -- to the point that Chrome and Firefox will require HTTP 2.0 requests to be encrypted.

This is an issue I've brought up with @benbalter from Github before, on a few occasions. We talked about it a bit last month on Twitter, and he raised the dual point that most people wouldn't turn on HTTPS, yet turning it on by default would wreck a lot of unsuspecting people's sites with mixed content warnings.

These are good points, but this can be addressed by:

In other words: a checkbox, defaulting to on for all future Github Pages.

This is the best of both worlds: no one gets surprised with mixed content warnings, and Github gets to proceed with a strong HTTPS policy that will bring a lot of content into the encrypted Internet (aka the future). People who really have to deal with non-HTTPS content can continue to use Pages by unchecking the box.

So how would this work? Covering *.github.io domains is comparatively straightforward - install a wildcard certificate.

However, if custom domains weren't supported at the same time, this could pose its own problems: I'm unsure how that would impact automatic redirects to custom domains -- it's not considered best practice to redirect from an HTTPS URL to an HTTP one, and I've seen Chrome flag such a redirect as a mixed content warning.

Additionally, it would require potentially confusing language and settings to handle different cases, as people add and remove CNAME files. So, it's probably worth tackling both situations at once.

While there are a few solutions, realistically, I believe this means building a dedicated settings pane for managing private keys and certificates. Certificates would need to be handled at the project level, but private keys could be managed at the user level.

I believe the infrastructure of web hosting can and will rework itself to make encryption on every wire standard and easy for publishers and consumers alike. Github is in a position to really help move that needle, and get huge praise for doing so -- not to mention a competitive edge in site hosting.

This is a non-trivial feature request, but the challenge it poses is why I'm not aware of any major option right now for simple, free, secure web hosting -- and why Github meeting this challenge would be so important. Making it easier for people to do powerful things is what Github is all about.

henhouse commented 9 years ago

:+1:

Miladiir commented 9 years ago

@sinak Probably to late, but here you go:

Self signed certificates provide a secure connection to the server. Non-self signed certificates (as in certificate issued by authority) are even more secure, as they provide a secure connection to the server AND the server is confirmed to be real.

To understand this issue imagine the following: Which would you trust more, a certificate for github.com signed by me or a certificate signed by verisign or globasign?

On the issue: I can do the full ssl thing, however I end up at a page saying that the system doesn't recognize the url. Implementing this would be a huge deal! For now I am just redirecting my page to another server with a proper ssl setup.

sinak commented 9 years ago

@Miladiir That makes sense, and I now understand why self-signed certificates are less secure. Thanks.

@konklone: I think I'm probably best off responding to your example with my own setup. You said:

That (and the reason why Strict SSL is more secure than Full SSL) is because CloudFlare isn't making requests to https://website.github.io. CloudFlare's systems aren't GitHub-aware, it doesn't know that your domain actually maps to some *.github.io domain.

So if you set up (say) konklone.io as a custom domain on GHP as I have, and you then add CloudFlare in front of it, then for either Full or Strict SSL CloudFlare will ask GitHub to respond to https://konklone.io and see what it gets.

Here's my example: I have my stopwatching.us and optin.stopwatching.us records as CNAMEs pointing to efforg.github.io. efforg.github.io supports HTTPS, so I would imagine that Cloudflare would be able to enable Full SSL. But when I enable that option, I get an HTML page saying "Domain stopwatching.us not found."

I guess it feels like your sentence "CloudFlare's systems aren't GitHub-aware, it doesn't know that your domain actually maps to some *.github.io domain" isn't true if the DNS record is a CNAME.

konklone commented 9 years ago

I know I'm probably being a bit silly, but I don't completely understand how Strict SSL is considerably more secure than Full SSL if the endpoint has a non-self-signed certificate. If website.github.io has a valid certificate - even if it isn't that for website.com - doesn't that prevents against a MitM pretty robustly?

@sinak - If CloudFlare doesn't validate the certificate at website.github.io, then it doesn't matter whether the certificate is valid or not. So even if you have a valid cert, it could be trivially replaced with a forged cert and CloudFlare wouldn't care. This is why Full SSL (non-Strict) is weaker than Strict, no matter what certificate is used.

But when I enable that option, I get an HTML page saying "Domain stopwatching.us not found."

I guess it feels like your sentence "CloudFlare's systems aren't GitHub-aware, it doesn't know that your domain actually maps to some *.github.io domain" isn't true if the DNS record is a CNAME.

I don't think that's correct. You get an HTML page saying "Domain stopwatching.us not found" because that's what GitHub's servers are telling CloudFlare. CloudFlare is not GitHub-aware, and is not asking GitHub for the content at efforg.github.io, but the content at stopwatching.us. GitHub's servers are not configured to respond to the custom domain over port 443, so they return an error.

I'm inferring from the outside here, and it'd help to have someone from CloudFlare clarify how this works. But my understanding is: when you give CloudFlare a "CNAME", that's not literally set as your domain's CNAME. It's helpful for you to think of it as a CNAME, because CloudFlare internally uses it to resolve which server it should be serving content from. (You can't set the CNAME to the same domain, because that would be circular and give CloudFlare no information.) CloudFlare resolves efforg.github.io to a GitHub IP address, and then asks that server to give it content corresponding to stopwatching.us, over port 443. (This is likely accomplished through the Host header over HTTP, and/or the servername flag in SNI for SSL.)

If you've got Strict on, then it will validate the cert that your server has installed for stopwatching.us and verify that the cert was issued for that domain name. Without Strict, any cert will do, but the server at hat IP will still have to respond properly to requests for stopwatching.us over port 443.

If CloudFlare used your CNAME's domain to validate the certificate, it wouldn't be validating that the origin's certificate was valid for the domain it's ultimately serving for the customer. The only way CloudFlare would do that is if it made an exception for GitHub Pages, which means it would have to be GitHub-aware. Right now, that's not the case.

konklone commented 9 years ago

I've reproduced the process CloudFlare goes through for either Strict or non-Strict configurations,by testing https://theunitedstates.io, which is hosted on GitHub Pages.

Here's my "DNS" configuration in CloudFlare for the domain:

cname

Domain set to use "Full SSL (Strict)"

Here's what it looks like with "Full (Strict)" enabled -- CloudFlare can't even make the handshake work. (It's certainly not requesting data from https://unitedstates.github.io.)

handshake failed

You can reproduce this yourself by trying to visit the HTTPS version of a custom domain on GitHub Pages that is not hosted on CloudFlare - for example, https://konklone.io. It just hangs.

Domain set to use "Full SSL" (non-Strict)

Now, here's what my domain looks like with just "Full" enabled, non-Strict -- the same "unknown domain" error you got:

unknown domain

Here's how to demonstrate what's happening, and what CloudFlare sees. If you do a DNS lookup on GitHub Pages' server for unitedstates.github.io, you can get one of GitHub Pages' Fastly IP addresses:

$ nslookup unitedstates.github.io

Server:     127.0.1.1
Address:    127.0.1.1#53

Non-authoritative answer:
unitedstates.github.io  canonical name = github.map.fastly.net.
Name:   github.map.fastly.net
Address: 23.235.39.133

If you then add this line to your /etc/hosts file to force your computer to resolve theunitedstates.io to that IP address:

23.235.39.133 theunitedstates.io

And then visit https://theunitedstates.io (in an Incognito window, if you're using Chrome, to clear the DNS cache), you'll get an invalid cert (in fact, it's GitHub.com's main cert!):

invalid domain

And if you click through that error, you'll get the same "unknown domain" error that CloudFlare saw, from GitHub Page's server:

got it

Conclusion

Those are the mechanics involved, and why right now, with GitHub's current server and CDN configuration, you cannot get a secure end-to-end connection to GitHub Pages' CDN.

Also, bear in mind -- even if we did manage to get a secure connection to GitHub Pages' CDN -- Fastly -- there's no visible guarantee that content is encrypted between Fastly and GitHub itself.

paddingme commented 9 years ago

+1 for HTTPS support for github pages on custom domains as well

hamishcampbell commented 9 years ago

:+1:

bhanuc commented 9 years ago

+1 for HTTPS support for github pages on custom domains as well

why-jay commented 9 years ago

+1 for HTTPS support for github pages on custom domains as well

garrettboatman commented 9 years ago

+1,000,000. I have no idea why at least flexible SSL isn't supported yet.

johntfoster commented 9 years ago

:+1:

parin95 commented 9 years ago

+1 for HTTPS support for github pages on custom domains

wsargent commented 9 years ago

https://letsencrypt.org/

timothybasanov commented 9 years ago

It would be really cool to have an HTTPS on my Domain using GitHub to serve content. I realize that it's hard to solve problem.

I'm willing to share my private key for SSL certificate so GitHub would establish HTTPS session on my custom domain. Even if I would need to have a private repo for that. Even storing it in a public one provides some guarantees for the end user (assuming that nobody modifies, only inspects traffic in flight). Assuming that client supports SNI (of course) it's theoretically possible.

And yes, I understand that maintain a key infrastructure on servers that terminate TLS would be a huge pain for GitHub. Paid option to limit number of certificates that you need to store?

cben commented 9 years ago

SNI is already assummed — all GH pages are served from about 4 IPs. (At least all custom domain pages.)

Putting your cert private key in public is really bad, turning it into security theater. Assuming MITM is tricky to pull off made some(?) sense 15 years ago but not in the age of coffee shop wifis and Firesheep, not to mention three-letter agencies... Even a sporadic active attack may compromise lots of other passively inspected communication by that user via stealing/setting cookies/phishing. Worse, I think(?) that if the encryption didn't feature Forward Secrecy, a passive observer having the secret key can just decrypt everything.

timothybasanov commented 9 years ago

Nah, they are using only one certificate now, that covers all the subdomains. But this is impossible in case of user-provided domains.

stevenroose commented 9 years ago

+1 for HTTPS support for github pages on custom domains as well

mlacorte commented 9 years ago

+1 for a native (non CloudFlare) solution.

I can get by with using the https://mlacorte.github.io domain for my personal blog, but I'd much rather be able to use my sexy https://blog.michaellacorte.com. I imagine this would be a dealbreaker for many other people/organizations.

philsturgeon commented 9 years ago

Current progress.

1604591_700b

adrifelt commented 9 years ago

:+1: I'd gotten excited about setting my new site up with GH pages + custom domain, but full end-to-end HTTPS support is important for me so I'm now stuck.

konklone commented 9 years ago

To the thread: what would be a useful thing to do here?

I can imagine an nginx proxy snippet, or one-button-deploy Heroku proxy server, that would do the work CloudFlare does not -- knowing to proxy https://mydomain.com to https://me.github.io/maybe-a-path-prefix/, and to validate the github.io certificate.

patcon commented 9 years ago

@konklone :+1: for unblocking ourselves

giodamelio commented 9 years ago

:+1:

CumpsD commented 9 years ago

Chiming in with the many voices before me. We just moved a year worth of interal work at our company onto GitHub to open source it, combined with a GitHub Pages frontend. Https is something we care about a lot, and would love to be able to enable it on our custom domain.

sikachu commented 9 years ago

:+1: to this as well.

I really don't know all the details, but I'm curious why I can point CloudFlare to, say, foo.herokuapp.com, and it works under Full SSL mode. I think GitHub is already serving the right SSL certificate, but they just need to fix their app router ... somewhat.

likethesky commented 9 years ago

@konklone are you saying that if I'm already on Heroku, that using my wildcard cert there I could possibly direct back to mysite.github.io and have end-to-end (strict) SSL/TLS ? IOW, I'm not using Cloudflare, I just want strict SSL for users who hit my GH Pages site. I'd be happy to run some experiments on a Heroku deploy at some subdomain on my site (I have a wildcard cert), if you think it'd be worth trying!

@sikachu this works because Heroku provides a fully valid wildcard cert for *.herokuapp.com (and possibly because Cloudflare is also 'Heroku aware'). Note that @konklone mentions in prior replies that CF is not 'GitHub Pages aware', I'm not sure whether that's part of why Heroku works in this case or not. For sure, also, Heroku does offer users the ability to serve their own certs, unlike GH Pages, which is what all of these +1s here are asking for--as I'm sure you're already aware--which is: for GitHub Pages to step up and do what Heroku has already done: namely, to allow user certs to be installed and used for their custom domains, so true strict SSL is possible--fully end-to-end with no MITM attacks possible (I dislike the fact that there's even such a name as full or flexible SSL, because let's be frank, it ain't SSL/TLS at all!)...

konklone commented 9 years ago

@sikachu Are you under Full SSL with Strict enabled? If so, can you share your CloudFlare "DNS" configuration?

@likethesky I think you could definitely set up a Heroku app that received traffic at https://yoursite.herokuapp.com and proxied it behind the scenes to https://yoursite.github.io/whatever/ (assuming that your proxy library was set to validate the HTTPS connection it's proxying to -- for example, nginx only added this functionality in the last year). Your canonical, public URL would be a herokuapp.com URL, but if that's fine with you, you should go for it.

cben commented 9 years ago

1.

If one would be fine with a FOO.herokuapp.com url, then a FOO.github.io url should also be acceptable (IIUC /whatever suffix can be avoided by using Organization rather than User Pages). The whole point of a heroku proxy is that Heroku does allow you to provide a cert and serve FOO.com. 2.

A heroku proxy forwarding requests to github is unlikely to perform as well as just serving the data from heroku. (In particular a freebie 1-dyno app will lose the CDN benefits of GH Pages.)

All it gives you is the convenience of automatic deploy when you push to gh-pages branch, but pushing to heroku remote is practically as easy.

So I don’t see why anyone would run such a proxy. It becomes more interesting to run a single proxy which can serve many projects, or many versions. Many projects doesn’t work well because of certs and trust; for many versions I am contemplating running a rawgit.com clone under my own domain, giving users ability to test any commit (including branches and forks). ​

roughani commented 9 years ago

+1 for HTTPS support for github pages on custom domains as well

davidmyersdev commented 9 years ago

Another +1 for HTTPS support on GitHub Pages with a custom domain. This would be incredibly beneficial to a plethora of site owners and would be an added layer of security for users.

bricejlin commented 9 years ago

+1 for https support with custom domain!

stephengroat commented 9 years ago

+1 for HTTPS support with a custom domain

kkirsche commented 9 years ago

+1

temghost03ajfksdf commented 9 years ago

+1 for SSL with custom domains.

cben commented 9 years ago

Turns out there is no end-to-end security even with foo.github.io domain. Got this response from GH support (emphasis mine):

Hi Beni,

AFAIK https://FOO.github.io has worked since April 2014 (for modern browsers supporting SNI)

GitHub Pages does not currently offer HTTPS (SSL) support. While third-party services such as CloudFlare, may in some cases be able to provide that functionality to the end user, at this time, we're not able to offer support for these configurations.

While HTTPS requests may appear to work, our CDN provider is adding and removing the encryption at their end, and then the request is transmitted over the open internet from our CDN provider to our GitHub Pages infrastructure, creating the appearance of trustability.

This is why we do not yet officially support HTTPS for GitHub Pages. We definitely appreciate the feedback and I'll add a +1 to this item on out internal Feature Request List.

P.S. Github's "contact a human" response speed is phenomenal :-)

cben commented 9 years ago

On the upside, this means that using a custom domain via Cloudflare with non-strict "full ssl" or even "flexible ssl" doesn't significantly degrade security. We have to weigh benefit of last-mile security vs harm of illusion-of-security but if we accept it we can as well use a custom domain :-)

Anyway, I wouldn't expect any progress on here until the more basic issue is resolved. Github: FWIW, I'd totally upgrade to paid user just for end-to-end TLS on *.github.io.

[P.S. are there convenient free end-to-end secure alternatives for non-custom domains? Heroku can be configured to auto-deploy from gh-pages (but unlike direct git push heroku it won't resolve submodules); the main downside is ~10-sec latency when waking up after >1h inactivity. Another option that springs to mind is cdn.rawgit.com — not sure but judging by https://twitter.com/rawgit/status/522158585053081600 I assume it's secure all the way. But it requires fixed commit/tag in URL.]

thedod commented 9 years ago

FWIW, here's a gist-sized solution. Add a cgit, and it's allready an RV-sized one :wink: https://gist.github.com/thedod/b487aa84e77f19423f56#file-readme-md

45H commented 9 years ago

+1 for HTTPS support with a custom domain!

roccozanni commented 9 years ago

+1 for HTTPS support with a custom domain

DarkPark commented 9 years ago

+1

pracucci commented 9 years ago

+1 for HTTPS support with a custom domain

dral3x commented 9 years ago

:thumbsup: for HTTPS support with a custom domain

iimog commented 9 years ago

+1

ewilliam commented 9 years ago

+1

enkrates commented 9 years ago

:+1: for SSL on custom domains.

vitalidze commented 9 years ago

+1 for HTTPS support on custom domains

heapwolf commented 9 years ago

+1

tiandavis commented 9 years ago

+1

AFouques commented 9 years ago

:+1:

hpurmann commented 9 years ago

:+1: I would appreciate it