5

There's a site I frequently visit that makes use of several CDN domains and subdomains. One of these CDN subdomains recently stopped working for some reason, and it is affecting others, not just me.

I noticed that requests for:

https://subdom_1.dom_1.com/somefile.png

are failing (nothing is served), but if I change the FQDN to:

https://subdom_2.dom_2.com/somefile.png

the file gets served correctly.

I want to avoid installing a browser extension, so I was thinking there might be a way to do this maybe via /etc/hosts (I'm on linux). Ample searches didn't give me the answers, but hints such as using /etc/resolv.conf or dnsmasq or using 0.0.0.0 subdom_1.dom_1.com subdom_2.dom_2.com in /etc/hosts came up. But the manuals were less than clear, and I rather not risk opening up some security hole into my machine by doing something I don't fully understand.

Anyone have any clues as to what I can do? Refs to manuals and explanations of security concerns, etc, would be greatly appreciated.

insaner
  • 385

2 Answers2

7
  1. /etc/hosts translates names to addresses; not to other names. Although there is a meaning to putting multiple hostnames in the same /etc/hosts line (the first name is returned in the "canonical name" field), browsers do not care about it; they only care about the IP address.

    A local DNS server that supports returning fake results (like dnsmasq or Unbound) would be needed to replace one domain with another, but with /etc/hosts all you can do is a static IP address mapping.

  2. As the requests are made over HTTPS, the replacement server needs a "valid" certificate for the domain that is in the URL. Your manual edits replace the actual URL with a new domain, so the new server's existing certificate works for it. But any external means – whether DNS or /etc/hosts or something else – would redirect the connection to a different address while keeping the browser thinking that the URL is still the same, and therefore the new server would need to have a valid certificate for the first domain. (It would rather defeat the point of HTTPS if the browser could be so easily tricked into expecting a different certificate by external means!)

  3. As the resource URL within the page remains the same (containing the original domain), the HTTP request will also be made with the 'Host:' header requesting that original domain, which the 2nd server might not recognize. Many HTTP servers – and CDNs especially – use "virtual hosts", the same machine serving different content for many different domains, so they rely on the browser specifying the correct host for each request.

It's likely that you'd need to redirect the requests to your own server configured to recognize the 1st domain, which proxies them to the actual 2nd CDN host and rewrites the 'Host:' request header to what the 2nd server will expect.

You cannot get a certificate from a public CA if you have no control over the domain (and of course can't ask the second CDN to install it anyway). So you'd need to run your own proxy host and to make your own CA, issuing a certificate for "subdom2" that's only valid on your own systems.

So if you want to do this externally to the browser, you'll need:

  • Apache or Nginx or a similar "reverse proxy" installed somewhere (maybe even on the same PC, maybe on WSL or on a cloud server);
  • something like XCA or Easy-RSA to issue your own internal-use HTTPS certificates;
  • the proxy configured with a <VirtualHost> for the "original" domain name (and with a certificate for that domain name), forwarding all requests to the new URL;
  • the custom CA certificate installed on your browser;
  • an /etc/hosts entry to map the original domain name to the IP address of the proxy.
grawity
  • 501,077
2

You can do this at the browser level with an extension. In Firefox, you can use an existing broadly-scoped extension. Alternatively, for both Firefox and Chrome you can create a custom extension more tightly scoped to a specific site.

For Firefox, the Request Control extension can be used like so:

Screenshot of rule

Specifically, you need to:

  1. Create a new rule
  2. Specify the host to be replaced
  3. Set path to * to match all paths
  4. Tick Any type
  5. Select Redirect
  6. Specify the new path with {protocol}newhostname{pathname}{search}{hash}, replacing newhostname with the new host you wish to use
  7. Save and enable the rule

Sadly, this same extension will not work directly in Chrome since their Manifest V3 changes that remove the old webRequest API. To achieve a similar effect in Chrome, you will need to create a custom extension and use the declarativeNetRequest API to specify a redirect with a transform. This method would also work on Firefox.

Bob
  • 63,170