1

Settings and goal

On a raspberry pi, I'm running a Lighttpd server (version: lighttpd/1.4.53 (ssl)). This server was initially installed by pi-hole, a DNS I'm starting to use to manage my network. I already managed to associate http://raspi.home to my raspberry pi IP.

This device already runs several services, for instance an R-shiny server on port 3838 and a homeassistant installation on port 8123, that I can thus access through http://raspi.home:3838/ and http://raspi.home:8123 respectively.

My goal is now to be able to access my services through user-friendly addresses, such as http://raspi.home/shiny (port 3838) and http://raspi.home/homeassistant (port 8123).

Since the lighttpd server was configured for pi-hole, /var/www/html/ contains only two folders: "pihole" and "admin". I can access pi-hole admin panel through http://raspi.home/admin and http://raspi.home/pihole is accessible but not of much use.

My goal is to make that browsing http://raspi.home/shiny/... serves http://raspi.home:3838/... (and same for homeassistant).

Advance so far

I'm modifying /etc/lighttpd/external.conf, which adds on /etc/lighttpd/lighttpd.conf (code here). I tried various things but lighttpd conf files are quite confusing to me, and I'm never sure what should I put at the root level or in a $HTTP["url"].

What worked the most so far was adding an URL mapping with the server definition:

$HTTP["url"] =~ "^/shiny" {
    proxy.header = (
        "map-urlpath" => ( "/shiny" => "/" ),
        "upgrade" => "enable"
    )
    proxy.server = ( "" => ( ( "host" =>  "localhost", "port" => 3838) ) )
}

Unfortunately, this changed all the relative URLs as well so that any image in http://raspi.home/shiny/index.html is searched in http://raspi.home/images/image.png instead of http://raspi.home/shiny/images/image.png. Therefore, no resource could be found.

If I remove the condition, the mapping is global so the app is usable, but since everything is mapped all other sites are now unusable. This is described in this bug but I couldn't make the solution provided work.

I tried with "map-urlpath" => ( "/shiny(.*)$" => "/$1" ) but inexpectedly this throws a 404 error (with or without the condition).

resources

Here are more resources that might be related/useful:

They didn't work for me, either because I didn't put the code on the right place or not adapted to my case, who knows...

Dan Chaltiel
  • 119
  • 5
  • I've put a lot of effort to make a good question with details, why would someone downvote it without even telling how to improve? – Dan Chaltiel Nov 11 '20 at 09:49
  • Please share concrete setup that you have tried, and what were the concrete issues with the setup. – Tero Kilkanen Nov 11 '20 at 22:10
  • @TeroKilkanen Here is my best shot so far, in the edit. 2 days ago, there was unfortunately no setup that worked enough to be presentable here. – Dan Chaltiel Nov 13 '20 at 08:50

1 Answers1

1
$HTTP["url"] =~ "^/shiny" {
    proxy.server = ( "" => ( ( "host" =>  "192.168.1.138", "port" => 3838 ) ) )
}

Delete proxy.header until you better understand what it does and does not do.

https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModProxy

proxy.header "map-urlpath" will modify the request-line of the HTTP headers, but lighttpd does not rewrite the response body, so your R-shiny server will have to understand it is rooted under /shiny/. I have not looked at R-shiny to see if that is possible.

A different alternative is to create DNS names shiny.raspi.home and homeassistant.raspi.home, which you can then configure lighttpd to reverse proxy

$HTTP["host"] =~ "shiny.raspi.home" {
    proxy.server = ( "" => ( ( "host" =>  "192.168.1.138", "port" => 3838 ) ) )
}

Please note that I changed the target "port" in my examples above, as I am guessing that is the reverse-proxy target host and port to which you would like lighttpd to reverse-proxy the request to http://shiny.raspi.home/

gstrauss
  • 221
  • 1
  • 5
  • Thank you for your answer. I'd like to have a configuration that is totally independent of the target if possible, so that the Shiny server remains accessible from its own address as well. Also, I messed up when writing my comment, the shiny-server is at localhost on a different port (but I intend to do it with 192.168.1.138::80 as well). – Dan Chaltiel Nov 14 '20 at 10:27
  • However, the DNS names `shiny.raspi.home` works very well, thanks! This is not what I intend to do but it is definitely a workaround solution. – Dan Chaltiel Nov 14 '20 at 10:30
  • You said that "lighttpd does not rewrite the response body", couldn't I use `map-host-response` for this? I tried but didn't manage to make it work. – Dan Chaltiel Nov 14 '20 at 10:35
  • lighttpd `proxy.header` mappings apply to HTTP request-line and HTTP response headers such as `Location`, but do not apply to the response **body**. (Note the word "header" in `proxy.header` directive is distinct from the word "body".) – gstrauss Nov 15 '20 at 10:34
  • I'm sorry not to understand fast enough but it felt like the *body* was a bit modified, since all URLs were rewritten. – Dan Chaltiel Nov 15 '20 at 14:11
  • Check the HTML source code of the response in your client browser to see URL links. Using relative-path urls in the response body is quite portable. – gstrauss Nov 16 '20 at 23:04