2024-03-30
LDAP
00

目录

第一部分 概述
1.1 OpenLDAP简介
1.2 OpenLDAP的特点
1.3 OpenLDAP的应用场景
第二部分 OpenLdap安装
2.1 CentOS准备
2.2 安装Libtool
2.3 安装/升级openssl
2.4 安装OpenLdap
2.5 配置日志
2.5.1 rsyslog
2.5.2 syslog
2.6 防火墙配置
2.7 启动与测试
2.7.1 启动服务
2.7.2 生成配置
2.7.4 测试连接
第三部分 附录
3.1 arm环境编译
3.2 安装BerkeleyDB
3.3 安装OpenLdap2.4.x
3.4 BerkeleyDB优化
3.5 Operating system: x86_64-whatever-linux2 You need Perl 5.
3.6 麒麟国防版系统安装OpenLdap2.5
3.7 openEuler20.03安装OpenLdap2.5

第一部分 概述

OpenLDAP是一个开源的LDAP(轻量级目录访问协议)服务器,它提供了一个健壮、高性能的目录服务,适用于多种应用场景。

1.1 OpenLDAP简介

OpenLDAP项目起始于1999年,是OpenLDAP2.0的后续版本。它由OpenLDAP社区维护,是一个功能丰富的目录服务器,支持LDAPv3协议,并且兼容LDAPv2。 OpenLDAP支持多种后端存储方式,包括但不限于Berkley DBHDB(Hierarchical Database)MDB(Memory-Mapped Database)以及Monitor backend。此外,OpenLDAP还提供了丰富的客户端库,允许开发者在各种编程语言中实现对LDAP服务器的操作。

1.2 OpenLDAP的特点

  • 高性能:OpenLDAP能够处理大量的并发访问,适合作为大型企业或服务的目录服务。
  • 可扩展性:OpenLDAP支持多种存储后端,可以根据实际需求灵活选择。
  • 安全性:提供了多种安全机制,包括TLS/SSL加密、SASL认证等,确保数据传输的安全性。
  • 灵活性:OpenLDAP支持LDAPv3协议,允许通过扩展来实现更多的特性。
  • 开源:OpenLDAP遵循开源协议,拥有活跃的社区支持,可以免费使用和修改。

1.3 OpenLDAP的应用场景

  • 身份验证和授权:OpenLDAP可以作为企业内部的用户认证中心,为各种应用和服务提供统一的认证机制。通过LDAP协议,应用可以查询用户信息,实现登录验证、权限控制等功能。
  • 目录服务:OpenLDAP可以存储组织结构信息,如员工信息、部门结构等,供内部或外部应用查询使用。例如,企业邮箱系统可以使用LDAP来查找和解析邮件地址。
  • 单点登录(SSO):利用OpenLDAP可以实现单点登录,用户只需登录一次,就可以访问所有集成了LDAP的应用和服务,提高了用户体验和安全性。
  • 网络服务管理:OpenLDAP可以管理网络设备和资源,如打印机、文件服务器等,通过LDAP可以方便地查询和控制这些资源的访问权限。
  • 开发和测试:开发者可以在开发和测试阶段使用OpenLDAP,模拟真实的目录服务环境,验证应用程序的LDAP接口实现。

第二部分 OpenLdap安装

提示

目前OpenLdap的LTS版本为2.5.x,最新版本为2.6.x,本文将采用CentOS7版本进行OpenLdap2.5.16版本的安装步骤进行详细说明,相同小版本的安装步骤基本相同,如需使用2.4.x,可参考附录部分说明。

2.1 CentOS准备

提示

如不使用CentOS,选择Linux的其他发行版系统,安装步骤基本相同,由于系统间的差异,可能会出现部份依赖组件缺失的情况,按照提示安装即可。另外,本文后续安装步骤仅适用于x86架构操作系统,如果使用arm架构操作系统,请查看附录部分说明。

下载地址:https://www.centos.org/download/,根据自己的需求下载合适的系统版本,本文使用CentOS-7-x86_64-Minimal-2009.iso,因为仅做演示使用,Minimal版本安装包最小。

CentOS7可以安装在物理机上,也可以作为虚拟机运行。如使用虚拟机,可以选择常用的虚拟机软件,例如:

CentOS系统的安装过程不在本文讨论的范围,需要读者自行处理,安装完后可通过cat /etc/os-release查看系统的版本发布信息。

NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:7" HOME_URL="https://www.centos.org/" BUG_REPORT_URL="https://bugs.centos.org/" CENTOS_MANTISBT_PROJECT="CentOS-7" CENTOS_MANTISBT_PROJECT_VERSION="7" REDHAT_SUPPORT_PRODUCT="centos" REDHAT_SUPPORT_PRODUCT_VERSION="7"

2.2 安装Libtool

提示

如系统中已安装Libtool工具,可忽略本节。要检测系统中是否已安装Libtool,可以使用以下几种方法:

  • 使用which命令:which libtool,如果系统中安装了Libtool,which命令会输出Libtool的路径。如果没有输出,则表示Libtool未安装。
  • 使用libtool命令的--version选项:libtool --version,这个命令会显示Libtool的版本信息,如果Libtool已安装,将看到版本号和其他相关信息。如果没有安装,命令将不会执行或提示找不到命令。

相关信息

Libtool是一个构建和测试共享库的辅助工具,它隐藏了不同操作系统创建共享库时的复杂性,使得开发者可以编写可移植的代码,而不必担心依赖库的构建细节。Libtool的主要作用包括:

  • 创建共享库:Libtool可以生成共享库(动态链接库),这些库可以在不同的操作系统和硬件平台上使用。
  • 版本控制:Libtool支持对共享库的版本进行管理,这允许开发者发布新版本的库,同时保留旧版本,确保向后兼容性。
  • 条件编译:Libtool可以根据目标平台的特性进行条件编译,生成适用于特定系统的代码。
  • 符号隐藏:Libtool可以隐藏库中的符号,防止它们被其他程序意外使用,这有助于减少潜在的冲突和提高程序的封装性。
  • 测试和调试:Libtool提供了一些工具,帮助开发者测试和调试共享库,确保库的稳定性和性能。

Libtool安装步骤如下:

  1. 下载安装包:http://ftp.gnu.org/gnu/libtool/libtool-2.2.6a.tar.gz
  2. 上传安装包:将第一步中下载的软件包上传至服务器指定位置,比如:/opt/soft。如使用wget等工具在服务器上直接下载则本步骤可忽略
  3. 执行如下命令进行安装
shell
cd /opt/soft # 以实际目录为准 tar -zxvf libtool-2.2.6a.tar.gz cd libtool-2.2.6 ./configure make make install

提示

在执行./configure可能会因为系统缺失必须的组件导致执行失败,比如博主使用的是Minimal版本的系统,有很多工具是不存在的,在执行该命令时会出现类似如下错误:

## ------------------------- ## ## Configuring libtool 2.2.6 ## ## ------------------------- ## checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for a thread-safe mkdir -p... /usr/bin/mkdir -p checking for gawk... gawk checking whether make sets $(MAKE)... yes checking whether subdir libobjs are useable... yes checking for gcc... no checking for cc... no checking for cl.exe... no configure: error: no acceptable C compiler found in $PATH See `config.log' for more details.

此时,可以先安装缺失的组件再重新执行./configure以及后续命令。

shell
yum -y install gcc gcc-c++ gcc-gfortran
  1. 修改/etc/ld.so.conf文件,在其中添加一行/usr/local/lib,修改后的文件内容参考如下:
include ld.so.conf.d/*.conf /usr/local/lib
  1. 执行/sbin/ldconfig -v

相关信息

除了按照上述手动安装方式外,还可以通过系统的包管理器进行安装。例如,在Debian或Ubuntu系统中,可以使用以下命令安装Libtool:

shell
sudo apt-get install libtool

在Red Hat或CentOS系统中,可以使用:

shell
sudo yum install libtool

2.3 安装/升级openssl

提示

OpenLdap2.5.x依赖openssl 1.1.1+,可以通过openssl version命令查看系统中的openssl的版本信息,若未安装或版本号低于要求的版本则需要安装/升级,否则忽略本节。

openssl安装升级步骤如下:

  1. 下载安装包:https://www.openssl.org/source/openssl-1.1.1t.tar.gz
  2. 上传安装包:将第一步中下载的软件包上传至服务器指定位置,比如:/opt/soft。如使用wget等工具在服务器上直接下载则本步骤可忽略
  3. 执行如下命令进行安装
shell
cd /opt/soft # 以实际目录为准 tar -zxvf openssl-1.1.1t.tar.gz cd openssl-1.1.1t ./config --prefix=/usr/local/openssl make make install
  1. 修改/etc/ld.so.conf.d/ssl.conf文件,在其中添加一行/usr/local/openssl/lib,修改后的文件内容参考如下:
/usr/local/openssl/lib
  1. 继续执如下命令:
shell
ldconfig -v mv /usr/bin/openssl /usr/bin/openssl_bak ln /usr/local/openssl/bin/openssl /usr/bin/openssl
  1. 执行openssl version查看openssl是否安装/升级成功

2.4 安装OpenLdap

OpenLdap安装步骤如下:

  1. 下载安装包:https://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-2.5.16.tgz
  2. 上传安装包:将第一步中下载的软件包上传至服务器指定位置,比如:/opt/soft。如使用wget等工具在服务器上直接下载则本步骤可忽略
  3. 执行如下命令进行安装
shell
cd /opt/soft # 以实际目录为准 tar -zxvf openldap-2.5.16.tgz cd openldap-2.5.16 ./configure --prefix=/opt/openLDAP --enable-debug --enable-dynamic \ --enable-cleartext --enable-crypt --enable-modules --enable-passwd \ --enable-overlays --enable-accesslog --enable-autoca=no \ --with-tls=openssl CPPFLAGS="-I/usr/local/openssl/include" \ LDFLAGS="-L/usr/local/openssl/lib" make depend make make install

注意

上述步骤安装完成后,OpenLdap会安装在/opt/openLDAP目录,在执行./configure时若出现无法找到openssl库文件信息,则需要调整CPPFLAGS参数,将其指向正确的openssl路径。通常情况按照2.3章节步骤安装/升级openssl,则在OpenLdap配置阶段 不会出现异常。另外在配置中使用了相对通用的配置参数,如您有特殊的业务需求则需要按需调整,但是如果您不清楚配置的含义以及修改后带来的影响,则建议您保持上述命令执行。

在OpenLdap2.5.x的版本中已经完全移除了对BDB数据库引擎的支持,默认采用MDB数据库引擎,所以在安装过程中不需要事先安装BDB

2.5 配置日志

提示

日志并不是强制需要配置的,但是通常为了可追溯,宕机问题可排查,建议对日志进行配置。OpenLdap默认使用LOCAL4记录日志,可以通过配置syslog不同步文件系统来提高某些系统上的日志记录性能(man syslogd/syslog.conf)。在Linux中,可以在syslog.conf中以“-”作为日志文件名的前缀。示例如下:

# LDAP logs local4.* -/var/log/slapd.log

配置日志时需要注意系统中使用的日志系统,根据不同的日志系统进行配置,常用的日志系统为rsyslogsyslog,二者在配置上有些许差异,请注意甄别,在现代系统中一般会使用rsyslog替代syslog

2.5.1 rsyslog

  1. 修改/etc/rsyslog.conf文件,在其中添加一行local4.* -/var/log/slapd.log
  2. 重启rsyslog服务
shell
service rsyslog restart

相关信息

如果系统正在使用rsyslog,那么/etc/syslog.conf文件可能会被忽略,而使用/etc/rsyslog.conf进行配置。在一些系统中,为了向后兼容性,/etc/rsyslog.conf文件可能会包含对/etc/syslog.conf中规则的转发。然而,最好的做法是直接编辑/etc/rsyslog.conf以配置现代的rsyslog服务

2.5.2 syslog

  1. 修改/etc/syslog.conf文件,在其中添加一行local4.* /var/log/slapd.log
  2. 重启syslog服务
shell
service syslog restart

2.6 防火墙配置

OpenLdap在运行后会使用389端口,如果操作系统启用了防火墙,则需要添加该端口,避免其他主机无法正常连接。参考命令如下:

shell
firewall-cmd --zone=public --add-port=389/tcp --permanent systemctl restart firewalld.service

2.7 启动与测试

至此OpenLdap已经安装完成,在本节中,我们将启动OpenLdap的服务进行测试验证。

2.7.1 启动服务

OpenLdap安装完成后,会生成一个默认的配置文件/opt/openLDAP/etc/openldap/slapd.conf,在验证阶段可以直接基于该文件启动服务。

在启动OpenLdap的服务之前,需要先检查数据文件存储的文件夹是否存在,如不存在则需要新创建,否则服务会启动失败。默认数据文件存储路径为/opt/openLDAP/var/openldap-data,可通过如下命令创建对应的文件夹:

shell
cd /opt/openLDAP/var/ mkdir openldap-data

准备工作完成后,执行如下命令启动OpenLdap服务:

shell
cd /opt/openLDAP/libexec && ./slapd

若配置了日志,则可通过日志查看OpenLdap的启动状态。

shell
tail -500f /var/log/slapd.log

成功启动的参考日志如下:

Mar 30 16:53:11 MiWiFi-R3-srv slapd[6055]: @(#) $OpenLDAP: slapd 2.5.16 (Mar 30 2024 16:08:56) $#012#011root@MiWiFi-R3-srv:/opt/soft/openldap-2.5.16/servers/slapd Mar 30 16:53:11 MiWiFi-R3-srv slapd[6056]: slapd starting

除了通过日志判断外,还可以通过进程以及端口信息判断OpenLdap的服务是否正常启动。

  • 进程ps -aux | grep slapd
  • 端口netstat -an|grep :389

相关信息

netstat命令无法使用,可通过如下命令安装常用的命令工具:

shell
yum -y install net-tools psmisc

2.7.2 生成配置

OpenLdap的服务启动后,对于首次安装的OpenLdap需要基于slapd.conf文件生成配置信息以验证配置文件是否正常,可通过如下命令生成配置:

shell
cd /opt/openLDAP/etc/openldap/ mkdir slapd.d cd /opt/openLDAP/sbin/ ./slaptest -f /opt/openLDAP/etc/openldap/slapd.conf -F /opt/openLDAP/etc/openldap/slapd.d/

若输出config file testing succeeded则表示配置正常,然后重启OpenLdap的服务。

shell
kill -9 $(cat /opt/openLDAP/var/run/slapd.pid) cd /opt/openLDAP/libexec && ./slapd

注意

如果目录/opt/openLDAP/etc/openldap/slapd.d下有文件,表示配置用slapd.d目录下的配置,slapd.conf的配置将不再生效,重新配置时需要删除slapd.d下的所有文件,重新用命令生成。

2.7.4 测试连接

在OpenLdap中内置了一些常用的工具,比如ldapsearch可用于搜索OpenLdap中的数据,可以使用该工具进行连接测试。

shell
cd /opt/openLDAP/bin ./ldapsearch -x -D "cn=Manager,dc=my-domain,dc=com" -W -b "cn=config"

执行命令后会要求输入密码,因为使用默认配置,在配置文件中的密码为secret,可以使用该密码进行认证,认证通过后返回参考数据如下则表示测试正常

# extended LDIF # # LDAPv3 # base <cn=config> with scope subtree # filter: (objectclass=*) # requesting: ALL # # search result search: 2 result: 32 No such object # numResponses: 1

相关信息

ldapsearch是一个用于查询服务器的命令行工具。它允许用户根据指定的搜索条件检索目录中的信息。ldapsearch支持多种参数,用于定制查询的行为和输出。以下是一些常用的ldapsearch参数及其含义:

  • -x:使用简单认证方式进行 LDAP 绑定。这通常意味着使用明文密码进行认证。
  • -D:指定绑定 DN(Distinguished Name),用于对 LDAP 服务器进行身份验证的用户的标识。
  • -W:提示用户输入绑定时使用的密码。
  • -H:指定 LDAP 服务器的 URL。
  • -b:指定搜索的基准 DN(Distinguished Name),即搜索的起始点。
  • -s:指定搜索范围,可以是 base(基本对象搜索),one(单级搜索),或 sub(子级搜索)。
  • -u:指定搜索的属性,只返回这些属性的值。

第三部分 附录

3.1 arm环境编译

arm架构下安装OpenLdap,整体步骤一致,在执行某些命令时可能会出现configure: error: cannot guess build type; you must specify one错误,则需要在执行的命令最后面加上--build=arm,比如:

shell
./configure --build=arm

3.2 安装BerkeleyDB

OpenLdap2.4.x版本中可以选择使用BDB作为数据库引擎,BDB的安装步骤如下:

  1. 下载安装包:http://download.oracle.com/berkeley-db/db-5.2.36.tar.gz
  2. 上传安装包:将第一步中下载的软件包上传至服务器指定位置,比如:/opt/soft。如使用wget等工具在服务器上直接下载则本步骤可忽略
  3. 执行如下命令进行安装
shell
cd /opt/soft # 以实际目录为准 tar -zxvf db-5.2.36.tar.gz cd db-5.2.36 ./dist/configure --prefix=/opt/BerkeleyDB make make install

相关信息

Berkeley DB是一个开源的嵌入式数据库系统,由Sleepycat Software公司开发,并在2006年被Oracle公司收购。它提供了一个高效的键值存储解决方案,广泛应用于各种需要数据存储和检索功能的应用程序中。

Berkeley DB的主要特点:

  • 嵌入式数据库:Berkeley DB是一个嵌入式数据库,意味着它可以直接集成到应用程序中,不需要单独的数据库服务器进程。这使得它非常适合于需要快速、轻量级数据访问的应用程序。
  • 键值存储:Berkeley DB提供了一个基于键值的数据存储模型,类似于哈希表。每个数据项都有一个唯一的键,通过这个键可以快速检索到对应的值。
  • 事务支持:Berkeley DB支持事务处理,这意味着可以对数据库进行一系列操作,并且这些操作要么全部成功,要么全部失败,保证了数据的一致性。
  • 并发控制:Berkeley DB支持多线程并发访问,允许多个线程同时对数据库进行读写操作,提高了应用程序的性能。
  • 数据持久性:Berkeley DB支持将数据持久化到磁盘,即使应用程序或系统崩溃,数据也不会丢失。
  • 跨平台:Berkeley DB可以在多种操作系统上运行,包括Windows、Linux、macOS等。
  • 灵活性:Berkeley DB提供了多种数据库配置选项,可以根据应用程序的需要进行定制。

Berkeley DB的应用场景:

  • 配置管理:Berkeley DB可以作为应用程序的配置存储,保存配置参数和用户偏好设置。
  • 缓存系统:由于其高性能和快速的数据访问能力,Berkeley DB经常被用作缓存系统,存储频繁访问的数据,以减少对后端数据库的访问。
  • 移动设备:Berkeley DB的轻量级特性使其适合在资源受限的移动设备上使用。
  • 文件系统:Berkeley DB可以作为文件系统的存储后端,提供高效的文件索引和检索功能。
  • 网络服务:在需要快速响应和高并发处理的网络服务中,Berkeley DB可以作为后端数据库来存储会话信息、用户状态等。
  • 嵌入式系统:Berkeley DB的小型和高效特性使其适合嵌入到各种嵌入式系统中,如家用电器、工业控制系统等。

3.3 安装OpenLdap2.4.x

OpenLdap2.4.x安装步骤如下:

  1. 下载安装包:https://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-2.4.59.tgz
  2. 上传安装包:将第一步中下载的软件包上传至服务器指定位置,比如:/opt/soft。如使用wget等工具在服务器上直接下载则本步骤可忽略
  3. 执行如下命令进行安装
shell
cd /opt/soft # 以实际目录为准 tar -zxvf openldap-2.4.59.tgz cd openldap-2.4.59 LD_LIBRARY_PATH="/opt/BerkeleyDB/lib" ./configure --prefix=/opt/openLDAP \ --enable-debug --enable-dynamic --enable-cleartext --enable-crypt \ --enable-modules --enable-monitor --enable-passwd --enable-overlays \ --enable-accesslog CPPFLAGS="-I/opt/BerkeleyDB/include" \ LDFLAGS="-L/opt/BerkeleyDB/lib" make depend make make install

注意

在安装OpenLdap2.4.x如果出现configure: error: Berkeley DB version mismatch*错误则需要更改配置命令,添加LD_LIBRARY_PATH="/opt/BerkeleyDB/lib,在上述命令中已经添加该参数。

3.4 BerkeleyDB优化

BDB数据库在默认情况下存在性能问题,所以使用BDB数据库存储数据时需要对其进行性能优化。在配置完slapd.conf文件后,启动OpenLdap之前,需要在数据库所在文件夹中添加DB_CONFIG文件对BDB数据进行优化以提升其性能(对已生成的BDB数据库文件夹中添加该文件无效),参考配置文件如下:

# $OpenLDAP$ # Example DB_CONFIG file for use with slapd(8) BDB/HDB databases. # # See the Oracle Berkeley DB documentation # <http://www.oracle.com/technology/documentation/berkeley-db/db/ref/env/db_config.html> # for detail description of DB_CONFIG syntax and semantics. # # Hints can also be found in the OpenLDAP Software FAQ # <http://www.openldap.org/faq/index.cgi?file=2> # in particular: # <http://www.openldap.org/faq/index.cgi?file=1075> # Note: most DB_CONFIG settings will take effect only upon rebuilding # the DB environment. # one 0.25 GB cache set_cachesize 0 268435456 1 # Data Directory #set_data_dir db # Transaction Log settings set_lg_regionmax 262144 set_lg_bsize 2097152 #set_lg_dir logs # Note: special DB_CONFIG flags are no longer needed for "quick" # slapadd(8) or slapindex(8) access (see their -q option).

3.5 Operating system: x86_64-whatever-linux2 You need Perl 5.

在编译openssl时,若出现Operating system: x86_64-whatever-linux2 You need Perl 5.错误,则可通过如下步骤安装perl:

  1. 下载安装包:https://www.cpan.org/src/5.0/perl-5.34.0.tar.gz
  2. 上传安装包:将第一步中下载的软件包上传至服务器指定位置,比如:/opt/soft。如使用wget等工具在服务器上直接下载则本步骤可忽略
  3. 执行如下命令进行安装
shell
cd /opt/soft # 以实际目录为准 tar -zxvf perl-5.34.0.tar.gz cd perl-5.34.0 ./Configure -des -Dprefix=$HOME/localperl make make test make install

3.6 麒麟国防版系统安装OpenLdap2.5

操作系统发版信息如下:

NAME="Kylin Linux Advanced Server" VERSION="V10 (GFB)" ID="kylin" VERSION_ID="V10" PRETTY_NAME="Kylin Linux Advanced Server V10 (GFB)" ANSI_COLOR="0;31"

在麒麟国防版系统中安装OpenLdap2.5,可以简化上述安装流程,无需手动安装libtoolopenssl。本文中2.4 安装OpenLdap(含)步骤可以合并为如下步骤:

  1. 下载安装包:https://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-2.5.16.tgz
  2. 上传安装包:将第一步中下载的软件包上传至服务器指定位置,比如:/opt/soft。如使用wget等工具在服务器上直接下载则本步骤可忽略
  3. 执行如下命令进行安装
shell
yum -y install make gcc gcc-c++ gcc-gfortran libtool libtool-ltdl libtool-ltdl-devel openssl-devel cd /opt/soft # 以实际目录为准 tar -zxvf openldap-2.5.16.tgz cd openldap-2.5.16 ./configure --prefix=/opt/openLDAP --enable-debug --enable-dynamic \ --enable-cleartext --enable-crypt --enable-modules --enable-passwd \ --enable-overlays --enable-accesslog --enable-autoca=no \ --with-tls=openssl make depend make make install

编译安装完成后,后续配置步骤与上述内容一致,无需特殊调整。

3.7 openEuler20.03安装OpenLdap2.5

使用openEuler20.03进行OpenLdap2.5编译安装时可能会出现如下错误:

make: /lib64/libc.so.6: version `GLIBC_2.34' not found (required by /usr/local/lib/libltdl.so.7)

该错误是因为系统中依赖glibc版本太低,此时可以将系统中yum源更换为22.03版本的信息,然后执行yum update glibc升级即可。

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:蒋固金

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!