I have a requirement where we need to support both HTTP and HTTPS on the same VIP. Your first thought may be that is not possible, but actually BIG-IP LTM makes this quite simple.
On this post we will detail the solution to Accept HTTP request on an HTTPS Virtual Server.
The solution to Accept HTTP request on an HTTPS Virtual Server
First of all we have a simple VIP, with a clientssl profile with all the defaults settings as shown below:
ltm virtual vip-1 {
description foo-vip
destination 10.100.10.250:snpp
ip-protocol tcp
mask 255.255.255.255
persist {
source_addr {
default yes
}
}
profiles {
clientssl_nossl {
context clientside
}
http { }
tcp { }
}
rules {
UP
}
source 0.0.0.0/0
source-address-translation {
type automap
}
translate-address enabled
translate-port enabled
vs-index 5
}
The VIP has an iRule assigned to it which will print UP, the code is below:
ltm rule UP {
when HTTP_REQUEST {
HTTP::respond 200 content {
UP
}
}
}
The VIP is configured to listen on port 444. So, if we run curl against this VIP, we will get this output:
curl -v -k https://10.100.10.250:444
* Rebuilt URL to: https://10.100.10.250:444/
* Trying 10.100.10.250...
* TCP_NODELAY set
* Connected to 10.100.10.250 (10.100.10.250) port 444 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=US; ST=WA; L=Seattle; O=MyCompany; OU=IT; CN=localhost.localdomain; emailAddress=root@localhost.localdomain
* start date: Mar 5 07:57:58 2017 GMT
* expire date: Mar 3 07:57:58 2027 GMT
* issuer: C=US; ST=WA; L=Seattle; O=MyCompany; OU=IT; CN=localhost.localdomain; emailAddress=root@localhost.localdomain
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET / HTTP/1.1
> Host: 10.100.10.250:444
> User-Agent: curl/7.58.0
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: BigIP
* HTTP/1.0 connection set to keep alive!
< Connection: Keep-Alive
< Content-Length: 6
<
UP
* Connection #0 to host 10.100.10.250 left intact
We can see the TLS handshake was successful and the UP output is shown. Now if we try to make a HTTP request to this VIP it will fail:
curl -v -k http://10.100.10.250:444
* Rebuilt URL to: http://10.100.10.250:444/
* Trying 10.100.10.250...
* TCP_NODELAY set
* Connected to 10.100.10.250 (10.100.10.250) port 444 (#0)
> GET / HTTP/1.1
> Host: 10.100.10.250:444
> User-Agent: curl/7.58.0
> Accept: */*
>
* Empty reply from server
* Connection #0 to host 10.100.10.250 left intact
curl: (52) Empty reply from server
This is expected as we have a clientssl assigned to the VIP with all the default settings. If we want however to allow non-SSL connections to the Virtual Server, we need to go to the profile assigned to it and select the option ‘Non-SSL Connections’ as shown below:
Now, if we run the same query we can see the F5 accepts the connection:
curl -v -k http://10.100.10.250:444
* Rebuilt URL to: http://10.100.10.250:444/
* Trying 10.100.10.250...
* TCP_NODELAY set
* Connected to 10.100.10.250 (10.100.10.250) port 444 (#0)
> GET / HTTP/1.1
> Host: 10.100.10.250:444
> User-Agent: curl/7.58.0
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: BigIP
* HTTP/1.0 connection set to keep alive!
< Connection: Keep-Alive
< Content-Length: 6
<
UP
* Connection #0 to host 10.100.10.250 left intact
And if we hit the VIP again but this time for HTTPS, we can see it still works:
curl -v -k https://10.100.10.250:444
* Rebuilt URL to: https://10.100.10.250:444/
* Trying 10.100.10.250...
* TCP_NODELAY set
* Connected to 10.100.10.250 (10.100.10.250) port 444 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=US; ST=WA; L=Seattle; O=MyCompany; OU=IT; CN=localhost.localdomain; emailAddress=root@localhost.localdomain
* start date: Mar 5 07:57:58 2017 GMT
* expire date: Mar 3 07:57:58 2027 GMT
* issuer: C=US; ST=WA; L=Seattle; O=MyCompany; OU=IT; CN=localhost.localdomain; emailAddress=root@localhost.localdomain
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET / HTTP/1.1
> Host: 10.100.10.250:444
> User-Agent: curl/7.58.0
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: BigIP
* HTTP/1.0 connection set to keep alive!
< Connection: Keep-Alive
< Content-Length: 6
<
UP
* Connection #0 to host 10.100.10.250 left intact
This post ‘Accepting HTTP Requests on an HTTPS Virtual Server’, has been written by our Principal Consultant Oscar Pucheta.