Skip to content

Instantly share code, notes, and snippets.

@pacmac
Last active March 9, 2023 05:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pacmac/1602c3b520d4595a41df59f8673d019c to your computer and use it in GitHub Desktop.
Save pacmac/1602c3b520d4595a41df59f8673d019c to your computer and use it in GitHub Desktop.
A small hack to allow a proxmox node web page to be displayed in the working panel.

I thought that I would add a menu to the proxmox node management page so that I could view the front page / web console of the node that is running on it.

This is early work and I have only been using it for a couple of days, but most seem to work.

I do have a problem with esphome websockets that is yet to be resolved but others appear to be working.

This inserts an iframe into the working panel on the right and uses nginx reverse proxy to display the pages in the iframe.

In order to get it to work I had to override the default CORS headers so this might introduce a security risk, particularly if your server is web facing.

I would not recommend using this if your proxmox host is web facing and, of course you use it entirely at your own risk.

To install: git clone https://gist.github.com/1602c3b520d4595a41df59f8673d019c.git

Basically here's what it does:

  1. Installs nginx
  2. creates nginx reverse proxy configs in /etc/nginx/snippets and /etc/nginx/conf.d
  3. copies a javascript file frontpage.js to the /usr/share/pve-manager/js folder
  4. appends the <script> source to /usr/share/pve-manager/index.html.tpl for the file above js file.

After installation, proxmox will be available on port 80.

You should see a new menu "Front Page" appear in the menu for each Node. In order to activate the front page for a node you will need to add a new entry to nginx/conf.d like this:

## /etc/nginx/conf.d/8101_plex.conf
server {
 include snippets/pveprox.conf;
 listen 8101 ssl;
 location / {
 proxy_pass http://plex.local:32400/;
 }

The file name is not important, after adding the entry you can test it with nginx -t and restart nginx with systemctl restart nginx

USE OF THIS IS ENTIRELY AT YOUR OWN RISK

/*
version 1.0
https://gist.githubusercontent.com/pacmac/1602c3b520d4595a41df59f8673d019c/raw/aee285f9be5c9457fcd1831d5995e5a0852e3fe8/frontpage.js
*/
var cl=console.log;
function waitForElementToDisplay(selector, callback, checkFrequencyInMs, timeoutInMs) {
var startTimeInMs = Date.now();
(function loopSearch() {
el = document.querySelector(selector);
if (el != null) {
callback(el);
return;
}
else {
setTimeout(function () {
if (timeoutInMs && Date.now() - startTimeInMs > timeoutInMs)
return;
loopSearch();
}, checkFrequencyInMs);
}
})();
}
function ifr(){
var ifr = document.createElement("iframe");
ifr.id = "fpiframe";
Object.assign(ifr.style, {
width: "100%",
height: "100%",
border: "0",
display: "",
top: "0",
position: "absolute",
zIndex: "-1000"
});
var div = document.querySelector('.x-toolbar + div[data-ref="body"]');
if(! document.querySelector("#fpiframe")){
//cl('adding');
div.appendChild(ifr);
}
}
window.onhashchange = addItem;
function addItem(){
try {
var wp = document.querySelector("#frontpage");
wp.innerHTML = '';
wp.remove();
document.querySelector("#fpiframe").remove();
}
catch(e){}
// wait for the dom to be ready
setTimeout(function(){
ifr()
},500)
var divs = document.querySelectorAll("ul.x-treelist-root-container.x-widget");
var div = divs[divs.length-1];
var node = document.createElement('li');
node.id = "frontpage";
div.append(node);
node.innerHTML = '<div class="x-treelist-row"><div class="x-treelist-item-wrap" style="margin-left: 0px;"><div class="x-treelist-item-icon fa fa-globe"></div><div class="x-treelist-item-text">Front Page</div><div class="x-treelist-item-expander"></div></div></div>';
node.onclick = function(e){
var nid = window.location.hash.split('%2F')[1].split(':')[0];
var divs = document.querySelectorAll(".x-treelist-item-selected");
for (i = 0; i < divs.length; ++i) {
divs[i].classList.remove('x-treelist-item-selected');
}
node.classList.add("x-treelist-item-selected");
var url = `${location.protocol}//${location.hostname}:8${nid}`
var ifr = document.querySelector("#fpiframe");
ifr.src=url;
ifr.style.zIndex = 1000
//cl(nid)
}
}
waitForElementToDisplay("#ext-widget-1",function(div){
//cl('ready');
addItem();
},100,9000);
#!/bin/bash
#
# INSTALL
# @@@@@@@
# git clone https://gist.github.com/1602c3b520d4595a41df59f8673d019c.git pve-fp
# cd pve-fp;
# chmod+x proxmox-frontpage.sh
# ./proxmox-frontpage.sh
# @@@@@@@@@@@@@@@
# https://gist.github.com/pacmac
# I created this for my own use but decided to share it, use entirely at your own risk.
# If your server is public facing or you don't trust any of your nodes then don't do it.
# CORS policies have been circumvented in the add_header X-Frame-Options for the iframe to load the frontpages.
# After each change please test thye configuration with "nginx -t"
# and restart the nginx service: systemctl restart nginx
# It would be nice to see this as an enhancement properly built into proxmox.
# @@@@@@@@@@@@@@@
function _help {
echo " #####################
## Example node entry
#####################
> For Each CT/VM node, add a new entry into the /etc/nginx/conf.d folder:
> The listen port needs to be the Node ID + 8000
> So in this example, the node id is 101 so the listen port is 8101
> either use the local dns host name or the ip address and port.
nano /etc/nginx/conf.d/8101_plex.conf
server {
include snippets/pveprox.conf;
listen 8101 ssl;
location / {
proxy_pass http://plex.local:32400/;
}
}
> Then test & restart nginx
nginx -t
systemctl restart nginx;
#####################
"
}
### Check for previous install & backup
function _check {
if [ -f "/usr/share/pve-manager/index.html.tpl.bak" ];then
echo "@@@ This installer has already been run once."
echo "@@@ Quitting."
exit 0;
else
echo "OK First Run, proceeding with install..."
cp -p /usr/share/pve-manager/index.html.tpl /usr/share/pve-manager/index.html.tpl.bak
fi
}
### Install nginx
function _install {
echo "Updaing repos & installing nginx..."
apt update && apt -y install nginx;
}
### Remove existing nginx defaults
function _ngclean {
rm -f /etc/nginx/sites-enabled/default
rm -f /etc/nginx/sites-available/default
rm -f /etc/nginx/snippets/*.conf
rm -f /etc/nginx/conf.d/*.conf
}
### insert proxmox.conf into /etc/nginx/conf.d
function _pmproxy {
pmox="upstream proxmox {
server "proxmox.local";
}
server {
listen 80 default_server;
rewrite ^(.*) https://\$host\$1 permanent;
}
server {
listen 443 ssl;
server_name _;
ssl_certificate /etc/pve/local/pve-ssl.pem;
ssl_certificate_key /etc/pve/local/pve-ssl.key;
proxy_redirect off;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass https://localhost:8006;
proxy_buffering off;
client_max_body_size 0;
proxy_connect_timeout 3600s;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
send_timeout 3600s;
}
}
"
echo "$pmox" > /etc/nginx/conf.d/proxmox.conf
}
## insert pveprox.conf include file into /etc/nginx/snippets
function _snippets {
echo "server_name _;
ssl_certificate /etc/pve/local/pve-ssl.pem;
ssl_certificate_key /etc/pve/local/pve-ssl.key;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host \$server_name;
proxy_set_header X-Forwarded-Proto https;
proxy_hide_header X-Frame-Options;
add_header X-Frame-Options \"ALLOWALL\";" > /etc/nginx/snippets/pveprox.conf
}
### append <script> to index.html.tpl
function _index {
FN="/usr/share/pve-manager/index.html.tpl"
## Backup the file
if [ ! -f "$FN.bak" ];then
cp -rp $FN "$FN.bak";
fi
if [ ! "$(cat $FN | grep frontpage.js)" ];then
echo "Inserting into $FN";
sed -i '/<\/head>/i <script type="text/javascript" src='\''/pve2/js/frontpage.js'\''></script>' $FN;
fi;
}
### Copy frontpage.js to pve folder
function _cpjs {
cp -rp ./frontpage.js /usr/share/pve-manager/js/frontpage.js
}
## restart nginx
function _restart {
nginx -t
systemctl restart nginx;
}
## MAIN
_check;
_install;
_ngclean;
_pmproxy;
_snippets;
_index;
_cpjs;
_restart;
_help;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment