ssh-certs users.
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1s
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1s
This commit is contained in:
9
environments/proxmoxes/group_vars/all/projects.yml
Normal file
9
environments/proxmoxes/group_vars/all/projects.yml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
project_users:
|
||||||
|
- name: test-nigger
|
||||||
|
sudo: true
|
||||||
|
#- name: ivan
|
||||||
|
# sudo: false
|
||||||
|
|
||||||
|
allowed_projects:
|
||||||
|
- zagon
|
||||||
|
- zagon2
|
||||||
94
playbooks/deploy_ssh_certs.yml
Normal file
94
playbooks/deploy_ssh_certs.yml
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
- hosts: all
|
||||||
|
become: yes
|
||||||
|
vars:
|
||||||
|
# Задайте пути к ключам на вашей локальной машине (где запускается Ansible),
|
||||||
|
# предварительно скачав их с сервера step-ca
|
||||||
|
local_ssh_user_ca_pub_path: "~/.step/secrets/ssh_user_ca_key.pub"
|
||||||
|
local_ssh_host_ca_key_path: "~/.step/secrets/ssh_host_ca_key"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
# --- ЭТАП 1: УПРАВЛЕНИЕ ПОЛЬЗОВАТЕЛЯМИ И КАТАЛОГАМИ ---
|
||||||
|
|
||||||
|
- name: Создание системной директории для принципалов
|
||||||
|
file:
|
||||||
|
path: /etc/ssh/auth_principals
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Создание локальных пользователей из списка проекта
|
||||||
|
user:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
shell: /bin/bash
|
||||||
|
create_home: yes
|
||||||
|
state: present
|
||||||
|
loop: "{{ project_users }}"
|
||||||
|
|
||||||
|
- name: Генерация файлов auth_principals для каждого пользователя
|
||||||
|
copy:
|
||||||
|
dest: "/etc/ssh/auth_principals/{{ item.name }}"
|
||||||
|
content: "{{ allowed_projects | join('\n') }}\n"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
loop: "{{ project_users }}"
|
||||||
|
|
||||||
|
- name: Настройка беспарольного sudo для администраторов проекта
|
||||||
|
copy:
|
||||||
|
dest: "/etc/sudoers.d/project-ssh-{{ item.name }}"
|
||||||
|
content: "{{ item.name }} ALL=(ALL) NOPASSWD:ALL"
|
||||||
|
validate: /usr/sbin/visudo -cf %s
|
||||||
|
mode: '0440'
|
||||||
|
loop: "{{ project_users }}"
|
||||||
|
when: item.sudo | bool
|
||||||
|
|
||||||
|
# --- ЭТАП 2: РАСКАТКА ДОВЕРИЯ К USER CA ---
|
||||||
|
|
||||||
|
- name: Копирование публичного ключа User CA на хост
|
||||||
|
copy:
|
||||||
|
src: "{{ local_ssh_user_ca_pub_path }}"
|
||||||
|
dest: /etc/ssh/ca.pub
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
# --- ЭТАП 3: ХОСТОВЫЕ СЕРТИФИКАТЫ (Опционально, локальный выпуск) ---
|
||||||
|
# Мы генерируем сертификат прямо на машине администратора с помощью локального step-cli
|
||||||
|
# и копируем готовый сертификат на целевой сервер.
|
||||||
|
|
||||||
|
- name: Локальная генерация Host-сертификата для целевой ноды
|
||||||
|
delegate_to: localhost
|
||||||
|
become: no
|
||||||
|
shell: >
|
||||||
|
step ssh certificate {{ inventory_hostname }} /tmp/{{ inventory_hostname }}_host.pub
|
||||||
|
--host --sign --ca-key {{ local_ssh_host_ca_key_path }} --no-password --insecure
|
||||||
|
--principal {{ inventory_hostname }} --principal {{ ansible_host }}
|
||||||
|
args:
|
||||||
|
creates: "/tmp/{{ inventory_hostname }}-cert.pub"
|
||||||
|
# Примечание: Для работы этой задачи на вашем ПК должен быть настроен step-cli контекст.
|
||||||
|
# Если это сложно автоматизировать, этот блок можно пока пропустить.
|
||||||
|
|
||||||
|
# --- ЭТАП 4: НАСТРОЙКА SSHD_CONFIG ---
|
||||||
|
|
||||||
|
- name: Сбор имен всех разрешенных пользователей для AllowUsers
|
||||||
|
set_fact:
|
||||||
|
allow_users_list: "{{ project_users | map(attribute='name') | join(' ') }}"
|
||||||
|
|
||||||
|
- name: Конфигурация OpenSSH Daemon
|
||||||
|
blockinfile:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
block: |
|
||||||
|
TrustedUserCAKeys /etc/ssh/ca.pub
|
||||||
|
AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u
|
||||||
|
AllowUsers {{ allow_users_list }} hogweed1
|
||||||
|
PasswordAuthentication no
|
||||||
|
PubkeyAuthentication yes
|
||||||
|
marker: "# {mark} ANSIBLE MANAGED ZERO TRUST BLOCK #"
|
||||||
|
notify: Restart SSH
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
- name: Restart SSH
|
||||||
|
service:
|
||||||
|
name: sshd
|
||||||
|
state: restarted
|
||||||
70
playbooks/deploy_ssh_user_certs.yml
Normal file
70
playbooks/deploy_ssh_user_certs.yml
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
- hosts: all
|
||||||
|
become: yes
|
||||||
|
vars:
|
||||||
|
# Путь к ПУБЛИЧНОМУ ключу User CA на вашей Ansible-машине
|
||||||
|
local_ssh_user_ca_pub_path: "/etc/step-ca/ssh_user_ca_key.pub"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Создание системной директории для принципалов
|
||||||
|
file:
|
||||||
|
path: /etc/ssh/auth_principals
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Создание локальных пользователей из списка проекта
|
||||||
|
user:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
shell: /bin/bash
|
||||||
|
create_home: yes
|
||||||
|
state: present
|
||||||
|
loop: "{{ project_users }}"
|
||||||
|
|
||||||
|
- name: Генерация файлов auth_principals с маппингом проектов
|
||||||
|
copy:
|
||||||
|
dest: "/etc/ssh/auth_principals/{{ item.name }}"
|
||||||
|
content: "{{ allowed_projects | join('\n') }}\n"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
loop: "{{ project_users }}"
|
||||||
|
|
||||||
|
- name: Настройка беспарольного sudo для администраторов проекта
|
||||||
|
copy:
|
||||||
|
dest: "/etc/sudoers.d/project-ssh-{{ item.name }}"
|
||||||
|
content: "{{ item.name }} ALL=(ALL) NOPASSWD:ALL"
|
||||||
|
validate: /usr/sbin/visudo -cf %s
|
||||||
|
mode: '0440'
|
||||||
|
loop: "{{ project_users }}"
|
||||||
|
when: item.sudo | bool
|
||||||
|
|
||||||
|
- name: Копирование публичного ключа User CA на хост
|
||||||
|
copy:
|
||||||
|
src: "{{ local_ssh_user_ca_pub_path }}"
|
||||||
|
dest: /etc/ssh/ca.pub
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Сбор имен всех разрешенных пользователей для AllowUsers
|
||||||
|
set_fact:
|
||||||
|
allow_users_list: "{{ project_users | map(attribute='name') | join(' ') }}"
|
||||||
|
|
||||||
|
- name: Настройка sshd_config для авторизации пользователей по сертификатам
|
||||||
|
blockinfile:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
block: |
|
||||||
|
TrustedUserCAKeys /etc/ssh/ca.pub
|
||||||
|
AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u
|
||||||
|
AllowUsers {{ allow_users_list }} hogweed1
|
||||||
|
PasswordAuthentication no
|
||||||
|
PubkeyAuthentication yes
|
||||||
|
marker: "# {mark} ANSIBLE MANAGED USER CERTIFICATE BLOCK #"
|
||||||
|
notify: Restart SSH
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
- name: Restart SSH
|
||||||
|
service:
|
||||||
|
name: sshd
|
||||||
|
state: restarted
|
||||||
67
playbooks/software/acme_sh.yml
Normal file
67
playbooks/software/acme_sh.yml
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
#### TODO заставить работать
|
||||||
|
|
||||||
|
|
||||||
|
# 1. Готовим окружение и папки
|
||||||
|
- name: Ensure git and curl are installed
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- git
|
||||||
|
- curl
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create SSL directory for Angie
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ angie_ssl_dir }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
# 2. Установка acme.sh (Идемпотентный способ через Git вместо curl | sh)
|
||||||
|
- name: Clone acme.sh repository
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: 'https://github.com'
|
||||||
|
dest: /root/acme.sh-src
|
||||||
|
version: master
|
||||||
|
depth: 1
|
||||||
|
|
||||||
|
- name: Check if acme.sh is already installed
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /root/.acme.sh/acme.sh
|
||||||
|
register: acme_installed
|
||||||
|
|
||||||
|
- name: Run acme.sh installer
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "./acme.sh --install -m {{ acme_email }}"
|
||||||
|
chdir: /root/acme.sh-src
|
||||||
|
when: not acme_installed.stat.exists
|
||||||
|
|
||||||
|
# 3. Выпуск сертификата через DNS Reg.ru
|
||||||
|
- name: Issue Let's Encrypt certificate via Reg.ru DNS
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >
|
||||||
|
/root/.acme.sh/acme.sh --issue --dns dns_regru
|
||||||
|
-d "{{ acme_domain }}"
|
||||||
|
--server https://acme-v02.api.letsencrypt.org/directory
|
||||||
|
# Передаем секреты строго внутри контекста выполнения этой задачи
|
||||||
|
environment:
|
||||||
|
REGRU_API_Username: "{{ regru_username }}"
|
||||||
|
REGRU_API_Password: "{{ regru_password }}"
|
||||||
|
register: issue_result
|
||||||
|
# acme.sh вернет ошибку, если сертификат уже есть и еще свежий.
|
||||||
|
# Игнорируем эту ошибку, чтобы плейбук не падал при повторных запусках.
|
||||||
|
failed_when:
|
||||||
|
- issue_result.rc != 0
|
||||||
|
- "'Sign failed: LE_OrderFinalize' not in issue_result.stderr"
|
||||||
|
- "'Create new order error' not in issue_result.stderr"
|
||||||
|
|
||||||
|
# 4. Привязка (инсталляция) сертификата в папки Angie и настройка автопродления
|
||||||
|
- name: Install certificate to Angie directory and configure reload cmd
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >
|
||||||
|
/root/.acme.sh/acme.sh --install-cert -d "{{ acme_domain }}"
|
||||||
|
--key-file "{{ angie_ssl_dir }}/key.pem"
|
||||||
|
--fullchain-file "{{ angie_ssl_dir }}/cert.pem"
|
||||||
|
--reloadcmd "systemctl reload angie"
|
||||||
|
# service angie force-reload заменен на более современный systemctl reload
|
||||||
Reference in New Issue
Block a user