一、说明

用户同一个虚拟服务器,配置了多个证书,用户想根据证书的 SNI 选择流量发往指定应用池。

1、环境

  • F5 V14 版本

  • F5 虚拟服务地址 192.168.13.220:443

  • 后端服务1: 10.10.10.20:80 ==> http 返回结果 Test_Side_20_80

  • 后端服务2: 10.10.10.30:80 ==> http 返回结果 Test_Side_30_80

  • **虚拟服务证书 **draw.yyds.spacewww.niux.plus

2、实现目标

(1)客户端访问 draw.yyds.space 解析到 192.168.13.220 ,转发到服务 10.10.10.20:80 所属的应用池。

(2)客户端访问 www.niux.plus 解析到 192.168.13.220 ,转发到服务 10.10.10.30:80 所属的应用池。

3、实现方式

方式1: 通过配置 ssl profile 中的 server name,客户端访问虚拟服务使用 [SSL::sni name] 获取匹配 ssl profile 的 server name 属性,来选择应用池,本文示例这种方式

1
2
3
4
5
6
7
8
9
10
11
when CLIENTSSL_CLIENTHELLO {
if { [string match [SSL::sni name]  "draw.yyds.space"] } {
pool pool_20
}
elseif { [string match [SSL::sni name]  "www.niux.plus"] } {
pool pool_30
}
else {
drop
}
}

方式2: 通过客户端访问虚拟服务使用 [SSL::extensions -type 0 ] 的方式,获取客户端 CLIENTHELLO 中的 sni 扩展,来选择应用池(这种方式无需配置ssl profile 中的 server name 字段,这种方式和上一种类似,本文不做演示)

1
2
3
4
5
6
7
8
9
10
11
when CLIENTSSL_CLIENTHELLO {
if { [ string match {*draw.yyds.space*} [SSL::extensions -type 0 ]] } {
pool pool_20
}
elseif { [ string match {*www.niux.plus*} [SSL::extensions -type 0 ]] } {
pool pool_30
}
else {
drop
}
}

二、F5 操作

1、F5上传 draw.yyds.spacewww.niux.plus 证书

**(1) 上传 **draw.yyds.space 的证书和私钥,证书和私钥名称尽量一致

image-20231102112833396

image-20231102112905711

**(2) 上传 **www.yyds.space 的证书和私钥,证书和私钥名称尽量一致

image-20231102112959516

image-20231102113040474

(3) 由下图可以查看到上传的证书和私钥完成。

image-20231102113209087

2、配置 SSL Profile 2 个

**注意: 配置多个 **SSL Profile 时需要配置一个默认的 SSL Profile ,当客户端 clienthelloSNI 未匹配到 SSL ProfileServer Name ,则使用该 SSL Profile

**(1) 配置 **draw.yyds.space 的 SSL Profile,并指定 Server Name

image-20231102114320379

image-20231102141740611

**(2) 配置 **www.niux.plus 的 SSL Profile,并指定 Server Name

image-20231102114456343

image-20231102141806577

(3) 在两个 SSL Profile 中根据实际情况配置一个默认的 SSL Profile。

image-20231102114356506

3、配置应用池

创建两个应用池 pool_20 和 Pool_30,用于区分不同业务。

image-20231102114645291

image-20231102114923069

4、配置 iRule

**策略规则 ,当F5 收到 客户端发来的 **ClientHello 并匹配 SSL Profile 后,返回该 SSL ProfileServer Name 的属性值 。

1
2
3
4
5
6
7
8
9
10
11
when CLIENTSSL_CLIENTHELLO {
if { [string match [SSL::sni name]  "draw.yyds.space"] } {
pool pool_20
}
elseif { [string match [SSL::sni name]  "www.niux.plus"] } {
pool pool_30
}
else {
drop
}
}

注意:CLIENTSSL_CLIENTHELLO 事件可以被 HTTP_REQUEST 替换

5、配置虚拟服务

创建虚拟服务,关联 http profile ,两个 ssl profile ,irules 和 应用池,地址转换和虚拟服务地址根据实际进行配置。

image-20231102115431973

image-20231102115453295

image-20231102115520935

三、客户端访问测试

**客户端访问 **https://www.niux.plus 结果发往应用池 pool_30

1
2
3
4
5
6
7
8
[root@localhost test2]# curl https://www.niux.plus
Test_side_30_80
[root@localhost test2]# curl https://www.niux.plus
Test_side_30_80
[root@localhost test2]# curl https://www.niux.plus
Test_side_30_80
[root@localhost test2]# curl https://www.niux.plus
Test_side_30_80

**客户端访问 **https://draw.yyds.space 结果发往应用池 pool_20

1
2
3
4
5
6
[root@localhost test2]# curl https://draw.yyds.space
Test_side_20_80
[root@localhost test2]# curl https://draw.yyds.space
Test_side_20_80
[root@localhost test2]# curl https://draw.yyds.space
Test_side_20_80

四、参考文档

CLIENTSSL_CLIENTHELLO (f5.com)

SSL::sni (f5.com)