Python Tacacs故障诊断记录

背景:客户现场说我们的设备在3A鉴权时失败,没有认证成功
第一步,先看下我们log
在这里插入图片描述
没有明显的错误记录,貌似认证成功了但是确提示认证失败,有点迷
第二步,家里搭建和现场一致的环境,模拟登录发现是可以进行3A认证的,继续迷
第三步,对比差异,家里用的Cisco的3A进行验证的,客户使用的是一家国内品牌做的3A鉴权服务,那问题可能出现在这里
第四部,继续对比差异,将两者的鉴权结果进行对比
国内3A品牌
国内品牌
Cisco 3A
在这里插入图片描述
差异不大,就一个Flag差异,对方说该Flag没有含义,但是作为程序员的Tiger表示怀疑。。。。

看代码。
下面是我们的程序,看起来没啥问题直接调用的Python库进行验证,目前看来valid字段被置为False了

cli = TACACSClient( data_server.encode("ascii"),
					data_port,
					data_secret.encode("ascii"),
					timeout=10,
					family=socket.AF_INET)
authen = cli.authenticate(username.encode("ascii"), password.encode("ascii"))
if authen.valid:
    verified = True

我们的代码没啥问题,继续跟踪Python库的代码,查看authenticate是如何实现的

def authenticate(self, username, password, priv_lvl=TAC_PLUS_PRIV_LVL_MIN,
                     authen_type=TAC_PLUS_AUTHEN_TYPE_ASCII,
                     chap_ppp_id=None, chap_challenge=None,
                     rem_addr=TAC_PLUS_VIRTUAL_REM_ADDR, port=TAC_PLUS_VIRTUAL_PORT):
        """
        Authenticate to a TACACS+ server with a username and password.

        :param username:
        :param password:
        :param priv_lvl:
        :param authen_type:    TAC_PLUS_AUTHEN_TYPE_ASCII,
                               TAC_PLUS_AUTHEN_TYPE_PAP,
                               TAC_PLUS_AUTHEN_TYPE_CHAP
        :param chap_ppp_id:    PPP ID when authen_type == 'chap'
        :param chap_challenge: challenge value when authen_type == 'chap'
        :param rem_addr:       AAA request source, default to TAC_PLUS_VIRTUAL_REM_ADDR
        :param port:           AAA port, default to TAC_PLUS_VIRTUAL_PORT
        :return:               TACACSAuthenticationReply
        :raises:               socket.timeout, socket.error
        """
        start_data = six.b('')
        if authen_type in (TAC_PLUS_AUTHEN_TYPE_PAP,
                           TAC_PLUS_AUTHEN_TYPE_CHAP):
            self.version_min = TAC_PLUS_MINOR_VER_ONE

            if authen_type == TAC_PLUS_AUTHEN_TYPE_PAP:
                start_data = six.b(password)

            if authen_type == TAC_PLUS_AUTHEN_TYPE_CHAP:
                if not isinstance(chap_ppp_id, six.string_types):
                    raise ValueError('chap_ppp_id must be a string')
                if len(chap_ppp_id) != 1:
                    raise ValueError('chap_ppp_id must be a 1-byte string')
                if not isinstance(chap_challenge, six.string_types):
                    raise ValueError('chap_challenge must be a string')
                if len(chap_challenge) > 255:
                    raise ValueError('chap_challenge may not be more 255 bytes')
                start_data = (
                    six.b(chap_ppp_id) +
                    six.b(chap_challenge) +
                    md5(six.b(
                        chap_ppp_id + password + chap_challenge
                    )).digest()
                )
        with self.closing():
            packet = self.send(
                TACACSAuthenticationStart(username, authen_type, priv_lvl,
                                          start_data, rem_addr=rem_addr, port=port),
                TAC_PLUS_AUTHEN
            )
            reply = TACACSAuthenticationReply.unpacked(packet.body)
            logger.debug('\n'.join([
                reply.__class__.__name__,
                'recv header <%s>' % packet.header,
                'recv body <%s>' % reply
            ]))
            if authen_type == TAC_PLUS_AUTHEN_TYPE_ASCII and reply.getpass:
                packet = self.send(TACACSAuthenticationContinue(password),
                                   TAC_PLUS_AUTHEN,
                                   packet.seq_no + 1)
                reply = TACACSAuthenticationReply.unpacked(packet.body)
                logger.debug('\n'.join([
                    reply.__class__.__name__,
                    'recv header <%s>' % packet.header,
                    'recv body <%s>' % reply
                ]))
                if reply.flags == TAC_PLUS_CONTINUE_FLAG_ABORT:
                    reply.status = TAC_PLUS_AUTHEN_STATUS_FAIL

        return reply

解读代码,因为我们的代码是直接调用插件的,所以没有设置的值使用的是默认值
authen_type=TAC_PLUS_AUTHEN_TYPE_ASCII所以默认的授权类型是使用ASCII进行的,

 def authenticate(self, username, password, priv_lvl=TAC_PLUS_PRIV_LVL_MIN,
                     authen_type=TAC_PLUS_AUTHEN_TYPE_ASCII,
                     chap_ppp_id=None, chap_challenge=None,
                     rem_addr=TAC_PLUS_VIRTUAL_REM_ADDR, port=TAC_PLUS_VIRTUAL_PORT):

所以可以看的当我们使用ASCII进行验证的时候会有以下流程
Authentication Start:认证开始时,客户端发送START消息,START消息中包括认证类型,同时可能包括用户名和一些认证数据。
Authentication Reply:REPLY消息是TACACS+服务器向客户端发送的唯一一种Authentication 消息,用于向客户端反馈当前认证的状态。
Authentication Continue:客户端收到REPLY消息后,如果确认认证过程没有结束,使用CONTINUE消息应答。
user_msg字段用于回应REPLY消息中的server_msg字段,向服务器提供客户端或用户的一些信息
flags字段用于中断认证过程

这是标准的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的回复。

所以建议国内的厂商还是要多查看下协议,被认为没有用的flag字段其实是有用的,在
Authentication Continue的过程中可以用来阻断认证的,那么我们看下代码里面是否有呢

if authen_type == TAC_PLUS_AUTHEN_TYPE_ASCII and reply.getpass:
                packet = self.send(TACACSAuthenticationContinue(password),
                                   TAC_PLUS_AUTHEN,
                                   packet.seq_no + 1)
                reply = TACACSAuthenticationReply.unpacked(packet.body)
                logger.debug('\n'.join([
                    reply.__class__.__name__,
                    'recv header <%s>' % packet.header,
                    'recv body <%s>' % reply
                ]))
                if reply.flags == TAC_PLUS_CONTINUE_FLAG_ABORT:
                    reply.status = TAC_PLUS_AUTHEN_STATUS_FAIL

可以看到当TACACSAuthenticationContinue过程中如果响应的flag被置上的话status的值是为fail的
那么回过头看下valid是如何取值的呢
可以看的它是做了一次运算的,结果可以知道valid返回的是False,所以鉴权失败

@property
    def valid(self):
        return self.status == TAC_PLUS_AUTHEN_STATUS_PASS

解决方案:
第一步让厂商吧该字段置为0;
第二步我们自己的代码应该根据灵活性,在做验证时可以灵活选择鉴权方式;

#authen_type TAC_PLUS_AUTHEN_TYPE_ASCII,TAC_PLUS_AUTHEN_TYPE_PAP, TAC_PLUS_AUTHEN_TYPE_CHAP
authen = cli.authenticate(username.encode("ascii"), password.encode("ascii"),authen_type=authen_type)
if authen.valid:
     verified = True

Ok,故障诊断完毕,支持结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/229829.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《文存阅刊》期刊发表简介

《文存阅刊》以“深研文化创新&#xff0c;崇尚科学真理&#xff0c;坚持双百方针&#xff0c;打造学术精品”为办刊宗旨&#xff0c;涵盖艺术、文学、社科等多项内容&#xff0c;适应了文化市场需求&#xff0c;很好的回应了广大文化理论工作者的关切&#xff0c;为下一步打造…

cuda lib 线程安全的要义

1, 概述 cuda lib 线程安全的几个多线程的情景&#xff1a; 单卡多线程&#xff1b; 多卡多线程-每卡单线程&#xff1b; 多卡多线程-每卡多线程&#xff1b; 需要考虑的问题&#xff1a; 每个 cublasHandle_t 只能有一个stream么&#xff1f; 每个cusolverHandle_t 只能有一…

DTS认证

一、什么叫DTS DTS 是“Digital Theatre System“的缩写&#xff0c;是”数字化影院系统“的意思。是一种音频格式&#xff0c;从技术上讲&#xff0c;把音效数据存储到另外的CD-ROM中&#xff0c;使其与影像数据同步。这样不但空间得到增加&#xff0c;而且数据流量也可以相对…

如何运用gpt改写出高质量的文章 (1)

大家好&#xff0c;今天来聊聊如何运用gpt改写出高质量的文章 (1)&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff1a; 如何运用GPT改写出高质量的文章 一、引言 随着人工智能技术的飞速发展&#xff0c;自然…

HHDESK右键管理简介

在HHDESK管理文件&#xff0c;除了基本的打开、删除、复制、粘贴、重命名外&#xff0c;还有多种便捷编辑方式。 可以分别以下列模式打开文档&#xff1a; 文本模式即是以文本编辑器打开文档。 1 二进制模式 可进行二进制编辑。 2 JSON模式 可对JSON文件进行直观的解析…

b样条原理与测试

为了保留贝塞尔曲线的优点&#xff0c;同时克服贝塞尔曲线的缺点&#xff0c;b样条在贝塞尔曲线上发展而来&#xff0c;首先来看贝塞尔曲线的定义&#xff1a; 对于贝塞尔中的基函数而言&#xff0c;是确定的&#xff0c;全局唯一的&#xff0c;这导致了如果控制点发生变换将会…

软件测试--selenium安装使用

安装selenium不少人使用pip命令来安装selenium&#xff0c;辛辛苦苦安装完之后&#xff0c;还是不能使用。所以我们可以是直接使用编译器&#xff0c;pycharm直接安装selenium扩展包。 file中点击settings 在Settings中点击Project Interpreter,点击加号就可以安装各种需要的扩…

11.30BST理解,AVL树操作,定义;快速幂,二分求矩阵幂(未完)

完全二叉树结点的度可能有1&#xff0c;满二叉树的度只能为0或2 BST构建 BST是左孩子都比根节点小&#xff0c;右孩子都比根节点大 二叉搜索树的插入&#xff0c;删除&#xff0c;调整 平衡树理解 任何一个平衡二叉树&#xff0c;它的中序遍历都是一样的&#xff0c;都是有…

PRCD-1229 : An attempt to access configuration of database

今天维护oda一体机时&#xff0c;发现无法在grid用户下面关闭数据库实例&#xff0c;如下 ASM1:/home/gridoda0>srvctl stop database -d orcl -o immeidate PRCD-1229 : An attempt to access configuration of database orcl was rejected because its version 11.2.0.4.…

SpringBoot Seata 死锁问题排查

现象描述&#xff1a;Spring Boot项目&#xff0c;启动的时候卡住了&#xff0c;一直卡在那里不动&#xff0c;没有报错&#xff0c;也没有日志输出 但是&#xff0c;奇怪的是&#xff0c;本地可以正常启动 好吧&#xff0c;姑且先不深究为什么本地可以启动而部署到服务器上就无…

【代码随想录刷题】Day20 二叉树06

文章目录 1.【654】最大二叉树1.1 题目描述1.2 解题思路1.3 java代码实现1.4 总结 2.【617】合并二叉树2.1 题目描述2.2 解题思路2.3 java代码实现 3.【700】二叉搜索树中的搜索3.1 题目描述3.2 解题思路3.3 java代码实现 4.【98】验证二叉搜索树4.1 题目描述4.2 解题思路4.3 j…

卷积神经网络18种有效创新方法汇总,涵盖注意力机制、空间开发等7大方向

作为深度学习中非常重要的研究方向之一&#xff0c;卷积神经网络&#xff08;CNN&#xff09;的创新不仅表现在提升模型的性能上&#xff0c;还更进一步拓展了深度学习的应用范围。 具体来讲&#xff0c;CNN的创新架构和参数优化可以显著提高模型在各种任务上的性能。例如&…

如何跑AI模型—ultralytics

这里以跑 ultralytics 为示例&#xff0c;记录了如何从 0-1 跑个简单的模型&#xff0c;包括环境搭建。我的是 Window 系统&#xff0c;其他系统也类似。 主要流程是环境搭建&#xff0c;找个官网的 demo&#xff0c;收集好所需素材&#xff08;模型&#xff0c;图片等&#x…

Python入门第1篇

前言 很久之前就知道有python这个东西&#xff0c;当时也想的学学&#xff0c;不过一直没做行动派。 那时候就听说用python进行Excel数据分析处理、爬虫等很是厉害&#xff0c;但是始终没有与python的关系更进一步。 Python简介 用我自己的话说&#xff0c;python也是一门面…

k8s上安装KubeSphere

安装KubeSphere 前置环境安装nfs-server文件系统配置nfs-client配置默认存储创建了一个存储类metrics-server集群指标监控组件 安装KubeSphere执行安装查看安装进度 前置环境 下载配置我都是以CentOS 7.9 安装 k8s(详细教程)文章的服务器作为示例&#xff0c;请自行修改为自己的…

【评测脚本】机器信息评测(初版)

背景 QA的实际工作过程中,除了业务相关的测试外,也会涉及到一些评测相关的工作,甚至还要做多版本、多维度的评估分析。尤其是现在火热的大模型,相关的评测内容更是核心中的核心。当然本文的内容只是做一些初级的机器相关的评测信息,更多更广的评测需要更多时间的积累和总…

插入排序——直接插入排序和希尔排序(C语言实现)

文章目录 前言直接插入排序基本思想特性总结代码实现 希尔排序算法思想特性总结代码实现 前言 本博客插入排序动图和希尔排序视频参考大佬java技术爱好者&#xff0c;如有侵权&#xff0c;请联系删除。 直接插入排序 基本思想 直接插入排序是一种简单的插入排序法&#xff…

042:el-table表格表头自定义高度(亲测好用)

第042个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

PairLIE论文阅读笔记

PairLIE论文阅读笔记 论文为2023CVPR的Learning a Simple Low-light Image Enhancer from Paired Low-light Instances.论文链接如下&#xff1a; openaccess.thecvf.com/content/CVPR2023/papers/Fu_Learning_a_Simple_Low-Light_Image_Enhancer_From_Paired_Low-Light_Instan…

解决Eslint和Prettier关于三元运算符的冲突问题

三元运算符Prettier的格式化 三元运算符Eslint的格式要求 解决办法 // eslint加入配置&#xff0c;屏蔽标红报错indent: [error, 2, { ignoredNodes: [ConditionalExpression] }]效果
最新文章