Foreman Smart Proxy behind a reverse proxy

Hello everybody,
we need to run the foreman smart proxy (version 2.1.3) behind a reverse proxy (apache 2.4). Currently we need to add the reverse proxy to the trusted_hosts parameter, because the smart proxy did not recognize something like “X-Forwarded-For”.
In my opinion this configuration is very unsecure, because everbody who can reach the reverse proxy, can call “verified” request again the smart proxy.

How can i configure the smart proxy or the reverse proxy, so the proxy only accepts requests from the forman nodes? Is there a way to set “request.env[‘REMOTE_ADDR’]” (which is used by the helper function “lib/proxy/helpers.rb”) to a different value?
I tried to “manipulate” the http header in apache with “RemoteIPHeader X-Forwarded-For”, but unfortunately without success.

You are correct that this is currently an unsupported deployment. It would probably also not understand the X-Forwarded-Proto header if you set that.

Let’s take a step back and ask what you want to achieve by running it behind a reverse proxy.

Reasons for us to use a reverse proxy:

  • First of all, its an company policy to use a proxy, when “entering” another network segment.
  • Furthermore we do not need to create firewall rules for all foreman host, but only for one reverse proxy.
  • With a reverse proxy, we are able to “load balance” the requests to foreman smart proxy

I think there are many more reasons why to use a reverse proxy.

As you can see, the Smart Proxy doesn’t support a HTTP (reverse) proxy. At this point I would suggest to try a TCP level proxy, such as HAProxy. If you do want HTTP level support, you will need to supply patches to it.

After having reviewed the code of the smart proxy and rack in more detail, it seems to me, that the code of foreman smart proxy must be extended to support reverse proxy.
it could be like:

 def remote_fqdn(forward_verify = true)
   if request.env['HTTP_X_FORWARDED_FOR']
      ip = request.env['HTTP_X_FORWARDED_FOR']
      ip = request.env['REMOTE_ADDR']

instead of

def remote_fqdn(forward_verify = true)
  ip = request.env['REMOTE_ADDR']

in lib/proxy/helpers.rb

Futhermore i found in the following section in some puma libaries:

  # From :
  # "Script authors should be aware that the REMOTE_ADDR and
  # REMOTE_HOST meta-variables (see sections 4.1.8 and 4.1.9)
  # may not identify the ultimate source of the request.
  # They identify the client for the immediate request to the
  # server; that client may be a proxy, gateway, or other
  # intermediary acting on behalf of the actual source client."

I would recommend to not only use “request.env[‘REMOTE_ADDR’]” in foreman and foreman smart proxy.

Sorry to resurrect a very old thread, but did you ever get this working @chr1s? I’m very interested if updating these few lines of code is all it took.