SCTP¶
SCTP LSM 支持¶
安全钩子¶
为了支持安全模块,SCTP 实现了三个特定钩子。
security_sctp_assoc_request()
security_sctp_bind_connect()
security_sctp_sk_clone()
security_sctp_assoc_established()
这些钩子的用法如下所述,SELinux 的实现详见SCTP SELinux 支持章节。
security_sctp_assoc_request()¶
将关联 INIT 包的 @asoc
和 @chunk->skb
传递给安全模块。成功返回 0,失败返回错误。
@asoc - pointer to sctp association structure.
@skb - pointer to skbuff of association packet.
security_sctp_bind_connect()¶
将一个或多个 IPv4/IPv6 地址传递给安全模块进行验证,验证基于 @optname
,这将导致绑定或连接服务,如下面的权限检查表所示。成功返回 0,失败返回错误。
@sk - Pointer to sock structure.
@optname - Name of the option to validate.
@address - One or more ipv4 / ipv6 addresses.
@addrlen - The total length of address(s). This is calculated on each
ipv4 or ipv6 address using sizeof(struct sockaddr_in) or
sizeof(struct sockaddr_in6).
------------------------------------------------------------------
| BIND Type Checks |
| @optname | @address contains |
|----------------------------|-----------------------------------|
| SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
| SCTP_PRIMARY_ADDR | Single ipv4 or ipv6 address |
| SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address |
------------------------------------------------------------------
------------------------------------------------------------------
| CONNECT Type Checks |
| @optname | @address contains |
|----------------------------|-----------------------------------|
| SCTP_SOCKOPT_CONNECTX | One or more ipv4 / ipv6 addresses |
| SCTP_PARAM_ADD_IP | One or more ipv4 / ipv6 addresses |
| SCTP_SENDMSG_CONNECT | Single ipv4 or ipv6 address |
| SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address |
------------------------------------------------------------------
@optname
条目摘要如下:
SCTP_SOCKOPT_BINDX_ADD - Allows additional bind addresses to be
associated after (optionally) calling
bind(3).
sctp_bindx(3) adds a set of bind
addresses on a socket.
SCTP_SOCKOPT_CONNECTX - Allows the allocation of multiple
addresses for reaching a peer
(multi-homed).
sctp_connectx(3) initiates a connection
on an SCTP socket using multiple
destination addresses.
SCTP_SENDMSG_CONNECT - Initiate a connection that is generated by a
sendmsg(2) or sctp_sendmsg(3) on a new association.
SCTP_PRIMARY_ADDR - Set local primary address.
SCTP_SET_PEER_PRIMARY_ADDR - Request peer sets address as
association primary.
SCTP_PARAM_ADD_IP - These are used when Dynamic Address
SCTP_PARAM_SET_PRIMARY - Reconfiguration is enabled as explained below.
为了支持动态地址重配置,必须在两个端点上都启用以下参数(或使用适当的 setsockopt(2))
/proc/sys/net/sctp/addip_enable
/proc/sys/net/sctp/addip_noauth_enable
然后,当相应的 @optname
存在时,以下 _PARAM_ 会在 ASCONF 数据块中发送给对等方
@optname ASCONF Parameter
---------- ------------------
SCTP_SOCKOPT_BINDX_ADD -> SCTP_PARAM_ADD_IP
SCTP_SET_PEER_PRIMARY_ADDR -> SCTP_PARAM_SET_PRIMARY
security_sctp_sk_clone()¶
每当通过 accept(2) 创建新套接字(即 TCP 风格的套接字)或当套接字被“剥离”时(例如用户空间调用 sctp_peeloff(3))都会调用此函数。
@asoc - pointer to current sctp association structure.
@sk - pointer to current sock structure.
@newsk - pointer to new sock structure.
security_sctp_assoc_established()¶
当接收到 COOKIE ACK 时调用,并且对等 secid 将保存到客户端的 @asoc->peer_secid
中。
@asoc - pointer to sctp association structure.
@skb - pointer to skbuff of the COOKIE ACK packet.
用于关联建立的安全钩子¶
下图显示了在建立关联时 security_sctp_bind_connect()
、security_sctp_assoc_request()
、security_sctp_assoc_established()
的使用。
SCTP endpoint "A" SCTP endpoint "Z"
================= =================
sctp_sf_do_prm_asoc()
Association setup can be initiated
by a connect(2), sctp_connectx(3),
sendmsg(2) or sctp_sendmsg(3).
These will result in a call to
security_sctp_bind_connect() to
initiate an association to
SCTP peer endpoint "Z".
INIT --------------------------------------------->
sctp_sf_do_5_1B_init()
Respond to an INIT chunk.
SCTP peer endpoint "A" is asking
for a temporary association.
Call security_sctp_assoc_request()
to set the peer label if first
association.
If not first association, check
whether allowed, IF so send:
<----------------------------------------------- INIT ACK
| ELSE audit event and silently
| discard the packet.
|
COOKIE ECHO ------------------------------------------>
sctp_sf_do_5_1D_ce()
Respond to an COOKIE ECHO chunk.
Confirm the cookie and create a
permanent association.
Call security_sctp_assoc_request() to
do the same as for INIT chunk Response.
<------------------------------------------- COOKIE ACK
| |
sctp_sf_do_5_1E_ca |
Call security_sctp_assoc_established() |
to set the peer label. |
| |
| If SCTP_SOCKET_TCP or peeled off
| socket security_sctp_sk_clone() is
| called to clone the new socket.
| |
ESTABLISHED ESTABLISHED
| |
------------------------------------------------------------------
| Association Established |
------------------------------------------------------------------
SCTP SELinux 支持¶
安全钩子¶
上面的SCTP LSM 支持章节描述了以下 SCTP 安全钩子,SELinux 特有细节在下面展开。
security_sctp_assoc_request()
security_sctp_bind_connect()
security_sctp_sk_clone()
security_sctp_assoc_established()
security_sctp_assoc_request()¶
将关联 INIT 包的 @asoc
和 @chunk->skb
传递给安全模块。成功返回 0,失败返回错误。
@asoc - pointer to sctp association structure.
@skb - pointer to skbuff of association packet.
- 安全模块执行以下操作:
如果这是
@asoc->base.sk
上的第一个关联,则将对等 sid 设置为@skb
中的值。这将确保只有一个对等 sid 分配给@asoc->base.sk
,该套接字可能支持多个关联。否则,验证
@asoc->base.sk peer_sid
与@skb peer sid
,以确定是否应允许或拒绝关联。将 sctp
@asoc sid
设置为套接字的 sid(来自asoc->base.sk
),MLS 部分取自@skb peer sid
。SCTP TCP 风格的套接字和剥离的连接将使用此值,因为它们会生成新的套接字。如果配置了 IP 安全选项 (CIPSO/CALIPSO),则在套接字上设置 IP 选项。
security_sctp_bind_connect()¶
根据 @optname
检查 IPv4/IPv6 地址所需的权限,如下所示:
------------------------------------------------------------------
| BIND Permission Checks |
| @optname | @address contains |
|----------------------------|-----------------------------------|
| SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
| SCTP_PRIMARY_ADDR | Single ipv4 or ipv6 address |
| SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address |
------------------------------------------------------------------
------------------------------------------------------------------
| CONNECT Permission Checks |
| @optname | @address contains |
|----------------------------|-----------------------------------|
| SCTP_SOCKOPT_CONNECTX | One or more ipv4 / ipv6 addresses |
| SCTP_PARAM_ADD_IP | One or more ipv4 / ipv6 addresses |
| SCTP_SENDMSG_CONNECT | Single ipv4 or ipv6 address |
| SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address |
------------------------------------------------------------------
SCTP LSM 支持总结了 @optname
条目,并描述了启用动态地址重配置时的 ASCONF 块处理。
security_sctp_sk_clone()¶
每当通过 accept(2) 创建新套接字(即 TCP 风格的套接字)或当套接字被“剥离”时(例如用户空间调用 sctp_peeloff(3))都会调用此函数。security_sctp_sk_clone()
会将新套接字的 sid 和对等 sid 分别设置为 @asoc sid
和 @asoc peer sid
中包含的值。
@asoc - pointer to current sctp association structure.
@sk - pointer to current sock structure.
@newsk - pointer to new sock structure.
security_sctp_assoc_established()¶
当接收到 COOKIE ACK 时调用,它会将连接的对等 sid 设置为 @skb
中的值。
@asoc - pointer to sctp association structure.
@skb - pointer to skbuff of the COOKIE ACK packet.
策略声明¶
内核中支持 SCTP 的类和权限如下:
class sctp_socket inherits socket { node_bind }
当以下策略能力被启用时:
policycap extended_socket_class;
SELinux SCTP 支持添加了用于连接到特定端口类型的 name_connect
权限和在下面章节中解释的 association
权限。
如果用户空间工具已更新,SCTP 将支持 portcon
声明,示例如下:
portcon sctp 1024-1036 system_u:object_r:sctp_ports_t:s0
SCTP 对等方标记¶
SCTP 套接字将只分配一个对等方标签。这将在第一个关联建立时分配。该套接字上的任何后续关联,其数据包对等方标签将与套接字的对等方标签进行比较,并且仅当它们不同时,才会验证 association
权限。这是通过检查套接字对等方 sid 与接收到的数据包对等方 sid 来验证的,以确定是否应该允许或拒绝关联。
- 注意事项
如果未启用对等方标记,则对等方上下文将始终为
SECINITSID_UNLABELED
(在参考策略中为unlabeled_t
)。由于 SCTP 可以在单个套接字上支持每个端点(多宿主)多个传输地址,因此可以配置策略和 NetLabel 为每个传输地址提供不同的对等方标签。由于套接字对等方标签由第一个关联的传输地址决定,建议所有对等方标签保持一致。
用户空间可以使用 getpeercon(3) 检索套接字的对等方上下文。
虽然不是 SCTP 特定的,但使用 NetLabel 时请注意,如果一个标签分配给特定接口,并且该接口“下线”,则 NetLabel 服务将删除该条目。因此,请确保网络启动脚本调用 netlabelctl(8) 来设置所需的标签(详情请参阅 netlabel-config(8) 辅助脚本)。
NetLabel SCTP 对等方标签规则如以下标记为“netlabel”的帖子集合中所述:https://www.paul-moore.com/blog/t。
CIPSO 仅支持 IPv4 地址:
socket(AF_INET, ...)
CALIPSO 仅支持 IPv6 地址:socket(AF_INET6, ...)
- 测试 CIPSO/CALIPSO 时请注意以下几点:
如果 SCTP 数据包因无效标签而无法送达,CIPSO 将发送一个 ICMP 数据包。
CALIPSO 不发送 ICMP 数据包,只是静默丢弃。
IPSEC 不受支持,因为 RFC 3554 - sctp/ipsec 支持尚未在用户空间实现(racoon(8) 或 ipsec_pluto(8)),尽管内核支持 SCTP/IPSEC。