第2节 IAM项目部署



❤️💕💕During the winter vacation, I followed up and learned two projects: tiktok project and IAM project, and summarized and practiced the CloudNative project and Go language. I learned a lot in the process.Myblog:http://nsddd.topopen in new window


[TOC]

前言

基本开发环境

查看我的环境:

root@cubmaster01:/# uname -va
Linux cubmaster01 5.4.0-135-generic #152-Ubuntu SMP Wed Nov 23 20:19:22 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
root@cubmaster01:/# go version 
go version go1.19.3 linux/amd64
root@cubmaster01:/# git version
git version 2.25.1

用户权限

使用普通用户登录和操作开发机也可以保证系统的安全性,这是一个比较好的习惯,所以我们在日常开发中也要尽量避免使用 Root 用户。

oot@cubmaster01:/# useradd cubiam
root@cubmaster01:/# passwd cubiam
New password: 
Retype new password: 
passwd: password updated successfully

添加 sudoers

普通用户也要用到 Root 的一些权限,但 Root 用户的密码一般是由系统管理员维护并定期更改的,每次都向管理员询问密码又很麻烦。因此,我建议你将普通用户加入到 sudoers 中,这样普通用户就可以通过 sudo 命令来暂时获取 Root 的权限。具体来说,你可以执行如下命令添加:

sed -i '/^root.*ALL=(ALL).*ALL/a\cubaim\tALL=(ALL) \tALL' /etc/sudoers

配置 $HOME/.bashrc 文件

我们登录新服务器后的第一步就是配置 $HOME/.bashrc 文件,以使 Linux 登录 shell 更加易用,例如配置 LANG 解决中文乱码,配置 PS1 可以避免整行都是文件路径,并将 $HOME/bin 加入到 PATH 路径中。配置后的内容如下:

# .bashrc
 
# User specific aliases and functions
# -i: 每次删除前提醒~
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
 
# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi
 
# User specific environment
# Basic envs
export LANG="en_US.UTF-8" # 设置系统语言为 en_US.UTF-8,避免终端出现中文乱码
export PS1='[\u@dev \W]\$ ' # 默认的 PS1 设置会展示全部的路径,为了防止过长,这里只展示:"用户名@dev 最后的目录名"
export WORKSPACE="$HOME/workspace" # 设置工作目录
export PATH=$HOME/bin:$PATH # 将 $HOME/bin 目录加入到 PATH 变量中
 
# Default entry folder
cd $WORKSPACE # 登录系统,默认进入 workspace 目录

有一点需要我们注意,在 export PATH 时,最好把 $PATH 放到最后,因为我们添加到目录中的命令是期望被优先搜索并使用的。配置完 $HOME/.bashrc 后,我们还需要创建工作目录 workspace。将工作文件统一放在 $HOME/workspace 目录中,有几点好处。

  1. 可以使我们的 HOME目录保持整洁,便于以后的文件查找和分类。
  2. 如果哪一天 /分区空间不足,可以将整个 workspace 目录 mv 到另一个分区中,并在 /分区中保留软连接,例如:/home/going/workspace -> /data/workspace/。
  3. 如果哪天想备份所有的工作文件,可以直接备份 workspace。

具体的操作指令是 mkdir -p $HOME/workspace。配置好 HOME/.bashrc 文件后,我们就可以执行 bash 命令将配置加载到当前 shell 中了。

安装 git

因为安装 IAM 系统、执行 go get 命令、安装 protobuf 工具等都是通过 Git 来操作的,所以接下来我们还需要安装 Git。由于低版本的 Git 不支持 --unshallow 参数,而 go get 在安装 Go 包时会用到 git fetch --unshallow 命令,因此我们要确保安装一个高版本的 Git,具体的安装方法如下:

$ cd /tmp
$ wget --no-check-certificate https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.39.0.tar.gz
$ tar -xvzf git-2.39.0.tar.gz
$ cd git-2.39.0/
$ ./configure
$ make
$ sudo make install
$ git --version          # 输出 git 版本号,说明安装成功
git version 2.39.0
tee -a $HOME/.bashrc <<'EOF'
# Configure for git
export PATH=/usr/local/libexec/git-core:$PATHEOF

配置 Git。我们直接执行如下命令配置 Git

git config --global user.name "Xinwei Xiong"    # 用户名改成自己的
git config --global user.email "3293172751nss@gmail.com"    # 邮箱改成自己的
git config --global credential.helper store    # 设置 Git,保存用户名和密码
git config --global core.longpaths true # 解决 Git 中 'Filename too long' 的错误

除了按照上述步骤配置 Git 之外,我们还有几点需要注意。首先,在 Git 中,我们会把非 ASCII 字符叫做 Unusual 字符。这类字符在 Git 输出到终端的时候默认是用 8 进制转义字符输出的(以防乱码),但现在的终端多数都支持直接显示非 ASCII 字符,所以我们可以关闭掉这个特性,具体的命令如下:

git config --global core.quotepath off

其次,GitHub 限制最大只能克隆 100M 的单个文件,为了能够克隆大于 100M 的文件,我们还需要安装 Git Large File Storage,安装方式如下:

git lfs install --skip-repo

go语言环境变量设置和含义

我们在设置Go语言的环境变量:

$ tee -a $HOME/.bashrc <<'EOF'
# Go envs
export GOVERSION=go1.18.3 # Go 版本设置
export GO_INSTALL_DIR=$HOME/go # Go 安装目录
export GOROOT=$GO_INSTALL_DIR/$GOVERSION # GOROOT 设置
export GOPATH=$WORKSPACE/golang # GOPATH 设置
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH # 将 Go 语言自带的和通过 go install 安装的二进制文件加入到 PATH 路径中
export GO111MODULE="on" # 开启 Go moudles 特性
export GOPROXY=https://goproxy.cn,direct # 安装 Go 模块时,代理服务器设置
export GOPRIVATE=
export GOSUMDB=off # 关闭校验 Go 依赖包的哈希值
EOF

为什么要增加这么多环境变量呢?这是因为,Go 语言是通过一系列的环境变量来控制 Go 编译器行为的。因此,我们一定要理解每一个环境变量的含义。

image-20230115235526661

因为 Go 以后会用 Go modules 来管理依赖,所以我建议你将 GO111MODULE 设置为 on。

在使用模块的时候,$GOPATH 是无意义的,不过它还是会把下载的依赖储存在 $GOPATH/pkg/mod 目录中,也会把 go install 的二进制文件存放在 $GOPATH/bin 目录中。

另外,我们还要将 $GOPATH/bin$GOROOT/bin 加入到 Linux 可执行文件搜索路径中。这样一来,我们就可以直接在 bash shell 中执行 go 自带的命令,以及通过 go install 安装的命令。

vim go-plug

安装:

git clone --depth=1 https://github.com/fatih/vim-go.git ~/.vim/pack/plugins/start/vim-go

vim-go 会用到一些 Go 工具,比如在函数跳转时会用到 guru、godef 工具,在格式化时会用到 goimports,所以你也需要安装这些工具。安装方式如下:执行 vi /tmp/test.go,然后输入 :GoInstallBinaries 安装 vim-go 需要的工具。安装后的 Go IDE 常用操作的按键映射如下表所示:

image-20230116195849590

ProtoBuf 编译环境安装

接着,我们再来安装 protobuf 的编译器 protocprotoc 需要 protoc-gen-go 来完成 Go 语言的代码转换,因此我们需要安装 protocprotoc-gen-go 这 2 个工具。它们的安装方法比较简单,你直接看我下面给出的代码和操作注释就可以了。

Protocol Buffers(缩写为 protobuf)是 Google 开发的一种数据交换格式。它是一种结构化数据存储格式,可用于结构化数据串行化,或者说把数据从程序中“变成”字节流,又可以把字节流重新“变成”程序中的数据。由于 protobuf 是跨语言的,所以它可以被多种语言的程序使用。

# 第一步:安装 protobuf
$ cd /tmp/
$ git clone -b v3.21.1 --depth=1 https://github.com/protocolbuffers/protobuf
$ cd protobuf
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install
$ protoc --version # 查看 protoc 版本,成功输出版本号,说明安装成功
libprotoc 3.21.1

# 第二步:安装 protoc-gen-go
$ go install github.com/golang/protobuf/protoc-gen-go@v1.5.2

IAM手动部署

和Kubernetes一样,可以支持手动部署和自动部署。

IAM 系统是一个企业级的项目,有一定的复杂度,安装的话需要小心~

部署的步骤:

  1. 安装和配置数据库:我们需要安装和配置 MariaDB、Redis 和 MongoDB。
  2. 安装和配置 IAM 服务:我们需要安装和配置 iam-apiserver、iam-authz-server、iam-pump、iamctl 和 man 文件。

有的人直接将整个环境打包了:

我自己是在 docker 容器中部署的,我把项目部署好的容器打包上传了,有需要的同学可以直接拉下来用(docker pull mjcjm/centos-go-project),启动参数一定要用:docker run -tid --name 容器名称 -v /sys/fs/cgroup:/sys/fs/cgroup --privileged=true 镜像 id /usr/sbin/init

下载项目代码

因为 IAM 的安装脚本存放在 iam 代码仓库中,安装需要的二进制文件也需要通过 iam 代码构建,所以在安装之前,我们需要先下载 iam 代码:

$ cd $WORKSPACE
$ git clone https://github.com/cubxxw/iam.git
$ go work use ./iam

设置别名和环境变量:

tee -a $HOME/.bashrc << 'EOF'
# Alias for quick access
export GOSRC="$WORKSPACE/"
export IAM_ROOT="$HOME/workspces/iam"
alias mm="cd $HOME/workspces"
alias i="cd $HOME/workspces/iam"
EOF

在安装配置IAM系统之前需要你执行以下命令export going 用户的密码,这里假设密码是 iam59!z$

export LINUX_PASSWORD='iam59!z$'

在项目开发中,像密码、密钥 Key 这类敏感信息,一般不会直接硬编码在系统中,而是通过环境变量的方式来使用。现网应用的配置文件是存放在一个安全的网络环境中,并且有访问授权流程,比较安全,这种配置文件中是可以配置密码等敏感信息的。

安装和配置数据库

因为 IAM 系统用到了 MariaDB、Redis、MongoDB 数据库来存储数据,而 IAM 服务在启动时会先尝试连接这些数据库,所以为了避免启动时连接数据库失败,这里我们先来安装需要的数据库。

MariaDB

mysql:

IAM 会把 REST 资源的定义信息存储在关系型数据库中,关系型数据库我选择了 MariaDB。为啥选择 MariaDB,而不是 MySQL 呢?。选择 MariaDB 一方面是因为它是发展最快的 MySQL 分支,相比 MySQL,它加入了很多新的特性,并且它能够完全兼容 MySQL,包括 API 和命令行。另一方面是因为 MariaDB 是开源的,而且迭代速度很快。

cd $IAM_ROOT
./scripts/install/mariadb.sh iam::mariadb::install

Redis

在 IAM 系统中,由于 iam-authz-server 是从 iam-apiserver 拉取并缓存用户的密钥 / 策略信息的,因此同一份密钥 / 策略数据会分别存在 2 个服务中,这可能会出现数据不一致的情况。数据不一致会带来一些问题,例如当我们通过 iam-apiserver 创建了一对密钥,但是这对密钥还没有被 iam-authz-server 缓存,这时候通过这对密钥访问 iam-authz-server 就会访问失败。

为了保证数据的一致性,我们可以使用 Redis 的发布订阅 (pub/sub) 功能进行消息通知。同时,iam-authz-server 也会将授权审计日志缓存到 Redis 中,所以也需要安装 Redis key-value 数据库。我们可以通过以下命令来安装和配置 Redis,并将 Redis 的初始密码设置为 iam59!z$

$ cd $IAM_ROOT
$ ./scripts/install/redis.sh iam::redis::install

这里我们要注意,scripts/install/redis.sh 脚本中 iam::redis::install 函数对 Redis 做了一些配置,例如修改 Redis 使其以守护进程的方式运行、修改 Redis 的密码为 iam59!z$等,详细配置可参考函数 iam::redis::install 函数。

 $ redis-cli -h 127.0.0.1 -p 6379 -a 'iam59!z$' # 连接 Redis,-h 指定主机,-p 指定监听端口,-a 指定登录密码

安装和配置 MariaDB

IAM 会把 REST 资源的定义信息存储在关系型数据库中,关系型数据库我选择了 MariaDB。为啥选择 MariaDB,而不是 MySQL 呢?。选择 MariaDB 一方面是因为它是发展最快的 MySQL 分支,相比 MySQL,它加入了很多新的特性,并且它能够完全兼容 MySQL,包括 API 和命令行。另一方面是因为 MariaDB 是开源的,而且迭代速度很快。首先,我们可以通过以下命令安装和配置 MariaDB,并将 Root 密码设置为 1234

MariaDB vs Mysql:

MariaDB是一种关系型数据库管理系统,是MySQL的一个分支。两者在技术上基本相同,但MariaDB有一些额外的特性和功能。

一个明显的区别是MariaDB是一个开源项目,而MySQL是Oracle公司拥有和维护。

MariaDB还添加了一些新特性,如支持更高版本的SQL标准和更好的性能,还有一些安全性增强。

但是, 一般来说,MariaDB和MySQL的性能相当接近,因为它们使用相同的存储引擎。

在一些情况下,MariaDB可能会更快,因为它有一些额外的优化和特性,例如更新的SQL解析器和更快的查询优化器。

另外, 也有一些测试结果表明MariaDB的性能比MySQL更优秀,但是这取决于具体的场景和使用方式。

对于开发人员来说,两者的语法和API几乎相同,所以从MySQL迁移到MariaDB是非常简单的。

总的来说,MariaDB是MySQL的一个很好的替代品,它在继承了MySQL的优秀特性的同时,还添加了许多新功能。

cd $IAM_ROOT; ./scripts/install/mariadb.sh iam::mariadb::install

安装redis

在 IAM 系统中,由于 iam-authz-server 是从 iam-apiserver 拉取并缓存用户的密钥/策略信息的,因此同一份密钥/策略数据会分别存在 2 个服务中,这可能会出现数据不一致的情况。数据不一致会带来一些问题,例如当我们通过 iam-apiserver 创建了一对密钥,但是这对密钥还没有被 iam-authz-server 缓存,这时候通过这对密钥访问 iam-authz-server 就会访问失败。

为了保证数据的一致性,我们可以使用 Redis 的发布订阅(pub/sub)功能进行消息通知。同时,iam-authz-server 也会将授权审计日志缓存到 Redis 中,所以也需要安装 Redis key-value 数据库。我们可以通过以下命令来安装和配置 Redis,并将 Redis 的初始密码设置为 iam59!z$

cd $IAM_ROOT$ ./scripts/install/redis.sh iam::redis::install

这里我们要注意,scripts/install/redis.sh 脚本中 iam::redis::install 函数对 Redis 做了一些配置,例如修改 Redis 使其以守护进程的方式运行、修改 Redis 的密码为 iam59!z$等,详细配置可参考函数 iam::redis::installopen in new window 函数。

安装完成后,我们可以通过以下命令,来测试 Redis 是否安装成功:

redis-cli -h 127.0.0.1 -p 6379 -a 'iam59!z$' 
# 连接 Redis,-h 指定主机,-p 指定监听端口,-a 指定登录密码

安装和配置 MongoDB

因为 iam-pump 会将 iam-authz-server 产生的数据处理后存储在 MongoDB 中,所以我们也需要安装 MongoDB 数据库。主要分两步安装:

  1. 首先安装 MongoDB
  2. 然后再创建 MongoDB 账号

第 1 步,安装 MongoDB

首先,我们可以通过以下 4 步来安装 MongoDB。

配置 MongoDB yum 源,并安装 MongoDB。

CentOS8.x 系统默认没有配置安装 MongoDB 需要的 yum 源,所以我们需要先配置好 yum 源再安装:

$ sudo tee /etc/yum.repos.d/mongodb-org-5.0.repo<<'EOF'
[mongodb-org-5.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/5.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc
EOF
 
$ sudo yum install -y mongodb-org

关闭 SELinux

在安装的过程中,SELinux 有可能会阻止 MongoDB 访问 /sys/fs/cgroup,所以我们还需要关闭 SELinux:

SELinux(Security-Enhanced Linux 或 Security-Enhanced Linux)是一种安全控制机制,由NSA公司开发,可以在Linux系统上提供更强大的安全性。它使用标签来区分操作系统上的文件和目录,并且可以在系统上实施特定的安全策略,以确保系统的安全。

$ sudo setenforce 0
$ sudo sed -i 's/^SELINUX=.*$/SELINUX=disabled/' /etc/selinux/config # 永久关闭 SELINUX

开启外网访问权限和登录验证

MongoDB 安装完之后,默认情况下是不会开启外网访问权限和登录验证,为了方便使用,我建议你先开启这些功能,执行如下命令开启:

$ sudo sed -i '/bindIp/{s/127.0.0.1/0.0.0.0/}' /etc/mongod.conf
$ sudo sed -i '/^#security/a\security:\n  authorization: enabled' /etc/mongod.conf

启动 MongoDB。

配置完 MongoDB 之后,我们就可以启动它了,具体的命令如下:

$ sudo systemctl start mongod
$ sudo systemctl enable mongod # 设置开机启动
$ sudo systemctl status mongod # 查看 mongod 运行状态,如果输出中包含 active (running)字样说明 mongod 成功启动

安装完 MongoDB 后,我们就可以通过 mongo 命令登录 MongoDB Shell。如果没有报错,就说明 MongoDB 被成功安装了。

mongosh --quiet "mongodb://127.0.0.1:27017&quot

第 2 步,创建 MongoDB 账号

安装完 MongoDB 之后,默认是没有用户账号的,为了方便 IAM 服务使用,我们需要先创建好管理员账号,通过管理员账户登录 MongoDB,我们可以执行创建普通用户、数据库等操作。

创建管理员账户

首先,我们通过 use admin 指令切换到 admin 数据库,再通过 db.auth("用户名","用户密码") 验证用户登录权限。如果返回 1 表示验证成功;如果返回 0 表示验证失败。具体的命令如下:

$ mongosh --quiet "mongodb://127.0.0.1:27017"
test> use admin 
switched to db admin
admin> db.createUser({user:"root",pwd:"iam59!z$",roles:["root"]})
{ ok: 1 }
admin> db.auth("root", "iam59!z$")
{ ok: 1 }

此外,如果想删除用户,可以使用 db.dropUser("用户名") 命令。

db.createUser 用到了以下 3 个参数。

  • user: 用户名。
  • pwd: 用户密码。
  • roles: 用来设置用户的权限,比如读、读写、写等。

因为 admin 用户具有 MongoDB 的 Root 权限,权限过大安全性会降低。为了提高安全性,我们还需要创建一个 iam 普通用户来连接和操作 MongoDB。

  1. 创建 iam 用户,命令如下:
$ mongosh --quiet mongodb://root:'iam59!z$'@127.0.0.1:27017/iam_analytics?authSource=admin # 用管理员账户连接 MongoDB
iam_analytics> db.createUser({user:"iam",pwd:"iam59!z$",roles:["dbOwner"]})
{ ok: 1 }
iam_analytics> db.auth("iam", "iam59!z$")
{ ok: 1 }

创建完 iam 普通用户后,我们就可以通过 iam 用户登录 MongoDB 了:

$ mongosh --quiet mongodb://iam:'iam59!z$'@127.0.0.1:27017/iam_analytics?authSource=iam_analytics

至此,我们成功安装了 IAM 系统需要的数据库 MariaDB、Redis 和 MongoDB。

安装和配置 IAM 系统

要想完成 IAM 系统的安装,我们还需要安装和配置 iam-apiserver、iam-authz-server、iam-pump 和 iamctl。这些组件的功能我们在第1讲open in new window详细讲过,如果不记得你可以翻回去看看。

提示:IAM 项目我会长期维护、定期更新,欢迎你 Star & Contributing。

准备工作:

在开始安装之前,我们需要先做一些准备工作,主要有 5 步。

  1. 初始化 MariaDB 数据库,创建 iam 数据库。
  2. 配置 scripts/install/environment.sh。
  3. 创建需要的目录。
  4. 创建 CA 根证书和密钥。
  5. 配置 hosts。

第 1 步,初始化 MariaDB 数据库,创建 iam 数据库。

安装完 MariaDB 数据库之后,我们需要在 MariaDB 数据库中创建 IAM 系统需要的数据库、表和存储过程,以及创建 SQL 语句保存在 IAM 代码仓库中的 configs/iam.sql 文件中。具体的创建步骤如下。

登录数据库并创建 iam 用户。

$ cd $IAM_ROOT
$ mysql -h127.0.0.1 -P3306 -uroot -p'iam59!z$' # 连接 MariaDB,-h 指定主机,-P 指定监听端口,-u 指定登录用户,-p 指定登录密码
MariaDB [(none)]> grant all on iam.* TO iam@127.0.0.1 identified by 'iam59!z$';
Query OK, 0 rows affected (0.000 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.000 sec)

用 iam 用户登录 MariaDB,执行 iam.sql 文件,创建 iam 数据库。

$ mysql -h127.0.0.1 -P3306 -uiam -p'iam59!z$'
MariaDB [(none)]> source configs/iam.sql;
MariaDB [iam]> show databases;
+--------------------+
| Database           |
+--------------------+
| iam                |
| information_schema |
+--------------------+
2 rows in set (0.000 sec)

上面的命令会创建 iam 数据库,并创建以下数据库资源。

  • 表:
    • user 是用户表,用来存放用户信息;
    • secret 是密钥表,用来存放密钥信息;
    • policy 是策略表,用来存放授权策略信息;
    • policy_audit 是策略历史表,被删除的策略会被转存到该表。
  • admin 用户:在 user 表中,我们需要创建一个管理员用户,用户名是 admin,密码是 Admin@2021
  • 存储过程:删除用户时会自动删除该用户所属的密钥和策略信息。

第 2 步,配置 scripts/install/environment.sh。

IAM 组件的安装配置都是通过环境变量文件 scripts/install/environment.sh 进行配置的,所以我们要先配置好 scripts/install/environment.sh 文件。这里,你可以直接使用默认值,提高你的安装效率。

第 3 步,创建需要的目录。

在安装和运行 IAM 系统的时候,我们需要将配置、二进制文件和数据文件存放到指定的目录。所以我们需要先创建好这些目录,创建步骤如下。

$ cd $IAM_ROOT
$ source scripts/install/environment.sh
$ sudo mkdir -p ${IAM_DATA_DIR}/{iam-apiserver,iam-authz-server,iam-pump} # 创建 Systemd WorkingDirectory 目录
$ sudo mkdir -p ${IAM_INSTALL_DIR}/bin #创建 IAM 系统安装目录
$ sudo mkdir -p ${IAM_CONFIG_DIR}/cert # 创建 IAM 系统配置文件存放目录
$ sudo mkdir -p ${IAM_LOG_DIR} # 创建 IAM 日志文件存放目录

第 4 步, 创建 CA 根证书和密钥。

为了确保安全,IAM 系统各组件需要使用 x509 证书对通信进行加密和认证。所以,这里我们需要先创建 CA 证书。CA 根证书是所有组件共享的,只需要创建一个 CA 证书,后续创建的所有证书都由它签名。

我们可以使用 CloudFlare 的 PKI 工具集 cfssl 来创建所有的证书。

安装 cfssl 工具集。

我们可以直接安装 cfssl 已经编译好的二进制文件,cfssl 工具集中包含很多工具,这里我们需要安装 cfssl、cfssljson、cfssl-certinfo,功能如下。

  1. cfssl:证书签发工具。
  2. cfssljson:将 cfssl 生成的证书(json 格式)变为文件承载式证书。

这两个工具的安装方法如下:

$ cd $IAM_ROOT
$ ./scripts/install/install.sh iam::install::install_cfssl

创建配置文件。

CA 配置文件是用来配置根证书的使用场景 (profile) 和具体参数 (usage、过期时间、服务端认证、客户端认证、加密等),可以在签名其它证书时用来指定特定场景:

$ cd $IAM_ROOT
$ tee ca-config.json << EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "iam": {
        "usages": [
          "signing",
          "key encipherment",
          "server auth",
          "client auth"
        ],
        "expiry": "876000h"
      }
    }
  }
}
EOF

上面的 JSON 配置中,有一些字段解释如下。

  • signing:表示该证书可用于签名其它证书(生成的 ca.pem 证书中 CA=TRUE)。
  • server auth:表示 client 可以用该证书对 server 提供的证书进行验证。
  • client auth:表示 server 可以用该证书对 client 提供的证书进行验证。
  • expiry:876000h,证书有效期设置为 100 年。

创建证书签名请求文件。

我们创建用来生成 CA 证书签名请求(CSR)的 JSON 配置文件:


$ cd $IAM_ROOT
$ tee ca-csr.json << EOF
{
  "CN": "iam-ca",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "marmotedu",
      "OU": "iam"
    }
  ],
  "ca": {
    "expiry": "876000h"
  }
}
EOF

上面的 JSON 配置中,有一些字段解释如下。

  • C:Country,国家。
  • ST:State,省份。
  • L:Locality (L) or City,城市。
  • CN:Common Name,iam-apiserver 从证书中提取该字段作为请求的用户名 (User Name) ,浏览器使用该字段验证网站是否合法。
  • O:Organization,iam-apiserver 从证书中提取该字段作为请求用户所属的组 (Group)。
  • OU:Company division (or Organization Unit – OU),部门 / 单位。

除此之外,还有两点需要我们注意。

  • 不同证书 csr 文件的 CN、C、ST、L、O、OU 组合必须不同,否则可能出现 PEER'S CERTIFICATE HAS AN INVALID SIGNATURE 错误。
  • 后续创建证书的 csr 文件时,CN、OU 都不相同(C、ST、L、O 相同),以达到区分的目的。
  • 创建 CA 证书和私钥

首先,我们通过 cfssl gencert 命令来创建:

$ cd $IAM_ROOT
$ source scripts/install/environment.sh
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
$ ls ca*
ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem
$ sudo mv ca* ${IAM_CONFIG_DIR}/cert # 需要将证书文件拷贝到指定文件夹下(分发证书),方便各组件引用

上述命令会创建运行 CA 所必需的文件 ca-key.pem(私钥)和 ca.pem(证书),还会生成 ca.csr(证书签名请求),用于交叉签名或重新签名。

创建完之后,我们可以通过 cfssl certinfo 命名查看 cert 和 csr 信息:

$ cfssl certinfo -cert ${IAM_CONFIG_DIR}/cert/ca.pem # 查看 cert(证书信息)
$ cfssl certinfo -csr ${IAM_CONFIG_DIR}/cert/ca.csr # 查看 CSR(证书签名请求)信息

第 5 步,配置 hosts。

iam 通过域名访问 API 接口,因为这些域名没有注册过,还不能在互联网上解析,所以需要配置 hosts,具体的操作如下:

$ sudo tee -a /etc/hosts <<EOF
127.0.0.1 iam.api.marmotedu.com
127.0.0.1 iam.authz.marmotedu.com
EOF

安装和配置 iam-apiserver

完成了准备工作之后,我们就可以安装 IAM 系统的各个组件了。首先我们通过以下 3 步来安装 iam-apiserver 服务。

第 1 步,创建 iam-apiserver 证书和私钥。

其它服务为了安全都是通过 HTTPS 协议访问 iam-apiserver,所以我们要先创建 iam-apiserver 证书和私钥。

创建证书签名请求

$ cd $IAM_ROOT
$ source scripts/install/environment.sh
$ tee iam-apiserver-csr.json <<EOF
{
  "CN": "iam-apiserver",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "marmotedu",
      "OU": "iam-apiserver"
    }
  ],
  "hosts": [
    "127.0.0.1",
    "localhost",
    "iam.api.marmotedu.com"
  ]
}
EOF

代码中的 hosts 字段是用来指定授权使用该证书的 IP 和域名列表,上面的 hosts 列出了 iam-apiserver 服务的 IP 和域名。

生成证书和私钥

$ cfssl gencert -ca=${IAM_CONFIG_DIR}/cert/ca.pem \
  -ca-key=${IAM_CONFIG_DIR}/cert/ca-key.pem \
  -config=${IAM_CONFIG_DIR}/cert/ca-config.json \
  -profile=iam iam-apiserver-csr.json | cfssljson -bare iam-apiserver
$ sudo mv iam-apiserver*pem ${IAM_CONFIG_DIR}/cert 
# 将生成的证书和私钥文件拷贝到配置文件目录

第 2 步,安装并运行 iam-apiserver。

iam-apiserver 作为 iam 系统的核心组件,需要第一个安装。

安装 iam-apiserver 可执行程序:

$ cd $IAM_ROOT
$ source scripts/install/environment.sh
$ make build BINS=iam-apiserver
$ sudo cp _output/platforms/linux/amd64/iam-apiserver ${IAM_INSTALL_DIR}/bin

生成并安装 iam-apiserver 的配置文件(iam-apiserver.yaml):

$ ./scripts/genconfig.sh scripts/install/environment.sh configs/iam-apiserver.yaml > iam-apiserver.yaml
$ sudo mv iam-apiserver.yaml ${IAM_CONFIG_DIR}

创建并安装 iam-apiserver systemd unit 文件:

$ ./scripts/genconfig.sh scripts/install/environment.sh init/iam-apiserver.service > iam-apiserver.service
$ sudo mv iam-apiserver.service /etc/systemd/system/

启动 iam-apiserver 服务:

$ sudo systemctl daemon-reload
$ sudo systemctl enable iam-apiserver
$ sudo systemctl restart iam-apiserver
$ systemctl status iam-apiserver # 查看 iam-apiserver 运行状态,如果输出中包含 active (running)字样说明 iam-apiserver 成功启动

第 3 步,测试 iam-apiserver 是否成功安装。

测试 iam-apiserver 主要是测试 RESTful 资源的 CURD:用户 CURD、密钥 CURD、授权策略 CURD。

首先,我们需要获取访问 iam-apiserver 的 Token,请求如下 API 访问:

$ curl -s -XPOST -H'Content-Type: application/json' -d'{"username":"admin","password":"Admin@2021"}' http://127.0.0.1:8080/login | jq -r .token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE

代码中下面的 HTTP 请求通过-H'Authorization: Bearer <Token>' 指定认证头信息,将上面请求的 Token 替换 <Token>

用户 CURD:

创建用户、列出用户、获取用户详细信息、修改用户、删除单个用户、批量删除用户,请求方法如下:

# 创建用户
$ curl -s -XPOST -H'Content-Type: application/json' -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' -d'{"password":"User@2021","metadata":{"name":"colin"},"nickname":"colin","email":"colin@foxmail.com","phone":"1812884xxxx"}' http://127.0.0.1:8080/v1/users

# 列出用户
$ curl -s -XGET -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' 'http://127.0.0.1:8080/v1/users?offset=0&limit=10'

# 获取 colin 用户的详细信息
$ curl -s -XGET -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' http://127.0.0.1:8080/v1/users/colin

# 修改 colin 用户
$ curl -s -XPUT -H'Content-Type: application/json' -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' -d'{"nickname":"colin","email":"colin_modified@foxmail.com","phone":"1867274xxxx"}' http://127.0.0.1:8080/v1/users/colin

# 删除 colin 用户
$ curl -s -XDELETE -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' http://127.0.0.1:8080/v1/users/colin

# 批量删除用户
$ curl -s -XDELETE -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' 'http://127.0.0.1:8080/v1/users?name=colin&name=mark&name=john'

密钥 CURD:

创建密钥、列出密钥、获取密钥详细信息、修改密钥、删除密钥请求方法如下:


# 创建 secret0 密钥
$ curl -s -XPOST -H'Content-Type: application/json' -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' -d'{"metadata":{"name":"secret0"},"expires":0,"description":"admin secret"}' http://127.0.0.1:8080/v1/secrets

# 列出所有密钥
$ curl -s -XGET -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' http://127.0.0.1:8080/v1/secrets

# 获取 secret0 密钥的详细信息
$ curl -s -XGET -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' http://127.0.0.1:8080/v1/secrets/secret0

# 修改 secret0 密钥
$ curl -s -XPUT -H'Content-Type: application/json' -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' -d'{"metadata":{"name":"secret0"},"expires":0,"description":"admin secret(modified)"}' http://127.0.0.1:8080/v1/secrets/secret0

# 删除 secret0 密钥
$ curl -s -XDELETE -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' http://127.0.0.1:8080/v1/secrets/secret0

这里我们要注意,因为密钥属于重要资源,被删除会导致所有的访问请求失败,所以密钥不支持批量删除。

授权策略 CURD:

创建策略、列出策略、获取策略详细信息、修改策略、删除策略请求方法如下:

# 创建策略
$ curl -s -XPOST -H'Content-Type: application/json' -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' -d'{"metadata":{"name":"policy0"},"policy":{"description":"One policy to rule them all.","subjects":["users:<peter|ken>","users:maria","groups:admins"],"actions":["delete","<create|update>"],"effect":"allow","resources":["resources:articles:<.*>","resources:printer"],"conditions":{"remoteIPAddress":{"type":"CIDRCondition","options":{"cidr":"192.168.0.1/16"}}}}}' http://127.0.0.1:8080/v1/policies

# 列出所有策略
$ curl -s -XGET -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' http://127.0.0.1:8080/v1/policies

# 获取 policy0 策略的详细信息
$ curl -s -XGET -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' http://127.0.0.1:8080/v1/policies/policy0

# 修改 policy0 策略
$ curl -s -XPUT -H'Content-Type: application/json' -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' -d'{"metadata":{"name":"policy0"},"policy":{"description":"One policy to rule them all(modified).","subjects":["users:<peter|ken>","users:maria","groups:admins"],"actions":["delete","<create|update>"],"effect":"allow","resources":["resources:articles:<.*>","resources:printer"],"conditions":{"remoteIPAddress":{"type":"CIDRCondition","options":{"cidr":"192.168.0.1/16"}}}}}' http://127.0.0.1:8080/v1/policies/policy0

# 删除 policy0 策略
$ curl -s -XDELETE -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' http://127.0.0.1:8080/v1/policies/policy0

# 创建策略
$ curl -s -XPOST -H'Content-Type: application/json' -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXBpLm1hcm1vdGVkdS5jb20iLCJleHAiOjE2NzY2MzI5MzcsImlkZW50aXR5IjoiYWRtaW4iLCJpc3MiOiJpYW0tYXBpc2VydmVyIiwib3JpZ19pYXQiOjE2NzY1NDY1MzcsInN1YiI6ImFkbWluIn0.FprBR_QLI_LS8Y087mat88tIRIQyWrYDo41RsRmnQjE' -d'{"metadata":{"name":"policy0"},"policy":{"description":"One policy to rule them all.","subjects":["users:<peter|ken>","users:maria","groups:admins"],"actions":["delete","<create|update>"],"effect":"allow","resources":["resources:articles:<.*>","resources:printer"],"conditions":{"remoteIPAddress":{"type":"CIDRCondition","options":{"cidr":"192.168.0.1/16"}}}}}' http://127.0.0.1:8080/v1/policies

安装 iamctl

上面,我们安装了 iam 系统的 API 服务。但是想要访问 iam 服务,我们还需要安装客户端工具 iamctl。具体来说,我们可以通过 3 步完成 iamctl 的安装和配置。

第 1 步,创建 iamctl 证书和私钥。

iamctl 使用 https 协议与 iam-apiserver 进行安全通信,iam-apiserver 对 iamctl 请求包含的证书进行认证和授权。iamctl 后续用于 iam 系统访问和管理,所以这里创建具有最高权限的 admin 证书。

创建证书签名请求

下面创建的证书只会被 iamctl 当作 client 证书使用,所以 hosts 字段为空。代码如下:

$ cd $IAM_ROOT
$ source scripts/install/environment.sh
$ cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "marmotedu",
      "OU": "iamctl"
    }
  ],
  "hosts": []
}
EOF

生成证书和私钥:

$ cfssl gencert -ca=${IAM_CONFIG_DIR}/cert/ca.pem \
  -ca-key=${IAM_CONFIG_DIR}/cert/ca-key.pem \
  -config=${IAM_CONFIG_DIR}/cert/ca-config.json \
  -profile=iam admin-csr.json | cfssljson -bare admin
$ mkdir -p $(dirname ${CONFIG_USER_CLIENT_CERTIFICATE}) $(dirname ${CONFIG_USER_CLIENT_KEY}) # 创建客户端证书存放的目录
$ mv admin.pem ${CONFIG_USER_CLIENT_CERTIFICATE} # 安装 TLS 的客户端证书
$ mv admin-key.pem ${CONFIG_USER_CLIENT_KEY} # 安装 TLS 的客户端私钥文件

第 2 步,安装 iamctl。

iamctl 是 IAM 系统的客户端工具,其安装位置和 iam-apiserver、iam-authz-server、iam-pump 位置不同,为了能够在 shell 下直接运行 iamctl 命令,我们需要将 iamctl 安装到$HOME/bin 下,同时将 iamctl 的配置存放在默认加载的目录下:$HOME/.iam。主要分 2 步进行。

安装 iamctl 可执行程序:

$ cd $IAM_ROOT
$ source scripts/install/environment.sh
$ make build BINS=iamctl
$ cp _output/platforms/linux/amd64/iamctl $HOME/bin

生成并安装 iamctl 的配置文件(iamctl.yaml):

$ ./scripts/genconfig.sh scripts/install/environment.sh configs/iamctl.yaml> iamctl.yaml
$ mkdir -p $HOME/.iam
$ mv iamctl.yaml $HOME/.iam

因为 iamctl 是一个客户端工具,可能会在多台机器上运行。为了简化部署 iamctl 工具的复杂度,我们可以把 config 配置文件中跟 CA 认证相关的 CA 文件内容用 base64 加密后,放置在 config 配置文件中。具体的思路就是把 config 文件中的配置项 client-certificate、client-key、certificate-authority 分别用如下配置项替换 client-certificate-data、client-key-data、certificate-authority-data。这些配置项的值可以通过对 CA 文件使用 base64 加密获得。

假如,certificate-authority 值为/etc/iam/cert/ca.pem,则 certificate-authority-data 的值为 cat "/etc/iam/cert/ca.pem" | base64 | tr -d '\r\n',其它-data 变量的值类似。这样当我们再部署 iamctl 工具时,只需要拷贝 iamctl 和配置文件,而不用再拷贝 CA 文件了。

第 3 步,测试 iamctl 是否成功安装。

执行 iamctl user list 可以列出预创建的 admin 用户,如下图所示:

image-20230216194553152

安装和配置 iam-authz-server

接下来,我们需要安装另外一个核心组件:iam-authz-server,可以通过以下 3 步来安装。

第 1 步,创建 iam-authz-server 证书和私钥。

创建证书签名请求:

$ cd $IAM_ROOT
$ source scripts/install/environment.sh
$ tee iam-authz-server-csr.json <<EOF
{
  "CN": "iam-authz-server",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "marmotedu",
      "OU": "iam-authz-server"
    }
  ],
  "hosts": [
    "127.0.0.1",
    "localhost",
    "iam.authz.marmotedu.com"
  ]
}
EOF

代码中的 hosts 字段指定授权使用该证书的 IP 和域名列表,上面的 hosts 列出了 iam-authz-server 服务的 IP 和域名。

生成证书和私钥:

$ cfssl gencert -ca=${IAM_CONFIG_DIR}/cert/ca.pem \
  -ca-key=${IAM_CONFIG_DIR}/cert/ca-key.pem \
  -config=${IAM_CONFIG_DIR}/cert/ca-config.json \
  -profile=iam iam-authz-server-csr.json | cfssljson -bare iam-authz-server
$ sudo mv iam-authz-server*pem ${IAM_CONFIG_DIR}/cert # 将生成的证书和私钥文件拷贝到配置文件目录

第 2 步,安装并运行 iam-authz-server。

安装 iam-authz-server 步骤和安装 iam-apiserver 步骤基本一样,也需要 4 步。

安装 iam-authz-server 可执行程序:

$ cd $IAM_ROOT
$ source scripts/install/environment.sh
$ make build BINS=iam-authz-server
$ sudo cp _output/platforms/linux/amd64/iam-authz-server ${IAM_INSTALL_DIR}/bin

生成并安装 iam-authz-server 的配置文件(iam-authz-server.yaml):

$ ./scripts/genconfig.sh scripts/install/environment.sh configs/iam-authz-server.yaml > iam-authz-server.yaml
$ sudo mv iam-authz-server.yaml ${IAM_CONFIG_DIR}

创建并安装 iam-authz-server systemd unit 文件:

$ ./scripts/genconfig.sh scripts/install/environment.sh init/iam-authz-server.service > iam-authz-server.service
$ sudo mv iam-authz-server.service /etc/systemd/system/

启动 iam-authz-server 服务:

$ sudo systemctl daemon-reload
$ sudo systemctl enable iam-authz-server
$ sudo systemctl restart iam-authz-server
$ systemctl status iam-authz-server 
# 查看 iam-authz-server 运行状态,如果输出中包含 active (running)字样说明 iam-authz-server 成功启动。

第 3 步,测试 iam-authz-server 是否成功安装。

重新登陆系统,并获取访问令牌

$ token=`curl -s -XPOST -H'Content-Type: application/json' -d'{"username":"admin","password":"Admin@2021"}' http://127.0.0.1:8080/login | jq -r .token`

创建授权策略:

$ curl -s -XPOST -H"Content-Type: application/json" -H"Authorization: Bearer $token" -d'{"metadata":{"name":"authztest"},"policy":{"description":"One policy to rule them all.","subjects":["users:<peter|ken>","users:maria","groups:admins"],"actions":["delete","<create|update>"],"effect":"allow","resources":["resources:articles:<.*>","resources:printer"],"conditions":{"remoteIPAddress":{"type":"CIDRCondition","options":{"cidr":"192.168.0.1/16"}}}}}' http://127.0.0.1:8080/v1/policies

创建密钥,并从命令的输出中提取 secretID 和 secretKey

$ curl -s -XPOST -H"Content-Type: application/json" -H"Authorization: Bearer $token" -d'{"metadata":{"name":"authztest"},"expires":0,"description":"admin secret"}' http://127.0.0.1:8080/v1/secrets
{"metadata":{"id":23,"instanceID":"secret-yj8m30","name":"authztest","createdAt":"2023-02-16T19:55:29.407+08:00","updatedAt":"2023-02-16T19:55:29.407+08:00"},"username":"admin","secretID":"Ouk0bP2SX36f5FgpGWnFZy6Tpom89VEljtUo","secretKey":"uIhkIKQ7GA7eSCIdjNYQgvRoE3d6n9bo","expires":0,"description":"admin secret"}

生成访问 iam-authz-server 的 token

iamctl 提供了 jwt sigin 命令,可以根据 secretID 和 secretKey 签发 Token,方便你使用。

$ iamctl jwt sign Ouk0bP2SX36f5FgpGWnFZy6Tpom89VEljtUo uIhkIKQ7GA7eSCIdjNYQgvRoE3d6n9bo # iamctl jwt sign $secretID $secretKey,替换成上一步创建的密钥对
eyJhbGciOiJIUzI1NiIsImtpZCI6Ik91azBiUDJTWDM2ZjVGZ3BHV25GWnk2VHBvbTg5VkVsanRVbyIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXV0aHoubWFybW90ZWR1LmNvbSIsImV4cCI6MTY3NjU1NTg3NywiaWF0IjoxNjc2NTQ4Njc3LCJpc3MiOiJpYW1jdGwiLCJuYmYiOjE2NzY1NDg2Nzd9.CdbBrm9-mErgysb5xwa0EQPboQWnXJpXOBZZk6K6M9E

如果你的开发过程中有些重复性的操作,为了方便使用,也可以将这些操作以 iamctl 子命令的方式集成到 iamctl 命令行中。

测试资源授权是否通过

我们可以通过请求 /v1/authz 来完成资源授权:

$ curl -s -XPOST -H'Content-Type: application/json' -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6Ik91azBiUDJTWDM2ZjVGZ3BHV25GWnk2VHBvbTg5VkVsanRVbyIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXV0aHoubWFybW90ZWR1LmNvbSIsImV4cCI6MTY3NjU1NTg3NywiaWF0IjoxNjc2NTQ4Njc3LCJpc3MiOiJpYW1jdGwiLCJuYmYiOjE2NzY1NDg2Nzd9.CdbBrm9-mErgysb5xwa0EQPboQWnXJpXOBZZk6K6M9E' -d'{"subject":"users:maria","action":"delete","resource":"resources:articles:ladon-introduction","context":{"remoteIPAddress":"192.168.0.5"}}' http://127.0.0.1:9090/v1/authz
{"allowed":true}

如果授权通过会返回:{"allowed":true}

安装和配置 iam-pump

安装 iam-pump 步骤和安装 iam-apiserver、iam-authz-server 步骤基本一样,具体步骤如下。

第 1 步,安装 iam-pump 可执行程序。

$ cd $IAM_ROOT
$ source scripts/install/environment.sh
$ make build BINS=iam-pump
$ sudo cp _output/platforms/linux/amd64/iam-pump ${IAM_INSTALL_DIR}/bin

第 2 步,生成并安装 iam-pump 的配置文件(iam-pump.yaml)。

$ ./scripts/genconfig.sh scripts/install/environment.sh configs/iam-pump.yaml > iam-pump.yaml
$ sudo mv iam-pump.yaml ${IAM_CONFIG_DIR}

第 3 步,创建并安装 iam-pump systemd unit 文件。

$ ./scripts/genconfig.sh scripts/install/environment.sh init/iam-pump.service > iam-pump.service
$ sudo mv iam-pump.service /etc/systemd/system/

第 4 步,启动 iam-pump 服务。

$ sudo systemctl daemon-reload
$ sudo systemctl enable iam-pump
$ sudo systemctl restart iam-pump
$ systemctl status iam-pump # 查看 iam-pump 运行状态,如果输出中包含 active (running)字样说明 iam-pump 成功启动。

第 5 步,测试 iam-pump 是否成功安装。

$ curl http://127.0.0.1:7070/healthz
{"status": "ok"}

经过上面这 5 个步骤,如果返回 {“status”: “ok”} 就说明 iam-pump 服务健康

安装 man 文件

IAM 系统通过组合调用包:github.com/cpuguy83/go-md2man/v2/md2mangithub.com/spf13/cobraopen in new window 的相关函数生成了各个组件的 man1 文件,主要分 3 步实现。

第 1 步,生成各个组件的 man1 文件。

$ cd $IAM_ROOT
$ ./scripts/update-generated-docs.sh

第 2 步,安装生成的 man1 文件。

$ sudo cp docs/man/man1/* /usr/share/man/man1/

第 3 步,检查是否成功安装 man1 文件。

$ man iam-apiserver

执行 man iam-apiserver 命令后,会弹出 man 文档界面,如下图所示:

image-20230216200626281

至此,IAM 系统所有组件都已经安装成功了,你可以通过 iamctl version 查看客户端和服务端版本,代码如下:

$ iamctl version -o yaml
clientVersion:
  buildDate: "2023-02-16T11:43:40Z"
  compiler: gc
  gitCommit: f39d4105e563c01fb4869bbaf1b19f5afa944400
  gitTreeState: dirty
  gitVersion: f39d410
  goVersion: go1.18.3
  platform: linux/amd64
serverVersion:
  buildDate: "2023-02-16T11:18:53Z"
  compiler: gc
  gitCommit: f39d4105e563c01fb4869bbaf1b19f5afa944400
  gitTreeState: dirty
  gitVersion: f39d410
  goVersion: go1.18.3
  platform: linux/amd64

一键安装

除此之外,还可以一键安装:

$ export LINUX_PASSWORD='iam59!z$' # 重要:这里要 export going 用户的密码
$ version=latest && curl https://marmotedu-1254073058.cos.ap-beijing.myqcloud.com/iam-release/${version}/iam.tar.gz | tar -xz -C / tmp/       
$ cd /tmp/iam/ && ./scripts/install/install.sh iam::install::install

总结

⚠️ 所有组件设置的密码都是 iam59!z$

image-20230216200735600

END 链接