Rack Elevation devicetype-images use the local server IP when accessing via full proxy #7807

Closed
opened 2025-12-29 20:28:28 +01:00 by adam · 7 comments
Owner

Originally created by @rnwolfe on GitHub (Mar 29, 2023).

NetBox version

v3.4.6

Python version

3.10

Steps to Reproduce

  1. Create an instance of netbox
  2. Deploy behind a full proxy
  3. Upload a front or rear device rack image to a devicetype
  4. View rack elevation for device while accessing through proxy.

Expected Behavior

Image to load using public URL, e.g. netbox.mydomain.com, and HREF to link using the same link as being used to access the server in the browser, i.e. a relative path.

Observed Behavior

Image is rendered using the local server's IP as the base url, e.g. http://192.168.100.10/media/devicetype-images/n9k-c9336c-fx2.png (cut off partially to obfuscate sensitive information)

image

Same element in inspect panel (note not using a relative path):

<image xmlns="http://www.w3.org/2000/svg" class="device-image" height="22" preserveAspectRatio="xMidYMid slice" width="220" x="32" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://192.168.100.22/media/devicetype-images/n9k-c93180yc-fx-front_1.png" y="24"/>

An empty rack location with Add Device (note the relative path):

<a xmlns="http://www.w3.org/2000/svg" target="_parent" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/dcim/devices/add/?site=1&amp;location=&amp;rack=1&amp;face=front&amp;position=41"><rect class="slot" height="22" width="220" x="32" y="90"/><text class="add-device" x="142.0" y="101.0">add device</text></a>

Note that if accessing directly (from local network), the images load since the 192.168.100.22 IP is accessible.

Also note that if accessing the device type itself, the images load as expected:
image

Originally created by @rnwolfe on GitHub (Mar 29, 2023). ### NetBox version v3.4.6 ### Python version 3.10 ### Steps to Reproduce 1. Create an instance of netbox 2. Deploy behind a full proxy 3. Upload a front or rear device rack image to a devicetype 4. View rack elevation for device while accessing through proxy. ### Expected Behavior Image to load using public URL, e.g. `netbox.mydomain.com`, and HREF to link using the same link as being used to access the server in the browser, i.e. a relative path. ### Observed Behavior Image is rendered using the local server's IP as the base url, e.g. `http://192.168.100.10/media/devicetype-images/n9k-c9336c-fx2.png` (cut off partially to obfuscate sensitive information) <img width="197" alt="image" src="https://user-images.githubusercontent.com/7844722/228612341-359a1597-2ac8-4a05-8350-21727f17be79.png"> Same element in inspect panel (note not using a relative path): ``` <image xmlns="http://www.w3.org/2000/svg" class="device-image" height="22" preserveAspectRatio="xMidYMid slice" width="220" x="32" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://192.168.100.22/media/devicetype-images/n9k-c93180yc-fx-front_1.png" y="24"/> ``` An empty rack location with `Add Device` (note the relative path): ``` <a xmlns="http://www.w3.org/2000/svg" target="_parent" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/dcim/devices/add/?site=1&amp;location=&amp;rack=1&amp;face=front&amp;position=41"><rect class="slot" height="22" width="220" x="32" y="90"/><text class="add-device" x="142.0" y="101.0">add device</text></a> ``` Note that if accessing directly (from local network), the images load since the `192.168.100.22` IP is accessible. Also note that if accessing the device type itself, the images load as expected: <img width="698" alt="image" src="https://user-images.githubusercontent.com/7844722/228615201-2e3f4fc1-2752-49ee-96c2-29b6f0036880.png">
adam added the type: bug label 2025-12-29 20:28:28 +01:00
adam closed this issue 2025-12-29 20:28:28 +01:00
Author
Owner

@rnwolfe commented on GitHub (Mar 29, 2023):

This appears to originate in the SVG rendering logic. If we compare the link creation mechanism of a rack space with add device:

0330c652bd/netbox/dcim/svg/racks.py (L269)

version one with a device image:

0330c652bd/netbox/dcim/svg/racks.py (L155)

The same url building logic as the device image link is used for the image src:

0330c652bd/netbox/dcim/svg/racks.py (L166-L173)

@rnwolfe commented on GitHub (Mar 29, 2023): This appears to originate in the SVG rendering logic. If we compare the link creation mechanism of a rack space with `add device`: https://github.com/netbox-community/netbox/blob/0330c652bdddab04ea0451b36dc6b3467aa1a0f8/netbox/dcim/svg/racks.py#L269 version one with a device image: https://github.com/netbox-community/netbox/blob/0330c652bdddab04ea0451b36dc6b3467aa1a0f8/netbox/dcim/svg/racks.py#L155 The same url building logic as the device image link is used for the image src: https://github.com/netbox-community/netbox/blob/0330c652bdddab04ea0451b36dc6b3467aa1a0f8/netbox/dcim/svg/racks.py#L166-L173
Author
Owner

@rnwolfe commented on GitHub (Mar 29, 2023):

As a quick test, I replaced the image url generation at:

0330c652bd/netbox/dcim/svg/racks.py (L167)

with:

            url = image.url
            # url = f'{self.base_url}{image.url}' if image.url.startswith('/') else image.url

And the images display (using a relative url):

<image xmlns="http://www.w3.org/2000/svg" class="device-image" height="22" preserveAspectRatio="xMidYMid slice" width="220" x="32" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/media/devicetype-images/n9k-c93180yc-fx-front_1.png" y="24"/>
image

I'd have to do some more digging to find the appropriate way to generate the HREF and SRC URLs for this object before doing an actual fix + PR, so if anyone with more present knowledge wants to have a go, certainly encourage it.

@rnwolfe commented on GitHub (Mar 29, 2023): As a quick test, I replaced the image url generation at: https://github.com/netbox-community/netbox/blob/0330c652bdddab04ea0451b36dc6b3467aa1a0f8/netbox/dcim/svg/racks.py#L167 with: ``` url = image.url # url = f'{self.base_url}{image.url}' if image.url.startswith('/') else image.url ``` And the images display (using a relative url): ``` <image xmlns="http://www.w3.org/2000/svg" class="device-image" height="22" preserveAspectRatio="xMidYMid slice" width="220" x="32" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/media/devicetype-images/n9k-c93180yc-fx-front_1.png" y="24"/> ``` <img width="199" alt="image" src="https://user-images.githubusercontent.com/7844722/228616612-1bd5cedd-fa75-4ace-b62d-dd5ccae69e36.png"> I'd have to do some more digging to find the appropriate way to generate the HREF and SRC URLs for this object before doing an actual fix + PR, so if anyone with more present knowledge wants to have a go, certainly encourage it.
Author
Owner

@kkthxbye-code commented on GitHub (Mar 29, 2023):

You sure your proxy is not just missing configuration for forwarding the ip?

https://github.com/netbox-community/netbox/wiki/Common-Issues#whats-happening-3

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host

@kkthxbye-code commented on GitHub (Mar 29, 2023): You sure your proxy is not just missing configuration for forwarding the ip? https://github.com/netbox-community/netbox/wiki/Common-Issues#whats-happening-3 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host
Author
Owner

@rnwolfe commented on GitHub (Mar 29, 2023):

Yes, the rendered HTML is coming from the server with the RFC 1918 IP address already in it, the proxy would not mess with the HTML payload itself.

The same can be confirmed by throwing a quick print statement for the base_url variable above the elevation call:

Mar 29 16:46:53 edge-netauto gunicorn[46969]: [2023-03-29 16:46:53 +0000] [46969] [INFO] Booting worker with pid: 46969
Mar 29 16:46:53 edge-netauto gunicorn[46970]: [2023-03-29 16:46:53 +0000] [46970] [INFO] Booting worker with pid: 46970
Mar 29 16:47:00 edge-netauto gunicorn[46966]: http://192.168.100.22/
Mar 29 16:47:02 edge-netauto gunicorn[46970]: http://192.168.100.22/

The code also looks for the url to start with / which /media always will, and replace it with base_url which is in this case http://192.168.100.22. This IP is also the backend service IP the proxy uses to reach it so it makes sense that netbox/django actually sees that as the base url.

@rnwolfe commented on GitHub (Mar 29, 2023): Yes, the rendered HTML is coming from the server with the RFC 1918 IP address already in it, the proxy would not mess with the HTML payload itself. The same can be confirmed by throwing a quick print statement for the `base_url` variable above the elevation call: ``` Mar 29 16:46:53 edge-netauto gunicorn[46969]: [2023-03-29 16:46:53 +0000] [46969] [INFO] Booting worker with pid: 46969 Mar 29 16:46:53 edge-netauto gunicorn[46970]: [2023-03-29 16:46:53 +0000] [46970] [INFO] Booting worker with pid: 46970 Mar 29 16:47:00 edge-netauto gunicorn[46966]: http://192.168.100.22/ Mar 29 16:47:02 edge-netauto gunicorn[46970]: http://192.168.100.22/ ``` The code also looks for the url to start with `/` which `/media` always will, and replace it with `base_url` which is in this case `http://192.168.100.22`. This IP is also the backend service IP the proxy uses to reach it so it makes sense that netbox/django actually sees that as the base url.
Author
Owner

@kkthxbye-code commented on GitHub (Mar 29, 2023):

Please confirm that you are setting the header first. You can't use relative urls in the SVG renderer as the svgs can both be downloaded and embedded.

I feel there is some misunderstanding here, please make sure you read the common issues link I posted.

@kkthxbye-code commented on GitHub (Mar 29, 2023): Please confirm that you are setting the header first. You can't use relative urls in the SVG renderer as the svgs can both be downloaded and embedded. I feel there is some misunderstanding here, please make sure you read the common issues link I posted.
Author
Owner

@rnwolfe commented on GitHub (Mar 29, 2023):

Gotcha, as this is an internal proxy setup - I am asking the needed people.

In terms of my nginx config, it does forward this, but as you may expect, it has 192.168.100.22 in it per the django debug panel.

@rnwolfe commented on GitHub (Mar 29, 2023): Gotcha, as this is an internal proxy setup - I am asking the needed people. In terms of my nginx config, it does forward this, but as you may expect, it has `192.168.100.22` in it per the django debug panel.
Author
Owner

@rnwolfe commented on GitHub (Mar 30, 2023):

This was the issue 😞. I even checked the common issues link prior to posting, but somehow must've overlooked the most relevant issue.

Thank you for the quick assistance!

@rnwolfe commented on GitHub (Mar 30, 2023): This was the issue 😞. I even checked the common issues link prior to posting, but somehow must've overlooked the most relevant issue. Thank you for the quick assistance!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#7807