当前位置: 首页 > news >正文

深入解析Python身份切换:安全权限管理实践指南

目录

  • 深入解析Python身份切换:安全权限管理实践指南
    • 引言
    • 一、身份切换基础理论
      • 1.1 身份切换安全模型
      • 1.2 Linux身份模型
      • 1.3 身份切换状态方程
    • 二、用户身份切换技术
      • 2.1 基础用户切换
      • 2.2 临时特权提升
    • 三、组身份管理
      • 3.1 组身份切换
      • 3.2 多组身份管理
    • 四、安全上下文与能力管理
      • 4.1 SELinux上下文切换
      • 4.2 Linux能力管理
    • 五、完整身份切换框架
    • 六、最佳实践与安全模式
      • 6.1 身份切换安全模式
      • 6.2 安全设计原则
      • 6.3 身份切换审计日志
    • 七、常见问题与解决方案
      • 问题1:权限不足导致切换失败
      • 问题2:能力泄露风险
      • 问题3:环境污染问题
      • 问题4:跨平台兼容性
    • 结语

深入解析Python身份切换:安全权限管理实践指南

引言

身份切换是系统安全的核心机制,它允许程序在执行过程中动态改变其权限上下文。在Python中实现安全的身份切换对于构建需要特权操作的应用至关重要。本文将全面解析Python身份切换的技术实现,涵盖用户切换、组管理、权限边界和安全上下文等关键主题,并通过完整代码示例展示如何在实际项目中应用这些技术。


一、身份切换基础理论

1.1 身份切换安全模型

请求
通过
拒绝
主体 Subject
身份切换机制
权限检查
新身份执行
操作失败
结果返回

1.2 Linux身份模型

身份类型描述Python访问方法
真实用户ID(RUID)启动进程的用户os.getuid()
有效用户ID(EUID)决定访问权限的用户os.geteuid()
保存用户ID(SUID)可恢复的EUIDos.setuid()
文件系统用户ID(FSUID)文件访问权限Linux特有
组ID(GID)用户组身份os.getgid()

1.3 身份切换状态方程

身份切换过程可表示为:
Snew=f(Scurrent,Ttarget,Ppolicy)S_{new} = f(S_{current}, T_{target}, P_{policy}) Snew=f(Scurrent,Ttarget,Ppolicy)
其中:

  • ScurrentS_{current}Scurrent 是当前身份状态
  • TtargetT_{target}Ttarget 是目标身份
  • PpolicyP_{policy}Ppolicy 是切换策略
  • fff 是切换函数

二、用户身份切换技术

2.1 基础用户切换

import os
import pwd
import sysdef switch_user(username):"""切换到指定用户身份"""try:# 获取目标用户信息target_user = pwd.getpwnam(username)target_uid = target_user.pw_uidtarget_gid = target_user.pw_gid# 预检查if os.geteuid() != 0:raise PermissionError("需要root权限执行用户切换")# 设置组ID(必须先于用户ID)os.setgid(target_gid)# 设置用户IDos.setuid(target_uid)# 更新环境变量os.environ['USER'] = usernameos.environ['HOME'] = target_user.pw_diros.environ['LOGNAME'] = usernameprint(f"成功切换到用户 {username} (UID={target_uid}, GID={target_gid})")return Trueexcept KeyError:print(f"错误:用户 '{username}' 不存在", file=sys.stderr)except PermissionError as e:print(f"权限错误:{str(e)}", file=sys.stderr)except Exception as e:print(f"切换失败:{str(e)}", file=sys.stderr)return False# 使用示例
if __name__ == "__main__":print(f"当前身份: UID={os.getuid()}, EUID={os.geteuid()}")if switch_user("nobody"):print(f"新身份: UID={os.getuid()}, EUID={os.geteuid()}")

2.2 临时特权提升

import os
import contextlib@contextlib.contextmanager
def elevated_privileges(user="root"):"""临时提升权限的上下文管理器"""original_uid = os.getuid()original_euid = os.geteuid()target_uid = pwd.getpwnam(user).pw_uid if user != "root" else 0try:# 保存当前身份current_uid = os.getuid()# 提升到目标用户if current_uid != target_uid:os.seteuid(target_uid)print(f"权限提升到 {user} (EUID={os.geteuid()})")yieldfinally:# 恢复原始身份if os.geteuid() != original_euid:os.seteuid(original_euid)print(f"权限恢复: EUID={os.geteuid()}")# 使用示例
def modify_system_file(path):with elevated_privileges():try:with open(path, 'a') as f:f.write("# 由特权进程修改\n")print("系统文件修改成功")except IOError as e:print(f"文件操作失败: {str(e)}")# 注意:需要CAP_DAC_OVERRIDE能力或root权限

三、组身份管理

3.1 组身份切换

import os
import grpdef switch_group(groupname):"""切换到指定组身份"""try:# 获取目标组信息target_group = grp.getgrnam(groupname)target_gid = target_group.gr_gid# 设置组IDos.setgid(target_gid)# 更新补充组os.setgroups([target_gid])print(f"成功切换到组 {groupname} (GID={target_gid})")return Trueexcept KeyError:print(f"错误:组 '{groupname}' 不存在", file=sys.stderr)except PermissionError as e:print(f"权限错误:{str(e)}", file=sys.stderr)return False# 使用示例
if __name__ == "__main__":print(f"当前组: GID={os.getgid()}")if switch_group("nogroup"):print(f"新组: GID={os.getgid()}")

3.2 多组身份管理

def manage_supplementary_groups(username):"""管理用户的补充组"""try:# 获取用户信息user_info = pwd.getpwnam(username)# 获取用户所属组group_ids = []for group in grp.getgrall():if username in group.gr_mem:group_ids.append(group.gr_gid)# 设置补充组os.setgroups(group_ids)print(f"用户 {username} 的补充组已设置: {group_ids}")return Trueexcept KeyError:print(f"错误:用户 '{username}' 不存在", file=sys.stderr)return False# 使用示例
manage_supplementary_groups("www-data")

四、安全上下文与能力管理

4.1 SELinux上下文切换

import ctypesclass SELinuxContextManager:"""SELinux安全上下文管理"""def __init__(self):try:# 加载SELinux库self.libselinux = ctypes.CDLL("libselinux.so.1")# 定义函数原型self.libselinux.setcon.argtypes = [ctypes.c_char_p]self.libselinux.setcon.restype = ctypes.c_intself.libselinux.getcon.argtypes = [ctypes.POINTER(ctypes.c_char_p)]self.libselinux.getcon.restype = ctypes.c_intself.libselinux.freecon.argtypes = [ctypes.c_char_p]except OSError:self.libselinux = Nonedef is_available(self):"""检查SELinux是否可用"""return self.libselinux is not Nonedef set_context(self, context):"""设置安全上下文"""if not self.is_available():print("警告: SELinux不可用")return Falseresult = self.libselinux.setcon(context.encode('utf-8'))if result != 0:print(f"设置上下文失败: {ctypes.get_errno()}")return Falsereturn Truedef get_current_context(self):"""获取当前安全上下文"""if not self.is_available():return Nonecontext_ptr = ctypes.c_char_p()if self.libselinux.getcon(ctypes.byref(context_ptr)) != 0:return Nonecontext = context_ptr.value.decode('utf-8')self.libselinux.freecon(context_ptr)return context# 使用示例
selinux_mgr = SELinuxContextManager()
if selinux_mgr.is_available():print(f"当前安全上下文: {selinux_mgr.get_current_context()}")if selinux_mgr.set_context("system_u:system_r:httpd_t:s0"):print(f"新安全上下文: {selinux_mgr.get_current_context()}")

4.2 Linux能力管理

import ctypes# Linux能力常量
CAP_CHOWN = 0
CAP_DAC_OVERRIDE = 1
CAP_NET_BIND_SERVICE = 10class CapabilityManager:"""Linux能力管理封装类"""def __init__(self):# 加载libcself.libc = ctypes.CDLL(ctypes.util.find_library('c'))# 定义prctl函数self.libc.prctl.argtypes = [ctypes.c_int, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong]self.libc.prctl.restype = ctypes.c_int# 定义常量self.PR_SET_KEEPCAPS = 8self.PR_CAPBSET_DROP = 24def drop_capability(self, cap):"""从边界集中删除能力"""if self.libc.prctl(self.PR_CAPBSET_DROP, cap, 0, 0, 0) != 0:raise OSError(ctypes.get_errno(), "删除能力失败")def set_effective_caps(self, caps):"""设置有效能力集"""# 导入libcaplibcap = ctypes.CDLL(ctypes.util.find_library('cap'))# 创建空能力集cap_t = libcap.cap_init()try:# 设置能力标志for cap in caps:libcap.cap_set_flag(cap_t, ctypes.c_uint(1),  # CAP_EFFECTIVEcap, ctypes.c_uint(1)   # 设置能力)# 应用能力设置if libcap.cap_set_proc(cap_t) != 0:raise OSError(ctypes.get_errno(), "设置能力失败")finally:libcap.cap_free(cap_t)# 使用示例
cap_mgr = CapabilityManager()
cap_mgr.drop_capability(CAP_CHOWN)
cap_mgr.set_effective_caps([CAP_NET_BIND_SERVICE])

五、完整身份切换框架

"""
Python身份切换框架完整实现
包含用户切换、组管理、安全上下文、能力管理等功能
"""
import os
import sys
import pwd
import grp
import logging
import ctypes
import ctypes.util
import contextlib
from typing import List, Optional, Tuple# 配置日志
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger("IdentitySwitch")class IdentitySwitchError(Exception):"""身份切换异常基类"""passclass UserSwitchError(IdentitySwitchError):"""用户切换异常"""passclass GroupSwitchError(IdentitySwitchError):"""组切换异常"""passclass SecurityContextManager:"""安全上下文管理器"""def __init__(self):self.original_uid = os.getuid()self.original_euid = os.geteuid()self.original_gid = os.getgid()self.original_groups = os.getgroups()self.current_user = Noneself.current_group = Nonedef switch_user(self, username: str) -> bool:"""切换到指定用户"""try:# 获取目标用户信息target_user = pwd.getpwnam(username)target_uid = target_user.pw_uidtarget_gid = target_user.pw_gid# 预检查if os.geteuid() != 0 and target_uid != os.getuid():raise UserSwitchError("需要特权切换用户")# 设置组ID(必须先于用户ID)os.setgid(target_gid)# 设置用户IDos.setuid(target_uid)# 更新补充组self._set_user_groups(username)# 更新环境变量os.environ['USER'] = usernameos.environ['HOME'] = target_user.pw_diros.environ['LOGNAME'] = usernameself.current_user = usernameself.current_group = grp.getgrgid(target_gid).gr_namelogger.info(f"切换到用户 {username} (UID={target_uid}, GID={target_gid})")return Trueexcept KeyError:raise UserSwitchError(f"用户 '{username}' 不存在")except PermissionError as e:raise UserSwitchError(f"权限错误: {str(e)}")except Exception as e:raise UserSwitchError(f"切换失败: {str(e)}")def switch_group(self, groupname: str) -> bool:"""切换到指定组"""try:# 获取目标组信息target_group = grp.getgrnam(groupname)target_gid = target_group.gr_gid# 设置组IDos.setgid(target_gid)# 更新补充组if self.current_user:self._set_user_groups(self.current_user)self.current_group = groupnamelogger.info(f"切换到组 {groupname} (GID={target_gid})")return Trueexcept KeyError:raise GroupSwitchError(f"组 '{groupname}' 不存在")except PermissionError as e:raise GroupSwitchError(f"权限错误: {str(e)}")def _set_user_groups(self, username: str):"""设置用户的补充组"""group_ids = []for group in grp.getgrall():if username in group.gr_mem:group_ids.append(group.gr_gid)os.setgroups(group_ids)logger.debug(f"设置用户 {username} 的补充组: {group_ids}")@contextlib.contextmanagerdef temporary_user(self, username: str):"""临时切换到指定用户的上下文管理器"""original_user = self.current_useroriginal_group = self.current_grouptry:self.switch_user(username)yieldfinally:if original_user:self.switch_user(original_user)elif self.original_uid != os.getuid():self.switch_user(pwd.getpwuid(self.original_uid).pw_name)if original_group:self.switch_group(original_group)@contextlib.contextmanagerdef temporary_elevation(self, user="root"):"""临时提升权限的上下文管理器"""original_euid = os.geteuid()target_uid = pwd.getpwnam(user).pw_uid if user != "root" else 0try:# 提升权限os.seteuid(target_uid)logger.info(f"权限提升到 {user} (EUID={os.geteuid()})")yieldfinally:# 恢复权限os.seteuid(original_euid)logger.info(f"权限恢复: EUID={os.geteuid()}")def restore_original_identity(self):"""恢复原始身份"""# 恢复用户original_user = pwd.getpwuid(self.original_uid).pw_nameif self.current_user != original_user:self.switch_user(original_user)# 恢复组original_group = grp.getgrgid(self.original_gid).gr_nameif self.current_group != original_group:self.switch_group(original_group)# 恢复补充组os.setgroups(self.original_groups)logger.info("身份已恢复到原始状态")class LinuxCapabilityManager:"""Linux能力管理器"""def __init__(self):# 加载libcself.libc = ctypes.CDLL(ctypes.util.find_library('c'))# 定义prctl函数self.libc.prctl.argtypes = [ctypes.c_int, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong]self.libc.prctl.restype = ctypes.c_int# 定义常量self.PR_CAPBSET_DROP = 24self.PR_CAPBSET_READ = 23def drop_capability(self, cap: int):"""从边界集中删除能力"""if self.libc.prctl(self.PR_CAPBSET_DROP, cap, 0, 0, 0) != 0:errno = ctypes.get_errno()raise OSError(errno, f"删除能力 {cap} 失败: {os.strerror(errno)}")def has_capability(self, cap: int) -> bool:"""检查能力是否在边界集中"""result = self.libc.prctl(self.PR_CAPBSET_READ, cap, 0, 0, 0)if result < 0:errno = ctypes.get_errno()raise OSError(errno, f"查询能力 {cap} 失败: {os.strerror(errno)}")return result == 1def set_effective_caps(self, caps: List[int]):"""设置有效能力集"""# 导入libcaplibcap = ctypes.CDLL(ctypes.util.find_library('cap'))# 创建空能力集cap_t = libcap.cap_init()if not cap_t:raise RuntimeError("无法创建能力集")try:# 设置能力标志for cap in caps:if libcap.cap_set_flag(cap_t, ctypes.c_uint(1),  # CAP_EFFECTIVEcap, ctypes.c_uint(1)   # 设置能力) != 0:raise RuntimeError(f"设置能力 {cap} 失败")# 应用能力设置if libcap.cap_set_proc(cap_t) != 0:errno = ctypes.get_errno()raise OSError(errno, f"应用能力失败: {os.strerror(errno)}")finally:libcap.cap_free(ctypes.c_void_p(cap_t))@contextlib.contextmanagerdef temporary_capabilities(self, caps: List[int]):"""临时能力上下文管理器"""# 保存原始能力original_caps = self._get_current_caps()try:# 设置新能力self.set_effective_caps(caps)yieldfinally:# 恢复原始能力self.set_effective_caps(original_caps)def _get_current_caps(self) -> List[int]:"""获取当前有效能力集(简化实现)"""# 实际实现需要解析/proc/self/statusreturn []class SELinuxContextManager:"""SELinux安全上下文管理器"""def __init__(self):try:# 加载SELinux库self.libselinux = ctypes.CDLL("libselinux.so.1")# 定义函数原型self.libselinux.setcon.argtypes = [ctypes.c_char_p]self.libselinux.setcon.restype = ctypes.c_intself.libselinux.getcon.argtypes = [ctypes.POINTER(ctypes.c_char_p)]self.libselinux.getcon.restype = ctypes.c_intself.libselinux.freecon.argtypes = [ctypes.c_char_p]self.original_context = self.get_current_context()except OSError:self.libselinux = Noneself.original_context = Nonedef is_available(self) -> bool:"""检查SELinux是否可用"""return self.libselinux is not Nonedef set_context(self, context: str) -> bool:"""设置安全上下文"""if not self.is_available():logger.warning("SELinux不可用")return Falseresult = self.libselinux.setcon(context.encode('utf-8'))if result != 0:errno = ctypes.get_errno()logger.error(f"设置上下文失败: {os.strerror(errno)}")return Falsereturn Truedef get_current_context(self) -> Optional[str]:"""获取当前安全上下文"""if not self.is_available():return Nonecontext_ptr = ctypes.c_char_p()if self.libselinux.getcon(ctypes.byref(context_ptr)) != 0:return Nonecontext = context_ptr.value.decode('utf-8')self.libselinux.freecon(context_ptr)return context@contextlib.contextmanagerdef temporary_context(self, context: str):"""临时安全上下文管理器"""if not self.is_available():yieldreturnoriginal_context = self.get_current_context()try:self.set_context(context)yieldfinally:if original_context:self.set_context(original_context)class IdentitySwitchFramework:"""身份切换框架"""def __init__(self):self.context_manager = SecurityContextManager()self.capability_manager = LinuxCapabilityManager()self.selinux_manager = SELinuxContextManager()def run_as_user(self, username: str, func: callable, *args, **kwargs):"""以指定用户身份运行函数"""with self.context_manager.temporary_user(username):return func(*args, **kwargs)def run_with_capabilities(self, caps: List[int], func: callable, *args, **kwargs):"""以指定能力运行函数"""with self.capability_manager.temporary_capabilities(caps):return func(*args, **kwargs)def run_in_context(self, context: str, func: callable, *args, **kwargs):"""在指定安全上下文中运行函数"""with self.selinux_manager.temporary_context(context):return func(*args, **kwargs)def secure_drop_privileges(self, username: str):"""安全降低权限"""# 第一步:删除危险能力dangerous_caps = [0, 1, 2, 3, 4, 5, 6]  # CAP_CHOWN, CAP_DAC_OVERRIDE等for cap in dangerous_caps:try:self.capability_manager.drop_capability(cap)except OSError as e:logger.warning(f"删除能力 {cap} 失败: {str(e)}")# 第二步:切换到非特权用户self.context_manager.switch_user(username)# 第三步:设置受限安全上下文if self.selinux_manager.is_available():self.selinux_manager.set_context(f"user_u:user_r:user_t:s0")logger.info(f"权限已安全降低到 {username}")# 使用示例
if __name__ == "__main__":def privileged_operation():"""需要特权的操作"""import timeprint("执行特权操作...")time.sleep(1)print("特权操作完成")def normal_operation():"""普通操作"""print("执行普通操作")# 创建框架实例framework = IdentitySwitchFramework()# 场景1:以nobody用户执行普通操作print("\n场景1: 以nobody用户执行普通操作")framework.run_as_user("nobody", normal_operation)# 场景2:临时提升权限执行操作print("\n场景2: 临时提升权限执行操作")with framework.context_manager.temporary_elevation():privileged_operation()# 场景3:安全降低权限print("\n场景3: 安全降低权限")if os.getuid() == 0:framework.secure_drop_privileges("nobody")print(f"当前用户: {pwd.getpwuid(os.getuid()).pw_name}")else:print("非root用户,无法演示权限降低")# 场景4:在特定安全上下文中运行print("\n场景4: 在特定安全上下文中运行")if framework.selinux_manager.is_available():framework.run_in_context("system_u:system_r:httpd_t:s0", normal_operation)else:print("SELinux不可用,跳过上下文测试")

六、最佳实践与安全模式

6.1 身份切换安全模式

启动
需要特权?
执行特权操作
降低权限
主业务逻辑
结束

6.2 安全设计原则

  1. 最小特权原则:只获取完成操作所需的最小权限
  2. 权限分离:将特权操作限制在最小范围
  3. 及时降权:特权操作后立即恢复普通权限
  4. 深度防御:在多个层级实施安全控制
  5. 审计跟踪:记录所有身份切换操作

6.3 身份切换审计日志

import json
from datetime import datetimeclass IdentityAudit:"""身份切换审计系统"""def __init__(self, log_file="/var/log/identity_audit.log"):self.log_file = log_filedef log_switch(self, action: str, source: str, target: str, status: str):"""记录身份切换事件"""entry = {"timestamp": datetime.utcnow().isoformat(),"action": action,"source": source,"target": target,"status": status,"pid": os.getpid(),"uid": os.getuid(),"euid": os.geteuid()}with open(self.log_file, "a") as f:f.write(json.dumps(entry) + "\n")# 在切换函数中添加审计
def audited_switch_user(username, audit):source = pwd.getpwuid(os.getuid()).pw_nametry:result = switch_user(username)audit.log_switch("user_switch", source, username, "success")return resultexcept Exception as e:audit.log_switch("user_switch", source, username, f"failed: {str(e)}")raise

七、常见问题与解决方案

问题1:权限不足导致切换失败

解决方案:分阶段切换

def safe_privileged_switch(username):"""安全的分阶段用户切换"""# 第一阶段:root切换到中间用户switch_user("privileged_runner")# 执行中间操作prepare_environment()# 第二阶段:切换到目标用户switch_user(username)

问题2:能力泄露风险

防护方案:能力边界控制

def secure_capability_handling():"""安全的能力处理流程"""# 1. 删除不需要的能力drop_unnecessary_capabilities()# 2. 执行特权操作perform_privileged_operation()# 3. 删除所有剩余能力drop_all_capabilities()

问题3:环境污染问题

清理策略

def clean_environment(username):"""清理环境变量"""user_info = pwd.getpwnam(username)os.environ.clear()os.environ.update({'PATH': '/usr/local/bin:/usr/bin:/bin','USER': username,'HOME': user_info.pw_dir,'SHELL': user_info.pw_shell or '/bin/sh','LOGNAME': username})

问题4:跨平台兼容性

抽象层实现

class PlatformIdentity:@staticmethoddef switch_user(username):if sys.platform == 'linux':return LinuxIdentity.switch_user(username)elif sys.platform == 'darwin':return MacIdentity.switch_user(username)elif sys.platform == 'win32':return WindowsIdentity.impersonate_user(username)else:raise NotImplementedError("Unsupported platform")

结语

Python身份切换是构建安全系统应用的关键技术。通过本文的深入探讨,我们掌握了:

  1. 基础理论:用户/组身份模型和安全上下文
  2. 核心技术:用户切换、组管理、能力控制
  3. 安全实践:最小特权原则、及时降权、审计跟踪
  4. 完整框架:可扩展的身份切换实现方案

“安全不是目的地,而是持续的过程。” —— Bruce Schneier

在实际应用中,请遵循以下最佳实践:

  • 最小特权:始终以最低必要权限运行
  • 深度防御:结合用户切换、能力控制和SELinux
  • 审计跟踪:记录所有身份变更操作
  • 错误处理:妥善处理切换失败场景
  • 持续测试:定期验证身份切换逻辑

通过合理应用本文介绍的技术,您将能够构建出安全可靠的Python系统应用,有效管理权限边界,降低安全风险。

http://www.dtcms.com/a/331021.html

相关文章:

  • MyBatis缓存模块深度解析
  • dolphinscheduler中任务输出变量的问题出现ArrayIndexOutOfBoundsException
  • MCP和Agent之间的区别和联系
  • vercel部署上线
  • lesson38:MySQL数据库核心操作详解:从基础查询到高级应用
  • 飞算JavaAI智慧零售场景实践:从用户洞察到供应链优化的全链路技术升级
  • UniApp 中使用 tui-xecharts插件(或类似图表库如 uCharts)
  • [ HTML 前端 ] 语法介绍和HBuilderX安装
  • 通过网页调用身份证阅读器http websocket方法-湖南步联科技美萍MP999A电子————仙盟创梦IDE
  • 15 ABP Framework 开发工具
  • Transformer网络结构解析
  • HTML <link rel=“preload“>:提前加载关键资源的性能优化利器
  • CNN - 卷积层
  • MicroVM-as-a-Service 后端服务架构设计与实现
  • 使用 Docker 部署 PostgreSQL
  • 加密货币交易所开发:如何打造安全、高并发的数字资产交易平台?
  • 基于ECharts和EdgeOne打造云上智能图表
  • 单体架构集训整理
  • css 属性@font-face介绍
  • 经典深度学习模型——LSTM【原理解释 代码(以2025年美赛C题为例)】
  • FreeRTOS-C语言指针笔记
  • 【入门级-C++程序设计:13、STL 模板:栈(stack)、队 列(queue)、 链 表(list)、 向 量(vector) 等容器】
  • gitlab的ci/cd变量如何批量添加
  • 【P81 10-7】OpenCV Python【实战项目】——车辆识别、车流统计(图像/视频加载、图像运算与处理、形态学、轮廓查找、车辆统计及显示)
  • 智能清扫新纪元:有鹿机器人如何用AI点亮我们的城市角落
  • Streamlit实现Qwen对话机器人
  • CVPR 2025 | 机器人操控 | RoboGround:用“掩码”中介表示,让机器人跨场景泛化更聪明
  • GaussDB数据库架构师修炼(十六) 如何选择磁盘
  • Helm-K8s包管理(三)新建、编辑一个Chart
  • k8s+isulad 重装