# Redirect based on virtual host

**URL:** <https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113>\
**Category:** Help!\
**Created:** [February 12, 2018, 9:27am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113 "2018-02-12T09:27:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mr.proxy](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mr.proxy](https://discourse.haproxy.org/u/mr.proxy)\
**Post date:** [February 12, 2018, 9:27am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/1 "2018-02-12T09:27:34Z")

</div>

Hello, I have a question.

I use HAProxy to redirect incomming traffic on post 80, 443 and 8000 and use a lot of different virtual hosts.

All incomming traffic on 443 is decrypted and forwared on port 80 to the web-servers on a closed network (using private IP addresses). Port 8000 is forwarded as is to the same internal web-servers. The web-servers have docker containers forwarding port 8000 to 443 inside the docker container.

I want to get rid of the port 8000 by replacing it by a new virtual host , lets call it [foobar.mydomain.com](http://foobar.mydomain.com). So in stead of calling [existing-virtual-host.mydomain.com:8000](http://existing-virtual-host.mydomain.com:8000) using SSL, the client will call [foobar.mydomain.com](http://foobar.mydomain.com)

Can HAProxy be configured to handle traffic to [foobar.mydomain.com](http://foobar.mydomain.com) (on 443) by forwarding it directly to the internal web-servers on port 8000?

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [February 12, 2018, 8:38pm UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/2 "2018-02-12T20:38:48Z")

</div>

Absolutely, you just set the port on the server line.

```
backend exampleback
 server srv1 192.168.1.55:8000
```

---

<div class="post-metadata">

**Author:** ![mr.proxy](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mr.proxy](https://discourse.haproxy.org/u/mr.proxy)\
**Post date:** [February 13, 2018, 6:58am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/3 "2018-02-13T06:58:14Z")

</div>

I know, but in this case we normally send all traffic to 192.1.2.3:80 except that traffic to [foobar.mydomain.com](http://foobar.mydomain.com) that shall be sent to 192.1.2.3:8000.  
The config line above do sent everything to port 8000

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [February 13, 2018, 8:08am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/4 "2018-02-13T08:08:01Z")

</div>

Ok, use a default backend for port 80 and a more specific backend for port 8000 and content switch in the frontend based on the host header.

```
frontend bla
 bind :443 ssl crt /etc/bla/bla.pem
 use_backend exampleBack8000 if { hdr(host) -i foobar.mydomain.com }
 default_backend exampleback

backend exampleback
 server srv1 192.168.1.55:80

backend exampleBack8000 
 server srv1 192.168.1.55:8000
```

---

<div class="post-metadata">

**Author:** ![mr.proxy](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mr.proxy](https://discourse.haproxy.org/u/mr.proxy)\
**Post date:** [February 13, 2018, 9:13am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/5 "2018-02-13T09:13:46Z")

</div>

It did not work. HAProxy failed to start with the use\_backend command:

Logs begin at Fri 2016-10-28 04:34:09 CEST, end at Tue 2018-02-13 10:05:45 CET. –  
Feb 13 10:05:35 proxy1 systemd[1]: haproxy.service start request repeated too quickly, refusing to start.  
Feb 13 10:05:35 proxy1 systemd[1]: Failed to start HAProxy Load Balancer.  
Subject: Unit haproxy.service has failed  
Defined-By: systemd  
Support: [http://lists.freedesktop.org/mailman/listinfo/systemd-devel](http://lists.freedesktop.org/mailman/listinfo/systemd-devel)

Unit haproxy.service has failed.

The result is failed.  
Feb 13 10:05:35 proxy1 systemd[1]: Unit haproxy.service entered failed state.

I got the following config:

```
frontend localhost
    bind <my public ip>:80
    bind <my pyblic ip>:443 ssl crt ....
    redirect scheme https if { hdr_dom(host) -m end .mydomain.com } !{ ssl_fc }
    redirect schema https if { hdr_dom(host) -m end .anotherdomain.com } !{ ssl_fc }
    use_backend nodes8 if { hdr_dom(host) -i foobar.mydomain.com }
    mode http
    default_backend nodes
```

---

<div class="post-metadata">

**Author:** ![mr.proxy](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mr.proxy](https://discourse.haproxy.org/u/mr.proxy)\
**Post date:** [February 13, 2018, 9:29am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/6 "2018-02-13T09:29:47Z")

</div>

I also tried the following config after readaing [this page](http://www.mattbeckman.com/2009/09/18/using-the-acl-in-haproxy-for-load-balancing-named-virtual-hosts/):

```
acl is_foobar hdr_dom(host) -i foobar.mydomain.com
use_backend nodes8 if is_foobar

```

but with the same result. It is the use\_backend line that seem to cause the problem. The acl line is OK and does not cause any problems.

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [February 13, 2018, 9:39am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/7 "2018-02-13T09:39:06Z")

</div>

Check the config with `haproxy -f /path/to/haproxy.cfg -c`

---

<div class="post-metadata">

**Author:** ![mr.proxy](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mr.proxy](https://discourse.haproxy.org/u/mr.proxy)\
**Post date:** [February 13, 2018, 9:50am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/8 "2018-02-13T09:50:42Z")

</div>

Thanks. It say

```
[ALERT] 043/104735 (3700) : Unable to use proxy 'nodes8' with wrong mode, required: http, has: tcp.
[ALERT] 043/104735 (3700) : You may want to use 'mode http'.
[ALERT] 043/104735 (3700) : Proxy 'localhost': unable to find required use_backend: 'nodes8'.

```

The nodes8 configuration is:  
backend nodes8  
mode tcp  
stats enable  
stats auth haproxy:  
balance roundrobin  
cookie JSESSIONID prefix  
option httpclose  
option forwardfor  
option httpchk HEAD /check.txt HTTP/1.0  
server webA 192.168.1.1:8000 cookie A check port 80  
server webB 192.168.1.2:8000 cookie B check port 80

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [February 13, 2018, 9:53am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/9 "2018-02-13T09:53:54Z")

</div>

There you go, you need to replace “mode tcp” with “mode http”. Your configuration does not make sense at all, you are using a lot of HTTP features with a TCP backend.

---

<div class="post-metadata">

**Author:** ![mr.proxy](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mr.proxy](https://discourse.haproxy.org/u/mr.proxy)\
**Post date:** [February 13, 2018, 9:56am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/10 "2018-02-13T09:56:45Z")

</div>

I see. The problem is that the port 8000 goes into a docker container with the port setting “0.0.0.0:8000-\>443/tcp” so we need to keep the https on. If I understand correctly setting mode http will force haproxy to decrypt the traffic before sending it to port 8000 on the backend servers?

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [February 13, 2018, 10:00am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/11 "2018-02-13T10:00:21Z")

</div>

Your frontend already has either plaintext traffic (port 80), or is decrypting SSL on port 443. What you are saying doesn’t make any sense. I assume this configuration is not in production and does not work (not even before the redirect based on vhost).

If you need SSL encryption on port 8000, you would add the `ssl` keyword on the server line and depending on your requirements `verify none`.

---

<div class="post-metadata">

**Author:** ![mr.proxy](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mr.proxy](https://discourse.haproxy.org/u/mr.proxy)\
**Post date:** [February 13, 2018, 10:33am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/12 "2018-02-13T10:33:58Z")

</div>

Thanks for your help.

This config IS in production and we serve http for some customers while other are forced to use SSL.

The problem is that the main web application use port 8000 to communicate with a sub-system (running in a docker container on the web servers) over SSL. But some customers do not allow other ports than 80 and 443. So we try to replace the traffic over 8000 with SSL to use a virtual host.

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [February 13, 2018, 10:50am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/13 "2018-02-13T10:50:31Z")

</div>

That impossibile because the haproxy configuration you have shown here cannot possibily work. Like I said, configure ssl on the backend server to make this happen.

---

<div class="post-metadata">

**Author:** ![mr.proxy](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mr.proxy](https://discourse.haproxy.org/u/mr.proxy)\
**Post date:** [February 21, 2018, 2:22pm UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/14 "2018-02-21T14:22:50Z")

</div>

Tried this today, but it does not seem to work. Haproxy forward it on port 80, not port 8000

The current config for the backend node is

```
backend nodes8
    mode http
    stats enable
    stats auth haproxy:secretworkshere
    balance roundrobin
    cookie JSESSIONID prefix
    option httpclose
    option forwardfor
    option httpchk HEAD /check.txt HTTP/1.0
    server webA 192.168.1.1:8000 ssl verify none cookie A check port 80
    server webB 192.158.1.2:8000 ssl verify none cookie B check port 80
```

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [February 21, 2018, 2:43pm UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/15 "2018-02-21T14:43:40Z")

</div>

Can you remove “port 80” from the configuration please.

---

<div class="post-metadata">

**Author:** ![mr.proxy](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mr.proxy](https://discourse.haproxy.org/u/mr.proxy)\
**Post date:** [February 21, 2018, 2:47pm UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/16 "2018-02-21T14:47:38Z")

</div>

You mean like this:

```
server webA 192.168.1.1:8000 ssl verify none cookie A check
server webB 192.158.1.2:8000 ssl verify none cookie B check

```

That did not change the behaviour. Still got it on port 80.

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [February 21, 2018, 2:57pm UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/17 "2018-02-21T14:57:20Z")

</div>

That’s not what haproxy does with this configuration.

I assume old haproxy instances are still running. Please kill all haproxy processes and start it again, so you are sure no old processes are still handling traffic with an obsolete configuration.

---

<div class="post-metadata">

**Author:** ![mr.proxy](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mr.proxy](https://discourse.haproxy.org/u/mr.proxy)\
**Post date:** [February 21, 2018, 2:59pm UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/18 "2018-02-21T14:59:09Z")

</div>

I have restarted it, but it still behave like this. I’ll look into this tomorrow.

---

<div class="post-metadata">

**Author:** ![mr.proxy](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mr.proxy](https://discourse.haproxy.org/u/mr.proxy)\
**Post date:** [February 22, 2018, 7:36am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/19 "2018-02-22T07:36:46Z")

</div>

I think the problem is in the frontend localhost config. While trying this 192.168.1.2 has been disabled. Then I tried to change the IP-address of webA to a different host, but still 192.168.1.1 get the request.

```
frontend localhost
    bind our-public-ip:80
    bind our-public-ip:443 ssl a-pem-file another-pem-file

    redirect scheme https if { hdr_dom(host) -m end .mydomain.com } !{ ssl_fc }
    redirect scheme https if { hdr_dom(host) -m end .anotherdomail.com } !{ ssl_fc }

    # Forward to docker containers.
    use_backend nodes8ssl if { hdr_dom(host) -m beg foobar.mydomain }

    mode http
    default_backend nodes

```

BTW, we use HA-Proxy version 1.5.8

---

<div class="post-metadata">

**Author:** ![mr.proxy](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mr.proxy](https://discourse.haproxy.org/u/mr.proxy)\
**Post date:** [February 22, 2018, 8:38am UTC](https://discourse.haproxy.org/t/redirect-based-on-virtual-host/2113/20 "2018-02-22T08:38:30Z")

</div>

It turned out that the proxy server I have been testing on was not the one that actually received the traffic from internet. For some reason the other proxy server handled it (turning it of did stopped everything).

So when I tried the config on the other proxy server, it worked.

Thanks to lukastribus for your help.
