适用于系统版本:CentOS 6/7/8的基线安全检测脚本
#!/bin/bash
#适用于系统版本:CentOS 6/7/8
echo "----------------检测是否符合密码复杂度要求----------------"
#把minlen(密码最小长度)设置为8-32位,把minclass(至少包含小写字母、大写字母、数字、特殊字符等4类字符中等3类或4类)设置为3或4;
st1=`cat /etc/security/pwquality.conf | grep minlen| grep -v '#'`
st2=`cat /etc/security/pwquality.conf | grep minclass| grep -v '#'`
if [ -z "$st1" ] && [ -z "$st2" ]; then
echo "检测结果为:未设置密码复杂度"
elif [ `cat /etc/security/pwquality.conf | grep minlen| grep -v '#' |awk -F ' ' '{print $3}'` -gt 8 ] && [ `cat /etc/security/pwquality.conf | grep minclass| grep -v '#' |awk -F ' ' '{print $3}'` -gt 2 ]; then
echo "检测结果为:密码复杂度符合要求"
else
echo "检测结果为:密码复杂度不符合要求"
fiecho "----------------检测rsyslog服务是否启用----------------"
#确保rsyslog服务已启用,记录日志用于审计
rsyslog="active(running)"
rsyslogstatus=`systemctl status rsyslog| grep Active | awk '{print$2$3}' `
if [ "$rsyslogstatus" == "$rsyslog" ]; then
echo "检测结果为:rsyslog服务已启用"
else
echo "检测结果为:rsyslog服务未启用"
fiecho "----------------检测是否禁止ROOT远程登录----------------"
#/etc/ssh/sshd_config文件中PermitRootLogin应设置为:no
set -e
cfgfile='/etc/ssh/sshd_config'
if [ "`cat ${cfgfile} | grep -E '^PermitRootLogin' | awk '{print $1}'`" == "#PermitRootLogin" -o "`cat ${cfgfile} | grep '^PermitRootLogin'`" == "" -o "`cat ${cfgfile} | grep '^PermitRootLogin' | awk '{print $2}'`" == "yes" ]
then
echo "检测结果为:未禁止root远程登录"else
echo "检测结果为:已禁止root远程登录"fiecho "----------------检测是否禁止空密码登录----------------"
#/etc/ssh/sshd_config文件中PermitEmptyPasswords应设置为:no
set -e
cfgfile='/etc/ssh/sshd_config'
if [ "`cat ${cfgfile} | grep 'PermitEmptyPasswords' | awk '{print $1}'`" == "#PermitEmptyPasswords" -o "`cat ${cfgfile} | grep 'PermitEmptyPasswords'`" == "" -o "`cat ${cfgfile} | grep 'PermitEmptyPasswords' | awk '{print $2}'`" == "yes" ]
then
echo "检测结果为:未禁止空密码登录"else
echo "检测结果为:已禁止空密码登录"fiecho "----------------检测密码重用是否限制为5次----------------"
#password sufficient pam_unix.so: 这部分指定了当用户尝试更改密码时,应使用pam_unix.so模块来验证新密码。sufficient意味着如果这个模块成功验证了密码,那么密码更改操作就成功,不需要继续检查其他PAM模块。
#remember=5: 这个参数指定了密码策略应检查新密码与过去5次使用的密码是否重复。如果新密码与这5次中的任何一次重复,该策略将拒绝更改密码。
set -e
Authcfg='/etc/pam.d/password-auth /etc/pam.d/system-auth'
for filename in ${Authcfg}
do
if [ -z "`grep -E 'password' ${filename} | grep 'sufficient' | grep remember=5 | grep pam_unix.so`" ]
then
echo "检测结果为:检测密码重用未限制为5次"
else
echo "检测结果为:检测密码重用已限制为5次"fi
doneecho "----------------检测是否设置密码失效时间----------------"
#/etc/login.defs 中将 PASS_MAX_DAYS 参数设置为 60-180之间;
pass_max_days=`cat /etc/login.defs | grep PASS_MAX_DAYS | grep -v '#'`
if [ -z "$pass_max_days" ]; then
echo "检测结果为:未设置密码失效时间"
elif [ `cat /etc/login.defs | grep PASS_MAX_DAYS | grep -v '#'| awk '{print $2}'` -gt 180 ] || [ `cat /etc/login.defs | grep PASS_MAX_DAYS | grep -v '#'| awk '{print $2}'` -lt 60 ]; then
echo "检测结果为:设置密码失效时间不在60-180天范围内"
else
echo "检测结果为:设置密码失效时间在60-180天范围内"
fiecho "----------------检测是否设置修改密码最小间隔时间----------------"
#在 /etc/login.defs 中将 PASS_MIN_DAYS 参数设置为7-14之间,建议为7:
pass_min_days=`cat /etc/login.defs | grep PASS_MIN_DAYS | grep -v '#'`
if [ -z "$pass_min_days" ]; then
echo "检测结果为:未设置修改密码最小间隔时间"
elif [ `cat /etc/login.defs | grep PASS_MIN_DAYS | grep -v '#'| awk '{print $2}'` -gt 14 ] || [ `cat /etc/login.defs | grep PASS_MAX_DAYS | grep -v '#'| awk '{print $2}'` -lt 7 ]; then
echo "检测结果为:设置修改密码最小间隔时间不在7-14天范围内"
else
echo "检测结果为:设置修改密码最小间隔时间在7-14天范围内"
fiecho "----------------检测密码过期告警时间是否大于等于7天----------------"
#密码过期警告时间应:大于等于7天;
set -e
cfgfile='/etc/login.defs'if [ `grep -E '^PASS_WARN_AGE' ${cfgfile} | awk '{print $2}'` -ge 7 ]
then
echo "检测结果为:密码过期告警时间已设置大于等于7天"else
echo "检测结果为:密码过期告警时间未设置大于等于7天"fiecho "----------------检测SSH访问是否受限制----------------"
#/etc/ssh/sshd_config文件中应存以下其中之一:
#AllowUsers <userlist>
#AllowGroups <grouplist>
#DenyUsers <userlist>
#DenyGroups <grouplist>
set -e ##返回任何非0状态即退出脚本执行
sshd_config='/etc/ssh/sshd_config'
sshstatus=`ps -ef | grep sshd | grep -v grep | awk -F ' ' '{print $8$9}'`
if [ -z "$sshstatus" ]
then
echo "检测结果为:未开启ssh服务"
exit 2
fi
if [ -z "`grep -E '^AllowUsers|^AllowGroups|^DenyUsers|^DenyGroups' ${sshd_config}`" ]
then
echo "检测结果为:SSH访问未受限制"
else
echo "检测结果为:SSH访问已受限制"
fiecho "----------------检测SSH LogLevel设置是否为INFO----------------"
#开启日志info日志格式可以记录很多的日志信息以便回溯,比如登录操作告警失败等信息
sshd_confi='/etc/ssh/sshd_config'
log_level=`cat $sshd_confi | grep "LogLevel"| grep -v '^#'| awk -F ' ' '{print$1}'`
if [ -z "$log_level" ]; then
echo "检测结果为:SSH LogLevel设置为INFO"
elif [ "`cat $sshd_confi | grep "LogLevel"| grep -v '^#LogLevel' | awk '{print $2}'`" == "INFO" ]; then
echo "检测结果为:SSH LogLevel设置为INFO"
else
echo "检测结果为:SSH LogLevel设置为$log_level"
fiecho "----------------检测SSH的MaxAuthTries是否设置为小于等于4----------------"
#用于指定SSH服务器允许客户端进行身份验证尝试的最大次数
set -e
cfg='/etc/ssh/sshd_config'
cfgstatus1=`cat $cfg | grep MaxAuthTries | grep -v '#'| awk -F ' ' '{print$1}'`
if [ -z "$cfgstatus1" ]
then
echo "检测结果为:未设置此参数"
elif [ `cat $cfg | grep MaxAuthTries | grep -v '#'| awk -F ' ' '{print$2}'` -le 6 ]
then
echo "检测结果为:已设置为小于等于6"
else
echo "检测结果为:未设置为小于等于6"
fiecho "----------------检测是否禁用ssh端口转发功能----------------"
#GatewayPorts 设置no或者注释掉
result=`cat /etc/ssh/sshd_config | grep GatewayPorts | grep -v '#' | awk -F ' ' '{print$NF}'`if [ "$result" == "no" ] | [ -z "$result" ];thenecho "检测结果为:已禁用ssh端口转发"
elseecho "检测结果为:已启用ssh端口转发"
fiecho "----------------检测ROOT是否UID为0的唯一用户----------------"
#root应为唯一的UID为0用户
set -e
cfgfile='/etc/passwd'
if [ `cat passwd | awk -F ':' '$3 == 0{print $1}'|wc -l` -eq 1 -a "`cat passwd | awk -F ':' '$3 == 0{print $1}'`" == "root" ]
then
echo "检测结果为:root是uid为0的唯一用户"else
echo "检测结果为:root不是uid为0的唯一用户"fiecho "----------------检测ROOT是否GID为0的唯一用户----------------"
#root应为唯一的GID为0用户
set -e
cfgfile='/etc/passwd'
root_gid=`cat ${cfgfile}|grep -E ^root | awk -F ':' '{print $4}'`
if [ ${root_gid} -eq 0 ]
then
echo "检测结果为:root是gid为0的唯一用户"else
echo "检测结果为:root不是gid为0的唯一用户"fiecho "----------------SSH空闲超时间隔是否设置----------------"
#/etc/ssh/sshd_config文件中 ClientAliveInterval应设置为:等于18000 ClientAliveCountMax应设置为:等于2
set -e
cfgfile='/etc/ssh/sshd_config'
ClientAliveInterval_key=`cat ${cfgfile} | grep ClientAliveInterval | awk '{print $1}'`
ClientAliveInterval_value=`cat ${cfgfile} | grep ClientAliveInterval | awk '{print $2}'`
ClientAliveCountMax_key=`cat ${cfgfile} | grep ClientAliveCountMax | awk '{print $1}'`
ClientAliveCountMax_value=`cat ${cfgfile} | grep ClientAliveCountMax | awk '{print $2}'`
if [ "${ClientAliveInterval_key}" == "" -o "${ClientAliveInterval_key}" == "#ClientAliveInterval" -o "${ClientAliveCountMax_key}" == "" -o "${ClientAliveCountMax_key}" == "#ClientAliveCountMax" ]
then
echo "检测结果为:未设置最大空闲时间"else
if [ ${ClientAliveInterval_value} -eq 18000 -a ${ClientAliveCountMax_value} -eq 2 ]
then
echo "检测结果为:最大空闲时间已设置为18000秒(5小时)X2=36000秒(10小时)"else
echo "检测结果为:最大空闲时间未设置为18000秒(5小时)X2=36000秒(10小时)"fi
fiecho "----------------检测是否禁止普通用户执行高危命令----------------"
#/usr/bin/yum 权限为700 /usr/bin/rpm权限为700 /usr/bin/rz权限为700 /usr/bin/sz权限为700 /usr/bin/scp权限为700
#file1="/usr/bin/rz" 禁止普通用户上传
file2="/usr/bin/sz" ##禁止普通用户下载(办公网与运维网场景不一样可能需要开放)
file4="/usr/bin/yum" ##禁止普通用户执行
file5="/usr/bin/rpm" ##禁止普通用户执行
permission="700" # 替换为你期望的权限值,此值为仅支持root用户执行
if [[ -f "$file1" && "$(stat -c '%a' "$file1")" == "$permission" ]]; then echo "检测结果为:已禁止普通用户执行rz命令"
elseecho "检测结果为:未禁止普通用户执行rz命令"
fi if [[ -f "$file2" && "$(stat -c '%a' "$file2")" == "$permission" ]]; then echo "检测结果为:已禁止普通用户执行sz命令"
elseecho "检测结果为:未禁止普通用户执行sz命令" fi if [[ -f "$file3" && "$(stat -c '%a' "$file3")" == "$permission" ]]; then echo "检测结果为:已禁止普通用户执行scp命令"
elseecho "检测结果为:未禁止普通用户执行scp命令"
fi if [[ -f "$file4" && "$(stat -c '%a' "$file4")" == "$permission" ]]; then echo "检测结果为:已禁止普通用户执行yum命令"
elseecho "检测结果为:未禁止普通用户执行yum命令"
fiif [[ -f "$file5" && "$(stat -c '%a' "$file5")" == "$permission" ]]; then echo "检测结果为:已禁止普通用户执行rpm命令"
elseecho "检测结果为:未禁止普通用户执行rpm命令" fiecho "----------------检测是否禁用普通用户修改高危文件----------------"
#/etc/passwd权限为644/etc/group权限为644/etc/shadow权限为400/etc/gshadow权限为400/etc/hosts.deny权限为644/etc/hosts.allow权限为644
file1="/etc/passwd" ##禁止普通用户更改
file2="/etc/shadow" ##禁止普通用户查看
file3="/etc/group" ##禁止普通用户更改
file4="/etc/gshadow" ##禁止普通用户查看
file5="/etc/hosts.deny" ##禁止普通用户更改
file6="/etc/hosts.allow" ##禁止普通用户更改
permission1="644" # 替换为你期望的权限值,此值为仅支持root用户更改
permission2="400" # 替换为你期望的权限值,即只有root用户可查看
if [[ -f "$file1" && "$(stat -c '%a' "$file1")" == "$permission1" ]]; then echo "检测结果为:已禁止普通用户更改passwd文件"
elseecho "检测结果为:未禁止普通用户更改passwd文件"
fi
if [[ -f "$file3" && "$(stat -c '%a' "$file3")" == "$permission1" ]]; then echo "检测结果为:已禁止普通用户更改group文件"
elseecho "检测结果为:未禁止普通用户更改group文件"
fi if [[ -f "$file2" && "$(stat -c '%a' "$file2")" == "$permission2" ]]; then echo "检测结果为:已禁止普通用户读取shadow文件"
elseecho "检测结果为:未禁止普通用户读取shadow文件" fi
if [[ -f "$file4" && "$(stat -c '%a' "$file4")" == "$permission2" ]]; then echo "检测结果为:已禁止普通用户读取gshadow文件"
elseecho "检测结果为:未禁止普通用户读取gshadow文件"
fi
if [[ -f "$file5" && "$(stat -c '%a' "$file5")" == "$permission2" ]]; then echo "检测结果为:已禁止普通用户更改hosts.deny文件"
elseecho "检测结果为:未禁止普通用户更改hosts.deny文件"
fi
if [[ -f "$file6" && "$(stat -c '%a' "$file6")" == "$permission2" ]]; then echo "检测结果为:已禁止普通用户更改hosts.allow文件"
elseecho "检测结果为:未禁止普通用户更改hosts.allow文件"
fi
相关文章:

适用于系统版本:CentOS 6/7/8的基线安全检测脚本
#!/bin/bash #适用于系统版本:CentOS 6/7/8 echo "----------------检测是否符合密码复杂度要求----------------" #把minlen(密码最小长度)设置为8-32位,把minclass(至少包含小写字母、大写字母、数字、特殊…...

Seata源码流程图
1.第一阶段分支事务的注册 流程图地址:https://www.processon.com/view/link/6108de4be401fd6714ba761d 2.第一阶段开启全局事务 流程图地址:https://www.processon.com/view/link/6108de13e0b34d3e35b8e4ef 3.第二阶段全局事务的提交 流程图地址…...

英飞凌电源管理PMIC的安全应用
摘要 本篇文档主要用来介绍英飞凌电源管理芯片TLF35584的使用,基于电动助力转向应用来介绍。包含一些安全机制的执行。 TLF35584介绍 TLF35584是英飞凌推出的针对车辆安全应用的电源管理芯片,符合ASIL D安全等级要求,具有高效多电源输出通道&…...
快速在Linux系统安装MySQL
虚拟机使用docker安装MySQL 使用docker拉去镜像 查看mysql的镜像 docker search mysql拉去mysql镜像 docker pull mysql查看下载的镜像 docker images启动容器 docker start mysql进入MySQL容器 docker exec -it mysql /bin/bash登录mysql mysql -u root -p检查是否进入…...
数据库相关理论知识(有目录便于直接锁定相关知识点+期末复习)
一,数据模型,关系型数据模型,网状模型,层次模型 1.数据库模型是用来描述和表示现实世界中的事物、概念以及它们之间的关系的工具,但是并不是越专业越好,还要平衡它的模型的复杂性、通用性和成本效益等因素…...
NCC环境配置
一、后端配置 1.安装eclipse汉化插件 2.安装svn插件...
用python实现Dubins曲线生成
Dubins曲线是连接两个具有指定方向和位置的点的最短路径,其中路径受到固定曲率约束(如车辆的转向限制)。Dubins曲线常用于机器人路径规划、车辆轨迹规划等领域。 Dubins曲线可以分为三种类型:CCC (Curve-Curve-Curve), CCL (Curv…...
智能技术上的“是”并不代表具体领域的“应该”
技术上的“是”并不代表具体领域的“应该” 。技术上的“是”仅仅是指某种方法或技术在实践中是否可行或有效,而不涉及是否该采取这种方法或技术。决定是否采取某种方法或技术还需要考虑伦理、法律、可行性等其他方面的因素。技术的发展可能会有各种可能性ÿ…...

永热爱 敢向前 | Paraverse平行云的2023 年终总结
永热爱,敢向前 值此新年,回顾2023,仅以此句,献给所有XR产业信仰者 2023 年,是XR产业技术和场景承上启下的关键之年 在这场波澜壮阔的技术潮中 「Paraverse平行云」踏浪前行 已是第八个年头,让我们一起…...
c/c++的内存分配,详细说一下栈、堆和静态存储区
栈区(Stack):由编译器自动分配和回收,栈中存放函数调用的相关信息,栈帧(记录函数的栈帧开始的位置),参数,局部变量,返回地址。其操作方法类似于数据结构中的栈…...
每日构造题训练——C. Divan and bitwise operations
每日构造题训练 题目链接: 题目传送门 前置知识: 按位或运算 一、题意: 1 1 1、 有一个长度为 n n n的但是元素未知的数组 a a a, 给定 m m m个约束,每个约束都有 l , r , x l, r, x l,r,x, 并且满足 1 ≤ l ≤ r ≤ n , 1 ≤ x < 2 30 , a [ l ] ∣ a [ l 1 …...

【C++练级之路】【Lv.13】多态(你真的了解虚函数和虚函数表吗?)
快乐的流畅:个人主页 个人专栏:《C语言》《数据结构世界》《进击的C》 远方有一堆篝火,在为久候之人燃烧! 文章目录 一、虚函数与重写1.1 虚函数1.2 虚函数的重写1.3 重写的特例1.4 final和override(C11)1.…...

如何在Windows系统安装Node.js环境并制作html页面发布公网远程访问?
文章目录 前言1.安装Node.js环境2.创建node.js服务3. 访问node.js 服务4.内网穿透4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5.固定公网地址 前言 Node.js 是能够在服务器端运行 JavaScript 的开放源代码、跨平台运行环境。Node.js 由 OpenJS Foundation࿰…...

C#,数值计算,希尔伯特矩阵(Hilbert Matrix)的算法与源代码
Hilbert, David (1862-1943) 1 希尔伯特(Hilbert) 德国数学家,在《几何学基础》中提出了第一套严格的几何公理(1899年)。他还证明了自己的系统是自洽的。他发明了一条简单的空间填充曲线,即埃里克魏斯汀的数学世界,即希尔伯特曲线,埃里克魏斯汀的数学世界,并证明了不…...

【C++教程从0到1入门编程】第八篇:STL中string类的模拟实现
一、 string类的模拟实现 下面是一个列子 #include <iostream> namespace y {class string{public: //string() //无参构造函数// :_str(nullptr)//{}//string(char* str) //有参构造函数// :_str(str)//{}string():_str(new char[1]){_str[0] \0;}string(c…...

学生时期学习资源同步-1 第一学期结业考试题6
原创作者:田超凡(程序员田宝宝) 版权所有,引用请注明原作者,严禁复制转载...

迁移学习怎么用
如果想实现一个计算机视觉应用,而不想从零开始训练权重,比方从随机初始化开始训练,更快的方式是下载已经训练好权重的网络结构,把这个作为预训练,迁移到你感兴趣的新任务上。ImageNet、PASCAL等等数据库已经公开在线。…...

医疗手持智能终端读取条码二维码的难点有哪些?
在医疗科技行业信息化的大潮中,医疗手持式智能终端的应用越发普及,医疗手持式智能终端对条码二维码技术应用显得尤为关键,作为信息朔源载体的条码二维码读取方面,在实际应用中却面临着诸多问题,我们该如何应对…...

Python小设计
1. 五个PPT上的界面打印【print、input函数】 (1)英雄商城登陆界面 print(英雄联盟商城登录界面 ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~1. 用户登录2. 新用户注册3. 退出系统 ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~…...
今日讲讲父子传值~
今天来讲讲父子传值中的几种方法~ 项目中往往会把一些常用的公共代码抽离出来,写成一个子组件。或者在一个页面中的代码太多,可以根据功能的不同抽离出相关代码写成子组件,这样代码结构会更加简洁明了,后续维护更加方便。…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...