1
votes

This is probably going to be a stretch, but it seems worth asking. Let's say I have a static Angular web app on nginx-host (linux) along with the following /etc/hosts file, automatically generated for the host by some stringy configuration management tool:

127.0.0.1 localhost
10.0.0.1  internalhost

Next, I have a stock Nginx configuration for nginx-host, nothing fancy is happening with the server blocks - with this problematic location block:

location ^~ /app {
    return 301 http://internalhost/end/point
}

The problem is that this block returns precisely the url listed in the location block without any sort of translation from internalhost to the appropriate IP, resulting in client-side errors - and I need it to resolve that IP before handing it back.

Please note, we can't use maps or upstreams here. The Immovable Wall here is that our configuration system handles all service discovery and host-dependency resolution by doing lookups and generating hostfiles, and it's entirely separated from our internal nginx configuration, so we can't connect the lookups to the nginx setup to allow for dynamic maps or upstreams. This is also happening across several isolated segments of network for varied testing environments, so it's a hard requirement that we reference the nginx host's /etc/hosts file to resolve the host name before passing back the redirect path, as internalhost can be anything from dev-internalhost to production-backup-internalhost, all of which have distinct IPs.

Note: proxy_pass is not a solution here, we need the redirect for SSO purposes, and when the request is made to the internalhost location, the request params need to carry on through to the internalhost machine from the nginx-host, and the client needs to see the redirect to know that it's now on speaking terms with the internalhost server.

Edit for clarity: the client has no way to resolve internalapp on its own: nginx-host has a static UI, a link on that UI hits the /app endpoint, and nginx needs to pass back an IP-based link derived from the generated local hosts file. internalapp has no DNS records at all aside from the local hosts file - but the IP address in the hosts file would resolve to something like dev-internalapp.example.com that could actually be reached

1

1 Answers

0
votes

The hostname in the 301 redirect is just text that's sent to the webbrowser.

The vast majority of clients out there will use DNS to find the IP address from the hostname in the URL.

If you have browsers "out there" on the Internet, they will have to have a fully qualified domainname (e.g. www.example.com) as internal or something similar will never point back to you. In this case you will have to change the message sent back by nginx. It's trivial if you have control over the configuration to do that...

If you only have internal hosts, your internal DNS should be more than able to allow internal hosts to properly resolve "internalhost" to its internal IP address. In essence, make sure they send a searchdomain record along with the DHCP responses.

How to setup the DHCP and DNS inside a company is relatively easy if they have an internal network/IT team that knows what they are doing. If they have a mess -that happens every so often- nothing will work properly, no matter what you do.

A lot depends on how they set things up, but in general to make names like "internalhost" resolv internally to an IP address, I'd use:

  1. pick an internal domainname (if they have not already). e.g. .local is an option, or historically in.example.com (where example.com is their external name). It does not have to be known externally, it just must not be used externally. Having it known externally makes it slightly harder, so avoid that.

  2. DHCP: I'd set DHCP to emit the optional "search domain". How to do that depends on what DHCP server they use, but e.g. https://serverfault.com/questions/481453/set-search-domain-on-dhcp-server-without-changing-domain-name shows an example. I typically make sure it emits in.example.com, example.com as that makes it easier on typing domain names.

  3. Internal DNS: now just add on the internal DNS server(s) an A record for internalhost.in.example.com. and point that to your RFC1918 address.

  4. Optional: I'd make sure the firewalls disallow internal clients from using external DNS servers - or (better?) redirect them transparently to the internal DNS server(s). that way you avoid users setting e.g. 8.8.8.8 and 8.8.4.4 as DNS servers, overruling what they get from the DHCP server, and hence not seeing your internal names.

That's it. http://internalhost/whatever will now go to the machine with the IP address given in step 3 above and browsers will send a Host: header (if you have virtual hosts!) of internalhost.