Technical Forum
Ask questions. Discover Answers.
cancel
Showing results for 
Search instead for 
Did you mean: 

Migration from HAProxy to F5

igor_
Altocumulus
Altocumulus

Hi all,

I have a conundrum of sorts.

We are currently in the process of evaluating how to migrate from HAProxy reverse proxy and load balancer to F5.

I have a couple of questions for someone who has been in the same boat, if any 😄

1. What type of licence do we need for Reverse Proxy/Load Balancing

2) I am posting a sample config of what I need to migrate to F5

Since I have been reading about iRules and LTM Local Traffic Policy I am thinking of going the LTM route since I've read that iRules are a lot more problematic and slower to go through.

Here is the sample config. Does anyone have an idea how to implement this into F5 using LTM?

 

 

frontend web11
  mode http
  bind 10.1.1.10:80
  bind 10.1.1.10:443 ssl crt /etc/ssl/web.pem
  
  # Redirect HTTP to HTTPS
  http-request redirect scheme https code 301 unless { ssl_fc }

  # Log the session cookie if passed
  capture cookie JSESSIONID= len 32
  
  acl web_url hdr(host) -i web11.com www.web11.com
    
  acl path_cxserver path -i -m beg /Thingworx/WS
  acl path_tunnelserver path -i -m beg /Thingworx/WSTunnelServer
  acl path_tunnelclient path -i -m beg /Thingworx/WSTunnelClient
  
  # Backend logic
  use_backend cxserver if web_url path_cxserver
  use_backend tunnelserver if web_url path_tunnelserver
  use_backend tunnelclient if web_url path_tunnelclient


  
  ##### Backend section
  
backend cxserver
  mode http
  balance roundrobin
  option forwardfor

  # sticky sessions
  cookie SERVER insert indirect nocache

  http-request set-header X-Forwarded-Port %[dst_port]
  http-request add-header X-Forwarded-Proto https if { ssl_fc }

  # health check
  option httpchk GET /Thingworx/health

  
  server cxserver1 10.0.10.10:8080 check inter 1000 fastinter 1000" cookie twx1
  server cxserver2 10.0.10.11:8080 check inter 1000 fastinter 1000" cookie twx2
  
  
backend tunnelserver
  mode http
  balance source
  option forwardfor
  option httpchk GET /

  server tunnelserver1 10.0.10.20:8080 check port 9009
  server tunnelserver2 10.0.10.21:8080 check port 9009
  
backend tunnelclient
  mode http
  balance roundrobin
  option forwardfor
  option httpchk HEAD /healthcheck.html HTTP/1.1
  
  server tunnelclient1 10.0.10.30:8080 check inter 1000 fastinter 1000" cookie twx1
  server tunnelclient2 10.0.10.31:8080 check inter 1000 fastinter 1000" cookie twx2
  server tunnelclient3 10.0.10.32:8080 check inter 1000 fastinter 1000" cookie twx3
  
  
  
# Default traffic to platform
default_backend NOSRV

 

 

Thanks for any suggestions 🙂 

If you need clarification of what each line does I will be happy to break them down further if needed 🙂

1 ACCEPTED SOLUTION

JRahm
Community Manager
Community Manager

Hi @igor_ 

I haven't used haproxy personally, but the config looks pretty self explanatory. Here's a start for some of the work to get you going. Note that the cookie names are going to be stock in this solution, the jsessionid is not handled yet, and only one of the three backends has been addressed. You can add the other two as rules to the policy once you build out the pools for them. Post back with any questions.

 

ltm monitor http cxserver-httpchk {
    adaptive disabled
    defaults-from http
    interval 5
    ip-dscp 0
    recv none
    recv-disable none
    send "GET /Thingworx/health\r\n"
    time-until-up 0
    timeout 16
}

ltm pool cxserver-pool {
    members {
        cxserver1:8080 {
            address 10.0.10.10
        }
        cxserver2:8080 {
            address 10.0.10.11
        }
    }
    monitor cxserver-httpchk
}

ltm policy test-policy {
    controls { forwarding }
    requires { http }
    rules {
        cxserver-match {
            actions {
                0 {
                    forward
                    select
                    pool cxserver-pool
                }
            }
            conditions {
                0 {
                    http-uri
                    values { /Thingworx/WS }
                }
            }
            ordinal 1
        }
    }
    status published
    strategy first-match
}

ltm policy http-to-https {
    controls { forwarding }
    requires { http tcp }
    rules {
        redirect {
            actions {
                0 {
                    http-reply
                    redirect
                    location tcl:https://[getfield [HTTP::host] ":" 1][HTTP::uri]
                }
            }
            conditions {
                0 {
                    tcp
                    port
                    values { 80 }
                }
            }
        }
    }
    status published
    strategy first-match
}

ltm virtual testapp-vip {
    destination 10.1.1.10:80
    ip-protocol tcp
    mask 255.255.255.255
    policies {
        http-to-https { }
    }
    profiles {
        http { }
        tcp { }
    }
    serverssl-use-sni disabled
    source 0.0.0.0/0
    translate-address enabled
    translate-port enabled
}
ltm virtual testappssl-vip {
    destination 10.1.1.10:443
    ip-protocol tcp
    mask 255.255.255.255
    persist {
        cookie {
            default yes
        }
    }
    policies {
        test-policy { }
    }
    profiles {
        clientssl {
            context clientside
        }
        http { }
        tcp { }
    }
    serverssl-use-sni disabled
    source 0.0.0.0/0
    source-address-translation {
        type automap
    }
    translate-address enabled
    translate-port enabled
}

 

high level from objects perspective (and this is imperative config, I highly encouarge you taking a look at the declarative automated tool chain):

Monitors for the pools
Pools for each of your backend servers
Cookie profiles if you want them to be named specifically
SSL profile for your front-end
LTM policy for redirecting from http->https
LTM policy for traffic matching, forwarding, and logging 
Virtual server for port 80
Virtual server for port 443

View solution in original post

10 REPLIES 10

JRahm
Community Manager
Community Manager

Hi @igor_ 

I haven't used haproxy personally, but the config looks pretty self explanatory. Here's a start for some of the work to get you going. Note that the cookie names are going to be stock in this solution, the jsessionid is not handled yet, and only one of the three backends has been addressed. You can add the other two as rules to the policy once you build out the pools for them. Post back with any questions.

 

ltm monitor http cxserver-httpchk {
    adaptive disabled
    defaults-from http
    interval 5
    ip-dscp 0
    recv none
    recv-disable none
    send "GET /Thingworx/health\r\n"
    time-until-up 0
    timeout 16
}

ltm pool cxserver-pool {
    members {
        cxserver1:8080 {
            address 10.0.10.10
        }
        cxserver2:8080 {
            address 10.0.10.11
        }
    }
    monitor cxserver-httpchk
}

ltm policy test-policy {
    controls { forwarding }
    requires { http }
    rules {
        cxserver-match {
            actions {
                0 {
                    forward
                    select
                    pool cxserver-pool
                }
            }
            conditions {
                0 {
                    http-uri
                    values { /Thingworx/WS }
                }
            }
            ordinal 1
        }
    }
    status published
    strategy first-match
}

ltm policy http-to-https {
    controls { forwarding }
    requires { http tcp }
    rules {
        redirect {
            actions {
                0 {
                    http-reply
                    redirect
                    location tcl:https://[getfield [HTTP::host] ":" 1][HTTP::uri]
                }
            }
            conditions {
                0 {
                    tcp
                    port
                    values { 80 }
                }
            }
        }
    }
    status published
    strategy first-match
}

ltm virtual testapp-vip {
    destination 10.1.1.10:80
    ip-protocol tcp
    mask 255.255.255.255
    policies {
        http-to-https { }
    }
    profiles {
        http { }
        tcp { }
    }
    serverssl-use-sni disabled
    source 0.0.0.0/0
    translate-address enabled
    translate-port enabled
}
ltm virtual testappssl-vip {
    destination 10.1.1.10:443
    ip-protocol tcp
    mask 255.255.255.255
    persist {
        cookie {
            default yes
        }
    }
    policies {
        test-policy { }
    }
    profiles {
        clientssl {
            context clientside
        }
        http { }
        tcp { }
    }
    serverssl-use-sni disabled
    source 0.0.0.0/0
    source-address-translation {
        type automap
    }
    translate-address enabled
    translate-port enabled
}

 

high level from objects perspective (and this is imperative config, I highly encouarge you taking a look at the declarative automated tool chain):

Monitors for the pools
Pools for each of your backend servers
Cookie profiles if you want them to be named specifically
SSL profile for your front-end
LTM policy for redirecting from http->https
LTM policy for traffic matching, forwarding, and logging 
Virtual server for port 80
Virtual server for port 443

Maybe you will only need an iRule to log the cookie:

 

https://clouddocs.f5.com/api/irules/HTTP__cookie.html

https://community.f5.com/t5/technical-articles/getting-started-with-irules-logging-comments/ta-p/290...

 The request logging profile can also be a nice feature:

https://my.f5.com/manage/s/article/K00847516

 

You can send the HTTP logs directly to a syslog or SIEM without saving them locally and the irules, F5 system or the request logging profile support HSL:

 

https://clouddocs.f5.com/api/irules/HSL.html

https://techdocs.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/bigip-external-monitoring-imple...

https://my.f5.com/manage/s/article/K50040950

 

 

 

 


when HTTP_REQUEST {
log local0. “JSESSIONID cookie: [HTTP::cookie value "JSESSIONID"] from source IP [IP::client_addr] ”
}

 

Maybe also check if One Connect will be needed as this could be enabled by default for HAProxy and you will need one connect profile for F5.

https://www.haproxy.com/blog/http-keep-alive-pipelining-multiplexing-and-connection-pooling

https://my.f5.com/manage/s/article/K91757375

 

For X-Forwarded options you play with the F5 HTTP profile as there is no need for irule or local traffic policies

https://my.f5.com/manage/s/article/K43444200

https://my.f5.com/manage/s/article/K4816

 

JRahm
Community Manager
Community Manager

@Nikoolayy1   Good call on one connect, forgot that. It is considered a misconfiguration on http without it. 

@igor_ iRules are totally acceptable, but it is best to do as much as you can without them, and sometimes an apples to apples configuration might require it, whereas a review of requirements for each app you're migrating might present an opportunity to make some changes that a) keep the config and therefore all the logic in native tmm objects and b) prep the config for easy automation when ready.

For the cookie logging need I think the irule is better than the local traffic policy with a log action and tcl substitution like "tcl:[HTTP::cookie value "JSESSIONID"]". I don't renember if the request logging profile also logged the HTTP cookies and their values.

 

https://techdocs.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/local-traffic-policies-getting-...

igor_
Altocumulus
Altocumulus

Hi guys,

Thanks for the proposed solutions. I will be going through them to see how to copy them into the configuration.

One question though since I am new to F5 @JRahm , the configuration you posted is that in a form which is then imported in F5 from GUI ?

I went from nginx -> f5, i used linux clustering with a single floating VIP to handle failover.

 

I would suggest just using irules.

Unless you are hammering the system and need all the performance you can get.

Why - well they both do about the same thing

Irules give you more ability to do just about anything.

For example we do stick session based upon jsessionid - which didn't fit with the persistance model built into the F5.

Setting up irules to do what the policies do is easy.

Also then thing about logging the request / response logging is not pretty  i wrote my own irule module to capature all of the events and record them as well as return headers from back end apps which included timing info.

Another nice thing as well we have https backends and http backends - irules to process that

 

Have fun

 

You mean Universal persistance based on the jsessionid cookie?

 

https://my.f5.com/manage/s/article/K7392

Yeah

JRahm
Community Manager
Community Manager

the config as provided is the configuration file version. For GUI would need screenshots or video walkthrough. I can look at that for next week, but on vacation the rest of this week.

igor_
Altocumulus
Altocumulus

Guys,

Much appreciated your answers. It gave me some directions on where to go in the first place.

@AlexS_yb The company is part of the PCI industry so every ms counts 😁 

Some initial feedback and some questions from my side:

I have created backend server pools.

I have created a virtual server with private ip and NAT-ed the public ip into the private one. 

The path looks like this:

Internet ----> Router -----> FIrewall (NAT) ----> F5 Virtual server IP (I will call it V1)

A question: Since the public website is https://app1.somesite.com, I have created an LTM policy using an article from this site written by Eric_Chen - SNI Routing with BIG-IP.

Now since in the backend, I have some servers which communicate over HTTP and others over HTTPS, can I mix and match protocols? Bear in mind that on the same Windows server under IIS, I have a service using HTTP on port 555, and another service using HTTPS on port 566 for example.

Under LTM Policy rules I have a lot of:

If HTTP Uri path starts with : /app1 forward traffic to pool (pool1) at request

If HTTP Uri path starts with : /app2 forward traffic to pool (pool2) at request

Now am I using this right since the traffic is encrypted until it hits the virtual server V1. From there based on condition it should be redirected to even the same pool of servers but different ports.

What I found out is that when setting the virtual server V1 if I select a certificate for SSL Profile (server) I can't connect pools that are running over HTTP and if I don't select SSL Profile (server) I can't communicate with backend pools over HTTPS. Can this be done automatically using one virtual server and combined LTM Policy rules? 

Any ideas?

Thanks,

Igor