本文最后更新于 2024-01-26,文章内容可能已经过时。

使用Ansible-playbook 自建CA,并签发客户端IP证书

需求

使用Ansible-playbook 来签发客户端IP证书

  • 签发单个IP地址,比如 脚本中使用{{ inventory_hostname }} 来获取主机的IP地址作为证书签发地址
---
- name: Generate and sign client IP certificate
  hosts: nginx
  become: true
  vars:
    # CA settings
    ca_name: CA
    ca_email: CA@example.com
    ca_key_size: 2048
    ca_cert_days: 3650
    ca_cert_path: /tmp/{{ ca_name }}.crt
    ca_key_path: /tmp/{{ ca_name }}.key
    # Client certificate settings
    client_name: server
    client_cert_days: 3650
    client_cert_path: /tmp/{{ client_name }}.crt
    client_key_path: /tmp/{{ client_name }}.key
  tasks:
    - name: Check if openssl is installed
      stat:
        path: /usr/bin/openssl
      register: openssl_installed
    - name: Install openssl if not installed
      yum:
        name: openssl
        state: present
      when: not openssl_installed.stat.exists
    - name: Generate CA private key
      shell: |
        openssl genrsa -out "{{ ca_key_path }}" "{{ ca_key_size }}"
      register: ca_key
    - name: Generate CA certificate
      shell: |
        openssl req -new -x509 -nodes \
        -key "{{ ca_key_path }}" \
        -subj "/CN={{ ca_name }}/emailAddress={{ ca_email }}" \
        -days "{{ ca_cert_days }}" \
        -out "{{ ca_cert_path }}"
      register: ca_cert
      args:
        executable: /bin/bash
      when: ca_key.changed
    - name: Generate client private key
      shell: |
        openssl genrsa -out "{{ client_key_path }}" "{{ ca_key_size }}"
      register: client_key
    - name: Generate client certificate signing request
      shell: |
        openssl req -new \
        -key "{{ client_key_path }}" \
        -subj "/CN={{ client_name }}" \
        -out /tmp/{{ client_name }}.csr
      register: client_csr
      args:
        executable: /bin/bash
      when: client_key.changed

    - name: Sign client certificate
      shell: |
        openssl x509 -req -in /tmp/{{ client_name }}.csr \
        -CA "{{ ca_cert_path }}" \
        -CAkey "{{ ca_key_path }}" \
        -CAcreateserial \
        -out "{{ client_cert_path }}" \
        -days "{{ client_cert_days }}" \
        -extfile <(echo "subjectAltName=IP:{{ inventory_hostname }}") \
        -sha256
      register: client_cert
      args:
        executable: /bin/bash
      when: client_csr.changed
    - name: Copy client certificate and key to target host
      copy:
        src: "{{ item }}"
        dest: /root
        mode: 0644
      with_items:
        - "{{ client_cert_path }}"
        - "{{ client_key_path }}"
  • 签发多个IP,例如脚本中的 subjectAltName=IP:192.168.1.100,IP:111.111.111.111
  • 私网IP,公网IP
---
- name: Generate and sign client IP certificate
  hosts: nginx
  become: true
  vars:
    # CA settings
    ca_name: CA
    ca_email: CA@example.com
    ca_key_size: 2048
    ca_cert_days: 3650
    ca_cert_path: /tmp/{{ ca_name }}.crt
    ca_key_path: /tmp/{{ ca_name }}.key
    # Client certificate settings
    client_name: server
    client_cert_days: 3650
    client_cert_path: /tmp/{{ client_name }}.crt
    client_key_path: /tmp/{{ client_name }}.key
  tasks:
    - name: Check if openssl is installed
      stat:
        path: /usr/bin/openssl
      register: openssl_installed
    - name: Install openssl if not installed
      yum:
        name: openssl
        state: present
      when: not openssl_installed.stat.exists
    - name: Generate CA private key
      shell: |
        openssl genrsa -out "{{ ca_key_path }}" "{{ ca_key_size }}"
      register: ca_key
    - name: Generate CA certificate
      shell: |
        openssl req -new -x509 -nodes \
        -key "{{ ca_key_path }}" \
        -subj "/CN={{ ca_name }}/emailAddress={{ ca_email }}" \
        -days "{{ ca_cert_days }}" \
        -out "{{ ca_cert_path }}"
      register: ca_cert
      args:
        executable: /bin/bash
      when: ca_key.changed
    - name: Generate client private key
      shell: |
        openssl genrsa -out "{{ client_key_path }}" "{{ ca_key_size }}"
      register: client_key
    - name: Generate client certificate signing request
      shell: |
        openssl req -new \
        -key "{{ client_key_path }}" \
        -subj "/CN={{ client_name }}" \
        -out /tmp/{{ client_name }}.csr
      register: client_csr
      args:
        executable: /bin/bash
      when: client_key.changed

    - name: Sign client certificate
      shell: |
        openssl x509 -req -in /tmp/{{ client_name }}.csr \
        -CA "{{ ca_cert_path }}" \
        -CAkey "{{ ca_key_path }}" \
        -CAcreateserial \
        -out "{{ client_cert_path }}" \
        -days "{{ client_cert_days }}" \
        -extfile <(echo "subjectAltName=IP:192.168.1.100,IP:111.111.111.111") \
        -sha256
      register: client_cert
      args:
        executable: /bin/bash
      when: client_csr.changed
    - name: Copy client certificate and key to target host
      copy:
        src: "{{ item }}"
        dest: /root
        mode: 0644
      with_items:
        - "{{ client_cert_path }}"
        - "{{ client_key_path }}"