配置Kerberos实战案例
配置Kerberos实战案例
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.Kerberos主要配置文件概述
krb5.conf:
作用:
krb5.conf是kerberos的首要配置文件,可以在这里配置KDC的位置,AS以及Kerberos域域主机名的映射。
此文件是kerberos客户端配置文件,只要客户端尝试使用kinit通过KDC进行身份验证,该文件就会被读取。此文件中的大多数配置参数可以使用默认值。
路径:
通常位于"/etc/krb5.conf"。
kdc.conf:
作用:
路径:
通常位于"/var/Kerberos/krb5kdc/kdc.conf";如果是源码安装通常位于安装目录(如"/yinzhengjie/softwares/kerberos")下的"var/krb5kdc/kdc.conf"。
当然,你也可以不遵守上述约定,因为该配置文件路径你是可以在krb5.conf中指定的哟~
kadm5.acl:
作用:
路径:
通常位于"/var/krb5kdc"目录下;如果是源码安装通常位于安装目录(如"/yinzhengjie/softwares/kerberos")下的"var/krb5kdc/"目录下。
二.配置kerberos客户端配置文件(krb5.conf)
1>.备份配置文件
[root@hadoop101.yinzhengjie.com ~]# cp /etc/krb5.conf /etc/krb5.conf-`date +%F`
2>.修改配置文件
[root@hadoop101.yinzhengjie.com ~]# vim /etc/krb5.conf [root@hadoop101.yinzhengjie.com ~]# [root@hadoop101.yinzhengjie.com ~]# cat /etc/krb5.conf # Configuration snippets may be placed in this directory as well includedir /etc/krb5.conf.d/ [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = YINZHENGJIE.COM dns_lookup_realm = false dns_lookup_kdc = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true [kdc] profile = /var/kerberos/krb5kdc/kdc.conf [realms] YINZHENGJIE.COM = { kdc = kdc.yinzhengjie.com admin_server = kdc.yinzhengjie.com } CERT.YINZHENGJIE.COM = { kdc = kdc.cert.yinzhengjie.com admin_server = kdc.cert.yinzhengjie.com }
[domain_realm] .yinzhengjie.com = YINZHENGJIE.COM yinzhengjie.com = YINZHENGJIE.COM .dev.yinzhengjie.com = YINZHENGJIE.COM dev.yinzhengjie.com = YINZHENGJIE.COM [root@hadoop101.yinzhengjie.com ~]#

[root@hadoop101.yinzhengjie.com ~]# ansible other -m copy -a 'src=/etc/krb5.conf dest=/etc/krb5.conf' #配置好krb5.conf文件后,必须将其复制到Hadoop集群中的每个节点上。 hadoop105.yinzhengjie.com | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "07b4e1bfac82f1ab4957670b9a16404ffaf100e3", "dest": "/etc/krb5.conf", "gid": 0, "group": "root", "md5sum": "1f343a0a8ed790b326f9dc8fe3f3bf0d", "mode": "0644", "owner": "root", "size": 797, "src": "/root/.ansible/tmp/ansible-tmp-1601691445.66-9638-247755547729680/source", "state": "file", "uid": 0 } hadoop102.yinzhengjie.com | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "07b4e1bfac82f1ab4957670b9a16404ffaf100e3", "dest": "/etc/krb5.conf", "gid": 0, "group": "root", "md5sum": "1f343a0a8ed790b326f9dc8fe3f3bf0d", "mode": "0644", "owner": "root", "size": 797, "src": "/root/.ansible/tmp/ansible-tmp-1601691445.64-9634-168045767927027/source", "state": "file", "uid": 0 } hadoop104.yinzhengjie.com | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "07b4e1bfac82f1ab4957670b9a16404ffaf100e3", "dest": "/etc/krb5.conf", "gid": 0, "group": "root", "md5sum": "1f343a0a8ed790b326f9dc8fe3f3bf0d", "mode": "0644", "owner": "root", "size": 797, "src": "/root/.ansible/tmp/ansible-tmp-1601691445.68-9637-54408979140843/source", "state": "file", "uid": 0 } hadoop103.yinzhengjie.com | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "07b4e1bfac82f1ab4957670b9a16404ffaf100e3", "dest": "/etc/krb5.conf", "gid": 0, "group": "root", "md5sum": "1f343a0a8ed790b326f9dc8fe3f3bf0d", "mode": "0644", "owner": "root", "size": 797, "src": "/root/.ansible/tmp/ansible-tmp-1601691445.66-9636-241348543456303/source", "state": "file", "uid": 0 } [root@hadoop101.yinzhengjie.com ~]#
3>.配置文件关键参数说明
[logging]: 作用: 用于指定kerberos守护进程的日志记录方式,换句话说,就是指定server端的日志打印位置。 常用标签: default: 指定默认的存储路径,默认值:"FILE:/var/log/krb5libs"。 kdc: 指定KDC日志的存储路径,默认值:"FILE:/var/log/krb5kdc.log"。 admin_server: 指定管理员服务器的日志,默认值:"FILE:/var/log/kadmind.log"。 [libdefaults]: 作用: 用于指定kerberos使用的默认配置。 例如:当进行身份验证而未指定Kerberos域时,则使用default_realm参数来指定的Kerberos域。 常用标签: default_realm: 标识客户端的默认Kerberos领域。将其值设置为您的Kerberos领域。如果未设置此值,则在调用诸如"kinit"之类的程序时,必须为每个Kerberos主体指定一个领域。 如果您有多个领域,只需向[realms]节(我"[realms]"自定义了2个领域,分别为"YINZHENGJIE.COM"和"CERT.YINZHENGJIE.COM")添加相应的领域信息即可。我将"YINZHENGJIE.COM"设置为默认领域。 dns_lookup_realm: 此模块查找DNS记录,以用于备用主机到领域的映射以及默认领域。仅当dns_lookup_realm变量设置为"true"时,它才起作用。默认值为"false" dns_lookup_kdc: 指示是否应使用DNS SRV记录来定位领域的KDC和其他服务器(如果未在领域的krb5.conf信息中列出它们)。默认值为"false"(请注意,admin_server条目必须在krb5.conf领域信息中才能联系kadmind,因为kadmin的DNS实现不完整。) 如果有人欺骗DNS记录并将您重定向到另一台服务器,则启用此选项的确会打开一种拒绝服务攻击。但是,这并不比拒绝服务更糟糕,因为伪造的KDC将无法对您发送的任何内容进行解码(除了初始票证请求之外,该请求没有加密数据),并且伪造的KDC所发送的任何内容都必须经过验证才能得到信任使用一些它不知道的秘密。 ticket_lifetime: 设置初始票证请求的默认生存期。默认值为1天(即24h) renew_lifetime: 设置初始票证请求的默认可更新生命周期。默认值为0。我这里设置的是"7d"。 将renew_lifetime属性的值设置为7天。这允许Hadoop组件(如hive,oozie,hue等)更新其Kerberos票据。一旦发放票据,可以在7天内续订。 forwardable: 如果此标志为true,则默认情况下,如果KDC允许,初始票证将是可转发的(这意味着如果具有TGT的用户登录到远程系统,则KDC可以颁发新的TGT,而不需要用户再次进行身份验证)。默认值为false。我这里设置的是"true" [kdc]: 作用: 本案例中,该字的作用在于指定kdc.conf文件的位置。 [realms] 作用: 文件的[realms]部分中的每个标记都是Kerberos领域的名称。标签的值是一个具有定义该特定领域的属性的关系的小节。 常用标签: kdc: 在该领域中运行KDC的主机的名称或地址。可以包括一个可选的端口号,以冒号与主机名分隔。如果名称或地址包含冒号(例如,如果它是IPv6地址),则将其括在方括号中,以将冒号与端口分隔符区分开。为了使您的计算机能够与每个领域的KDC通信,必须在配置文件的每个领域子部分中为该标记赋予一个值,或者必须有DNS SRV记录指定KDC。 可以为KDC指定一个端口,如果没有配置,则KDC使用默认端口88。 admin_server: 标识运行管理服务器的主机。通常,这是主Kerberos服务器。必须为此标签赋予一个值,以便与该领域的kadmind服务器通信。 可以为admin_server指定一个端口,如果没有配置,则使用默认端口749。 [domain_realm]: 作用: 提供了从域名或主机名到Kerberos领域名称的转换(指定DNS域名和Kerberos域名之间的映映射关系。指定服务器的FQDN,对应的domain_realm值决定了主机所属的域)。 标签名称可以是主机名或域名,其中域名以句点(.)表示。该关系的值是该特定主机或域的Kerberos领域名称。除非提供明确的域名关系,否则主机名关系将隐式提供相应的域名关系。可以在领域部分中或使用DNS SRV记录来标识Kerberos领域。主机名和域名应小写。 博主推荐阅读: https://www.cnblogs.com/yinzhengjie/p/10765503.html https://web.mit.edu/kerberos/krb5-latest/doc/admin/conf_files/krb5_conf.html
三.配置KDC的配置文件(kdc.conf)
对于通常仅在KDC上使用的程序,例如:"krb5kdc"和"kadmind"守护程序以及"kdb5_util"程序,kdc.conf文件补充了krb5.conf。此处记录的关系也可以在krb5.conf中指定;对于提到的KDC程序,krb5.conf和kdc.conf将合并到一个配置文件中。 通常,kdc.conf文件位于KDC状态目录 LOCALSTATEDIR中/krb5kdc。您可以通过设置环境变量KRB5_KDC_PROFILE覆盖默认位置。 温馨提示:
您需要重新启动KDC守护程序才能使所有配置更改生效。
1>.创建KDC的配置文件(该文件需要手动创建)
[root@kdc.yinzhengjie.com ~]# vim /yinzhengjie/softwares/kerberos/var/krb5kdc/kdc.conf [root@kdc.yinzhengjie.com ~]# [root@kdc.yinzhengjie.com ~]# cat /yinzhengjie/softwares/kerberos/var/krb5kdc/kdc.conf [kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] YINZHENGJIE.COM = { profile = /etc/krb5.conf supported_enctypes = aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal allow-null-ticket-addresses = true database_name = /yinzhengjie/softwares/kerberos/data/principal #master_key_type = aes256-cts acl_file = /yinzhengjie/softwares/kerberos/data/kadm5.acl dict_file = /yinzhengjie/softwares/kerberos/share/dict/words max_life = 2d 0h 0m 0s max_renewable_life = 7d 0h 0m 0s admin_database_lockfile = /yinzhengjie/softwares/kerberos/data/kadm5_adb.lock key_stash_file = /yinzhengjie/softwares/kerberos/data/.k5stash kdc_ports = 88 kadmind_port = 749 default_principal_flags = +renewable } [root@kdc.yinzhengjie.com ~]#
2>.配置文件关键参数说明
[kdcdefaults]: 作用: 指定领域变量的默认值,如果[realms]子部分不包含标签的关系,则使用这些缺省值。 常用标签: kdc_ports: 在1.15版之前,此关系列出了krb5kdc守护程序用来侦听UDP请求的端口 。在版本1.15和更高版本中,如果未定义关系,则其含义与"kdc_listen"相同。此处我设置的默认UDP端口是"88"。 如果您的Kerberos版本大于1.15版本,可以直接配置kdc_listen标签即可。 kdc_tcp_ports: 在1.15版之前,此关系列出了krb5kdc守护程序用来侦听UDP请求的端口 。在版本1.15和更高版本中,如果未定义该关系,则其含义与kdc_tcp_listen相同 。此处我设置的TCP默认端口是"88" 同上,如果您的Kerberos版本大于1.15版本,可以直接配置kdc_tcp_listen标签即可。 [realms]: 作用: 每个标签都是Kerberos领域的名称。标签的值是一个小节,其中关系定义了该特定领域的KDC参数。 常用标签: profile:(官方未找到该参数) 指定"krb5.conf"文件的路径,我这里设置的是"/etc/krb5.conf"。 supported_enctypes: 指定此领域的默认主体的键/盐组合。通过kadmin创建的任何主体都将具有这些类型的密钥。此标记的默认值为。我设置的值是"aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal" 关于Kerberos支持的"密钥算法"和"盐"相关参数,可参考官网: https://web.mit.edu/kerberos/krb5-latest/doc/admin/conf_files/kdc_conf.html#keysalt-lists allow-null-ticket-addresses:(官方未找到该参数) true database_name: 如果正在使用DB2模块,并且[dbmodules]配置节未指定数据库名称,则此关系指定此领域的Kerberos数据库的位置。默认值为LOCALSTATEDIR/krb5kdc/principal。我自定义数据库为本地路径"/yinzhengjie/softwares/kerberos/data/principal" master_key_type: 指定主密钥的密钥类型。的默认值为aes256-cts-hmac-sha1-96。 关于加密类型可参考官网: https://web.mit.edu/kerberos/krb5-latest/doc/admin/conf_files/kdc_conf.html#encryption-types acl_file: 访问控制列表文件的位置, kadmind用于确定允许哪些主体在Kerberos数据库上获得哪些权限。要在没有ACL文件的情况下进行操作,请使用将此关系设置为空字符串。 默认值为LOCALSTATEDIR。我自定义的路径为"/yinzhengjie/softwares/kerberos/data/kadm5.acl"。 关于Kerberos ACL文件的更多信息可参考官网: https://web.mit.edu/kerberos/krb5-latest/doc/admin/conf_files/kadm5_acl.html#kadm5-acl-5 dict_file: 字典文件的位置,其中包含不允许用作密码的字符串。该文件每行应包含一个字符串,且不能包含其他空格。如果未指定任何内容,或者没有为主体分配任何策略,则不会执行密码的字典检查。 此处我指定的路径为:"/yinzhengjie/softwares/kerberos/share/dict/words" max_life: 指定票证在此领域中可能有效的最长时间。默认值为24小时。 此处我自定义的时间为2天(即"2d 0h 0m 0s") 关于自定义时间的格式可参考官网: https://web.mit.edu/kerberos/krb5-latest/doc/basic/date_format.html#duration max_renewable_life: 指定可以在该领域中更新有效票证的最长时间。默认值为0。 我这里设置的时间是7天(即"7d 0h 0m 0s") admin_database_lockfile:(官方未找到该参数) /yinzhengjie/softwares/kerberos/data/kadm5_adb.lock key_stash_file: 指定主密钥的存储位置(通过kdb5_util存储)。缺省值为LOCALSTATEDIR/krb5kdc/.k5.REALM,其中REALM是Kerberos领域。 此处我自定义的存储位置为本地路径:"/yinzhengjie/softwares/kerberos/data/.k5stash" kdc_ports: 在1.15版之前,此关系列出了krb5kdc守护程序用来侦听UDP请求的端口 。在版本1.15和更高版本中, 如果未定义关系,则其含义与kdc_listen相同。 此处我自定义的端口为"88",需要注意的是官方已经不推荐使用该标签啦,强烈推荐大家使用kdc_listen。 kadmind_port: 指定kadmind守护程序用于侦听此领域的端口。在kadmind_listen条目中指定的端口号 将覆盖此端口号。为kadmind分配的端口是749,默认情况下使用。 关于kadmind命令的使用可参考官方链接: https://web.mit.edu/kerberos/krb5-latest/doc/admin/admin_commands/kadmind.html#kadmind-8 default_principal_flags: 指定在该领域中创建的主体的默认属性。该字符串的格式是用逗号分隔的标志列表,在应启用的每个标志之前带有“ +”,在应禁用的每个标志之前带有“-”。 需要注意的是,postdateable, forwardable, tgt-based, renewable, proxiable, dup-skey, allow-tickets, and service 标志默认是启用的。 官方支持的flag说明如下: allow-tickets: 启用此标志意味着KDC将为此主体发行票证。禁用此标志实际上会禁用该领域内的主体。 dup-skey: 启用此标志将使KDC可以为此主体颁发用户到用户的服务票证。 forwardable: 启用此标志允许委托人获得可转发票证。 hwauth 如果启用了此标志,则要求主体在接收任何票证之前使用硬件设备进行预认证。 no-auth-data-required 启用此标志可防止将PAC或AD-SIGNEDPATH数据添加到主体的服务票证中。 ok-as-delegate 如果启用了此标志,则暗示客户端可以并且应该在对服务进行身份验证时委派凭据。 ok-to-auth-as-delegate 启用此标志将允许委托人使用S4USelf票证。 postdateable 启用此标志可使委托人获得可更新日期的票证。 preauth 如果在客户端主体上启用了此标志,则在接收任何票证之前,要求该主体对KDC进行预身份验证。在服务主体上,启用此标志意味着该主体的服务票证将仅颁发给带有已设置了预认证位的TGT的客户端。 proxiable 启用此标志将允许委托人获得代理票证。 pwchange 启用此标志将强制为此主体更改密码。 pwservice 如果启用此标志,则将此主体标记为密码更改服务。这仅应在特殊情况下使用,例如,如果用户的密码已过期,则用户必须获得该主体的票证,而无需通过常规的密码身份验证才能更改密码。 renewable 启用此标志可以使委托人获得可再生票证。 service 启用此标志将使KDC可以为此主体发行服务票证。在版本1.17和更高版本中,如果设置了dup-skey标志,则仍允许使用用户到用户的服务票证。 tgt-based 启用此标志将允许委托人基于票证授予票证获得票证,而不是重复用于获取TGT的身份验证过程。
3>.温馨提示
kdc.conf文件有两个主要部分。[kdcdefaults]部分包含在此文件中列出的所有领域的通用配置;[realms]部分列出了每个领域的配置。
当然,如果您仔细看过官方文档应该还知道有[dbdefaults]定义默认数据库设置,[dbmodules]定义每个数据库的设置以及[logging]控制Kerberos守护程序如何执行日志记录。官方文档参考下面的链接。
博主推荐阅读: https://web.mit.edu/kerberos/krb5-latest/doc/admin/conf_files/kdc_conf.html
四.配置访问控制列表文件(kadm5.acl)
1>.访问控制列表文件概述
Kerberos kadmind守护程序使用访问控制列表(ACL)文件来管理对Kerberos数据库的访问权限。对于影响主体的操作,ACL文件还控制哪些主体可以对其他哪些主体进行操作。
Kerberos ACL文件的默认位置是 LOCALSTATEDIR/krb5kdc/kadm5.acl,除非它被kdc.conf中的acl_file变量覆盖(很明显,我上面自定义来了acl_file的路径为"/yinzhengjie/softwares/kerberos/data/kadm5.acl")。
2>.访问控制文件语法格式说明
ACL单行的语法格式为: principal permissions [target_principal [restrictions] ] 关键参数说明: 主体(principal): 指定要设置其权限的主体。我们可以指定部分或完全限定的Kerberos主体名称,因为名称的每个组成部分都可以使用* 字符进行通配符。 权限(permissions): 指定匹配特定条目的委托人可以执行或可以不执行哪些操作 。这是一个或多个以下字符列表或大写字母的字符串。如果字符是大写字母,则不允许该操作。如果字符是小写字母,则允许该操作。 支持的权限列表如下所示: a[A]: 允许[禁止]添加主体(principals)或策略(policies)。 c[C]: 允许[禁止]更改主体(principals)密码 d[D]: 允许[禁止]添加主体(principals)或策略(policies)。 e[E]: 允许[禁止]提取主体(principals)的keys信息。该extract特权不包括在通配符(即下面提到的"*"和"x"特权)特权中;必须对其进行明确分配。
此特权允许用户从数据库中提取密钥,并且必须非常小心地进行操作,以避免泄露重要的密钥,例如:"kadmin/*"或"krbtgt/*"主体的密钥。所述lockdown_keys主要属性可以被用来防止从特定主体密钥提取不管授予特权。 i[I]: 允许[禁止]查询主体(principals)或策略(policies)。 l[L]: 允许[禁止]列出所有主体(principals)或策略(policies)。 m[M]: 允许[禁止]修改主体(principals)或策略(policies)。 p[P]: 允许[禁止]传播主体(principals)数据库(用于增量数据库传播,比如多机房) s[S]: 允许[禁止]显式设置主体(principals)的密钥 x[X]: admcilsp的缩写。代指所有特权(除外e)。 *: 与X相同。 目标主体(target_principal): (可选。部分或完全限定的Kerberos主体名称。)指定可以对其应用权限的主体。名称的每个组件可以使用*字符进行通配符。 target_principal还可以包含对principal的反向引用,其中*number与principal中对应的通配符匹配。 限制条件(restrictions): (可选)一串标志。允许的限制为: {+|-}flagnameflag: 标志被强制为指示值。允许的标志与kdc.conf中的default_principal_flags 变量的标志相同。 -clearpolicypolicy: 策略被强制为空。 -policy pol: 政策被迫成为政治政策。 -{expire, pwexpire, maxlife, maxrenewlife} time: 关联值将被强制为MIN(time,请求值)。 关于getdate time可参考官方文档: https://web.mit.edu/kerberos/krb5-latest/doc/basic/date_format.html#getdate-time 温馨提示: 空行和以尖号(#)开头的行将被忽略。 ACL文件中的行顺序很重要。第一个匹配条目将控制对目标主体上的参与者主体的访问。 以上标志用作对由于该ACL行而允许的任何添加或修改操作的限制。 博主推荐阅读: https://web.mit.edu/kerberos/krb5-latest/doc/admin/conf_files/kadm5_acl.html
3>.案例说明

[root@kdc.yinzhengjie.com ~]# mkdir -pv /yinzhengjie/softwares/kerberos/data mkdir: created directory ‘/yinzhengjie/softwares/kerberos/data’ [root@kdc.yinzhengjie.com ~]# [root@kdc.yinzhengjie.com ~]# vim /yinzhengjie/softwares/kerberos/data/kadm5.acl [root@kdc.yinzhengjie.com ~]# [root@kdc.yinzhengjie.com ~]# cat /yinzhengjie/softwares/kerberos/data/kadm5.acl */admin@YINZHENGJIE.COM * [root@kdc.yinzhengjie.com ~]#
案例一: */admin@YINZHENGJIE.COM * 说明如下: YINZHENGJIE.COM具有admin实例的领域中的任何主体都具有除提取密钥之外的所有管理特权。
在我的访问控制文件中,默认就是用了案例一的配置。 案例二: jason@YINZHENGJIE.COM ADMCIL jason/*@YINZHENGJIE.COM i */root@YINZHENGJIE.COM 说明如下: jason除了使用admin实例提取键jason/admin@YINZHENGJIE.COM(与案例一)外,用户具有所有权限。 他对空实例没有任何权限,jason@YINZHENGJIE.COM。他的root和其他非admin、非空实例(例如extra或dbadmin)对具有实例根的任何主体具有inquire权限。 案例三: */root@YINZHENGJIE.COM ci *1@YINZHENGJIE.COM 说明如下: 任何root委托人都YINZHENGJIE.COM可以查询或更改其null实例的密码,但不能查询或更改其他null实例的密码。(在这里,*1表示对与actor主体中的第一个通配符匹配的组件的反向引用。) 案例四: */root@YINZHENGJIE.COM l * 说明如下: 任何root主体都YINZHENGJIE.COM可以在数据库中生成主体列表,并在数据库中生成策略列表。该行与案例三分开,因为列表权限只能全局授予,而不能授予特定的目标主体。 案例五: sms@YINZHENGJIE.COM x * -maxlife 9h -postdateable 说明如下: 最后,服务管理系统主体 sms@YINZHENGJIE.COM具有除提取密钥之外的所有权限,但是它创建或修改的任何主体都将无法获得可更新日期的票证或寿命超过9小时的票证。
五.Hadoop相关的Kerberos设置
博主推荐阅读: https://www.cnblogs.com/yinzhengjie2020/p/13616881.html
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。 欢迎加入基础架构自动化运维:598432640,大数据SRE进阶之路:959042252,DevOps进阶之路:526991186
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架