Public url via http

hey so it seems devices public URLs aren’t being redirected from http to https and are accessible via http too, is this by design? is there anyway we can adjust this?

Hi @jmarshall
It is by design that both HTTP and HTTPS work - but it does make sense to be able to disable HTTP access, so I’ve added it to our internal feature request tracking.

Whilst, as @pcarranzav says, we don’t have support to solve this built-in, if this is important to you then you can work around it yourself using HSTS: https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security.

If you return an HSTS header with all responses, then after a given user’s browser receives its first HTTPS response, their browser will automatically redirect from HTTP to the HTTPS resources for all future requests.

This won’t work if the user’s first request is HTTP only, and I don’t think you can detect HTTP/HTTPS server-side with a public URL, so you can’t automatically redirect to HTTPS there yourself. You could detect this in JavaScript though, and trigger a redirect client-side.

With that you can ensure a given user is always on a secure connection, after their first request. There’s HSTS preloading in browser releases, which in principle could let you do this for the first request, but is probably overkill for per-device URLs imo (since you’d have to submit all your device URLs to mozilla/google/et al). Hopefully we’ll take a look at this in future though, which would solve this more thoroughly anyway.

Tim,

having some problems implementing this as all we can only serve HTTP over the VPN, see Open https via public URL
It seems all the HTTPS is offloaded by your reverse proxy. we can only see the request coming in as HTTP. so would never see a HTTPS connection unless as suggested we pick it up client-side, is of course open to manipulation. preloading i think is overkill too.

It would help massively if it was optionally to enable or disable. i’m surprised no one else is concerned about it.

Totally agree full support would be useful! This is in our feature requests list now, and we’ll certainly be considering it in future - I’m just trying to put together a workaround to help you out in the meantime.

The fact that a plain HTTP client-side scripting redirect is open to manipulation shouldn’t matter here - the traditional plain HTTP server-side redirect is open to exactly the same manipulation too, so they’re more or less equivalent in practice. I think the only difference is if you have clients that can’t/won’t run JS, but if you’re only worrying about browsers that’s unlikely to be a major concern.

Anyway, I think you should still be able to get the essential core of this functionality right now, even just with a simple HTTP-only server, even if you don’t want to do client-side redirects.

You should just need to return HSTS headers in all your server’s responses, including on plain HTTP requests. If you do that, then any user who does make an HTTPS request to the public url will receive their HTTPS response with valid HSTS headers, and that’ll take effect completely as normal from their point of view, even though it appears as plain HTTP to you. That will immediately block plain HTTP for this URL in that user’s browser. You can’t ensure that users who make HTTP requests straight from day 1 are guaranteed to be safe (although, to be fair, that’s also true for 100% of non-HSTS-preloaded domains on the internet), but if you just add those headers to your responses you can ensure that all users who’ve made at least one HTTPS request before can never accidentally end up on HTTP in future.

While I agree built-in support is much more convenient, without some kind of preloading this is actually very nearly the best guarantee here that you can get anyway. Even we blocked HTTP entirely in our servers, any user making an initial insecure HTTP request can get intercepted and MitM’d before their request reaches Resin.io in the first place.

@jmarshall any thoughts on the above? I’d love to know if you’ve tried this, and how it’s working for you in practice.

Networking is not a strength area for me. But if i’m understanding this right, this doesn’t matter if you are the only user of your public URL.

For my use case I’m trying to make API calls between our remote devices and our AWS servers, API calls will be bi-directional. In order to have the servers hit our resin devices I was going to have it use the public URL. I’ve been digging on if it is secure or not, and it seems to depend on if we use http or https before the rest of the URL. Is this because we aren’t actually accessing the device on port 80? What we are actually doing is being forwarded that port by the Resin.io server? I don’t need to make each device have its own self signed cert because i’m actually talking to Resin.io which has its own cert?

Am I right on this? Sorry to bump old material but making a new post seems un-needed.

I am working on a solution which requires a device to be accessible for local area network and to be accessible for support via the balena public url. This works by use of HTTP for both local area network and balena public url.

The problem is that the balena public url proxies both a HTTP and HTTPS version of the HTTP device web service.

Are there any status/discussions/changes to the guide about using HSTS and client side redirect or on the balena public url proxy HTTP disable/enable feature?

Furthermore, the local area network needs to be served as HTTPS in near future.

Any status/discussion about providing the device HTTPS port on balena public url instead of the proxyed HTTPS version of the device HTTP port? This is not a question about trust model, but more if this will/can be allowed at some point when multiple ports with public url is supported.

Hi there, we currently have a feature in internal testing which will allow https public urls to be terminated at the device when using a custom domain. This would allow you to handle requests on both ports 80 and 443 on your devices and redirect/reject http connections appropriately and serve https via both balena’s vpn and locally on the LAN. Additionally, there is currently (albeit limited) support for multiple ports on public urls: both ports 80 and 8080 will be forwarded to the device.

Hi @wrboyce

What does it mean by internal testing. Like in a solution which needs to be battle proven or trying to make a solution. Any idea about time estimate?

I am tried to add a webdav to an existing solution, but got some concerns about the fallback to http if the end user by mistake type http instead of https

We have implemented the feature itself, we now need to test it in several different scenarios to ensure that we don’t release any harmful bugs to production, but the lions share of the work is done. I would estimate that within a week or two this will be available. The http fallback is a valid concern, I’m not sure if we would be redirecting https -> http after release. I will raise a ticket internally so that we can discuss this.