# Sub directory not redirecting

**URL:** <https://discourse.haproxy.org/t/sub-directory-not-redirecting/4006>\
**Category:** Help!\
**Created:** [July 3, 2019, 3:28pm UTC](https://discourse.haproxy.org/t/sub-directory-not-redirecting/4006 "2019-07-03T15:28:56Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![wontbeherelong](https://avatars.discourse-cdn.com/v4/letter/w/779978/32.png) [@wontbeherelong](https://discourse.haproxy.org/u/wontbeherelong)\
**Post date:** [July 3, 2019, 3:28pm UTC](https://discourse.haproxy.org/t/sub-directory-not-redirecting/4006/1 "2019-07-03T15:28:56Z")

</div>

Hi,

Anyone able to tell me what I’m doing wrong here? Most of my services are run on sub domains and work perfectly, However, for SSO to work I need Plex to be a sub directory. My dashboard service (Organizr) is at [mydomain.com](http://mydomain.com/), and for plex I have told it to point to [mydomain.com/plex](http://mydomain.com/plex). So, the relevant part of my config currently looks something like this:

```auto
frontend shared-frontend-merged
	acl ACL1	var(txn.txnhost) -m str -i mydomain.co.uk
	acl ACLPlex	var(txn.txnpath) -m beg -i /plex

use_backend Organizr_ipvANY if ACL1 
	use_backend Plex_ipvANY if ACLPlex 

```

Yet when I try to access Plex through Organizr I’m faced with a 404 served up by nginx. Have I missed something obvious?

---

<div class="post-metadata">

**Author:** ![ciprian.craciun](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/ciprian.craciun/32/722_2.png) [@ciprian.craciun](https://discourse.haproxy.org/u/ciprian.craciun)\
**Post date:** [July 3, 2019, 3:33pm UTC](https://discourse.haproxy.org/t/sub-directory-not-redirecting/4006/2 "2019-07-03T15:33:18Z")

</div>

The first backend wins because the `ACL1` matches both in both conditions.

Einter switch the `use_backend` order, or (to be clear) add an `if ACL1 !ACPlex` for the first one, and `ACL1 ACLPlex` for the second one.

(Else only by using `ACLPlex` one could use any domain that points to that IP to access your service.)

---

<div class="post-metadata">

**Author:** ![wontbeherelong](https://avatars.discourse-cdn.com/v4/letter/w/779978/32.png) [@wontbeherelong](https://discourse.haproxy.org/u/wontbeherelong)\
**Post date:** [July 3, 2019, 3:42pm UTC](https://discourse.haproxy.org/t/sub-directory-not-redirecting/4006/3 "2019-07-03T15:42:19Z")

</div>

Hmm, that makes sense and it has definitely done something. However, both methods are now returning a 401 unauthorized. Does this provide any clue as to where to go from here? Apologies, I’m rather new to HAproxy. I probably should have done this with nginx but I’m so far down the rabbit hole I’d like to get it finished!

---

<div class="post-metadata">

**Author:** ![ciprian.craciun](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/ciprian.craciun/32/722_2.png) [@ciprian.craciun](https://discourse.haproxy.org/u/ciprian.craciun)\
**Post date:** [July 3, 2019, 3:44pm UTC](https://discourse.haproxy.org/t/sub-directory-not-redirecting/4006/4 "2019-07-03T15:44:08Z")

</div>

Unless you’ve explicitly configured authentication in HAProxy, then the status code 401 most likely is replied by the backend servers (i.e. NGinx or something downstream).

Perhaps paste the entire HAProxy configuration?

---

<div class="post-metadata">

**Author:** ![wontbeherelong](https://avatars.discourse-cdn.com/v4/letter/w/779978/32.png) [@wontbeherelong](https://discourse.haproxy.org/u/wontbeherelong)\
**Post date:** [July 3, 2019, 4:08pm UTC](https://discourse.haproxy.org/t/sub-directory-not-redirecting/4006/5 "2019-07-03T16:08:27Z")

</div>

Thanks for this, I’m sure you’re going to tell me I’ve done something really strange lol.

```
 # Generated on: 2019-07-03 16:44
global
maxconn 1000
log /var/run/log	syslog	debug
stats socket /tmp/haproxy.socket level admin 
uid 80
gid 80
nbproc 1
hard-stop-after 15m
chroot /tmp/haproxy_chroot
daemon
tune.ssl.default-dh-param	2048
log-send-hostname HaproxyMasterNode
server-state-file /tmp/haproxy_server_state

listen HAProxyLocalStats
bind 127.0.0.1:2200 name localstats
mode http
stats enable
stats admin if TRUE
stats show-legends
stats uri /haproxy/haproxy_stats.php?haproxystats=1
timeout client 5000
timeout connect 5000
timeout server 5000

frontend http-to-https
bind 62.20.15.210:80 name 62.20.15.210:80   
mode http
log global
option http-keep-alive
timeout client 30000
acl mydomain.co.uk-Redirect	var(txn.txnhost) -m beg -i mydomain.co.uk
http-request set-var(txn.txnhost) hdr(host)
http-request redirect scheme https 

frontend shared-frontend-merged
bind 62.20.15.210:443 name 62.20.15.210:443 no-sslv3 force-tlsv12 ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 ssl crt-list /var/etc/haproxy/shared-frontend.crt_list  
mode http
log global
option http-keep-alive
option forwardfor
acl https ssl_fc
http-request set-header X-Forwarded-Proto http if !https
http-request set-header X-Forwarded-Proto https if https
timeout client 30000
acl ACL1	var(txn.txnhost) -m str -i mydomain.co.uk
acl ACLPlex	var(txn.txnpath) -m beg -i /plex
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^fileshare\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^grafana\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^matrix\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^nextcloud\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^ombi\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^pfsense\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^portainer1\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^portainer2\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^proxmox\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^radarr\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^riot\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^sonarr\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^ssh\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl aclcrt_shared-frontend	var(txn.txnhost) -m reg -i ^wiki\.mydomain\.co\.uk(:([0-9]){1,5})?$
acl ACL2	var(txn.txnhost) -m str -i riot.mydomain.co.uk
acl ACL3	var(txn.txnhost) -m str -i matrix.mydomain.co.uk
acl ACL4	var(txn.txnhost) -m str -i sonarr.mydomain.co.uk
acl ACL5	var(txn.txnhost) -m str -i radarr.mydomain.co.uk
acl ACL6	var(txn.txnhost) -m str -i nextcloud.mydomain.co.uk
acl ACL7	var(txn.txnhost) -m str -i ombi.mydomain.co.uk
acl ACL12	req.cook_cnt(organizr_token_b112kkk-hjib-7891-9ed6-e8eb190763f2) gt 0
acl ACL8	var(txn.txnhost) -m str -i fileshare.mydomain.co.uk
acl ACL9	var(txn.txnhost) -m str -i grafana.mydomain.co.uk
acl ACL11	var(txn.txnhost) -m str -i pfsense.mydomain.co.uk
acl ACL13	var(txn.txnhost) -m str -i proxmox.mydomain.co.uk
acl ACL18	var(txn.txnhost) -m str -i portainer1.mydomain.co.uk
acl ACL14	var(txn.txnhost) -m str -i portainer2.mydomain.co.uk
acl ACL16	var(txn.txnhost) -m str -i ssh.mydomain.co.uk
http-request set-var(txn.txnhost) hdr(host)
http-request set-var(txn.txnpath) path
use_backend Organizr_ipvANY if ACL1 !ACLPlex 
use_backend Plex_ipvANY if ACL1 ACLPlex 
use_backend Riot_ipvANY if ACL2 
use_backend Matrix_ipvANY if ACL3 
use_backend Sonarr_ipvANY if ACL4 ACL12 
use_backend Radarr_ipvANY if ACL5 ACL12 
use_backend Nextcloud_ipvANY if ACL6 ACL12 
use_backend Ombi_ipvANY if ACL7 ACL12 
use_backend Fileshare_ipvANY if ACL12 ACL8 
use_backend Grafana_ipvANY if ACL9 ACL12 
use_backend PFsense_ipvANY if ACL11 ACL12 
use_backend Proxmox_ipvANY if ACL13 ACL12 
use_backend Portainer_ipvANY if ACL18 ACL12 
use_backend Portainer2_ipvANY if ACL14 ACL12 
use_backend SSH_ipvANY if ACL16 ACL12 

backend Organizr_ipvANY
mode http
id 100
log global
timeout connect 30000
timeout server 30000
retries 3
server Organizr 192.168.2.10:8899 id 101 check inter 1000  

backend Plex_ipvANY
mode http
id 110
log global
timeout connect 30000
timeout server 30000
retries 3
server Plex 192.168.1.12:32400 id 101 check inter 1000  

backend Riot_ipvANY
mode http
id 102
log global
timeout connect 30000
timeout server 30000
retries 3
server Riot 192.168.2.10:443 id 101 ssl check inter 1000 verify none 

backend Matrix_ipvANY
mode http
id 103
log global
timeout connect 30000
timeout server 30000
retries 3
server Matrix 192.168.2.10:443 id 101 ssl check inter 1000 verify none 

backend Sonarr_ipvANY
mode http
id 104
log global
timeout connect 30000
timeout server 30000
retries 3
server Sonarr 192.168.1.14:8989 id 101 check inter 1000  

backend Radarr_ipvANY
mode http
id 105
log global
timeout connect 30000
timeout server 30000
retries 3
server Sonarr 192.168.1.14:7878 id 101 check inter 1000  

backend Nextcloud_ipvANY
mode http
id 106
log global
timeout connect 30000
timeout server 30000
retries 3
server Nextcloud 192.168.2.10:8080 id 101 check inter 1000  

backend Ombi_ipvANY
mode http
id 107
log global
timeout connect 30000
timeout server 30000
retries 3
server Ombi 192.168.1.14:3579 id 101 check inter 1000  

backend Fileshare_ipvANY
mode http
id 108
log global
timeout connect 30000
timeout server 30000
retries 3
server Fileshare 192.168.2.10:8000 id 111 check inter 1000  

backend Grafana_ipvANY
mode http
id 109
log global
timeout connect 30000
timeout server 30000
retries 3
server Grafana 192.168.2.10:3000 id 101 check inter 1000  

backend PFsense_ipvANY
mode http
id 112
log global
timeout connect 30000
timeout server 30000
retries 3
server PFsense 192.168.1.1:81 id 101 ssl check inter 1000 verify none 

backend Proxmox_ipvANY
mode http
id 113
log global
timeout connect 30000
timeout server 30000
retries 3
server Proxmox 192.168.1.2:8006 id 101 ssl check inter 1000 verify none 

backend Portainer_ipvANY
mode http
id 114
log global
timeout connect 30000
timeout server 30000
retries 3
server Portainer 192.168.1.14:9000 id 115 check inter 1000  

backend Portainer2_ipvANY
mode http
id 117
log global
timeout connect 30000
timeout server 30000
retries 3
server Portainer2 192.168.2.10:9000 id 115 check inter 1000  

backend SSH_ipvANY
mode http
id 116
log global
timeout connect 30000
timeout server 30000
retries 3
server SSH 192.168.2.10:5800 id 111 check inter 1000
```

---

<div class="post-metadata">

**Author:** ![ciprian.craciun](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/ciprian.craciun/32/722_2.png) [@ciprian.craciun](https://discourse.haproxy.org/u/ciprian.craciun)\
**Post date:** [July 3, 2019, 4:18pm UTC](https://discourse.haproxy.org/t/sub-directory-not-redirecting/4006/6 "2019-07-03T16:18:43Z")

</div>

> [@wontbeherelong](#):
>
> I’m sure you’re going to tell me I’ve done something really strange lol.

Yup… Very strange…

But before that, quickly looking through your configuration I wouldn’t say that the 401 is from HAProxy, but in fact from one of the backend servers… (I would certainly search there…)

Check the log to see if a server was actually selected.

* * *

Now for the “very strange part”:

- you could give some relevant names to the ACL’s, as it’s almost impossible to trace them…
- the `aclcrt_shared-frontend` isn’t used anywhere; moreover it would be useless, as any behaving HTTP(S) client (given that HAProxy listens on only 443), wouldn’t send such a `Host` header…
- you use `var(txt...)` when you don’t need to (because you are using request headers only in the request processing, thus they are available;) (you could use them if you needed these values in response processing;)
- do not use `-m beg` with domain names; (as for example `whatever.mydomain.co.uk` won’t be matched;) (use instead `-m dom` if I remember correctly;)
- I don’t think SSH would work this way (unless you have something that proxies between HTTP and SSH);

---

<div class="post-metadata">

**Author:** ![wontbeherelong](https://avatars.discourse-cdn.com/v4/letter/w/779978/32.png) [@wontbeherelong](https://discourse.haproxy.org/u/wontbeherelong)\
**Post date:** [July 3, 2019, 4:28pm UTC](https://discourse.haproxy.org/t/sub-directory-not-redirecting/4006/7 "2019-07-03T16:28:38Z")

</div>

Well, looks like I have some homework to do! With ACLnames you’re absolutely right and it soon spiralled, changing them is on the list! The rest appears appears to be a combination of tutorials I followed and the options availale in the PFsense package (eg. “host matches”). As for the SSH, I installed an SSH client in docker that serves a web interface, so I can use that to SSH on my lan (as the container makes the requests). I’ll go and do some research in that case, disappointing that it wasn’t a quick fix! Thanks for your time though, appreciated.

---

<div class="post-metadata">

**Author:** ![dinaj88](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/dinaj88/32/1700_2.png) [@dinaj88](https://discourse.haproxy.org/u/dinaj88)\
**Post date:** [May 4, 2022, 1:31am UTC](https://discourse.haproxy.org/t/sub-directory-not-redirecting/4006/8 "2022-05-04T01:31:05Z")

</div>

I know this is an older thread but were you ever able to get your setup working? Mind sharing the solution 🙂

I’m new to HAProxy and running into issues. Trying to set up a bunch of subdirectories for ‘/sonarr’, ‘/radarr’, ‘/plex’, etc.
