Warning: Array to string conversion in /home/wwwroot/myf5/wp-content/plugins/wpjam-basic/public/wpjam-utils.php on line 496
F5 bigip自11.5.0版本后增加了socks profile的支持,即可以利用LTM提供socks4,4a以及socks5的服务。socks位于OSI模型的会话层上,可以透明的为TCP或UDP提供中转代理服务。
[title]socks profile配置项含义[/title]
protocol versions:选择需要支持的协议版本,可以为4,4a,5,默认则全部支持
DNS resolver:一个需要提前在网络部分配置好的resolver(只需配置resolver,无需配置系统级的DNS IP),以提供4a,5版本对访问目标地址为域名时的代理解析支持。即address type=domain,例如:
Socks Protocol
Version: 5
Command: Connect (1)
Reserved: 0
Address Type: Domain Name (3)
Remote name: www.myf5.net
Port: 443
抓包范例:立即下载
Route domain:指LTM代理发起新连接时,新连接所走网络应该处于的route domain。
Tunnel name: 指LTM发起的代理新连接处于哪个tunnel里,所以如果需要额外VS来处理LTM发起的代理新连接,则这个额外的VS应该监听在这里指定的tunnel上
Default Connect handling: 指明发起的代理新连接是否需要额外的VS来处理,勾选表示无需额外VS,不勾选表示需要额外VS。 注意:即便勾选时,如果相应tunnel有可以处理代理连接的额外VS,则这些额外VS还是会接管这些流量(即一旦tunnel有额外vs能处理这些代理连接,则是否勾选都会有一样的行为)。
利用将代理连接交给额外的VS处理,可以实现对代理连接的进一步控制和处理,例如实现代理连接走指定线路出去等。
另外,对于配置socks profile的VS,其中的目的地址和目的端口转换选项必须保持勾选状态。
[title]不同配置组合下的行为[/title]
enable Default Connect Handling + tunnel内无可转发流量vs + socks VS无snat = 无法代理访问立即下载
enable Default Connect Handling + tunnel内无可转发流量vs + socks VS有snat = 可以代理访问,访问源地址是socks vs的SNAT地址. 此时route-domain设置无效。立即下载
enable Default Connect Handling + tunnel内有可转发流量vs + socks VS无snat = 可以代理访问,访问源地址去往可转发流量vs的时候使用原始客户端地址,经过转发vs后按转发vs规则处理立即下载
enable Default Connect Handling + tunnel内有可转发流量vs + socks VS有snat = 可以代理访问,访问源地址去往可转发流量vs的时候使用SNAT后的地址,经过转发vs后按转发vs规则处理立即下载
disable Default Connect Handling + tunnel内无可转发流量vs + socks VS有snat = 无法代理访问
disable Default Connect Handling + tunnel内无可转发流量vs + socks VS无snat = 无法代理访问
disable Default Connect Handling + tunnel内有可转发流量vs + socks VS无snat = 可以代理访问,访问源地址去往可转发流量vs的时候使用原始客户端地址,经过转发vs后按转发vs规则处理
disable Default Connect Handling + tunnel内有可转发流量vs + socks VS有snat = 可以代理访问,访问源地址去往可转发流量vs的时候使用原始客户端地址,经过转发vs后按转发vs规则处理
[title]socks irule[/title]
目前支持三个socks命令:
SOCKS::allowed 返回控制状态或设置控制是否容许使用socks
SOCKS::destination 返回或设置代理连接的目标域名/IP/port,例如:
when SOCKS_REQUEST {
log local0. "[SOCKS::destination host]"
}
Aug 3 15:46:30 ltm3900 info tmm[10394]: Rule /Common/socks_irule <SOCKS_REQUEST>: www.myf5.net
Aug 3 15:46:30 ltm3900 info tmm3[10394]: Rule /Common/socks_irule <SOCKS_REQUEST>: s22.cnzz.com
Aug 3 15:46:31 ltm3900 info tmm[10394]: Rule /Common/socks_irule <SOCKS_REQUEST>: z1.cnzz.com
Aug 3 15:46:31 ltm3900 info tmm1[10394]: Rule /Common/socks_irule <SOCKS_REQUEST>: c.cnzz.com
Aug 3 15:46:31 ltm3900 info tmm2[10394]: Rule /Common/socks_irule <SOCKS_REQUEST>: z1.cnzz.com
Aug 3 15:46:31 ltm3900 info tmm3[10394]: Rule /Common/socks_irule <SOCKS_REQUEST>: cnzz.mmstat.co
SOCKS::version 返回连接所用的版本
一个事件:
SOCKS_REQUEST 事件在socks连接发起到验证前被触发
[title]udp associate穿透[/title]
目前还不支持UDP的穿透(ID591610),在特定环境下,可以使用irule来模拟解决(需使用V12.1.2HF1以上版本.ID641360)
配置一个前端vs(不关联socks profile),关联以下irule。 然后该vs通过virtual 命令引导vs处理后的流量到真实的socks vs vs_proxy_real_sock上
when RULE_INIT {
# Set your own UDP vs IP and port
set static::UDP_PROXY_IP "10.*.*.*"
set static::UDP_PROXY_PORT 10000
}
when CLIENT_ACCEPTED {
set authenticated 0
virtual vs_proxy_real_sock
TCP::collect
}
when CLIENT_DATA {
set cdata [TCP::payload]
set clen [TCP::payload length]
log local0. "Client payload length: ${clen}"
if { ${authenticated} == 0 } {
binary scan ${cdata} ccc version count method0
if { ! || ${version} != 5 || ! || ${count} < 1 || ! || ${method0} != 0 } {
log local0. "Unknown first packet; bypass processing"
TCP::release
return
} else {
incr authenticated
binary scan ${cdata} H* hexcdata
log local0. "Authentication packet detected: ${hexcdata}"
}
} else {
set cursor 0
binary scan ${cdata} cc version command
incr cursor 2
if { ! || ${version} != 5 || ! || ${command} != 3 } {
log local0. "Command is not UdpAssociate <${command}>; bypass processing"
TCP::release
return
} else {
binary scan ${cdata} x${cursor}cc reserved atype
incr cursor 2
if { && && ${atype} == 1 } {
binary scan ${cdata} x${cursor}ccccS a1 a2 a3 a4 port
incr cursor 6
if { && && && && } {
set a1 [expr {${a1} & 0xff}]
set a2 [expr {${a2} & 0xff}]
set a3 [expr {${a3} & 0xff}]
set a4 [expr {${a4} & 0xff}]
set port [expr {${port} & 0xffff}]
log local0. "UDP client: ${a1}.${a2}.${a3}.${a4}:${port}"
TCP::payload replace 0 ${clen} ""
set t1 [getfield ${static::UDP_PROXY_IP} "." 1]
set t2 [getfield ${static::UDP_PROXY_IP} "." 2]
set t3 [getfield ${static::UDP_PROXY_IP} "." 3]
set t4 [getfield ${static::UDP_PROXY_IP} "." 4]
TCP::respond [binary format ccccccccS 5 0 0 1 ${t1} ${t2} ${t3} ${t4} ${static::UDP_PROXY_PORT}]
return
}
}
TCP::payload replace 0 0 ${authprefix}
TCP::release
return
}
}
TCP::release
TCP::collect
}
when LB_SELECTED {
log local0. "LB_SELECTED"
}
在UDP vs上关联:
when CLIENT_ACCEPTED {
set cdata [UDP::payload]
set clen [UDP::payload length]
set cursor 0
binary scan ${cdata} SccccccS reserved frag atype a1 a2 a3 a4 port
incr cursor 10
if { && && && && && && && } {
if { ${atype} == 1 } {
# Only handle IPv4 in this iRule
# Normalize the scanned numbers
set a1 [expr {${a1} & 0xff}]
set a2 [expr {${a2} & 0xff}]
set a3 [expr {${a3} & 0xff}]
set a4 [expr {${a4} & 0xff}]
set port [expr {${port} & 0xffff}]
log local0. "UDP destination: ${a1}.${a2}.${a3}.${a4}:${port}"
binary scan ${cdata} x${cursor}a* actual_data
if { } {
binary scan ${cdata} a${cursor} cheader
log local0. "Actual data size: [string length ${actual_data}]"
UDP::payload replace 0 0 ${actual_data}
UDP::payload replace [string length ${actual_data}] ${clen} "" <<<<<<<<<<<< ${clen} should not the correct length.
log local0. "UDP payload size after modification: [UDP::payload length]" <<<<<<< Look at the log messages, always the same as before modification!
#node "${a1}.${a2}.${a3}.${a4}:${port}"
node ${a1}.${a2}.${a3}.${a4} ${port}
} else {
log local0. "No data is found; packet dropped"
drop
}
}
}
}
when LB_SELECTED {
log local0. "LB_SELECTED"
}
when CLIENT_DATA {
log local0. "CLIENT_DATA"
}
when SERVER_CONNECTED {
log local0. "SERVER_CONNECTED"
}
when SERVER_DATA {
log local0. "SERVER_DATA"
if { } {
UDP::payload replace 0 0 ${cheader}
log local0. "Response size after modification: [UDP::payload length]"
}
}
需要注意,上述两个vs(关联socks profile的tcp,udp)是两个完全独立的连接,根据socks协议规范,tcp和udp两个连接是伴生关系,因此注意tcp vs的idle timeout不要过早的删除连接导致udp跟着断开.
[title]BIND连接方法[/title]
不支持,以下测试服务器未返回消息
(echo -ne "\x05\x01\x00"; sleep 1; echo -ne "\x05\x02\x00\x01\xb8\x18\x62\x62\x00\x50";sleep 1;) | nc ip 1080
[title]socks服务代理验证[/title]
待更新
Array
文章评论