Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration for WebUI base url for use in reverse proxy #5693

Open
Fastjur opened this issue Aug 31, 2016 · 66 comments · May be fixed by #21471
Open

Configuration for WebUI base url for use in reverse proxy #5693

Fastjur opened this issue Aug 31, 2016 · 66 comments · May be fixed by #21471
Labels
Bounty Feature request Waiting info Waiting for participants to supply more info/fulfill template requirements WebUI WebUI-related issues/changes

Comments

@Fastjur
Copy link

Fastjur commented Aug 31, 2016

This issue seems to be getting quite some thumbs up's from people who would like to see this added
Please, to keep the mailboxes of everyone clean, do not +1 this as a comment, but rather click the thumbs up icon beneath this very first message.

For the people landing here from Google:

A workaround can be found here: https://github.com/qbittorrent/qBittorrent/wiki/NGINX-Reverse-Proxy-for-Web-UI


I have searched for this and it appears to not be possible as of yet.

It would be really useful if there is an option to specify the base URL path for use in reverse proxies. This way one can circumvent having to type the port number into the URL.

For instance, when the qBittorent web UI is running on port 8080, and the base url is set to /qbt. Then the complete URL would become 127.0.0.1:8080/qbt. One can then use, per example, nginx to reverse proxy this to a more friendly url like so:

server {
  listen  80;
  server_name jt.REDACTED.net localhost 192.168.1.6;

  location /qbt {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

Thus allowing one to goto jt.REDACTED.net/qbt and land on the qBittorrent page.


There is a $50 open bounty on this issue. Add to the bounty at Bountysource.
DISCLAIMER: There are trustworthiness and solvency issues with BountySource. qBittorrent is not affiliated with them. Use them at your own risk.

@Fastjur Fastjur changed the title Configuration for base url for use in reverse proxy [Request / Web UI] Configuration for base url for use in reverse proxy Aug 31, 2016
@ghost

This comment has been minimized.

@sruon
Copy link

sruon commented Dec 26, 2016

Since this is pretty much the only result that comes up when searching for reverse proxy support in QBittorrent, here's a workaround that I'm using and appears to work fine.

location ~ /qbt/(?<url>.*) {
         proxy_pass  http://127.0.0.1:8080/$url;
<insert other directives..>
}

@MichaelHub
Copy link

MichaelHub commented Jan 13, 2017

The above configuration worked for me. The only issue was that when navigating to the URL (ex. domain.com/qbt) Nginx would return a 404 error, but when a trailing slash was added (ex. domain.com/qbt/) it would work fine. I ended up just configuring a redirect to the trailing slash URL.

location /qbt {
	rewrite ^(.*[^/])$ $1/ permanent;
}

@jdmag00
Copy link

jdmag00 commented Feb 12, 2017

Would love to see a base URL, or root folder option added for reverse proxy.

@pozemka
Copy link

pozemka commented Apr 4, 2017

Both @sruon and @MichaelHub workarounds work, but when I select "Peers" tab it shows empty list and displays something like "qbittorrent client inaccessible". However using direct connection via ip:port works fine.
Another thing is that reverse-proxied interface have no favicon.

@MichaelHub
Copy link

@asc7uni Oh, I hadn't used the WebUI before setting it up and thought it was just flakey like that. I'll take a look at my configuration this week and see if I can find a fix.

@WarriorXK

This comment has been minimized.

@ztaale

This comment has been minimized.

@Quiksmage

This comment has been minimized.

@klara31

This comment has been minimized.

1 similar comment
@blackley

This comment has been minimized.

@ghost

This comment has been minimized.

1 similar comment
@arebokert

This comment has been minimized.

@thalieht
Copy link
Contributor

thalieht commented Sep 2, 2017

This looks like a popular request, tagging @Chocobo1 if he's interested.

@mky

This comment has been minimized.

4 similar comments
@umm7yass

This comment has been minimized.

@ghost

This comment has been minimized.

@scytalezero

This comment has been minimized.

@ghost

This comment has been minimized.

@SuperTrembler
Copy link

SuperTrembler commented Dec 19, 2017

+1
Current nginx config in wiki breaks bypass authentication for clients in subnet as it wont pass real ip I believe

@bdelwood

This comment has been minimized.

@Fastjur
Copy link
Author

Fastjur commented Jan 5, 2018

As stated in the original feature request:

This issue seems to be getting quite some thumbs up's from people who would like to see this added
Please, to keep the mailboxes of everyone clean, do not +1 this as a comment, but rather click the thumbs up icon beneath this very first message.

@kurosh
Copy link

kurosh commented Jan 26, 2018

Another +1 for this, not working for me behind Nginx. Login screen appears (without any images strangely) then when I submit the password appears in the URL and goes to blank screen :|

@kurosh

This comment has been minimized.

@kurosh

This comment has been minimized.

TommyE123 referenced this issue in TommyE123/AtoMiC-ToolKit Feb 19, 2018
@boywiz

This comment has been minimized.

1 similar comment
@IIIdefconIII

This comment has been minimized.

@Routhinator
Copy link

I've put a bounty on this. I'd like something that works with Apache.

@sledgehammer999 sledgehammer999 changed the title [Request / Web UI] Configuration for base url for use in reverse proxy [$50] [Request / Web UI] Configuration for base url for use in reverse proxy Nov 22, 2020
@boredazfcuk
Copy link

I'd like to see this added too... I'm running everything inside Docker containers, so my nginx reverse proxy configuration would look like this:

location /qbittorrent/ {
   include      reverse_proxy.conf;
   include      security_headers_https.conf;
   set          $qbittorrent_upstream   http://qbittorrent:8080;
   proxy_pass   $qbittorrent_upstream;
}

I'm using set $qbittorrent_upstream http://qbittorrent:8080; so nginx evaluates the IP address of the qbittorrent container on every connection. Without it, nginx will only evaluate the IP address of the qbittorrent container when nginx launches. Without the set command, nginx will continue to contact a dead IP address if the qbittorrent container changes IP after a restart, or host migration. Restarting nginx to pick up the new IP address of the qbittorrent container disrupts other services.

Unfortunately the set directive in nginx does not allow the variable to end with a trailing slash, so the published nginx solution doesn't work.

Having qbittorrent operate out of a webroot such as http://<IP Address>:8080/qbittorrent would be ideal for all reverse proxies to handle.

@Ferk
Copy link

Ferk commented Feb 4, 2021

The reason the proxying fails for me is because the Web UI is internally sending requests to the host without using the base URL.
In order for this to work the Web UI would need to send the api requests to /qbt/api rather than /api (or at least use relative paths). And the same will happen with any assets, images or external css/js that the WebUI might want to load.

Just for the record, this would be how it's done in lighttpd, in case someone wants to use that instead of nginx:

$HTTP["url"] =~ "^/qbt" {
    proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => 1340 ) ) )
    proxy.header = ( "map-urlpath" => ( "/qbt" => "/" ) )
}

But of course it has the same issue.

@FranciscoPombal FranciscoPombal changed the title [Request / Web UI] Configuration for base url for use in reverse proxy Configuration for WebUI base url for use in reverse proxy Mar 3, 2021
kharenis added a commit to kharenis/qBittorrent that referenced this issue Apr 14, 2021
Adds a base path configuration option to the WebUI.
WebApplication injects base path into content paths on initial
configuration. Requires a restart to update.
Internally, the path is stripped from the request to maintain the
existing api/file structure.
Requests without the path trigger a 303 redirect response.
Closes qbittorrent#5693
kharenis added a commit to kharenis/qBittorrent that referenced this issue Apr 14, 2021
Adds a base path configuration option to the WebUI.
WebApplication injects base path into content paths on initial
configuration. Requires a restart to update.
Internally, the path is stripped from the request to maintain the
existing api/file structure.
Requests without the path trigger a 303 redirect response.
Closes qbittorrent#5693
@glassez
Copy link
Member

glassez commented Apr 14, 2021

I'm sorry, maybe I'm off topic and don't understand something... but I am sure that Proxies should not require any additional worries on the part of the services behind them.

at least use relative paths

Maybe that's really the problem?
@Chocobo1, what do you think of all this?

@kharenis
Copy link

kharenis commented Apr 14, 2021

I'm sorry, maybe I'm off topic and don't understand something... but I am sure that Proxies should not require any additional worries on the part of the services behind them.

at least use relative paths

Maybe that's really the problem?
@Chocobo1, what do you think of all this?

At present, all the client-side references point to the root directory. You're able to load the first page, but none of the dependencies load because they don't include whatever path you've configured your reverse proxy to use.
Having a configurable base path seems to be a pretty commonplace way to account for this.

Edit:
I've done some more testing and it seems the problem lies in the trailing / on the URL, reverse proxies must be configured with a / on the end of the path. (eg. http://locahost/qbt/ rather than http://localhost/qbt)

In the changes I've made, I'm prepending all the resource URLs in the client-side code with a static path including the configured base path. This forces everything to point to the right place without having to worry about the URL being correct for relative paths.

@Chocobo1
Copy link
Member

@Chocobo1, what do you think of all this?

I've done some more testing and it seems the problem lies in the trailing / on the URL.

I think we can fix this trailing / issue, but we'll need more info on it, it isn't clear how/where we should handle this.

(and have their proxy setup to remove duplicate / )

I suppose qbt could add a workaround for this (duplicate /) IF this is a separate issue of the aforementioned one.
https://stackoverflow.com/a/40683096

@kharenis
Copy link

kharenis commented Apr 19, 2021

@Chocobo1, what do you think of all this?
I've done some more testing and it seems the problem lies in the trailing / on the URL.

I think we can fix this trailing / issue, but we'll need more info on it, it isn't clear how/where we should handle this.

The simplest way without a configurable base path would probably be a js snippet in the index page to redirect the page if it's missing the trailing /.
It's only a problem because the relative paths only work if the path is empty, or there's a trailing / in the URL if there is a path.

(and have their proxy setup to remove duplicate / )

I suppose qbt could add a workaround for this (duplicate /) IF this is a separate issue of the aforementioned one.
https://stackoverflow.com/a/40683096

On second thoughts a duplicate / isn't really an issue for qbt, it's up to the user to configure their reverse proxy correctly. (And would only be caused if they hadn't done so)

I'll throw together a branch that redirects the page with a trailing / if missing and do a bit of testing to see if everything works correctly.

@boredazfcuk
Copy link

boredazfcuk commented Apr 19, 2021

I run SABnzbd, whose URL ends with a trailing slash, and that has no issues. Proxies handle trailing slashes on URLs just fine.

Double forward slash in a URL would be an issue though. Nginx would need a non-default module installing to perform a string replacement (https://github.com/yaoweibin/ngx_http_substitutions_filter_module) of "//" to "/".

That's going to cause issues with any legitimate uses of double forward slashes though... e.g. https://mydomain.com, for example, would become https:/mydomain.com.

kharenis added a commit to kharenis/qBittorrent that referenced this issue Apr 19, 2021
Closes qbittorrent#5693
Index pages now automatically redirect to a path with a trailing
"/". If the site was accessed through a proxy with a modified path,
a missing trailing "/" would break the relative paths.
@luzpaz
Copy link
Contributor

luzpaz commented Sep 27, 2023

What's left to do here ?

@luzpaz luzpaz added the Waiting info Waiting for participants to supply more info/fulfill template requirements label Sep 27, 2023
@jakobbouchard
Copy link

I think there's still an issue with the CSS and JS not loading correctly when using a different base URL. In my case, using the method from this comment, I could load all the HTML correctly, but the rest didn't load at all. Part of it could be fixed by adding a <base /> tag, but it wouldn't fix any JavaScript. It would also required adding an option to the Web UI tab where we could specify our base URL, a bit like Radarr and Sonarr do.

@CapivaraTupiniquim
Copy link

CapivaraTupiniquim commented Dec 14, 2023

Is there any plan to have a Base URL configuration, like in raddar, sonarr and the like? I use Caddy as a reverse proxy

@markmetcalfe
Copy link

I've found the solution for NGINX defined in the wiki doesn't completely work for me. Some API requests - such as getting the content list for an individual torrent - do not work.

The NGINX solution specified in linuxserver's reverse proxy configs works completley for me - I haven't run into any issues with the following conf:

server {
    listen 443 ssl;
    server_name xyz.com;

    # ...

    location = /qbittorrent {
        return 301 /qbittorrent/;
    }

    location ~/qbittorrent(.*)$ {
        proxy_pass http://localhost:30000;
        include includes/proxypass.conf;
        rewrite /qbittorrent(.*) $1 break;
        
        # Extra options here, e.g: 
        # client_max_body_size 100M;
        # ...
    }
}

Note the rewrite directive is important.

@samwh1te
Copy link

I don't suppose there's any way around the CSS/JS issue without a base url being implemented? Does anyone know if there's an alternative frontend which might have base url support?

@Piccirello Piccirello linked a pull request Oct 2, 2024 that will close this issue
@Piccirello
Copy link
Member

Piccirello commented Oct 2, 2024

I have a draft PR up (#21471) that implements this feature and would like some feedback. Ideally, folks can test my branch and verify it adequately satisfies their use case. This is working well with my test nginx setup (nginx config included below), but you may have a different setup that this does not work for. If so, let me know.

Note the trailing slash in both the location directive and the proxy_pass directive:

server {
    listen 80;
    server_name example.com;

    location /qbit/ {
        proxy_pass  http://localhost:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

@kevinpeno
Copy link

kevinpeno commented Oct 13, 2024

Hey folks. Sorry to barge in on your 8 year old discussion, but I thought I'd bring some insight as someone who has worked with websites and services for almost 18 years. I'm sorry if I missed some important details, its a pretty long thread.

While silly compared to OSes, the web has a fairly strict requirement to know the difference between a "directory" and an "endpoint". In the file system, there's typically a directory mime type available for the system to extrapolate from and know that thing or thing/ refers to a directory. This was never standardized for HTTP and the web. (Note: it technically might have been standardized later on but no one has implemented it because it would break the web and the web hates breaking things)

As such, while there is nothing technically in the standards regarding directories, the consensus is that with a slash means a directory and without means an endpoint, aka resource or file. That means a trailing slash is a requirement when you're trying to do something like map an internal service from :80/ to :80/qbit/. To break it down, here's the use cases:

  • If URL of :80/qbit with relative url of either something/thing.file or ./something/thing.file means grab something/thing.file from :80/something/thing.file.
  • If URL of :80/qbit/ with relative url of either something/thing.file or ./something/thing.file means grab something/thing.file from :80/qbit/something.thing.file.

So, if you intend to resolve /qbit to a directory (or re-root qbit via proxy), add a 301 Permanent redirection rule for /qbit and point the user to /qbit/ and proxy via /qbit/ as was done by this comment and in the wiki referenced in the OP.

Other resources on the subject: Google Search Console, URL rewriting (StackOverflow; see top two answers for details)

Happy to answer any questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bounty Feature request Waiting info Waiting for participants to supply more info/fulfill template requirements WebUI WebUI-related issues/changes
Projects
None yet