通过 saltstack 批量更新 SSL 证书

哈喽大家好,我是咸鱼。

之前写过两篇关于 SSL 过期巡检脚本的文章:

  1. SSL 证书过期巡检脚本
  2. SSL 证书过期巡检脚本(Python 版)

这两篇文章都是讲如何通过脚本去自动检测 SSL 过期时间的,当我们发现某一域名的 SSL 证书过期之后,就要及时更换。

如果这个域名下有很多服务器,我们一台一台手动登录机器然后更新证书的话效率是非常低的,所以我们可以通过一些自动化运维工具去完成这些大量重复的工作。

像 ansible、puppet 这类工具也可以实现同样的效果,但是咸鱼这边主要用的还是 saltstack,所以今天介绍一些如何通过 saltstack 去批量更新 SSL 证书。

关于 saltstck 的介绍:

  1. 干货篇 | 自动化运维工具-saltstack(上)
  2. 干货篇 | 自动化运维工具-saltstack(中)
  3. 干货篇 | 自动化运维工具-saltstack(下)

首先我们在 salt-master 的主目录下创建一个新的目录,用于存放 SSL 证书和脚本,我自己机器上的 master 主目录为 /home/salt/

bash 复制代码
mkdir -pv /home/salt/ssl_update/ssl

然后把 SSL 证书放在 /home/salt/ssl_update/ssl 目录下,如果有多个域名的话需要在下面创建多个对应的目录

bash 复制代码
[root@localhost]# tree /home/salt/ssl_update/
/home/salt/ssl_update
├── rollback.sls
├── update.sls
├── ssl
│   ├── domain1
│   │   ├── server.key
│   │   └── server.pem
│   ├── domain2
│   │   ├── server.key
│   │   └── server.pem
│   └── domain3
        ├── server.key
        └── server.pem

接下来我们开始编写 saltstack 状态脚本:

  1. update.sls 负责更新证书
  2. rollback.sls 负责回滚证书

因为之前遇到过更新证书之后由于证书链不完整导致证书失效,然后不得不紧急手动还原之前的证书。

所以觉得有必要做一个回滚操作,这样新证书有问题的时候能够及时自动还原。

我们先来看一下负责更新证书的 update.sls,这个脚本分成了三个模块:

  1. SSL 证书备份
  2. SSL 证书更新
  3. Nginx 重启
bash 复制代码
{% set domain = 'doamin1' %}
{% set ssl_dir = '/usr/local/nginx/ssl' %}
{% set dst_dir = ssl_dir + '/' + domain %}
{% set bak_dir = '/opt/backup/ssl/' + domain %}

backup_ssl:
  cmd.run:
      - name: "year=$(openssl x509 -in {{ dst_dir }}/server.pem -noout -dates|grep Before|awk '{print $4}') && mkdir -p {{ bak_dir }}/${year} && \\cp {{dst_dir}}/* {{ bak_dir }}/${year}"

ssl_update:
  file.recurse:
    - source: salt://ssl_check/ssl/{{domain}}
    - name: {{ dst_dir }}
    - require:
      - cmd: backup_ssl


nginx_reload:
  cmd.run:
    - name: /usr/local/nginx/sbin/nginx -t && /usr/local/nginx/sbin/nginx -s reload
    - require:
      - file: ssl_update

首先是变量的定义

bash 复制代码
{% set domain = 'doamin1' %}
{% set ssl_dir = '/usr/local/nginx/ssl' %}
{% set dst_dir = ssl_dir + '/' + domain %}
{% set bak_dir = '/opt/backup/ssl/' + domain %}
  • domain: 设置域名为 'doamin1'
  • ssl_dir: 设置 SSL 证书存放目录为 '/usr/local/nginx/ssl'
  • dst_dir: 设置 SSL 证书实际存放路径为 ssl_dir + '/' + domain
  • bak_dir: 设置备份目录为 '/opt/backup/ssl/' + domain

然后就是 SSL 证书备份。首先创建名为 backup_ssl 的命令执行模块,通过 cmd.run 执行 shell 命令,这个命令通过 OpenSSL 获取证书的有效期限,然后将证书拷贝到备份目录,以年份为子目录。

bash 复制代码
backup_ssl:
  cmd.run:
      - name: "year=$(openssl x509 -in {{ dst_dir }}/server.pem -noout -dates|grep Before|awk '{print $4}') && mkdir -p {{ bak_dir }}/${year} && \\cp {{dst_dir}}/* {{ bak_dir }}/${year}"

这条命令看着很长,其实可以拆解成

bash 复制代码
# 获取证书有效期限然后赋值给 year 变量
year=$(openssl x509 -in {{ dst_dir }}/server.pem -noout -dates|grep Before|awk '{print $4}')

# 创建带年份后缀的备份目录
mkdir -p {{ bak_dir }}/${year} 

# 把当前的证书备份到备份目录中
cp {{dst_dir}}/* {{ bak_dir }}/${year}

接着我们开始更新 SSL 证书。创建名为 ssl_update 的文件递归模块,然后通过 file.recurse 把 salt-master 上的证书复制到指定服务器目录

bash 复制代码
ssl_update:
  file.recurse:
    - source: salt://ssl_check/ssl/{{domain}}
    - name: {{ dst_dir }}
    - require:
      - cmd: backup_ssl

更新完之后我们还要对指定服务器上的 Nginx 服务进行配置检查并重启一下

bash 复制代码
nginx_reload:
  cmd.run:
    - name: /usr/local/nginx/sbin/nginx -t && /usr/local/nginx/sbin/nginx -s reload
    - require:
      - file: ssl_update

然后我们看一下负责回滚证书的 rollback.sls,这个脚本分成了两个个模块:

  1. 证书回滚
  2. Nginx 重启
bash 复制代码
{% set domain = 'doamin1' %}
{% set ssl_dir = '/usr/local/nginx/ssl' %}
{% set dst_dir = ssl_dir + '/' + domain %}
{% set bak_dir = '/opt/backup/ssl/' + domain %}
{% set year = salt['pillar.get']('year') or salt['cmd.run']('echo $(date +%Y) - 1| bc') %}


rollback:
  cmd.run:
    - name: "cp {{ bak_dir }}/$(({{ year }}))/* {{ dst_dir }}"

start:
  cmd.run:
    - name: /usr/local/nginx/sbin/nginx -t && /usr/local/nginx/sbin/nginx -s reload
    - require:
      - cmd: rollback

设置变量 year 的命令有点复杂,我们来看一下

bash 复制代码
{% set year = salt['pillar.get']('year') or salt['cmd.run']('echo $(date +%Y) - 1| bc') %}
  1. salt['pillar.get']('year'): 尝试从 Salt Pillar 中获取名为 year 的变量的值。
  2. or: 如果前面的操作未成功(即 year 在 Pillar 中不存在),or 后面的表达式将会被执行。
  3. salt['cmd.run']('echo $(date +%Y) - 1| bc'): 这部分代码使用 SaltStack 的 cmd.run 模块执行一个 shell 命令,该命令通过 date 命令获取当前年份,然后减去 1 得到前一年的年份。bc 是一个计算器工具,用于执行数学运算。
  4. 总结一下:首先从 Salt Pillar 中查找,如果找不到则使用 shell 命令获取前一年的年份,确保在没有 Pillar 配置的情况下也有一个默认的年份

然后就是 SSL 证书回滚。创建名为 rollback 的命令执行模块,通过 cmd.run 执行 shell 命令

该命令通过将指定服务器备份目录中指定年份的证书拷贝到 SSL 证书目录实现回滚。

bash 复制代码
rollback:
  cmd.run:
    - name: "cp {{ bak_dir }}/$(({{ year }}))/* {{ dst_dir }}"

回滚完之后对指定服务器上的 Nginx 服务进行配置检查并重启一下,上面内容有,这里就不再介绍了。

相关推荐
江湖有缘13 分钟前
Linux系统之whereis命令的基本使用
linux·运维·服务器
zhkmxx93023 分钟前
docker pull Error response from daemon问题
运维·docker·容器
晚秋贰拾伍1 小时前
每天学点小知识之设计模式的艺术-策略模式
运维·设计模式·系统安全·运维开发·策略模式
monstercl2 小时前
ubuntu磁盘扩容
linux·运维·ubuntu·磁盘扩容
我是唐青枫3 小时前
Linux ifstat 命令使用详解
linux·运维·网络
A.sir啊4 小时前
爬虫基础(三)Session和Cookie讲解
运维·服务器·前端·网络·网络爬虫
工程师焱记5 小时前
linux通过lvm调整分区大小
linux·运维·服务器
007php0075 小时前
HTTPS域名443端口证书到期问题排查与解决
开发语言·网络·网络协议·计算机网络·http·golang·https
马船长9 小时前
bat脚本实现自动化漏洞挖掘
运维·网络安全·自动化
kfepiza10 小时前
Nginx反向代理 笔记250203
运维·服务器·笔记·nginx