# Reverse proxy (rnode or node) to SSL service

**URL:** <https://discourse.openondemand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080>\
**Category:** Get Help\
**Created:** [November 4, 2023, 3:09pm UTC](https://discourse.openondemand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080 "2023-11-04T15:09:32Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![griznog](https://sea1.discourse-cdn.com/flex015/user_avatar/discourse.openondemand.org/griznog/32/39_2.png) [@griznog](https://discourse.openondemand.org/u/griznog)\
**Post date:** [November 4, 2023, 3:09pm UTC](https://discourse.openondemand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080/1 "2023-11-04T15:09:32Z")

</div>

Hi,

I’m trying to set up an app which will proxy to a service that requires SSL. I found this post:

> [@Use HTTPS on Reverse Proxys (/node & /rnode)](https://discourse.openondemand.org/t/use-https-on-reverse-proxys-node-rnode/2404):
>
> I’m able to to use the OOD builtin Reverse Proxy to hit an upstream host via HTTP with no issues. For example, a simple NGINX server is running on node04. [https://head.cluster/rnode/node04.cluster/80](https://head.cluster/rnode/node04.cluster/80) → works [https://head.cluster/rnode/node04.cluster/443](https://head.cluster/rnode/node04.cluster/443) → Fails with expected ‘The plain HTTP request was sent to HTTPS port’ I’m having trouble figuring out where to set a forced HTTPS protocol within the HTTPD & LUA configs that I believe are relevant to what OOD is doing. I see the /rnode Locat…

and tried the solution there, but I still get

> Bad Request  
> Your browser sent a request that this server could not understand.  
> Reason: You’re speaking plain HTTP to an SSL-enabled server port.  
> Instead use the HTTPS scheme to access this URL, please.

In case it matters, the app in question (NoMachine) handles all authentication so all I really need to do here is reserve the node and produce a link that will reverse proxy to the web interface. Restricting the service to a specific user is something we’ll add later via Slurm prolog/epilog scripts to manage the nxserver config.

My current `view.html.erb` is

```auto
<p>
   The link below will launch your NoMachine Workstation desktop in a browser
   window/tab. If you'd prefer to use the NoMachine native client, create an
   ssh tunnel to the session:
</p>
<ol>
  <li><pre>ssh login-01 -L 24000:<%= host %>:4000</pre></li>
  <li>Add a NoMachine connection to "localhost" using port "24000" and the NX protocol.</li>
</ol>
<hr>
<a href="/node/<%= host %>/<%= port %>" target="_blank" rel="noreferrer noopener">NoMachine Web Interface (node)</a>
<hr>
<a href="/rnode/<%= host %>/<%= port %>" target="_blank" rel="noreferrer noopener">NoMachine Web Interface (rnode)</a>

```

The submitted job just grabs the node with `--exclusive` to make sure no one else can start jobs on it, starting `sleep 90d`.

In `/opt/ood/mod_ood_proxy/lib/ood/proxy.lua` I have added this:

```auto
function set_reverse_proxy(r, conn)
  -- find protocol used by parsing the request headers
  local protocol = (r.headers_in['Upgrade'] and "ws://" or "http://")
  if upstreamPort then
    -- If specified port was used, then use secure protocols
    if upstreamPort == '4443' then
      protocol = (r.headers_in['Upgrade'] and "wss://" or "https://")
    end
  end

```

And `SSLProxyEngine On` is in the VirtualHost config.

I set the port in `before.sh.erb`:

```auto
# Export the module function if it exists
[[$(type -t module) == "function"]] && export -f module

export port=4443

```

When a session starts, the generated URLs in the view are:

```auto
https://ondemand.bruno.czbiohub.org/node/gpu-sm01-14.clusternet/4443
https://ondemand.bruno.czbiohub.org/rnode/gpu-sm01-14.clusternet/4443

```

Both producing the error I mentioned above.

I’m not sure where to look next for where this is going off the rails.

griznog

---

<div class="post-metadata">

**Author:** ![hrandquist](https://sea1.discourse-cdn.com/flex015/user_avatar/discourse.openondemand.org/hrandquist/32/2536_2.png) [@hrandquist](https://discourse.openondemand.org/u/hrandquist)\
**Post date:** [November 7, 2023, 3:08pm UTC](https://discourse.openondemand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080/2 "2023-11-07T15:08:13Z")

</div>

Could you share the entirety of your modified proxy.lua file as a txt file? That would help me to do a little bit of digging.

---

<div class="post-metadata">

**Author:** ![griznog](https://sea1.discourse-cdn.com/flex015/user_avatar/discourse.openondemand.org/griznog/32/39_2.png) [@griznog](https://discourse.openondemand.org/u/griznog)\
**Post date:** [November 7, 2023, 10:34pm UTC](https://discourse.openondemand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080/3 "2023-11-07T22:34:07Z")

</div>

The complete file is:

```auto
--[[
  set_reverse_proxy

  Modify a given request to utilize mod_proxy for reverse proxying.
--]]
function set_reverse_proxy(r, conn)
  -- find protocol used by parsing the request headers
  local protocol = (r.headers_in['Upgrade'] and "ws://" or "http://")
  if upstreamPort then
    -- If specified port was used, then use secure protocols
    if upstreamPort == '4443' then
      protocol = (r.headers_in['Upgrade'] and "wss://" or "https://")
    end
  end

  -- setup request to use mod_proxy for the reverse proxy
  r.handler = "proxy-server"
  r.proxyreq = apache2.PROXYREQ_REVERSE

  -- define reverse proxy destination using connection object
  if conn.socket then
    r.filename = "proxy:unix:" .. conn.socket .. "|" .. protocol .. "localhost" .. conn.uri
  else
    r.filename = "proxy:" .. protocol .. conn.server .. conn.uri
  end

  -- include useful information for the backend server

  -- provide the protocol used
  r.headers_in['X-Forwarded-Proto'] = r.is_https and "https" or "http"

  -- provide the authenticated user name
  r.headers_in['X-Forwarded-User'] = conn.user or ""

  -- **required** by PUN when initializing app
  r.headers_in['X-Forwarded-Escaped-Uri'] = r:escape(conn.uri)

  -- set timestamp of reverse proxy initialization as CGI variable for later hooks (i.e., analytics)
  r.subprocess_env['OOD_TIME_BEGIN_PROXY'] = r:clock()
end

return {
  set_reverse_proxy = set_reverse_proxy
}

```

---

<div class="post-metadata">

**Author:** ![hrandquist](https://sea1.discourse-cdn.com/flex015/user_avatar/discourse.openondemand.org/hrandquist/32/2536_2.png) [@hrandquist](https://discourse.openondemand.org/u/hrandquist)\
**Post date:** [November 8, 2023, 2:14pm UTC](https://discourse.openondemand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080/4 "2023-11-08T14:14:16Z")

</div>

I’m wondering about the bit of code that’s missing that’s in the solution you linked to, but not your file - `upstreamPort` isn’t declared or set anywhere. What happens when you include this:

```auto
-- find protocol used by parsing the request headers
  -- Check if an upstream port was set for reverse proxies.
  local upstreamPort = nil
  local isUpstreamPortSet = (r.subprocess_env['MATCH_PORT'] and 'true' or 'false')
  if isUpstreamPortSet == 'true' then
    upstreamPort = r.subprocess_env['MATCH_PORT']
  end

```

---

<div class="post-metadata">

**Author:** ![griznog](https://sea1.discourse-cdn.com/flex015/user_avatar/discourse.openondemand.org/griznog/32/39_2.png) [@griznog](https://discourse.openondemand.org/u/griznog)\
**Post date:** [November 8, 2023, 10:49pm UTC](https://discourse.openondemand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080/5 "2023-11-08T22:49:43Z")

</div>

Thanks @hrandquist , I had missed getting all the change they made into it. Adding that has some impact, the error I get is now:

```auto
Proxy Error
The proxy server could not handle the request
Reason: Error during SSL Handshake with remote server

```

Which I’m going to assume is a problem with the NoMachine self-signed cert and start digging into the Apache config.

---

<div class="post-metadata">

**Author:** ![griznog](https://sea1.discourse-cdn.com/flex015/user_avatar/discourse.openondemand.org/griznog/32/39_2.png) [@griznog](https://discourse.openondemand.org/u/griznog)\
**Post date:** [November 8, 2023, 10:56pm UTC](https://discourse.openondemand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080/6 "2023-11-08T22:56:43Z")

</div>

And with the addition of

```auto
  - 'SSLVerifyClient none'
  - 'SSLProxyVerify none'
  - 'SSLProxyProtocol TLSv1.2'
  - 'SSLProxyCheckPeerName off'

```

to my portal/httpd config, I now get an error from the NoMachine client:

```auto
Error
An unexpected error was encountered during the installation of the Web Player component.

```

Which means, I think, that the proxying is working but the extra stuff in the URL is breaking the NoMachine web client.

---

<div class="post-metadata">

**Author:** ![griznog](https://sea1.discourse-cdn.com/flex015/user_avatar/discourse.openondemand.org/griznog/32/39_2.png) [@griznog](https://discourse.openondemand.org/u/griznog)\
**Post date:** [November 9, 2023, 9:34pm UTC](https://discourse.openondemand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080/7 "2023-11-09T21:34:32Z")

</div>

I contacted NoMachine support, and their recommendation for putting it behind a reverse proxy using Apache is the config:

```auto
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN Off
SSLProxyCheckPeerName Off
SSLProxyCheckPeerExpire Off

ProxyPass "/" "https://192.168.3.201:4443/"
ProxyPassReverse "/" "https://192.168.3.201:4443/"
ProxyPass "/nxplayer" "https://192.168.3.201:4443/nxplayer"
ProxyPassReverse "/nxplayer" "https://192.168.3.201:4443/nxplayer"

```

How do I get the equivalent of those `ProxyPass*` directives into OnDemand?

---

<div class="post-metadata">

**Author:** ![hrandquist](https://sea1.discourse-cdn.com/flex015/user_avatar/discourse.openondemand.org/hrandquist/32/2536_2.png) [@hrandquist](https://discourse.openondemand.org/u/hrandquist)\
**Post date:** [November 13, 2023, 2:49pm UTC](https://discourse.openondemand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080/8 "2023-11-13T14:49:00Z")

</div>

After speaking with a colleague about this, I believe we already implement the behavior you’re looking for, and it’s possible you just need to add the correct settings to the SSL config. What happens if you add

```auto
 SSLVerifyClient none
 SSLProxyVerify none
 SSLProxyProtocol TLSv1.2
 SSLProxyCheckPeerName off
 SSLProxyVerify none
 SSLProxyCheckPeerCN Off
 SSLProxyCheckPeerName Off
 SSLProxyCheckPeerExpire Off

```

to the ssl config?

---

<div class="post-metadata">

**Author:** ![griznog](https://sea1.discourse-cdn.com/flex015/user_avatar/discourse.openondemand.org/griznog/32/39_2.png) [@griznog](https://discourse.openondemand.org/u/griznog)\
**Post date:** [November 14, 2023, 2:40pm UTC](https://discourse.openondemand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080/9 "2023-11-14T14:40:10Z")

</div>

The SSL part is all sorted now, I think, at least I no longer get any SSL related errors and instead get a problem with the URLs the NoMachine webplayer expects to work through the proxy.

For anyone coming across this in the future, I opened this issue on github:

> <https://github.com/OSC/ondemand/issues/3186>
>
> Opening this issue based on this discourse thread:
> 
> https://discourse.openonde…mand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080/7
> 
> with two goals:
> 
> 
> 1. Solve my current issue trying to run NoMachine's web service behind OnDemand (as an alternative to noVNC)
> 2. Request a general way to handle the case of using OnDemand with backend apps that use HTTPS other than my current method below of hard-coding a specific port in \`/opt/ood/mod\_ood\_proxy/lib/ood/proxy.lua\`.
> 
> What I've done so far to get this to work is to add this to my portal config:
> \`\`\`
> ssl:
> - 'SSLProxyEngine On'
> - 'SSLVerifyClient none'
> - 'SSLProxyVerify none'
> - 'SSLProxyProtocol TLSv1.2'
> - 'SSLProxyCheckPeerName off'
> - 'SSLProxyCheckPeerCN Off'
> - 'SSLProxyCheckPeerExpire Off'
> \`\`\`
> 
> Which solves the issue of NoMachine using a self-signed certificate and enables Apache proxying to HTTPS backends.
> 
> Next I've modified \`/opt/ood/mod\_ood\_proxy/lib/ood/proxy.lua\` to be:
> 
> \`\`\`
> \--\[\[
> set\_reverse\_proxy
> 
> Modify a given request to utilize mod\_proxy for reverse proxying.
> \--\]\]
> function set\_reverse\_proxy(r, conn)
> 
> -- find protocol used by parsing the request headers
> -- Check if an upstream port was set for reverse proxies.
> local upstreamPort = nil
> local isUpstreamPortSet = (r.subprocess\_env\['MATCH\_PORT'\] and 'true' or 'false')
> if isUpstreamPortSet == 'true' then
> upstreamPort = r.subprocess\_env\['MATCH\_PORT'\]
> end
> 
> local protocol = (r.headers\_in\['Upgrade'\] and "ws://" or "http://")
> if upstreamPort then
> -- If specified port was used, then use secure protocols
> if upstreamPort == '4443' then
> protocol = (r.headers\_in\['Upgrade'\] and "wss://" or "https://")
> end
> end
> 
> -- setup request to use mod\_proxy for the reverse proxy
> r.handler = "proxy-server"
> r.proxyreq = apache2.PROXYREQ\_REVERSE
> 
> -- define reverse proxy destination using connection object
> if conn.socket then
> r.filename = "proxy:unix:" .. conn.socket .. "|" .. protocol .. "localhost" .. conn.uri
> else
> r.filename = "proxy:" .. protocol .. conn.server .. conn.uri
> end
> 
> -- include useful information for the backend server
> 
> -- provide the protocol used
> r.headers\_in\['X-Forwarded-Proto'\] = r.is\_https and "https" or "http"
> 
> -- provide the authenticated user name
> r.headers\_in\['X-Forwarded-User'\] = conn.user or ""
> 
> -- \*\*required\*\* by PUN when initializing app
> r.headers\_in\['X-Forwarded-Escaped-Uri'\] = r:escape(conn.uri)
> 
> -- set timestamp of reverse proxy initialization as CGI variable for later hooks (i.e., analytics)
> r.subprocess\_env\['OOD\_TIME\_BEGIN\_PROXY'\] = r:clock()
> end
> 
> return {
> set\_reverse\_proxy = set\_reverse\_proxy
> }
> \`\`\`
> 
> With these changes it almost works. I can successfully reach the NoMachine service on 4443 via an \`/rnode\` URL, but get the error:
> 
> \`\`\`
> Error
> An unexpected error was encountered during the installation of the Web Player component.
> \`\`\`
> 
> NoMachine support suggested these settings to reverse proxy behind Apache:
> 
> \`\`\`
> SSLProxyEngine On
> SSLProxyVerify none
> SSLProxyCheckPeerCN Off
> SSLProxyCheckPeerName Off
> SSLProxyCheckPeerExpire Off
> 
> 
> ProxyPass "/" "https://192.168.3.201:4443/"
> ProxyPassReverse "/" "https://192.168.3.201:4443/"
> ProxyPass "/nxplayer" "https://192.168.3.201:4443/nxplayer"
> ProxyPassReverse "/nxplayer" "https://192.168.3.201:4443/nxplayer"
> \`\`\`
> 
> But I don' t know how/where to translate them so I get the equivalent behavior when using \`/rnode/...\` to proxy to the service. 
> 
> Happy to provide additional information, but note that I'm not adept at troubleshooting web stuff so would appreciate guidance in how to collect any information needed to troubleshoot this further.

Which I then closed as it more or less duplicates these two issues:

1. For addressing origin servers that use SSL:  
[naive support for secure origins · Issue #3179 · OSC/ondemand · GitHub](https://github.com/OSC/ondemand/issues/3179)

2. For handling things that need extra help proxying to specifc URLS:  
[mod\_subsitute to correct assets/links on proxied applications · Issue #2311 · OSC/ondemand · GitHub](https://github.com/OSC/ondemand/issues/2311)

It doesn’t seem possible to get NoMachine to work without the functionality of 2311 and I’m kind of reluctant to release something to users that depend on me locally modifying the `/opt/ood/mod_ood_proxy/lib/ood/proxy.lua` file as I’m certain to forget or break that in the future 🙂

Thanks to everyone who looked (and is looking into) this, also for Open OnDemand in general which is invaluable to us and our users and the work that goes into it is greatly appreciated.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex015/uploads/osc/original/2X/b/bae70bd0ed39a3ae769c2108155f4cb3e9da8385.png) [@system](https://discourse.openondemand.org/u/system)\
**Post date:** [May 12, 2024, 2:41pm UTC](https://discourse.openondemand.org/t/reverse-proxy-rnode-or-node-to-ssl-service/3080/10 "2024-05-12T14:41:01Z")

</div>

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.
