Tacscs+协议原理


参考资料:https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-18


其他文章:


TACACS+ 简介

本文档介绍了(Terminal Access Controller Access-Control
System Plus )终端访问控制器访问控制系统增强版(TACACS +)协议。 它最初被构想为通用的身份验证,授权和计费(AAA)协议。 它在当今得到了广泛的部署,但主要限于AAA(Authentication, Authorization and Accounting )的特定子集:设备管理,即:验证对网络设备的访问,提供操作的集中授权以及审核这些操作。

大量的TACACS+客户端和服务器已经部署在生产网中。它们所基于的TACACS+协议是在一个最初打算用于IETF发布的草案文档中定义的,但从未标准化。该草案被称为“草案(The Draft)”。

该草案是时代的产物,并没有解决设计现代标准时考虑的所有关键安全问题。因此,部署必须谨慎执行。后续安全部分讨论了这些问题。

此信息性文档的主要目的是阐明“草案”的子集,这是支持设备管理的实现常见的子集。所有符合本文档的实现都将符合“草案”。然而,并不是所有符合“草案”的实现都将符合本文档。《草案》的以下功能已被删除:

  • 出于安全原因,本文档正式删除了SENDPASS。
  • 对遗留特性(如ARAP和outbound authtication)的规范描述已被删除。

TACACS+协议允许任意长度和内容的身份验证交换,以支持其他身份验证机制。它是可扩展的,可以提供站点定制和未来的开发特性,并且它使用TCP来确保可靠的交付。该协议允许TACACS+客户端请求(fine-grained)细粒度的访问控制,并允许服务器响应该请求的每个组件。

认证、授权和计费的分离是TACACS+协议设计的关键。从本质上说,它使TACACS+成为一套三种协议。本文档将分别在不同的部分对每一个问题进行讨论。尽管TACACS+定义了这三种方法,但实现或部署并不需要采用这三种方法。分离元素对于设备管理用例非常有用,特别是对于会话中单个命令的授权。请注意,在协议级别没有为认证与授权请求关联作出规定。

技术定义

本节提供了一些适用于本文档的基本定义。

  • Client,客户端

    Client(客户端)是发起TACACS+协议请求以进行访问的任何设备,主要用于设备管理用例。

  • Server,服务端

    服务器根据其业务模型接收TACACS+协议请求,并根据本文档中定义的流进行应答。

  • Packet,包

    除非另有明确说明,否则在本文档中,Packet(包)一词的所有用法都指TACACS+协议数据单元。非正式术语“Packet”已经成为定义的一部分。

  • Connection,连接

    TACACS+使用TCP进行传输。TCP服务器端口49是由IANA分配给TACACS+流量的。

  • Session,会话

    整个文档都使用了会话的概念。TACACS+会话是单个认证序列、单个授权交换或单个计费交换。

    一个计费和授权会话将由一对数据包(请求和它的应答)组成。认证会话可能涉及正在交换的任意数量的数据包。会话是维护在TACACS+客户机和服务器之间的操作概念。它不一定对应于给定的用户或用户操作。

  • Treatment of Enumerated Protocol Values,枚举协议值的处理

    此文档描述了信息包报头中的各种枚举值以及特定信息包类型的报头。例如,在身份验证启动包类型中,本文档用三个值定义动作字段TAC_PLUS_AUTHEN_LOGIN、TAC_PLUS_AUTHEN_CHPASS和TAC_PLUS_AUTHEN_SENDAUTH。

    如果服务器没有实现它所接收的包中所定义的选项之一,或者它遇到了未在该文档中列出的头字段的选项,那么它应该以错误响应并终止会话。这将允许客户端尝试不同的选项。

    如果发生错误,但无法确定传入数据包的类型,则必须返回具有相同的明文报头但序列号增加1且长度设置为0的数据包来表示错误。

  • Treatment of Text Strings,文本字符串的处理

    TACACS+协议大量使用了文本字符串。最初的草案打算将这些字符串作为字节数组处理,其中每个字节代表一个US-ASCII字符。

    最近,服务器实现已经扩展到与外部标识服务交互,因此需要更细致的方法。Usernames必须使用RFC8265 [RFC8265]中指定的UsernameCasePreserved 配置文件进行编码和处理。

    特别提到的地方,数据字段包含协议处理所需的任意字节数组。它们不打算通过用户界面对用户可见。TACACS+中的所有其他文本字段必须作为RFC 20 [RFC0020]定义的US-ASCII的可打印字节数组处理。这里使用的术语“printable,可打印”意味着字段必须排除rfc20 [RFC0020]第5.2节中定义的“控制字符”。

Tacacs+ Packets and Sessions,报文和会话

Tacacs+的报文头:

所有的TACACS+数据包都以以下12字节的头开始。报头描述了包的其余部分:

1
2
3
4
5
6
7
8
9
10
11
1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8
+----------------+----------------+----------------+----------------+
|major | minor | | | |
|version| version| type | seq_no | flags |
+----------------+----------------+----------------+----------------+
| |
| session_id |
+----------------+----------------+----------------+----------------+
| |
| length |
+----------------+----------------+----------------+----------------+

以下通用规则适用于所有TACACS+报文类型:

  • 若要表示任何可变长度数据字段未使用,则将相应的长度值设置为零。这些字段必须被忽略,并像不存在一样处理。
  • 数据包中的数据和消息字段的长度由它们对应的长度字段指定(不以null终止)。
  • 所有长度值都是unsigned无符号的,按网络字节顺序排列。

Tacscs+报文头字端解释:

  • major_version: TACACS协议主版本号,当前版本号为0xc

    TAC_PLUS_MAJOR_VER := 0xc

  • minor_version: Tacscs协议次版本号,当前版本号为0x0.

    TAC_PLUS_MINOR_VER_DEFAULT := 0x0;

    TAC_PLUS_MINOR_VER_ONE := 0x1

  • type:Tacacs协议报文类型,包括认证(0x01)、授权(0x02)和计费(0x03)。

    • TAC_PLUS_AUTHEN := 0x01 (Authentication)
    • TAC_PLUS_AUTHOR := 0x02 (Authorization)
    • TAC_PLUS_ACCT := 0x03 (Accounting)
  • seq_no: 这是当前数据包的序列号。会话中的第一个包必须具有序列号1,随后的每个包将增加序列号1。TACACS+客户端只发送包含奇数序列号的数据包,而TACACS+服务器只发送包含偶数序列号的数据包。

    序列号永远不能换行,也就是说,如果达到序列号2^8-1,该会话必须终止并以序列号1重新启动。

    对于同一个会话,当前报文的序列号,取值范围为1~254。

  • flags : 此字段包含各种位图标志。

    • TAC_PLUS_UNENCRYPTED_FLAG := 0x01

      报文主体加密标记,0表示对报文主体加密,1表示不对报文主体加密。

      此标志表明发送方没有加密包的主体。在生产中不能使用此选项。安全部分将介绍此标志的应用。

      这个标志在所有部署中都应该是清晰的。现代网络流量工具在配置共享密钥时支持加密流量,因此即使在测试期间也可以而且应该使用加密模式。

    • The single-connection flag:

      TAC_PLUS_SINGLE_CONNECT_FLAG := 0x04

      此标志用于允许客户端和服务器协商单一连接模式。

    读取时必须忽略所有其他位,写入时应设置为零。

  • session_id: 会话ID,当前会话的唯一标识。

    此TACACS+会话的Id。此字段在TACACS+会议期间不会更改。此数字必须由加密的强随机数生成方法生成。如果不这样做,将危及会话的安全性。

  • length: TACACS报文主体的长度,不包括报文头

Tacacs+ 报文主体:

在数据包报头中定义了TACACS+主体类型。本文档的下一部分将介绍不同TACACS+正文的内容。

单连接模式:

单连接模式( Single Connection Mode)是为了提高性能,有很多客户端和服务器之间的流量通过允许复用多个会话在一个TCP连接。

数据包头包含客户端和服务器用来协商使用单连接模式的TAC_PLUS_SINGLE_CONNECT_FLAG。

客户端设置此标志,以表明它支持在单个TCP连接上多路传输TACACS+会话。在单连接状态建立之前,客户端不能在连接上发送第二个数据包。

为了表示它将支持单一连接模式,服务器将在响应客户端的第一个请求的第一个应答包中设置此标志(Flag)。即使客户端没有设置该标志,服务器也可以设置该标志,但是客户端可以忽略该标志并在会话完成后关闭连接。

该标志只与连接上的前两个包相关,以允许客户端和服务器建立单一连接模式。在前两个包之后没有更改单个连接模式的规定:客户端和服务器必须忽略连接上第二个包之后的标志。

如果在TCP连接的前两个包中没有建立单连接模式,那么客户端和服务器都会在第一次会话结束时关闭连接。

客户端采用单连接模式,提高了效率。服务器可能拒绝允许客户端使用单连接模式。例如,在某些部署中,可能不适合将持久的TCP连接分配给特定的客户端。即使服务器被配置为允许特定客户端使用单一连接模式,服务器也可以关闭连接。例如:服务器必须配置为在一段特定的不活动时期后超时单个连接模式TCP连接,以保留其资源。即使建立了单个连接模式,客户端也必须在TCP会话上适应这种终止。

由于服务器或中间连接的超时,单连接模式下的TCP连接最终将关闭。如果一个会话正在进行,当客户端检测到断开连接,那么客户端应该处理它。如果会话没有进行,那么客户端将需要检测它,并在它启动下一个会话时重新启动单连接模式。

Session Completion,会话完成

在下面的小节(认证、授权和计费)中为包类型定义的应答包包含一个状态字段。此字段的完整选项集取决于包类型,但所有三种应答包类型都定义了表示PASS、ERROR和FAIL的值,这些值表明常规会话(未中止的会话)的最后一个包。

服务器以PASS或FAIL响应,表明请求的处理已经完成,客户端可以回应结果(PASS或FAIL)来控制提示将请求发送到服务器的操作的执行。

服务器响应一个EEROR,表明该请求的处理没有完成。客户端无法回应结果,并且它的行为必须与服务器无法连接一样。例如,客户端尝试其他方法(如果有的话),比如将请求发送到备份服务器,或者使用本地配置来确定是否应该执行提示请求的操作。

当会话完成,那么TCP连接应该处理如下,根据单连接模式是否协商:

  • 如果没有协商成单连接模式,连接应该关闭。

  • 如果单连接模式被启用,那么连接应该打开,但仍可能被关闭在超时时间保存部署资源。

  • 如果启用了单连接模式,但是由于连接问题(比如不正确的密码,而出现错误,那么该连接上不能接受任何新的会话。如果有任何会议已经建立,那么他们可能会完成。一旦所有活动会话完成,则必须关闭连接。

建议客户端实现提供健壮的方案来处理无法连接到的服务器。选项包括提供用于冗余的服务器列表,以及在无法到达服务器时提供本地回退配置的选项。具体细节将是特定于实现的。

客户端应该管理连接并处理服务器建立连接但不响应的情况。确切的行为是特定于实现的。建议客户端在出现可配置的超时后关闭连接。

Data Obfuscation,数据混淆(加密):

数据包的主体可以被混淆。下面的章节描述了协议中支持的混淆方法。在“草案”中,这一过程实际上被称为加密,但该算法不符合现代标准,因此在本文档中不会被称为加密。

混淆机制依赖于一个私密的密钥,一个客户端和服务器都知道的共享密钥值。密钥必须保密。

服务器实现必须允许与每个客户机关联唯一的密钥。使用单独密钥的是否合适,这取决于站点。

标志(flag)字段必须配置如下位如下:

1
TAC_PLUS_UNENCRYPTED_FLAG = 0x0

因此,数据包的主体是混淆的做(byte-wise)逐字节 XOR-ing与(pseudo-random pad)伪随机载荷。

1
ENCRYPTED {data} = data ^ pseudo_pad

然后,包体可以通过用伪随机载荷按字节对其进行XOR-ing来消除混淆。

1
data = ENCRYPTED {data} ^ pseudo_pad

该(pad)载荷是通过连接一系列MD5散列(每个16字节长)并将其截断为输入数据的长度而生成的。

在本文档中,MD5指的是“RSA数据安全公司”。MD5消息摘要算法”,在RFC1321 [RFC1321]中指定。

1
pseudo_pad = {MD5_1 [,MD5_2 [ ... ,MD5_n]]} truncated to len(data)

第一个MD5哈希是通过连接session_id、secret key、版本号和序列号,然后在这些数据上运行MD5生成的。除了在TACACS+客户端和服务器之间共享的密钥之外,所有这些输入值都可以在数据包报头中使用。

版本号和session_id是从报文头中提取的,后续的散列是通过使用相同的输入流生成的,但是将之前的散列值连接到输入流的末尾。

1
2
3
MD5_1 = MD5{session_id, key, version, seq_no} MD5_2 = MD5{session_id,
key, version, seq_no, MD5_1} .... MD5_n = MD5{session_id, key,
version, seq_no, MD5_n-1}

当服务器检测到它为设备配置的密钥不匹配时,它必须返回ERROR。

1
TAC_PLUS_UNENCRYPTED_FLAG == 0x1

不赞成使用此选项,不能在生产中使用。在这种情况下,整个数据包主体是明文的。如果TAC_PLUS_UNENCRYPTED_FLAG设置为True,则必丢弃请求。

在包体去混淆之后,对包中字段值的长度进行求和。 如果总和与报头中的明文数据长度值不同,则必须丢弃该分组,并发出错误信号。

当客户端和TACACS+服务器之间的密钥不匹配时,通常会出现这样的故障。

Authentication,认证

认证是确定用户(或实体)是谁的动作。 认证可以采用多种形式。 传统身份验证使用name和固定密码。 但是,固定密码是易受攻击,因此许多现代身份验证机制都使用“one-time,一次性”密码或质询响应查询。 TACACS +旨在支持所有这些功能,并且足够灵活以处理将来的任何机制。

认证通常在用户首次登录到计算机或请求其服务时进行。 认证不是强制性的; 它是一个站点配置的选项。 一些站点不需要它。 其他人仅对某些服务需要它(请参阅下面的授权)。 当用户尝试获得额外的特权时,还必须进行认证,并且必须将自己标识为拥有这些特权所需的信息(密码等)的人。

The Authentication START Packet Body,认证开始报文:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8
+----------------+----------------+----------------+----------------+
| action | priv_lvl | authen_type | authen_service |
+----------------+----------------+----------------+----------------+
| user_len | port_len | rem_addr_len | data_len |
+----------------+----------------+----------------+----------------+
| user ...
+----------------+----------------+----------------+----------------+
| port ...
+----------------+----------------+----------------+----------------+
| rem_addr ...
+----------------+----------------+----------------+----------------+
| data...
+----------------+----------------+----------------+----------------+

各字段解释如下:

  • action : 具体的认证动作。

    1
    2
    3
    TAC_PLUS_AUTHEN_LOGIN := 0x01
    TAC_PLUS_AUTHEN_CHPASS := 0x02
    TAC_PLUS_AUTHEN_SENDAUTH := 0x04
  • priv_lvl: 用户的权限级别。

  • authen_type: 认证的类型。

    1
    2
    3
    4
    5
    TAC_PLUS_AUTHEN_TYPE_ASCII := 0x01
    TAC_PLUS_AUTHEN_TYPE_PAP := 0x02
    TAC_PLUS_AUTHEN_TYPE_CHAP := 0x03
    TAC_PLUS_AUTHEN_TYPE_MSCHAP := 0x05
    TAC_PLUS_AUTHEN_TYPE_MSCHAPV2 := 0x06
  • authen_service: 请求认证的服务类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #TAC_PLUS_AUTHEN_SVC_NONE选项用于该字段的授权应用程序,它表示设备没有执行任何认证。
    TAC_PLUS_AUTHEN_SVC_NONE := 0x00
    #TAC_PLUS_AUTHEN_SVC_LOGIN选项表示客户端设备的常规登录(而不是ENABLE。
    TAC_PLUS_AUTHEN_SVC_LOGIN := 0x01
    #TAC_PLUS_AUTHEN_SVC_ENABLE选项标识ENABLE authen_service,这是指请求身份验证以授予用户不同权限的服务。 这相当于Unix的“ su(1)”命令,该命令将当前用户的身份替换为另一个。 仅当其他authen_service值都不适合时,才使用authen_service值NONE。 可以单独请求启用,协议没有对先前的认证或授权提出要求。
    TAC_PLUS_AUTHEN_SVC_ENABLE := 0x02
    #其他选项还包括了legacy/backwards兼容性。
    TAC_PLUS_AUTHEN_SVC_PPP := 0x03
    TAC_PLUS_AUTHEN_SVC_PT := 0x05
    TAC_PLUS_AUTHEN_SVC_RCMD := 0x06
    TAC_PLUS_AUTHEN_SVC_X25 := 0x07
    TAC_PLUS_AUTHEN_SVC_NASI := 0x08
    TAC_PLUS_AUTHEN_SVC_FWPROXY := 0x09
  • user, user_len: 用户名在此数据包中是可选的,具体取决于认证方式。如果不存在,则客户端必须将user_len设置为0。如果存在用户名,user_len以字节表示user字段的长度。

  • port, port_len: 请求认证的用户接口名,最大长度为47。对于管理员用户,该字段是指用户终端接口(例如“console0”、“vty1”等)。例如,Telnet用户的authen_type为ASCII,service为LOGIN,port为vtyx。对于其他用户,该字段是指用户接入的接口名称。

    这个字段的值是自由格式的文本,并且是特定于客户端的。这个参数的示例包括表示第10个tty行的“tty10”和表示第10个异步接口的“async10”。客户文档应该定义该字段的值及其含义。

    port_len表示端口字段的长度,以字节为单位。

  • rem_addr, rem_addr_len :登录用户的IP地址。 rem_addr字段的长度.字节为单位。

    当TACACS+用于拨号(dial-up)服务时,该值包含调用者ID。

    当TACACS+用于设备管理时,用户通常通过网络连接,在这种情况下,该值用于保存网络地址,IPv4或IPv6。

    此字段是可选的(因为信息可能不可用)。

  • data, data_len: 认证数据区,根据action和authen_type的不同封装不同的数据。例如PAP认证时,该字段内容为PAP显示密码。

    data_len,以字节表示认证数据区的长度。

The Authentication REPLY Packet Body, 认证回应报文:

TACACS+服务器只向客户端发送一种类型的认证包(REPLY包)。

1
2
3
4
5
6
7
8
1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8
+----------------+----------------+----------------+----------------+
| status | flags | server_msg_len |
+----------------+----------------+----------------+----------------+
| data_len | server_msg ...
+----------------+----------------+----------------+----------------+
| data ...
+----------------+----------------+

各字段信息解释如下:

  • status : 认证的状态

    1
    2
    3
    4
    5
    6
    7
    8
    TAC_PLUS_AUTHEN_STATUS_PASS := 0x01 #认证成功PASS(0x01)
    TAC_PLUS_AUTHEN_STATUS_FAIL := 0x02 #认证失败FAIL(0x02
    TAC_PLUS_AUTHEN_STATUS_GETDATA := 0x03#请求用户信息GETDATA(0x03
    TAC_PLUS_AUTHEN_STATUS_GETUSER := 0x04 #请求用户名GETUSER(0x04
    TAC_PLUS_AUTHEN_STATUS_GETPASS := 0x05 #请求密码GETPASS(0x05
    TAC_PLUS_AUTHEN_STATUS_RESTART := 0x06 #请求重新发起认证开始RESTART(0x06
    TAC_PLUS_AUTHEN_STATUS_ERROR := 0x07 #服务器收到认证报文有误ERROR(0x07
    TAC_PLUS_AUTHEN_STATUS_FOLLOW := 0x21 #服务器要求重新进行认证过程FOLLOW(0x21
  • flags: 位图标志,用于修改要执行的操作。

    1
    2
    #控制客户端是否将用户输入的密码回显。如果该标志位置1,则用户输入的密码不会回显。
    TAC_PLUS_REPLY_FLAG_NOECHO := 0x01
  • server_msg, server_msg_len : 要显示给用户的消息。该字段是可选的。server_msg_len表示server_msg字段的长度,以字节为单位。

  • data, data_len : 认证数据区,用于向客户端提供一些信息。此字段保存身份验证交换的一部分数据,用于客户端处理,而不是用户。它不是一种可打印的文本编码。

    data_len表示数据字段的长度,以字节为单位。

The Authentication CONTIUNE Packet Body,认证持续报文中:

在收到服务器的应答包后,此报文从客户机发送到服务器。

1
2
3
4
5
6
7
8
1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8
+----------------+----------------+----------------+----------------+
| user_msg len | data_len |
+----------------+----------------+----------------+----------------+
| flags | user_msg ...
+----------------+----------------+----------------+----------------+
| data ...
+----------------+

各字段解释如下:

  • user_msg, user_msg_len :

    登录用户输入的字符串,用于回应认证回应报文中的server_msg字段,向服务器提供用户登录时输入的密码。

    user_len表示用户字段的长度,以字节为单位。

  • data, data_len: 认证数据区,根据action和authen_type的不同封装不同的数据。例如PAP认证时,该字段内容为PAP显示密码。它不是一种可打印的文本编码。data_len表示数据字段的长度,以字节为单位。

  • flags: 认证持续标记,0表示认证过程持续,1表示认证过程终止。

    1
    TAC_PLUS_CONTINUE_FLAG_ABORT := 0x01

认证过程:

The action、authen_type和authen_service字段(如上所述)组合起来表示要执行的认证类型。每个认证START, REPLY and CONTIUNE都包含一个数据字段。该字段的使用取决于认证的类型。

本文档定义了TACACS+支持的一组核心认证流。每个认证流由一个START报文组成。服务器响应更多信息的请求(GETDATA、GETUSER或GETPASS)或终止PASS、FAIL、ERROR或RESTART。当服务器发送RESTART或ERROR时,操作和意义是常见的,下面将进一步描述。

当REPLY状态等于TAC_PLUS_AUTHEN_STATUS_GETDATA、TAC_PLUS_AUTHEN_STATUS_GETUSER或TAC_PLUS_AUTHEN_STATUS_GETPASS时,认证继续进行,服务器应该为客户端提供server_msg内容,以提示用户获取更多信息。然后客户端必须返回一个CONTINUE包,其中包含user_msg字段中所请求的信息。

客户端应该将TAC_PLUS_AUTHEN_STATUS_GETUSER解释为对用户名的请求,而将TAC_PLUS_AUTHEN_STATUS_GETPASS解释为对密码的请求。TAC_PLUS_AUTHEN_STATUS_GETDATA是获取更多信息的通用请求,以灵活地支持未来的需求。

如果服务器从客户端请求的信息是敏感的,则服务器应设置TAC_PLUS_REPLY_FLAG_NOECHO标志。 当客户端向用户查询信息时,在输入用户界面时,其响应绝不能反映在用户界面中。

数据字段仅在下面明确定义的REPLY中使用。

Version Behavior,版本行为:

TACACS +协议经过版本控制,可以在保持向后兼容性的同时进行修订。 版本号在每个数据包头中。 minor_version 0和1之间的更改仅适用于认证过程,并且全部处理CHAP和PAP认证的处理方式。 minor_version 1仅可用于下表中明确要求它的身份验证类型:

1
2
3
4
5
             LOGIN    CHPASS   SENDAUTH
ASCII v0 v0 -
PAP v1 - v1
CHAP v1 - v1
MS-CHAPv1/2 v1 - v1
  • “-”符号表示该选项无效。
  • 所有授权和计费以及ASCII认证都使用minor_version数字0。
  • PAP、CHAP和MS-CHAP登录使用minor_version 1。通常的交换是来自客户端的单个START包和来自服务器的单个REPLY。
  • SENDPASS的删除是出于安全考虑,不再被认为是TACACS+协议的一部分。

通用认证流程:

本节描述常见的认证流程。如果服务器没有实现某个选项,则必须使用
TAC_PLUS_AUTHEN_STATUS_FAIL。

1. ASCII Login:

1
2
3
action = TAC_PLUS_AUTHEN_LOGIN
authen_type = TAC_PLUS_AUTHEN_TYPE_ASCII
minor_version = 0x0

这是标准的ASCII认证。START包可能包含用户名。如果用户不包含用户名,那么服务器必须通过一个CONTINUE包的TAC_PLUS_AUTHEN_STATUS_GETUSER从客户端获取它。如果用户没有提供用户名,那么服务器可以发送另一个TAC_PLUS_AUTHEN_STATUS_GETUSER请求,但是服务器必须限制允许的重试次数,建议限制为三次。当服务器获得用户名时,它将使用带有TAC_PLUS_AUTHEN_STATUS_GETPASS的CONTINUE获得密码。ASCII登录使用user_msg字段作为用户名和密码。START和CONTINUE包中的数据字段都不用于ASCII登录,任何内容都必须被忽略。该会话由一个单独的START,接着是零个或更多对REPLYs,然后CONTINUEs,最后是一个是表示PASS、FAIL或ERROR的回复。

2. PAP Login:

1
2
3
action = TAC_PLUS_AUTHEN_LOGIN
authen_type = TAC_PLUS_AUTHEN_TYPE_PAP
minor_version = 0x1

整个交换必须由单个START包和单个REPLY组成。START包必须包含用户名,data字段必须包含PAP ASCII密码。PAP认证只包含用户名和密码RFC1334 。来自服务器的REPLY必须是“PASS”、“FAIL”或“ERROR”。

3. CHAP login:

1
2
3
action = TAC_PLUS_AUTHEN_LOGIN
authen_type = TAC_PLUS_AUTHEN_TYPE_CHAP
minor_version = 0x1

整个交换必须由单个STAET和单个REPLY组成。STAET包必须在user字段中包含用户名,而data字段是PPP id、challenge(挑战值)和response的连接。

挑战值的长度可以由da ta字段的长度减去id的长度(总是1个八位元)和response字段的长度(总是16个八位元)来确定。

为了执行认证,服务器计算在PPP认证RFC1334中定义的PPP哈希值,然后将该值与response进行比较。始终使用MD5算法选项。来自服务器的应答必须是“PASS”、“FAIL”或“ERROR”。

挑战的选择和长度不是TACACS+协议的一个方面。但是,强烈建议将客户端/端站交互配置为安全挑战。当验证的挑战小于最小长度(建议最小长度为8字节)时,TACACS+服务器可以通过拒绝验证来提供帮助。

4. MS-CHAP v1 login:

1
2
3
action = TAC_PLUS_AUTHEN_LOGIN
authen_type = TAC_PLUS_AUTHEN_TYPE_MSCHAP
minor_version = 0x1

整个交换必须由单个STAET和单个REPLY组成。START包必须在user字段中包含用户名,data字段将是一个连接的PPP id、MS-CHAP challenge和MS-CHAP response。

挑战值的长度可以由data字段的长度减去id的长度(总是1个八位字节)和响应字段的长度(总是49个八位字节)来确定。

要执行认证,服务器将对用户的secret和challenge使用MD4和DES的组合,如RFC2433 [RFC2433]中定义的那样,然后将结果值与响应进行比较。来自服务器的应答必须PASS或者FAIL。有关最佳实践,请参阅RFC2433 [RFC2433]。当验证请求偏离RFC中定义的8字节时,TACACS+服务器必须拒绝验证。

5. MS-CHAP v2 login:

1
2
3
action = TAC_PLUS_AUTHEN_LOGIN
authen_type = TAC_PLUS_AUTHEN_TYPE_MSCHAPV2
minor_version = 0x1

整个交换必须由单个STAET和单个REPLY组成。START包必须在user字段中包含用户名,data字段将是一个连接的PPP id、MS-CHAP challenge和MS-CHAP response。

挑战值的长度可以由data字段的长度减去id的长度(总是1个八位字节)和响应字段的长度(总是49个八位字节)来确定。

为了执行认证,服务器将对用户的secret和challenge使用指定的算法RFC2759 [RFC2759],然后将结果值与响应进行比较。来自服务器的应答必须PASS或FAIL。关于MS-CHAP v2的最佳实践,请参考RFC2759 [RFC2759]。当验证请求偏离RFC中定义的16字节时,TACACS+服务器必须拒绝验证。

6. Enable Requests:

1
2
3
4
action = TAC_PLUS_AUTHEN_LOGIN
priv_lvl = implementation dependent
authen_type = not used
service = TAC_PLUS_AUTHEN_SVC_ENABLE

这是一个ENABLE请求,用于更改用户当前运行的特权级别。当服务器收集它需要的信息以允许更改主体的特权级别时,交换可能包含多个消息。这种交换非常类似于ASCII登录。

为了方便地将enable请求与其他类型的请求区分开来,在请求enable时,必须将authen_service字段的值设置为TAC_PLUS_AUTHEN_SVC_ENABLE。在请求任何其他操作时,不能将其设置为此值。

7. ASCII change passwrod requests:

1
2
action = TAC_PLUS_AUTHEN_CHPASS
authen_type = TAC_PLUS_AUTHEN_TYPE_ASCII

此交换由多个消息组成,同时服务器收集更改用户密码所需的信息。它非常类似于ASCII登录。状态值TAC_PLUS_AUTHEN_STATUS_GETPASS只能在请求“新”密码时使用。它可能被发送多次。请求“旧”密码时,状态值必须设置为TAC_PLUS_AUTHEN_STATUS_GETDATA。

终止一个认证会话:

客户端可以通过在CONTIUNE消息中设置TAC_PLUS_CONTINUE_FLAG_ABORT标志来提前终止会话。如果设置了此标志,则消息的data部分可能包含解释中止原因的消息。这些信息将由服务器根据部署的需求进行处理。

在PASS、FAIL或ERROR的情况下,服务器可以在server_msg中插入一条消息显示给用户。

草案定义了一种机制,可以将认证请求直接发送到另一台服务器。这种机制被认为是不安全的,不推荐使用,这里不讨论。客户端应该将TAC_PLUS_AUTHEN_STATUS_FOLLOW处理为TAC_PLUS_AUTHEN_STATUS_FAIL。

如果状态等于TAC_PLUS_AUTHEN_STATUS_ERROR,那么主机表示它遇到了一个不可恢复的错误,认证将继续进行,就像无法联系到该主机一样。data字段可能包含要在管理控制台或日志中打印的消息。

如果状态等于TAC_PLUS_AUTHEN_STATUS_RESTART,那么认证将使用来自客户机的新的STAET包(具有新的Session_Id)重新启动,并将seq_no设置为1。这个REPLY包表明当前的authen_type值(在开始包中指定)对于这个会话是不可接受的。客户端可以尝试另一种authen_type。

如果客户机没有实现TAC_PLUS_AUTHEN_STATUS_RESTART选项,那么它必须处理响应,就像状态为TAC_PLUS_AUTHEN_STATUS_FAIL一样。

Authorization,授权

在TACACS+协议中,授权是决定允许用户做什么的操作。通常,认证先于授权,尽管客户端不一定必须使用用于授权的相同服务进行认证。授权请求可能表明用户没有经过认证(我们不知道他们是谁)。在这种情况下,由服务器根据其配置决定是否允许未经身份验证的用户使用相关服务。

授权不仅仅提供是或否的答案,它还可以为特定用户定制服务。授权的一种常见用法是,当用户首次登录设备以管理该设备时,提供shell会话。TACACS+服务器可能通过允许服务来响应请求,但是在登录shell上设置时间限制。

在TACACS+协议中,授权始终是一对消息:来自客户机的REQUEST和来自服务器的REPLY。

授权REQUEST消息包含一组固定的字段(指示用户是如何进行身份验证的)和一组可变的参数(描述请求授权的服务和选项)。

REPLY包含一组可变的响应参数(参数-值对),它们可以限制或修改客户端的操作。

The Authorization REQUEST Packet Body, 授权请求报文:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8
+----------------+----------------+----------------+----------------+
| authen_method | priv_lvl | authen_type | authen_service |
+----------------+----------------+----------------+----------------+
| user_len | port_len | rem_addr_len | arg_cnt |
+----------------+----------------+----------------+----------------+
| arg_1_len | arg_2_len | ... | arg_N_len |
+----------------+----------------+----------------+----------------+
| user ...
+----------------+----------------+----------------+----------------+
| port ...
+----------------+----------------+----------------+----------------+
| rem_addr ...
+----------------+----------------+----------------+----------------+
| arg_1 ...
+----------------+----------------+----------------+----------------+
| arg_2 ...
+----------------+----------------+----------------+----------------+
| ...
+----------------+----------------+----------------+----------------+
| arg_N ...
+----------------+----------------+----------------+----------------+

各字段解释如下:

  • authen_method : 该字段允许客户端指定获取用户信息所使用的认证方式。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    TAC_PLUS_AUTHEN_METH_NOT_SET := 0x00 #没有设置认证方式
    TAC_PLUS_AUTHEN_METH_NONE := 0x01 #不认证
    TAC_PLUS_AUTHEN_METH_KRB5 := 0x02 # KRB5认证
    TAC_PLUS_AUTHEN_METH_LINE := 0x03 # 固定密码认证
    TAC_PLUS_AUTHEN_METH_ENABLE := 0x04 # 通过认证来授予特权命令
    TAC_PLUS_AUTHEN_METH_LOCAL := 0x05 # 客户端本地认证
    TAC_PLUS_AUTHEN_METH_TACACSPLUS := 0x06 # Tacacs+服务器认证
    TAC_PLUS_AUTHEN_METH_GUEST := 0x08 # 访客认证
    TAC_PLUS_AUTHEN_METH_RADIUS := 0x10 # Radius服务器认证
    TAC_PLUS_AUTHEN_METH_KRB4 := 0x11 # Kerberos 4认证
    TAC_PLUS_AUTHEN_METH_RCMD := 0x20

由于某些信息并不总是需要验证,因此建议将这一部分进行评估。LINE是指用于获得访问的终端线路相关联的固定密码。LOCAL是一个客户端本地用户数据库。ENABLE是通过认证来授予新特权的命令。当然,TACACSPLUS就是TACACS+。GUEST是访客认证。RADIUS是RADIUS认证协议。RCMD指的是通过Berkeley Unix的R-command协议提供的身份验证。KRB5和KRB4是Kerberos版本5和4。

如上所述,客户端使用此字段表明如何去进行认证。其中一个选项(TAC_PLUS_AUTHEN_METH_TACACSPLUS: = 0 x06) TACACS +本身,所以客户端如何执行的这个选项的细节在身份验证部分。对于所有其他选项,如KRB和RADIUS, TACACS +协议在认证阶段没有发挥任何作用;因为这些交互不是使用TACACS+协议进行的,所以这里不会对它们进行记录。对于需要其他协议细节的客户端实现者,请参考各自的Kerberos [RFC4120]和RADIUS [RFC3579] rfc。

  • priv_lvl : 此字段的使用方式与认证请求中的priv_lvl字段相同,它表示用户当前的特权级别。

  • authen_type : 这个字段对应于上面的认证部分中的authen_type字段。它指示所执行的身份验证类型。如果此信息不可用,那么客户端将把authen_type设置为:TAC_PLUS_AUTHEN_TYPE_NOT_SET:= 0x00。此值仅在授权和计费请求中有效。

  • authen_service: 认证服务类型。

  • arg_cnt : 授权请求报文中携带的属性数。

  • arg_1 … argN : 指定授权请求报文的属性。

    属性是授权交互的主要元素。在请求包中,它们描述被请求的授权的细节。每个属性在包中被编码为一个arg字段(arg_1…arg_N),并带有相应的长度字段(以字节为单位表示每个参数的长度)。

    REQUEST和REPLY中的授权属性都是(属性-值)对。属性和值在一个字符串中,用”=” (0X3D)或”*” (0X2A)分隔。等号表示一个强制参数。星号表示可选

    属性名称不能包含这两个分隔符。属性值可以包含分隔符。这意味着必须解析属性,直到遇到第一个分隔符,属性中在这个分隔符之后的所有字符都被解释为属性值。

    可选属性是客户端或服务器都可以忽略的属性。强制属性要求接收方能够处理该属性,即:它的实现和配置包括如何对其进行操作的细节。如果客户端接收到无法处理的强制属性,则必须认为授权失败。属性-值对的值部分可以为空,也就是说:值的长度可以为零。

    属性-值字符串不是NULL终止的,而是它们的长度值表示它们的结束。属性数值字符串的最大长度为255个字符。最小值是两个字符(one name- value character and the separator)。

    尽管属性允许可扩展性,但客户端和服务器应该支持一组通用的核心授权属性,这些在下面的授权属性部分中列出。

The Authorization REPLY Packet Body, 授权回应报文:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8
+----------------+----------------+----------------+----------------+
| status | arg_cnt | server_msg len |
+----------------+----------------+----------------+----------------+
+ data_len | arg_1_len | arg_2_len |
+----------------+----------------+----------------+----------------+
| ... | arg_N_len | server_msg ...
+----------------+----------------+----------------+----------------+
| data ...
+----------------+----------------+----------------+----------------+
| arg_1 ...
+----------------+----------------+----------------+----------------+
| arg_2 ...
+----------------+----------------+----------------+----------------+
| ...
+----------------+----------------+----------------+----------------+
| arg_N ...
+----------------+----------------+----------------+----------------+

各字段解释如下:

  • status : 指定用户的授权状态,包括:

    1
    2
    3
    4
    5
    TAC_PLUS_AUTHOR_STATUS_PASS_ADD := 0x01 #授权通过
    TAC_PLUS_AUTHOR_STATUS_PASS_REPL := 0x02 #授权请求报文中的属性被TACACS服务器修改
    TAC_PLUS_AUTHOR_STATUS_FAIL := 0x10 #授权失败
    TAC_PLUS_AUTHOR_STATUS_ERROR := 0x11 #授权服务器上出现了错误
    TAC_PLUS_AUTHOR_STATUS_FOLLOW := 0x21 #重新指定授权服务器
  • arg_cnt: 授权回应报文中携带的授权属性数。

  • argN : 这些属性描述了所请求的授权的细节。

如果status等于TAC_PLUS_AUTHOR_STATUS_FAIL,则必须拒绝请求的授权。

如果status等于TAC_PLUS_AUTHOR_STATUS_PASS_ADD,则REQUEST中指定的属性得到授权,REPLY中的属性必须根据上述规则回应。

如果status等于TAC_PLUS_AUTHOR_STATUS_PASS_REPL,那么客户端必须在回应中使用授权属性-值对(如果有的话),而不是使用请求中的授权属性-值对。

为了批准授权而不进行任何修改,服务器将status设置为TAC_PLUS_AUTHOR_STATUS_PASS_ADD,将arg_cnt设置为0。

Status为TAC_PLUS_AUTHOR_STATUS_ERROR表示服务器上发生了ERROR。如果设置了ERROR,所有的arg值都没有任何相关性,必须忽略。

当状态等于TAC_PLUS_AUTHOR_STATUS_FOLLOW时,则arg_cnt必须为0。在这种情况下,要采取的action和data字段的内容与用于认证的TAC_PLUS_AUTHEN_STATUS_FOLLOW状态相同。

Accounting,计费

计费通常是认证和授权之后的第三个操作。但是,同样,不需要认证或授权。计费是记录用户正在做什么和/或已经做了什么的行为。TACACS+中的计费有两个用途:它可以用作安全服务的审计工具。它还可以用于计算所使用的服务,例如在计费环境中。为此,TACACS+支持三种类型的计费记录。启动记录表明服务即将开始。停止记录表示服务刚刚终止,而更新记录是中间通知,表示服务仍在执行中。TACACS+计费记录包含授权记录中使用的所有信息,还包含特定于计费的信息,如启动和停止时间(适当时)和资源使用信息。计费部分定义了计费属性列表。

The Account REQUEST Packet Body, 计费请求报文:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8
+----------------+----------------+----------------+----------------+
| flags | authen_method | priv_lvl | authen_type |
+----------------+----------------+----------------+----------------+
| authen_service | user_len | port_len | rem_addr_len |
+----------------+----------------+----------------+----------------+
| arg_cnt | arg_1_len | arg_2_len | ... |
+----------------+----------------+----------------+----------------+
| arg_N_len | user ...
+----------------+----------------+----------------+----------------+
| port ...
+----------------+----------------+----------------+----------------+
| rem_addr ...
+----------------+----------------+----------------+----------------+
| arg_1 ...
+----------------+----------------+----------------+----------------+
| arg_2 ...
+----------------+----------------+----------------+----------------+
| ...
+----------------+----------------+----------------+----------------+
| arg_N ...
+----------------+----------------+----------------+----------------+

各字段解释如下:

  • flags: 计费类型。

    1
    2
    3
    TAC_PLUS_ACCT_FLAG_START := 0x02 #开始计费
    TAC_PLUS_ACCT_FLAG_STOP := 0x04 #结束计费
    TAC_PLUS_ACCT_FLAG_WATCHDOG := 0x08 #实时计费

所有其他字段都在上面的授权和认证部分中定义,具有相同的语义。

The Accounting REPLY Packet Body, 请求回应报文:

计费的目的是记录在客户身上发生的操作。服务器必须仅在计费请求后才成功答复。 如果服务器没有记录计费请求,则它必须以ERROR答复。

1
2
3
4
5
6
7
8
1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8  1 2 3 4 5 6 7 8
+----------------+----------------+----------------+----------------+
| server_msg len | data_len |
+----------------+----------------+----------------+----------------+
| status | server_msg ...
+----------------+----------------+----------------+----------------+
| data ...
+----------------+

字段解释:

  • Status: 指定计费状态:

    1
    2
    3
    TAC_PLUS_ACCT_STATUS_SUCCESS := 0x01 # 计费成功
    TAC_PLUS_ACCT_STATUS_ERROR := 0x02 # 计费失败
    TAC_PLUS_ACCT_STATUS_FOLLOW := 0x21 # 重新进行计费过程

当status等于TAC_PLUS_ACCT_STATUS_FOLLOW时,要采取的action和data字段的内容与用于认证的TAC_PLUS_AUTHEN_STATUS_FOLLOW状态相同,请求重新计费过程。

TACACS+计费用于记录客户端上的各种类型的事件,例如:登录会话、命令输入,以及客户端实现所需的其他事件。这些事件在草案中统称为“任务”。

TAC_PLUS_ACCT_FLAG_START标志表示这是一个开始计费消息。START消息只在任务启动时发送一次。TAC_PLUS_ACCT_FLAG_STOP表示这是一个停止记录,并且任务已经终止。TAC_PLUS_ACCT_FLAG_WATCHDOG标志表示这是一条更新记录。

计费报文汇总:

1
2
3
4
5
6
7
8
9
10
11
12
+----------+-------+-------+-------------+-------------------------+
| Watchdog | Stop | Start | Flags & 0xE | Meaning |
+----------+-------+-------+-------------+-------------------------+
| 0 | 0 | 0 | 0 | INVALID |
| 0 | 0 | 1 | 2 | Start Accounting Record |
| 0 | 1 | 0 | 4 | Stop Accounting Record |
| 0 | 1 | 1 | 6 | INVALID |
| 1 | 0 | 0 | 8 | Watchdog, no update |
| 1 | 0 | 1 | A | Watchdog, with update |
| 1 | 1 | 0 | C | INVALID |
| 1 | 1 | 1 | E | INVALID |
+----------+-------+-------+-------------+-------------------------+

START和STOP标志是互斥的。

客户端使用WATCHDOG标志来表示通信长时间运行的任务的当前状态。更新记录由客户自行决定发送。更新的频率取决于预期的应用程序: 提供进度指示的watchdog需要比daily keep-alive频率更高。当WATCHDOG标志与START标志一起设置时,它指示更新记录提供来自原始开始记录的附加或更新的属性。如果没有设置START标志,那么这只表明该任务仍在运行,并且没有提供任何新信息(服务器必须忽略任何属性)。STOP标志不能与WATCHDOG标志同时设置。

如果客户端请求一个无效(INVLID)的选项,服务器必须用TAC_PLUS_ACCT_STATUS_ERROR响应。

Argument-Value Pairs,属性-值对

TACACS+是一个可扩展的协议。在授权和计费中使用的属性不受本文件的限制。下面为常见用例定义了一些属性,客户端在支持相应的用例时必须使用这些属性。

Value Encoding,值编码

所有属性值都被编码为字符串。应该遵循以下类型表示:

  • Numeric(数字): 除非另有说明,否则属性-值字符串中的所有数值都是十进制数字。所有属性都包含一个长度字段,而TACACS+实现在尝试处理数值属性之前必须验证它们能够适应它们的长度。如果不能调整长度,则必须将属性视为未处理,并且必须使用授权中有关参数处理的逻辑。
  • Boolean(布尔值):所有布尔值都用值“true”或“false”编码。
  • IP-Address(IP地址):为了避免歧义,建议主机指定为IP地址。IPv4地址被指定为由点(‘.’)分隔的8位数字,IPv6地址文本表示在RFC5952 [RFC5952]中定义。
  • Date Time(日期时间):日期/时间的绝对日期/时间是从1970年1月1日12点开始指定的秒数。时区必须是UTC,除非指定了时区参数。
  • String(字符串):许多值没有特定的类型表示,它们被解释为纯字符串。
  • Empty Values( 空值):空值属性可以不带值提交,在这种情况下,它们由名称和强制或可选分隔符组成。例如,没有值的参数”cmd”被传输为四个字符的字符串”cmd=”。

Authorization Arugments,授权属性:

  • service (String) :

    主要的服务。指定服务属性表明这是对该服务的授权或计费请求。例如:“shell”,“tty-server”,“connection”,“system”和“firewall”,其他的应用程序可以选择。必须始终包含此参数。

  • protocol (String):协议字段可用于表示服务的一个子集。

  • cmd (String): shell (exec) command。这表示要运行的命令的command name。如果service = “shell”,则必须指定”cmd”参数。

    shell命令的授权是TACACS+协议的常见用例。命令授权通常采用两种形式之一: (sessioin-based)基于会话的和(command-based)基于命令的:

    • 对于基于会话的shell授权,“cmd”属性将具有一个空值。客户端根据授权中的属性确定会话中允许哪些命令。
    • 在基于命令的授权中,客户机请求服务器通过对每个命令发出授权请求来确定是否允许某个命令。“cmd”参数将以命令名作为其值。
  • cmd-arg (String): shell (exec)命令的参数。这表示要运行的shell命令的参数。可以指定多个cmd-arg参数,它们是依赖于顺序的。

  • acl (Numeric) : 表示连接访问列表的数字。仅适用于基于会话的shell授权。

  • inacl (String) : 接口输入访问列表的标识符(name)。

  • outacl (String): 接口输出访问列表的标识符(名称)。

  • addr (IP-Address) : 网络地址。

  • addr-pool (String) : 地址池的标识符,客户端可以从中分配地址。

  • timeout (Numeric) : 连接的绝对计时器(以分钟为单位)。值为零表示没有超时。

  • idletime (String) : 连接的空闲超时(以分钟为单位)。值为零表示没有超时。

  • autocmd (String) : 要运行的(auto-command)自动命令。仅适用于基于会话的shell授权。

  • noescape (Boolean): 阻止用户使用转义字符。仅适用于基于会话的shell授权。

  • nohangup (Boolean) : 不要在自动命令后断开连接。仅适用于基于会话的shell授权。

  • priv-lvl (Numeric) : 要分配的特权级别(privilege level)。

Accounting Arguments, 计费属性:

以下参数仅为TACACS+计费定义。它们必须位于上面授权部分中定义的任何属性-值对之前。

  • task_id (String) : 同一事件的启动和停止记录必须具有匹配的task_id 属性值。客户端必须确保活动的task_id不被复制:客户端在发送了task_id的停止记录之前,不能将task_id重用为开始记录。服务器绝对不能对task_id的格式做出假设。
  • start_time : (Date Time) : 操作的开始时间(自纪元以来的秒数)。
  • stop_time: (Date Time): 操着的结束时间。
  • elapsed_time (Numeric) : 操作的运行时间。
  • timezone (String) : 此包中包含的所有时间戳的时区缩写。这里维护一个时区数据库:TZDB
  • event (String) : 仅在“service=system”时使用。当前值是“net_acct”、“cmd_acct”、“conn_acct”、“shell_acct”、“sys_acct”和“clock_change”。这些表示系统级别的更改。flags字段应表明服务是已启动还是已停止。
  • reason (String) : 伴随事件的属性,它描述了事件发生的原因。
  • bytes (Numeric) : 此操作传输的字节数
  • bytes_in (Numeric) : 从服务器到客户端这个操作传输的字节数。
  • bytes_out (Numeric) : 从客户端到服务器这个操作传输的字节数。
  • paks (Numeric) :此操作传输的数据包数目。
  • paks_in (Numeric) : 从服务器到客户端这个操作传输的包数量。
  • paks_out (Numeric) : 从客户端到服务器这个操作传输的包数据。
  • err_msg (String) : 关于这个操作的status描述。

Privilege Levels, 权限级别

TACACS+协议通过可扩展属性支持灵活的授权模式。有一种方案被内置于协议中,并广泛用于基于会话的shell授权: Privilege Levels 。权限级别是从0到15的有序值,每个级别都是下一个较低值的超集。客户端的配置和实现将操作(例如执行特定命令的权限)映射到不同的权限级别。 将命令分配给特权级别在很大程度上取决于部署。 。常见分配如下:

1
2
3
4
5
6
7
8
# 通常分配给未经认证的会话。
TAC_PLUS_PRIV_LVL_MIN := 0x00.
# 通常分配给经过认证的常规会话的级别
TAC_PLUS_PRIV_LVL_USER := 0x01.
# 通常分配给由高特权用户认证的会话的级别,以允许对系统有重大影响的命令。
TAC_PLUS_PRIV_LVL_ROOT := 0x0f.
# 最高权限级别
TAC_PLUS_PRIV_LVL_MAX := 0x0f.

权限级别可以在启动时分配给Shell(EXEC)会话。 客户端将允许执行与此级别关联的动作。 服务器在基于会话的shell授权中返回此特权级别(当“service”等于“shell”且“ cmd”为空时)。 当用户需要执行映射到更高权限级别的操作时,客户端可以启动ENABLE类型的重新认证。 客户端会将所需的权限级别插入到认证报文头中,以启用认证请求。

客户端不是必须使用权限级别来确定基于会话的命令和资源访问。 尽管权限级别方案得到了广泛的支持,但它在要求单个单调的权限层次结构方面缺乏灵活性,这意味着其他session-based的命令授权方案已经发展。 但是,它仍然很常见,服务器应该支持它。

用户级别 命令级别 说明
0 参观级(0) 网络诊断工具命令(ping、tracert)、从本设备出发访问外部设备的命令(Telnet客户端)、部分display命令等。
1 参观级(0)、监控级(1) 用于系统维护,包括display等命令。说明:并不是所有display命令都是监控级,比如display current-configuration命令和display saved-configuration命令是3级管理级。
2 参观级(0)、监控级(1)、配置级(2) 业务配置命令,包括路由、各个网络层次的命令,向用户提供直接网络服务。
3 参观级(0)、监控级(1)、配置级(2)、管理级(3) 用于系统基本运行的命令,对业务提供支撑作用,包括文件系统、FTP、TFTP下载、命令级别设置命令以及用于业务故障诊断的debugging命令等。

Security Considerations, 安全注意事项

1998年最初的TACACS +草案 [TheDraft]并未解决设计现代标准时考虑的所有关键安全问题。 本节解决了已知的局限性和担忧,这些局限性和担忧会影响该协议以及部署该协议以管理集中认证,授权或网络设备管理计费的系统的整体安全性。 最初的TACACS +“草案” [TheDraft]中描述的协议的多种实现已被部署。 由于该协议从未被标准化,因此当前的实现可能以非显而易见的方式不兼容,从而带来了额外的安全风险。 本部分并不要求枚举所有可能的安全漏洞。

General Security of the Protocol:

TACACS +协议不包含可以满足现代要求的安全机制。 这些安全机制最好被称为“obfuscation,混淆”,而不是“encryption,加密”,因为它们没有提供有意义的完整性,隐私或重放保护。 应该假定具有访问数据流的攻击者能够读取和修改所有TACACS +数据包。 如果不采取缓解措施,则可能会发生以下一系列风险:

  • 中间人攻击者可能会修改计费信息,从而使此类日志不适合也不可用于审计目的。
  • 中间人攻击者可能会在已知偏移量的各个字段中插入无效或误导性的值,以试图绕过认证或授权检查,甚至在被混淆的内部也是如此。

虽然协议提供了某种程度的传输隐私,但它至少容易受到以下攻击:

  • 暴力破解利用提高MD5摘要计算效率。
  • 已知的明文攻击,可以降低暴力攻击的成本。
  • 选择纯文本攻击,可以降低暴力攻击的成本。
  • 没有向前保密(No forward secrecy)

尽管,据作者所知,这种加密方法没有经过严格的测试,但已有足够的信息表明,最好将其称为“obfuscation 混淆”,而不是“encryption 加密”。

由于这些原因,在其环境中部署TACACS+协议的用户必须限制对已知客户端的访问,并且必须控制整个传输路径的安全性。攻击者谁能猜出密钥或打破混淆将获得不受限制和不被发现的访问所有的TACACS+流量。确保像TACACS+这样的集中AAA系统部署在安全传输上,对于管理此类攻击的安全风险至关重要。

本节的下面部分只列举了会话特有的风险,这些风险是与完全混淆和缺乏完整性检查相关的一般风险之外的。

Security of Authentication Sessions, 认证会话的安全性:

认证会话应该通过安全的传输方式使用,因为中间人攻击可能会完全破坏它们。 即使CHAP(可能被认为可以抵抗密码拦截)也是不安全的,因为它不能保护用户名免受琐碎的中间人攻击。

本文档弃用了使用原始草案中包含的TAC_PLUS_AUTHEN_STATUS_FOLLOW选项的重定向机制。 作为此过程的一部分,新服务器的密钥已发送到客户端。 这种密钥的公开交换意味着一旦一个会话中断,就有可能利用该密钥来攻击与其他服务器的连接。 在现代部署中不得使用此机制。 绝对不能在安全部署之外使用它。

Security of Authorization Sessions,授权会话的安全性:

授权会话应该通过安全传输来使用,因为要成功地执行改变请求或响应中众所周知的明文的中间人攻击是很容易的。

例如,使用字段“ authen_method”。 在实际部署中,通常会授权通过设备本地串行端口(console控制台端口)接收到的所有命令,因为通常由于设备位于物理上安全的位置而被认为是安全的。 如果管理员将授权系统配置为允许用户在本地控制台上输入的所有命令来帮助进行故障排除,则这将使所有攻击者都可以访问所有命令,从而能够将“ authen_method”从TAC_PLUS_AUTHEN_METH_TACACSPLUS更改为TAC_PLUS_AUTHEN_METH_LINE 。 在这方面,协议本身提供的混淆不会有太大帮助,因为:

  • 缺乏完整性意味着有效载荷中的任何字节都可以更改,而无需任何一方检测到更改。
  • 已知的明文意味着攻击者可以确定地知道哪个八位位组是攻击的目标(在这种情况下,标头之后的第一个八位位组)。
  • 结合已知的明文,攻击者可以确定用于混淆原始八位位组的密码填充八位位组的值。

Security of Accounting Sessions, 计费会话的安全性:

计费会话应通过安全的传输方式使用。尽管计费会话不直接参与设备上的认证或授权操作,但是中间人攻击者可以执行以下任何操作:

  • 用新的有效数据或垃圾数据替换审计数据,这可能会使迷惑审计者或隐藏与其认证和/或授权攻击尝试有关的信息。
  • 尝试使用旨在使系统以非预期的方式运行的条目来破坏计费日志(包括TACACS+ server和任何其他管理计费条目的系统)。

    除了这些直接操作之外,不同的客户端实现还传递不同的计费数据保真度。 一些供应商将敏感数据(例如密码,加密密钥等)作为审计日志的一部分进行传递。 由于缺乏具有完善的向前保密性的强加密功能,将来可能会泄露此数据,从而导致安全事件。

TACACS+ Best Practices, TACACS+最佳实践:

关于上述安全问题的观察,网络管理员不能依赖于混淆的TACACS+协议。必须在安全部署中使用TACACS+: TACACS+必须部署在网络上,以确保通信的私密性和完整性,并且必须部署在与其他通信分离的网络上。如果不这样做,将影响整个网络安全。以下建议对如何应用该协议施加了限制。在最初的草案中没有施加这些限制。新的实现和当前实现的升级必须实现这些建议。厂商应该提供一些机制来帮助管理员实现这些最佳实践。

1. Shared Secrets, 共享密钥:

TACACS+服务器和客户端必须将共享密钥当作敏感数据来安全地管理,就像对其他敏感数据(如身份凭证信息)所期望的那样。服务器不能泄露敏感数据。例如:

  • TACACS+服务器不能在日志中公开共享密钥。

  • TACACS+服务器必须允许为每个客户端定义一个专用密钥。

  • TACACS+服务器管理系统必须提供一种机制来跟踪密钥的生命周期,并通知管理员定期更新它们。TACACS+服务器管理员应该定期更改密钥。

  • TACACS+服务器管理员应该总是为每个客户端定义一个密钥。
  • TACACS+服务器和客户端必须支持至少32个字符长的共享密钥。
  • TACACS+服务器必须支持为共享密钥定义最小复杂度的策略。
  • TACACS+客户端不允许在没有共享密钥或共享密钥小于16个字符的情况下配置服务器。
  • TACACS+服务器管理员应该配置最小16个字符长度的密钥。

2. Connections and Obfuscation, 连接与混淆:

TACACS+服务器必须允许定义单个客户端。服务器必须只接受来自这些已定义的已知客户端的网络连接尝试。

TACACS+服务器必须拒绝使用TAC_PLUS_UNENCRYPTED_FLAG设置的连接。服务器上必须为请求连接的客户端提供一个共享密钥设置。

如果在为客户端处理数据包时检测到无效的共享密钥,那么TACACS+服务器一定不能在该连接上接受任何新的会话。TACACS+服务器必须在完成之前在连接上使用有效共享密钥建立的任何会话上及时终止连接。

TACACS +客户端不能设置TAC_PLUS_UNENCRYPTED_FLAG。 必须以显式配置的方式来实现客户端,以启用TAC_PLUS_UNENCRYPTED_FLAG的使用,当客户端在生产中时,不得使用此选项。

当一个TACACS+客户端从服务器接收到以下响应时,

  • 从配置了共享密钥的服务器接收到响应数据包,但该数据包设置了TAC_PLUS_UNENCRYPTED_FLAG。
  • 从配置为不使用混淆处理的服务器接收到响应数据包,但该数据包未设置TAC_PLUS_UNENCRYPTED_FLAG。

然后,TACACS +客户端必须关闭TCP会话,并以与收到TAC_PLUS_AUTHEN_STATUS_FAIL(认证会话)或TAC_PLUS_AUTHOR_STATUS_FAIL(授权会话)相同的方式处理响应。

3. Authentication, 认证:

为了帮助TACACS +管理员选择较少的弱认证选项,TACACS +服务器必须允许管理员将服务器配置为仅接受(challenge/response)质询的挑战/响应选项(authen_type的TAC_PLUS_AUTHEN_TYPE_CHAP或TAC_PLUS_AUTHEN_TYPE_MSCHAP或TAC_PLUS_AUTHEN_TYPE_MSCHAPV2)。

TACACS +服务器管理员应启用上一段中提到的选项。由于identity/password系统的要求,在不可避免的情况下,TACACS +服务器部署应仅启用其他选项(例如TAC_PLUS_AUTHEN_TYPE_ASCII或TAC_PLUS_AUTHEN_TYPE_PAP)。

TACACS +服务器管理员不应允许将相同的凭据应用于基于质询的(TAC_PLUS_AUTHEN_TYPE_CHAP或TAC_PLUS_AUTHEN_TYPE_MSCHAP或TAC_PLUS_AUTHEN_TYPE_MSCHAPV2)和非基于质询的authen_type选项,因为后者的不安全性将损害前者的安全性。

出于安全方面的考虑,不应使用原始草案中提到的TAC_PLUS_AUTHEN_SENDAUTH和TAC_PLUS_AUTHEN_SENDPASS选项。 TACACS +服务器不应实现它们。如果必须实施它们,则服务器必须默认使用禁用的选项,并且必须警告管理员这些选项不安全。

4. Authorization, 授权:

授权和计费特性旨在提供可扩展性和灵活性。本文档中定义了一个基本字典,但是在部署中可以通过使用新的属性名称对其进行扩展。灵活性的代价是,管理员和实现者必须确保客户端和服务器之间共享的属性-值对具有一致的解释。接收到无法识别的强制属性的TACACS+客户端必须像接收到TAC_PLUS_AUTHOR_STATUS_FAIL一样评估服务器响应。

5. Redirection Mechanism, 重定向机制:

最初的草案描述了一个重定向机制(TAC_PLUS_AUTHEN_STATUS_FOLLOW)。这个特性很难保证安全。在服务器列表中发送密钥的选项是特别不安全的,因为它会泄露客户端共享的秘密。

TACACS+服务器必须弃用重定向机制。

如果实现了重定向机制,那么TACACS+服务器必须在默认情况下禁用它,并且必须警告TACACS+服务器管理员,由于暴露共享机密的风险,只能在安全部署中启用它。TACACS+客户端应该通过将TAC_PLUS_AUTHEN_STATUS_FOLLOW处理为TAC_PLUS_AUTHEN_STATUS_FAIL来反对该特性。

Tacacs+总结

Tacacs+主要用来部署在服务器上,对网络设备进行统一的身份认证,授权,计费等。

报文类型总结:

3种认证报文:

  • 认证开始报文(Authentication Start)认证开始时,客户端向服务器发送认证开始报文,该报文中包括认证类型,同时可能包括用户名和一些认证数据。
  • 认证持续报文(Authentication Continue):客户端接收到服务器回应的认证回应报文后,如果确认认证过程没有结束,则使用认证持续报文响应
  • 认证回应报文(Authentication Reply):服务器接收到客户端发送的认证开始报文或认证持续报文后,向客户端发送的唯一一种认证报文,用于向客户端反馈当前认证的状态。

2种授权报文:

  • 授权请求报文(Authorization Request):TACACS的认证和授权是分离的,用户可以使用TACACS认证而使用其他协议进行授权。如果需要通过TACACS进行授权,则客户端向服务器发送授权请求报文,该报文中包括了授权所需的一切信息。
  • 授权回应报文(Authorization Response)服务器接收到授权请求报文后,向客户端发送授权回应报文,该报文中包括了授权的结果

2种计费报文:

  • 计费请求报文(Accounting Request):该报文中包括了计费所需的信息。
  • 计费回应报文:(Accounting Response):服务器接收并成功记录计费请求报文后,需要回应一个计费响应报文。

Tacacs报文交互流量:

以Telnet用户为例,说明使用Tacacs+对用户进行认证、授权和计费的过程。

tacacs

图Tacase报文交互流程图

在整个过程中的基本消息交互流程如下:

  1. Telnet用户请求登录设备。
  2. Tacacs+客户端收到请求之后,向Tacacs+服务器发送认证开始报文。
  3. Tacacs+服务器发送认证回应报文,请求用户名。
  4. Tacacs+客户端收到回应报文后,向用户询问用户名。
  5. 用户输入用户名。
  6. Tacacs+客户端收到用户名后,向Tacacs+服务器发送认证持续报文,其中包括了用户名。
  7. Tacacs+服务器发送认证回应报文,请求密码。
  8. Tacacs+客户端收到认证回应报文,向用户询问密码。
  9. 用户输入密码。
  10. Tacacs+客户端收到密码后,向Tacacs+服务器发送认证持续报文,其中包括了密码信息。
  11. Tacacs+服务器发送认证回应报文,指示用户通过认证。
  12. Tacacs+客户端向Tacacs+服务器发送授权请求报文。
  13. Tacacs+服务器发送授权回应报文,指示用户通过授权。
  14. Tacacs+客户端收到授权回应报文,向用户输出设备的配置界面。
  15. Tacacs+客户端向Tacacs+服务器发送计费开始请求报文。
  16. Tacacs+服务器发送计费开始回应报文,指示计费开始请求报文已经收到。
  17. 用户请求断开连接。
  18. Tacacs+客户端向Tacacs+服务器发送计费结束请求报文。
  19. Tacacs+服务器发送计费结束回应报文,指示计费结束请求报文已经收到。

Tacacs+协议与Radius协议的区别:

Tacacs+ RADIUS
通过TCP传输,网络传输更可靠。 通过UDP传输,网络传输效率更高。
除了标准的TACACS报文头,对报文主体全部进行加密。 只是对认证报文中的密码字段进行加密。
认证与授权分离,使得认证、授权服务可以在不同的安全服务器上实现。例如,可以用一台TACACS服务器进行认证,另外一台TACACS服务器进行授权。 认证与授权结合,难以分离。
支持对设备上的配置命令进行授权使用。即用户可使用的命令行受到命令级别和AAA授权的双重限制,某一级别的用户输入的每一条命令都需要通过TACACS服务器授权,如果授权通过,命令才可以被执行。 不支持对设备上的配置命令进行授权使用。用户登录设备后可以使用的命令行由用户级别决定,用户只能使用级别等于或低于用户级别的命令行。
适于进行安全控制。 适于进行计费。

其他文章:


参考资料:

https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-18

https://support.huawei.com/hedex/hdx.do?docid=EDOC1100101225&lang=zh&idPath=24030814%7C21782165%7C21782236%7C22318638%7C7542409

坚持原创技术分享,您的支持将鼓励我继续创作!