### Feature and motivation

### Feature
Add `--external-uri` configuration parameter to `server` section. This will allow nodes to provide a URI to hub (or distributor) which is route-able when SE node is running behind some sort proxy.

### Motivation
There are cases when nodes cannot report self URI that is route-able from hub during node registration process in which case the node get's stuck in `Sending registration event...` loop, while the hub logs will show connection timeouts or unknown host exceptions.

I believe this can be easily fixed in `org.openqa.selenium.grid.server.BaseServerOptions#getExternalUri` by first reading this newly added `external-uri` parameter. When empty, implementation can fall back to the current one otherwise it could just use the provided value.

### Our concrete use case:
We run ~5000 selenium tests. For performance reasons we deploy ~60 instances of our app each bundled with a SE node across ~20 single node k8s clusters (so each cluster runs 3 apps each with a chrome SE node). One extra k8s cluster runs on the CI agent itself where SE hub is running. For various reasons - which for brevity I don't want to detail - these clusters communicate with each other via node ports (on private IPs). 

So I end up in a situation where I can configure SE node so it can reach SE hub via (let's say 192.168.1.2:30027-30030) and I can configure it to report its own IP correctly (let's say 192.168.1.3, via `--host`), but I get into a problem with `--port`.
If I leave it on it's default (5555), then hub will try to connect to it on 192.168.1.3:5555 (but that is not route-able). One solution that works is picking a port from node port range and use that port both for node port and start SE node on that port inside the container but this has an unwanted administration overhead as well as adding non deterministic behavior as static node port range is only available on k8s version 1.27 in a feature that is not generally available yet.

It is a lot simpler if this feature is added.

### Usage example

Until docker part is updated we could use `SE_OPTS` to supply `--external-uri=http://<node-ip>:<node-port>`.
return config.getBool(SERVER_SECTION, "allow-cors").orElse(false);
  }
  public boolean getBindHost() {
    return config.getBool(SERVER_SECTION, "bind-host").orElse(true);
  }
  public boolean isSecure() {
    return config.get(SERVER_SECTION, "https-private-key").isPresent()
        && config.get(SERVER_SECTION, "https-certificate").isPresent();
  }
  public File getPrivateKey() {
    String privateKey = config.get(SERVER_SECTION, "https-private-key").orElse(null);
    if (privateKey != null) {
      return new File(privateKey);
    }
    throw new ConfigException(
        "Please provide a private key via --https-private-key " + "when using --https");
  }
  public File getCertificate() {
    String certificatePath = config.get(SERVER_SECTION, "https-certificate").orElse(null);
    if (certificatePath != null) {
      return new File(certificatePath);
    }
    throw new ConfigException(
        "Please provide a certificate via --https-certificate " + "when using --https");
  }
  public boolean isSelfSigned() {
    return config.getBool(SERVER_SECTION, "https-self-signed").orElse(false);
  }
}