bastienwirtz / homer

A very simple static homepage for your server.
https://homer-demo.netlify.app/
Apache License 2.0
9.12k stars 772 forks source link

Ping function improvement #621

Open masterlog80 opened 1 year ago

masterlog80 commented 1 year ago

Hello, I think it would be useful to have an URL for the ping function, and another one for the link to open.

Viphen commented 1 year ago

The Ping function works as such using either a lone application URL or accompanied with an endpoint: URL.

In this configuration, you could Ping an application for connectivity using just the local URL as the endpoint:. Then in the config.yml for url:, you can then point it to a domain.tld instead of the local webUI application URL. This setup also makes it ideal for CORS with the Ping service as the endpoint is doing the connectivity check for it, while also allowing for a different URL to be used when the application card is clicked on.

See below:

2023-03-25_14-35

masterlog80 commented 1 year ago

Hello @Viphen, That was a very strong improvemente, thanks! But per my tests it still doesn't work for (local) websites using self-signed certificates (e.g. ProxMox, showing a clear Error: unable to verify the first certificate message via the browser). I am wondering if that may be fixed by the proxy configuration. Also, I have noticed that it needs to have a Web server running, so it can't be used to monitor a specific port if open or not (e.g. I would like the status of the SSH connection, but I see it offline, getting Error Error: connect EHOSTUNREACH 192.168.***.***:22 on the browser, but indeed, that seems a different feature. Regards,

masterlog80 commented 1 year ago

Another unexpected behavior happens with Portainer, getting message Error: connect EHOSTUNREACH 192.168.***.***:9443, despite ort 9443 is open and accepting connections from the browsers. I guess this happens because Portainer redirect connections to URL https://192.168.***.***:9443/#!/home or something related. Regards,

Viphen commented 1 year ago

Hello @Viphen, That was a very strong improvemente, thanks! But per my tests it still doesn't work for (local) websites using self-signed certificates (e.g. ProxMox, showing a clear Error: unable to verify the first certificate message via the browser). I am wondering if that may be fixed by the proxy configuration. Also, I have noticed that it needs to have a Web server running, so it can't be used to monitor a specific port if open or not (e.g. I would like the status of the SSH connection, but I see it offline, getting Error Error: connect EHOSTUNREACH 192.168.***.***:22 on the browser, but indeed, that seems a different feature. Regards,

Fairly certain that if you're using https:// localhost, that you would need to use CORS-Anywhere to proxy it for the service to show online on the dashboard card.

That is correct about the application requiring a running WebUI (web server) in order for Homer to monitor the connectivity of it (whether online or offline). Monitoring just a specific port from a service without a running WebUI from that application is unlikely to work (e.g. SSH connections and login pages without a UI, favoring Ping method of "get" or "head" wouldn't be read). You would need to use an application such as UptimeKuma for that connectivity status feature. Then setup a webhook and get notified when the connection is down and when it's back up.

Short of that, you might be able to get away with an SSH client docker image or Guacamole and put it behind something like ContainerNursery (to put it to sleep and wake it up based off usage) and an SSO like Authentik or Authelia which, once the SSH client container is finally up and running (or Guacamole), should show a WebUI to authenticate with before landing into terminal. Homer should see something here with Ping used. I would imagine that CORS-Anywhere is required still based off your local configuration with self-signed certs though.

Note: I of course forgot about that you're using Proxmox.

Another unexpected behavior happens with Portainer, getting message Error: connect EHOSTUNREACH 192.168.***.***:9443, despite ort 9443 is open and accepting connections from the browsers. I guess this happens because Portainer redirect connections to URL https://192.168.***.***:9443/#!/home or something related. Regards,

This is something that CORS-Anywhere should address once you configure it to proxy 443 instead of 8080, if we are still talking about the Homer Ping service for Portainer here.

I haven't setup a config like yours to test/troubleshoot on, so take all of this as speculation.

masterlog80 commented 1 year ago

Hello @Viphen, Thank you again for getting back.

Hello @Viphen, That was a very strong improvemente, thanks! But per my tests it still doesn't work for (local) websites using self-signed certificates (e.g. ProxMox, showing a clear Error: unable to verify the first certificate message via the browser). I am wondering if that may be fixed by the proxy configuration. Also, I have noticed that it needs to have a Web server running, so it can't be used to monitor a specific port if open or not (e.g. I would like the status of the SSH connection, but I see it offline, getting Error Error: connect EHOSTUNREACH 192.168.***.***:22 on the browser, but indeed, that seems a different feature. Regards,

Fairly certain that if you're using https:// localhost, that you would need to use CORS-Anywhere to proxy it for the service to show online on the dashboard card.

Correct, I have some local services (e.g. Portainer, etc.) which are running on a HTTPS webserver with a self-signed certificate, and it would be great if I can use the ping feature on it.

That is correct about the application requiring a running WebUI (web server) in order for Homer to monitor the connectivity of it (whether online or offline). Monitoring just a specific port from a service without a running WebUI from that application is unlikely to work (e.g. SSH connections and login pages without a UI, favoring Ping method of "get" or "head" wouldn't be read). You would need to use an application such as UptimeKuma for that connectivity status feature. Then setup a webhook and get notified when the connection is down and when it's back up.

Interesting, I will give it a try and luckily I am already using UptimeKuma.

Another unexpected behavior happens with Portainer, getting message Error: connect EHOSTUNREACH 192.168.***.***:9443, despite ort 9443 is open and accepting connections from the browsers. I guess this happens because Portainer redirect connections to URL https://192.168.***.***:9443/#!/home or something related. Regards,

This is something that CORS-Anywhere should address once you configure it to proxy 443 instead of 8080, if we are still talking about the Homer Ping service for Portainer here.

Mhhh.... I have already take a look at CORS-Anywhere and it seems very complex to run. So, at this point setting up a webhook for all the service(s) I want to monitor by ping seems the simplest way to proceed, so I will give it a look!

Thank you again.

masterlog80 commented 1 year ago

Mhhh... after some tests it doesn't seem that CORS-Anywhere can be used for the scope of this, as it may required a scecific request header (it shows Missing required request header. Must specify one of: origin,x-requested-with), which, I guess, Homer doesn't use. So, the services using HTTPS or a port different than 80, will be shown as Offline.

Viphen commented 1 year ago

By default CORS-Anywhere uses 8080 (have you tried a different port here?), which can be set to anything. I chose something else.

The Homer endpoint: you'll add in the config.yml will use the following once CORS-Anywhere is setup (if https:// is used per example via localhost): http://cors:port/https://app:port should proxy the URL as http://cors:port/https://app:port so as long as the CORS port has been changed from 8080 (which you cannot use with your setup). If 443 is specified, the CORS URL in the endpoint: would change to something like in this example: https://cors:port or https://10.0.0.5:443/https://10.0.0.10:9000.

Homer requires "Access-Control-Allow-Origin" which in the CORS-Anywhere server.js (edit in terminal) you can set for requireHeader ['origin', 'x-requested-with'], or use a wildcard. I chose to whitelist all so this header doesn't matter anymore.

Under the originBlacklist: and originWhitelist: you want to set as originBlacklist, and originWhitelist, respectively (test this config first then adjust accordingly).

See below for details:

2023-03-28_06-16

Crazy amount of edits this time around, as I'm running out of time (will check back later). The changes above are used in a working setup for me as shown here: https://github.com/bastienwirtz/homer/issues/608

UPDATE: @masterlog80 I think this might be the hangup on my side, so I did some digging and it looks like you need to add the following below to server.js as well.

In the screenshot above you'll see where everything needs to go.

You want to look for this: cors_proxy.createServer({

Then add this on a new line (change dir path to your self-signed certs): httpsOptions: { key: fs.readFileSync('/privkey.pem'), cert: fs.readFileSync('/fullchain.pem') },

Make sure CORS-Anywhere is using port 443 (test with another port if it wont run) if you use the httpsOptions above.

As I've mentioned, I don't have a setup like yours. So this is something you will need to test/troubleshoot, even for the endpoint URL in Homer using either http://cors:port/http://app:port or with https:// in front instead, after the snippet above has been saved in server.js and the CORS-Anywhere container restarted.

If this doesnt work for you, I will kindly bow out and hopefully someone with a similar config can assist you better!

Cheers!

masterlog80 commented 1 year ago

Hello @Viphen, Thank you again for your assistance! First of all, I didn't believe this sort of modification required to have this working, so a solution out of the box would be better (e.g. based on something like nmap?)! However, at this point, per the complexity I need to double check this and eventually implement on my side as well, considering that I don't have such experience about HTML, etc. :-)

Thanks again for your detailed explanation and assistance~!

masterlog80 commented 1 year ago

Hello @Viphen, It has passed some time, but I was stuck with my job. :-( However, I have spent the last days on this: despite I had my server.js file is exactly to the one on the comment above (and it was like that since the beginning, so apart from the port I didn't change anything), I am still unable to have Homer showing the status correctly for services which are not using the port 80 (e.g. uptime-kuma which is using HTTP but on port 3001). There are some unclear points on your message (e.g. I chose to whitelist all so this header doesn't matter anymore. how?) which you may eventually clarify.

I don't really understand why your setup is different from mine: unless you have set all your services to run on port 80, it should be very similar to mine! :-)

Regards,

Viphen commented 1 year ago

Hi @masterlog80

Regarding the whitelist point I made, I had (at the time) removed the entries listed for requireHeaders so it didn't have to match any specific one for CORS to proxy it, rather it will proxy anything (wildcard sort to speak and for local IP use only).

Your UptimeKuma card should be displaying online status in your Homer dashboard if it's not HTTPS, not sure what that is about. I'm using custom ports for all local application WebUIs.

A quick rundown of my setup consists of serving specific applications WebUI outside the network using SWAG, CF, Argo, Crowdsec and Authentik with webhooks going to Mattermost, while also keeping the majority of my applications local IP WebUI accessible only. Monitoring with UptimeKuma and webhook alerts. Should I need to access any of these applications WebUI outside the network (like on mobile for instance), I then use WireGuard tunneling. I also use ContainerNursery to proxy these services with SWAG, which keeps the specific applications WebUI (the ones accessible outside the network via domain) in a stopped state until I authenticate through Authentik, which will start them back up, updating me with another webhook of the status change of the application state. Once the allotted idle time is met, the container will go back into a stopped state again; applications like Kasm and Code Server are good examples.

I have my Homer running local, with the use of WG for outside network access. I didn't feel the need to publicly serve Homer. If I need access to my server dashboard from anywhere instead of through mobile, I just authenticate with Authentik and go right into Kasm (profile persistence) and access local domain through there.

The only hang-up I had at the time when first using Homer, was getting familiar with CORS Anywhere to proxy Homer's Ping method properly. You run mostly HTTPS local services with self signed certs (this is where our setups differ and with troubleshooting it). I use HTTP local services with CORS status proxy and HTTPS public domains for other services as the endpoints (because the domain would be down with the use of ContainerNursery) within Homer's config.yml. The status changes once the domain is up again, instead of entering the local IP and custom port of the application as the endpoint.

masterlog80 commented 1 year ago

Hello @Viphen, Thank you for your message:

Regarding the whitelist point I made, I had (at the time) removed the entries listed for requireHeaders so it didn't have to match any specific one for CORS to proxy it, rather it will proxy anything (wildcard sort to speak and for local IP use only).

My point is exactly how to do that! :-) Like... just removing the line requireHeader: ['origin', 'x-requested-with'],?

Btw, if I open the link on my browser for uptime-kuma using the URL http://<cors_IP>:443/http://<uptime-kuma_ip>:3001 I get the following message: Not found because of proxy error: Error: connect EHOSTUNREACH 192.168.10.251:3001 But at this point, I am starting to think it's a Network issue, and I will check later. For other services like Proxmox, using the URL http://<cors_IP>:443/http://<proxmox_ip>:8006 I get the following message: Not found because of proxy error: Error: unable to verify the first certificate Which I am assuming can be fixed by your message above, once I do understand how... 😉

Regards,

Viphen commented 1 year ago

My point is exactly how to do that! :-) Like... just removing the line requireHeader: ['origin', 'x-requested-with'],?

You remove: 'origin', 'x-requested-with' so that it looks like requireHeader: [],

masterlog80 commented 1 year ago

Hello @Viphen, Thank you for the clarification! I was able to address the Network issue and at this moment I have just a few containers (e.g. Portainer, Proxmox, etc.) not being shown as "Active". Those seems to be the only ones with a self-signed certificate. Checking the URL http://<cors_IP>:443/http://<uptime-kuma_ip>:3001 in the browser, I get the following message: Not found because of proxy error: Error: connect EHOSTUNREACH 192.168.10.251:3001

Per this, I have understood that the would be to add this line: httpsOptions: { key: fs.readFileSync('/privkey.pem'), cert: fs.readFileSync('/fullchain.pem') }, So, my understanding is to store locally the self-signed certificate. I am not an expert on this, but this seems pretty hard to achieve as any service (e.g. Portainer, Proxmox, etc.) is using their own self-signed certificate. I don't think there is a simple workaround for this, so I hope homer will be improved by just checking the status of a given port to report the status of a service.

Regards,

MuratovAS commented 10 months ago

Those seems to be the only ones with a self-signed certificate.

You are not alone :) I also tried to solve this problem. I solved this by implementing a simple ping service. I documented everything in detail in httpGoPing