feat: добавлена роль devops и оптимизирована структура проекта
Some checks failed
Ansible Testing / lint (push) Has been cancelled
Ansible Testing / test (default) (push) Has been cancelled
Ansible Testing / test (minimal) (push) Has been cancelled
Ansible Testing / test (performance) (push) Has been cancelled
Ansible Testing / deploy-check (push) Has been cancelled
Some checks failed
Ansible Testing / lint (push) Has been cancelled
Ansible Testing / test (default) (push) Has been cancelled
Ansible Testing / test (minimal) (push) Has been cancelled
Ansible Testing / test (performance) (push) Has been cancelled
Ansible Testing / deploy-check (push) Has been cancelled
- Создана роль devops с функциями: * Создание пользователя devops * Генерация безопасного пароля (30 символов) * Настройка SSH доступа по ключу * Добавление в sudoers без пароля * Полная документация и тесты - Оптимизирована структура проекта: * Удален Dockerfile из корня (сборка из dockerfiles/ansible-controller) * Заменены внешние образы на локальные ansible-controller * Обновлен Makefile для использования локальных образов * Зашифрован vault/secrets.yml с помощью ansible-vault - Добавлена документация: * Руководство по работе с vault (docs/vault-guide.md) * Подробная документация роли devops * Примеры использования и тесты - Улучшена безопасность: * Все секреты зашифрованы * Обновлен .gitignore для vault файлов * Добавлены инструкции по безопасности
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,6 +4,8 @@
|
||||
# ---> Vault (секретные файлы)
|
||||
vault/.vault
|
||||
vault/secrets/*.yml
|
||||
# Зашифрованные vault файлы (если не нужно коммитить)
|
||||
# vault/*.yml
|
||||
|
||||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
stages:
|
||||
- test
|
||||
test:
|
||||
stage: test
|
||||
script:
|
||||
- make role test
|
||||
57
Dockerfile
57
Dockerfile
@@ -1,57 +0,0 @@
|
||||
# =============================================================================
|
||||
# AnsibleLab - Dockerfile для тестирования
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
# =============================================================================
|
||||
|
||||
FROM quay.io/ansible/creator-ee:latest
|
||||
|
||||
# Установка дополнительных зависимостей
|
||||
USER root
|
||||
|
||||
# Обновление системы и установка необходимых пакетов
|
||||
RUN dnf update -y && \
|
||||
dnf install -y \
|
||||
python3-pip \
|
||||
git \
|
||||
curl \
|
||||
jq \
|
||||
ca-certificates \
|
||||
iproute2 \
|
||||
iputils \
|
||||
procps-ng \
|
||||
net-tools \
|
||||
sudo \
|
||||
vim \
|
||||
&& dnf clean all
|
||||
|
||||
# Установка Python пакетов
|
||||
RUN pip3 install --upgrade pip && \
|
||||
pip3 install \
|
||||
ansible-lint \
|
||||
molecule \
|
||||
molecule-docker \
|
||||
docker-compose
|
||||
|
||||
# Создание рабочей директории
|
||||
WORKDIR /ansible
|
||||
|
||||
# Копирование файлов проекта
|
||||
COPY . /ansible/
|
||||
|
||||
# Установка прав доступа
|
||||
RUN chmod +x /ansible/scripts/*.sh 2>/dev/null || true
|
||||
|
||||
# Переключение на пользователя ansible
|
||||
USER ansible
|
||||
|
||||
# Установка Ansible коллекций
|
||||
RUN ansible-galaxy collection install -r requirements.yml --force
|
||||
|
||||
# Настройка переменных окружения
|
||||
ENV ANSIBLE_FORCE_COLOR=1
|
||||
ENV ANSIBLE_STDOUT_CALLBACK=yaml
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
# Команда по умолчанию
|
||||
CMD ["/bin/bash"]
|
||||
10
Jenkinsfile
vendored
10
Jenkinsfile
vendored
@@ -1,10 +0,0 @@
|
||||
pipeline {
|
||||
agent any
|
||||
stages {
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh 'make role test'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Makefile
12
Makefile
@@ -260,7 +260,7 @@ vault:
|
||||
echo "🔐 Создание файла секретов..."; \
|
||||
read -p "Введите имя файла (без .yml): " FILE; \
|
||||
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
|
||||
quay.io/ansible/creator-ee:latest \
|
||||
$(DOCKER_IMAGE) \
|
||||
ansible-vault create --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \
|
||||
edit) \
|
||||
echo "🔐 Редактирование секретов..."; \
|
||||
@@ -268,7 +268,7 @@ vault:
|
||||
echo ""; \
|
||||
read -p "Введите имя файла (без .yml): " FILE; \
|
||||
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
|
||||
quay.io/ansible/creator-ee:latest \
|
||||
$(DOCKER_IMAGE) \
|
||||
ansible-vault edit --vault-password-file vault/.vault vault/$$FILE.yml;; \
|
||||
show) \
|
||||
echo "🔐 Просмотр секретов..."; \
|
||||
@@ -276,7 +276,7 @@ vault:
|
||||
echo ""; \
|
||||
read -p "Введите имя файла (без .yml): " FILE; \
|
||||
docker run --rm -v "$(PWD):/workspace" -w /workspace \
|
||||
quay.io/ansible/creator-ee:latest \
|
||||
$(DOCKER_IMAGE) \
|
||||
ansible-vault view --vault-password-file vault/.vault vault/$$FILE.yml;; \
|
||||
delete) \
|
||||
echo "🔐 Удаление секретов..."; \
|
||||
@@ -290,7 +290,7 @@ vault:
|
||||
echo ""; \
|
||||
read -p "Введите имя файла (без .yml): " FILE; \
|
||||
docker run --rm -v "$(PWD):/workspace" -w /workspace \
|
||||
quay.io/ansible/creator-ee:latest \
|
||||
$(DOCKER_IMAGE) \
|
||||
ansible-vault encrypt --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \
|
||||
decrypt) \
|
||||
echo "🔐 Расшифровка файла..."; \
|
||||
@@ -298,7 +298,7 @@ vault:
|
||||
echo ""; \
|
||||
read -p "Введите имя файла (без .yml): " FILE; \
|
||||
docker run --rm -v "$(PWD):/workspace" -w /workspace \
|
||||
quay.io/ansible/creator-ee:latest \
|
||||
$(DOCKER_IMAGE) \
|
||||
ansible-vault decrypt --vault-password-file vault/.vault vault/$$FILE.yml;; \
|
||||
rekey) \
|
||||
echo "🔐 Смена пароля..."; \
|
||||
@@ -306,7 +306,7 @@ vault:
|
||||
echo ""; \
|
||||
read -p "Введите имя файла (без .yml): " FILE; \
|
||||
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
|
||||
quay.io/ansible/creator-ee:latest \
|
||||
$(DOCKER_IMAGE) \
|
||||
ansible-vault rekey --vault-password-file vault/.vault vault/$$FILE.yml;; \
|
||||
check) \
|
||||
echo "🔍 Проверка vault файлов..."; \
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
trigger:
|
||||
- main
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
stages:
|
||||
- stage: Test
|
||||
jobs:
|
||||
- job: TestJob
|
||||
steps:
|
||||
- script: make role test
|
||||
249
docs/vault-guide.md
Normal file
249
docs/vault-guide.md
Normal file
@@ -0,0 +1,249 @@
|
||||
# Руководство по работе с Ansible Vault
|
||||
|
||||
## Автор
|
||||
Сергей Антропов
|
||||
Сайт: https://devops.org.ru
|
||||
|
||||
## Описание
|
||||
|
||||
Это руководство описывает работу с зашифрованными секретами в Ansible Vault для проекта AnsibleTemplate.
|
||||
|
||||
## Безопасность
|
||||
|
||||
⚠️ **ВАЖНО**: Зашифрованные файлы содержат секретные данные и должны храниться в безопасности!
|
||||
|
||||
## Команды для работы с Vault
|
||||
|
||||
### Инициализация Vault
|
||||
|
||||
```bash
|
||||
# Создание файла с паролем для vault
|
||||
make vault init
|
||||
```
|
||||
|
||||
### Основные операции
|
||||
|
||||
```bash
|
||||
# Создание нового файла секретов
|
||||
make vault create
|
||||
|
||||
# Редактирование существующих секретов
|
||||
make vault edit
|
||||
|
||||
# Просмотр содержимого секретов
|
||||
make vault show
|
||||
|
||||
# Шифрование существующего файла
|
||||
make vault encrypt
|
||||
|
||||
# Расшифровка файла
|
||||
make vault decrypt
|
||||
|
||||
# Смена пароля шифрования
|
||||
make vault rekey
|
||||
|
||||
# Удаление файла секретов
|
||||
make vault delete
|
||||
|
||||
# Проверка vault файлов
|
||||
make vault check
|
||||
```
|
||||
|
||||
## Структура файлов
|
||||
|
||||
```
|
||||
vault/
|
||||
├── .vault # Файл с паролем для vault (НЕ коммитится в git)
|
||||
├── secrets.yml # Зашифрованный файл с секретами
|
||||
└── secrets/ # Директория для незашифрованных секретов
|
||||
└── *.yml # Незашифрованные файлы секретов
|
||||
```
|
||||
|
||||
## Примеры использования
|
||||
|
||||
### 1. Создание нового файла секретов
|
||||
|
||||
```bash
|
||||
# Создать новый файл
|
||||
make vault create
|
||||
# Введите имя файла (без .yml): my-secrets
|
||||
```
|
||||
|
||||
### 2. Редактирование секретов
|
||||
|
||||
```bash
|
||||
# Редактировать существующий файл
|
||||
make vault edit
|
||||
# Введите имя файла (без .yml): secrets
|
||||
```
|
||||
|
||||
### 3. Просмотр секретов
|
||||
|
||||
```bash
|
||||
# Показать содержимое файла
|
||||
make vault show
|
||||
# Введите имя файла (без .yml): secrets
|
||||
```
|
||||
|
||||
### 4. Шифрование файла
|
||||
|
||||
```bash
|
||||
# Зашифровать незашифрованный файл
|
||||
make vault encrypt
|
||||
# Введите имя файла (без .yml): secrets
|
||||
```
|
||||
|
||||
### 5. Расшифровка файла
|
||||
|
||||
```bash
|
||||
# Расшифровать файл для редактирования
|
||||
make vault decrypt
|
||||
# Введите имя файла (без .yml): secrets
|
||||
```
|
||||
|
||||
## Использование в Playbook
|
||||
|
||||
### Передача пароля vault
|
||||
|
||||
```bash
|
||||
# Запуск playbook с паролем vault
|
||||
ansible-playbook -i inventory/hosts.ini roles/deploy.yml --ask-vault-pass
|
||||
|
||||
# Использование файла с паролем
|
||||
ansible-playbook -i inventory/hosts.ini roles/deploy.yml --vault-password-file vault/.vault
|
||||
```
|
||||
|
||||
### Переменные из vault
|
||||
|
||||
```yaml
|
||||
# В playbook
|
||||
- name: "Использование секретов из vault"
|
||||
hosts: all
|
||||
vars_files:
|
||||
- vault/secrets.yml
|
||||
tasks:
|
||||
- name: "Использование SSH ключа"
|
||||
authorized_key:
|
||||
user: "{{ devops_user.name }}"
|
||||
key: "{{ devops_ssh_keys.public_key }}"
|
||||
```
|
||||
|
||||
## Безопасность и лучшие практики
|
||||
|
||||
### 1. Защита пароля vault
|
||||
|
||||
```bash
|
||||
# Установка правильных прав на файл пароля
|
||||
chmod 600 vault/.vault
|
||||
|
||||
# Добавление в .gitignore
|
||||
echo "vault/.vault" >> .gitignore
|
||||
```
|
||||
|
||||
### 2. Ротация паролей
|
||||
|
||||
```bash
|
||||
# Смена пароля vault
|
||||
make vault rekey
|
||||
# Введите имя файла (без .yml): secrets
|
||||
```
|
||||
|
||||
### 3. Резервное копирование
|
||||
|
||||
```bash
|
||||
# Создание резервной копии зашифрованного файла
|
||||
cp vault/secrets.yml vault/secrets.yml.backup
|
||||
|
||||
# Создание резервной копии пароля
|
||||
cp vault/.vault vault/.vault.backup
|
||||
```
|
||||
|
||||
### 4. Проверка целостности
|
||||
|
||||
```bash
|
||||
# Проверка vault файлов
|
||||
make vault check
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Проблема: "Unable to read source file"
|
||||
|
||||
```bash
|
||||
# Убедитесь, что файл существует
|
||||
ls -la vault/*.yml
|
||||
|
||||
# Проверьте права доступа
|
||||
ls -la vault/
|
||||
```
|
||||
|
||||
### Проблема: "Vault password not provided"
|
||||
|
||||
```bash
|
||||
# Убедитесь, что файл .vault существует
|
||||
ls -la vault/.vault
|
||||
|
||||
# Проверьте содержимое файла
|
||||
cat vault/.vault
|
||||
```
|
||||
|
||||
### Проблема: "Invalid vault password"
|
||||
|
||||
```bash
|
||||
# Проверьте пароль в файле .vault
|
||||
cat vault/.vault
|
||||
|
||||
# Пересоздайте файл пароля
|
||||
rm vault/.vault
|
||||
make vault init
|
||||
```
|
||||
|
||||
## Интеграция с CI/CD
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
```yaml
|
||||
# .github/workflows/deploy.yml
|
||||
- name: "Deploy with Vault"
|
||||
run: |
|
||||
echo "${{ secrets.VAULT_PASSWORD }}" > vault/.vault
|
||||
ansible-playbook -i inventory/hosts.ini roles/deploy.yml --vault-password-file vault/.vault
|
||||
```
|
||||
|
||||
### GitLab CI
|
||||
|
||||
```yaml
|
||||
# .gitlab-ci.yml
|
||||
deploy:
|
||||
script:
|
||||
- echo "$VAULT_PASSWORD" > vault/.vault
|
||||
- ansible-playbook -i inventory/hosts.ini roles/deploy.yml --vault-password-file vault/.vault
|
||||
```
|
||||
|
||||
## Мониторинг и логирование
|
||||
|
||||
### Проверка статуса vault
|
||||
|
||||
```bash
|
||||
# Проверка всех vault файлов
|
||||
make vault check
|
||||
|
||||
# Проверка конкретного файла
|
||||
ansible-vault view vault/secrets.yml --vault-password-file vault/.vault
|
||||
```
|
||||
|
||||
### Логирование операций
|
||||
|
||||
```bash
|
||||
# Включение подробного логирования
|
||||
export ANSIBLE_VERBOSITY=4
|
||||
|
||||
# Запуск с логированием
|
||||
ansible-playbook -i inventory/hosts.ini roles/deploy.yml --vault-password-file vault/.vault -vvv
|
||||
```
|
||||
|
||||
## Поддержка
|
||||
|
||||
- 📧 Email: через сайт https://devops.org.ru
|
||||
- 📖 Документация: `docs/`
|
||||
- 🧪 Тесты: `roles/*/tests/`
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
# Ansible Collections для Molecule Universal
|
||||
collections:
|
||||
- name: community.docker
|
||||
version: ">=3.0.0"
|
||||
- name: community.general
|
||||
version: ">=7.0.0"
|
||||
- name: ansible.posix
|
||||
version: ">=1.5.4"
|
||||
@@ -6,4 +6,5 @@
|
||||
- name: Развертывание всех ролей
|
||||
hosts: all
|
||||
roles:
|
||||
- ping
|
||||
# - ping
|
||||
- devops
|
||||
|
||||
120
roles/devops/QUICKSTART.md
Normal file
120
roles/devops/QUICKSTART.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Быстрый старт - Роль devops
|
||||
|
||||
## Автор
|
||||
Сергей Антропов
|
||||
Сайт: https://devops.org.ru
|
||||
|
||||
## Что делает роль
|
||||
|
||||
Роль `devops` автоматически:
|
||||
1. ✅ Создает пользователя `devops`
|
||||
2. ✅ Генерирует безопасный пароль (30 символов)
|
||||
3. ✅ Настраивает SSH доступ по ключу
|
||||
4. ✅ Добавляет права sudo без пароля
|
||||
5. ✅ Создает домашнюю директорию
|
||||
|
||||
## Быстрый запуск
|
||||
|
||||
### 1. Базовое использование
|
||||
```bash
|
||||
ansible-playbook -i inventory/hosts.ini roles/deploy.yml
|
||||
```
|
||||
|
||||
### 2. С SSH ключом из vault
|
||||
```bash
|
||||
ansible-playbook -i inventory/hosts.ini roles/deploy.yml \
|
||||
--ask-vault-pass \
|
||||
-e "devops_ssh_public_key={{ devops_ssh_keys.public_key }}"
|
||||
```
|
||||
|
||||
### 3. Только роль devops
|
||||
```bash
|
||||
ansible-playbook -i inventory/hosts.ini roles/devops/playbook.yml
|
||||
```
|
||||
|
||||
## Проверка результата
|
||||
|
||||
После выполнения проверьте:
|
||||
|
||||
```bash
|
||||
# Проверка пользователя
|
||||
ansible all -i inventory/hosts.ini -m shell -a "id devops"
|
||||
|
||||
# Проверка sudo прав
|
||||
ansible all -i inventory/hosts.ini -m shell -a "sudo -l -U devops"
|
||||
|
||||
# Проверка SSH директории
|
||||
ansible all -i inventory/hosts.ini -m shell -a "ls -la /home/devops/.ssh/"
|
||||
```
|
||||
|
||||
## Настройка SSH ключа
|
||||
|
||||
1. Добавьте ваш SSH ключ в `vault/secrets.yml`:
|
||||
```yaml
|
||||
devops_ssh_keys:
|
||||
public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7vbqajDhA... your@email.com"
|
||||
```
|
||||
|
||||
2. Запустите playbook с передачей ключа:
|
||||
```bash
|
||||
ansible-playbook -i inventory/hosts.ini roles/deploy.yml \
|
||||
--ask-vault-pass \
|
||||
-e "devops_ssh_public_key={{ devops_ssh_keys.public_key }}"
|
||||
```
|
||||
|
||||
## Кастомизация
|
||||
|
||||
### Изменить имя пользователя
|
||||
```yaml
|
||||
vars:
|
||||
devops_user:
|
||||
name: "myuser"
|
||||
home: "/home/myuser"
|
||||
```
|
||||
|
||||
### Изменить длину пароля
|
||||
```yaml
|
||||
vars:
|
||||
devops_password:
|
||||
length: 40
|
||||
```
|
||||
|
||||
### Добавить группы
|
||||
```yaml
|
||||
vars:
|
||||
devops_user:
|
||||
groups: ["sudo", "docker", "wheel", "adm"]
|
||||
```
|
||||
|
||||
## Безопасность
|
||||
|
||||
- 🔒 Пароль генерируется автоматически и не сохраняется в логах
|
||||
- 🔑 SSH доступ только по ключу (если настроен)
|
||||
- 🛡️ Пользователь добавлен в sudoers с правами NOPASSWD
|
||||
- 📁 SSH директория имеет правильные права доступа (700)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Проблема: Пользователь не создан
|
||||
```bash
|
||||
# Проверьте права sudo
|
||||
ansible all -i inventory/hosts.ini -m shell -a "sudo whoami"
|
||||
```
|
||||
|
||||
### Проблема: SSH не работает
|
||||
```bash
|
||||
# Проверьте права на SSH директорию
|
||||
ansible all -i inventory/hosts.ini -m shell -a "ls -la /home/devops/.ssh/"
|
||||
```
|
||||
|
||||
### Проблема: Sudo не работает
|
||||
```bash
|
||||
# Проверьте sudoers файл
|
||||
ansible all -i inventory/hosts.ini -m shell -a "sudo visudo -c"
|
||||
```
|
||||
|
||||
## Поддержка
|
||||
|
||||
- 📧 Email: через сайт https://devops.org.ru
|
||||
- 📖 Документация: `roles/devops/README.md`
|
||||
- 🧪 Тесты: `roles/devops/tests/test.yml`
|
||||
167
roles/devops/README.md
Normal file
167
roles/devops/README.md
Normal file
@@ -0,0 +1,167 @@
|
||||
# Роль devops
|
||||
|
||||
Роль для создания пользователя devops с безопасным паролем, SSH доступом и правами sudo.
|
||||
|
||||
## Автор
|
||||
Сергей Антропов
|
||||
Сайт: https://devops.org.ru
|
||||
|
||||
## Описание
|
||||
|
||||
Эта роль выполняет следующие функции:
|
||||
1. Создание пользователя `devops`
|
||||
2. Генерация безопасного пароля длиной 30 символов
|
||||
3. Назначение пароля пользователю
|
||||
4. Добавление пользователя в sudoers с правами выполнения команд без пароля
|
||||
5. Настройка SSH доступа через публичный ключ
|
||||
|
||||
## Требования
|
||||
|
||||
- Ansible >= 2.9
|
||||
- Python >= 3.6
|
||||
- Права root/sudo для выполнения задач
|
||||
|
||||
## Переменные
|
||||
|
||||
### Основные переменные (defaults/main.yml)
|
||||
|
||||
```yaml
|
||||
# Настройки пользователя devops
|
||||
devops_user:
|
||||
name: "devops"
|
||||
home: "/home/devops"
|
||||
shell: "/bin/bash"
|
||||
groups: ["sudo", "docker"]
|
||||
create_home: true
|
||||
state: "present"
|
||||
|
||||
# Настройки пароля
|
||||
devops_password:
|
||||
length: 30
|
||||
special_chars: true
|
||||
min_special: 4
|
||||
min_upper: 4
|
||||
min_lower: 4
|
||||
min_digits: 4
|
||||
|
||||
# Настройки sudo
|
||||
devops_sudo:
|
||||
nopasswd: true
|
||||
commands: "ALL"
|
||||
|
||||
# SSH настройки
|
||||
devops_ssh:
|
||||
authorized_keys_file: "/home/devops/.ssh/authorized_keys"
|
||||
ssh_dir: "/home/devops/.ssh"
|
||||
ssh_dir_mode: "0700"
|
||||
authorized_keys_mode: "0600"
|
||||
```
|
||||
|
||||
### Переменные из vault/secrets.yml
|
||||
|
||||
```yaml
|
||||
# SSH ключи для пользователя devops
|
||||
devops_ssh_keys:
|
||||
public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7vbqajDhA... devops@example.com"
|
||||
```
|
||||
|
||||
## Использование
|
||||
|
||||
### Базовое использование
|
||||
|
||||
```yaml
|
||||
- hosts: all
|
||||
become: true
|
||||
roles:
|
||||
- devops
|
||||
```
|
||||
|
||||
### С передачей SSH ключа
|
||||
|
||||
```yaml
|
||||
- hosts: all
|
||||
become: true
|
||||
vars:
|
||||
devops_ssh_public_key: "{{ devops_ssh_keys.public_key }}"
|
||||
roles:
|
||||
- devops
|
||||
```
|
||||
|
||||
### С кастомными настройками
|
||||
|
||||
```yaml
|
||||
- hosts: all
|
||||
become: true
|
||||
vars:
|
||||
devops_user:
|
||||
name: "mydevops"
|
||||
home: "/home/mydevops"
|
||||
devops_password:
|
||||
length: 40
|
||||
roles:
|
||||
- devops
|
||||
```
|
||||
|
||||
## Безопасность
|
||||
|
||||
- Пароль генерируется автоматически с использованием криптографически стойкого алгоритма
|
||||
- Пароль содержит минимум 4 символа каждого типа (специальные, заглавные, строчные, цифры)
|
||||
- SSH ключи добавляются в authorized_keys для безопасного доступа
|
||||
- Пользователь добавляется в sudoers с правами NOPASSWD для удобства использования
|
||||
|
||||
## Поддерживаемые ОС
|
||||
|
||||
- Ubuntu (focal, jammy)
|
||||
- Debian (bullseye, bookworm)
|
||||
- RHEL (8, 9)
|
||||
- CentOS (8, 9)
|
||||
- Rocky Linux (8, 9)
|
||||
- AlmaLinux (8, 9)
|
||||
|
||||
## Теги
|
||||
|
||||
- `devops` - основная функциональность
|
||||
- `user-management` - управление пользователями
|
||||
- `security` - настройки безопасности
|
||||
- `ssh` - SSH конфигурация
|
||||
- `sudo` - настройки sudo
|
||||
|
||||
## Примеры
|
||||
|
||||
### Создание пользователя с SSH ключом
|
||||
|
||||
```bash
|
||||
ansible-playbook -i inventory/hosts.ini playbook.yml \
|
||||
--ask-vault-pass \
|
||||
-e "devops_ssh_public_key={{ devops_ssh_keys.public_key }}"
|
||||
```
|
||||
|
||||
### Проверка создания пользователя
|
||||
|
||||
```bash
|
||||
ansible all -i inventory/hosts.ini -m shell -a "id devops"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Проблема с sudoers
|
||||
|
||||
Если возникают проблемы с sudoers, проверьте синтаксис:
|
||||
|
||||
```bash
|
||||
sudo visudo -c
|
||||
```
|
||||
|
||||
### Проблема с SSH
|
||||
|
||||
Проверьте права доступа к SSH директории:
|
||||
|
||||
```bash
|
||||
ls -la /home/devops/.ssh/
|
||||
```
|
||||
|
||||
Должны быть права 700 для директории и 600 для authorized_keys.
|
||||
|
||||
## Лицензия
|
||||
|
||||
MIT
|
||||
34
roles/devops/defaults/main.yml
Normal file
34
roles/devops/defaults/main.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# Переменные по умолчанию для роли devops
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
# Настройки пользователя devops
|
||||
devops_user:
|
||||
name: "devops"
|
||||
home: "/home/devops"
|
||||
shell: "/bin/bash"
|
||||
groups: ["sudo", "docker"]
|
||||
create_home: true
|
||||
state: "present"
|
||||
|
||||
# Настройки пароля
|
||||
devops_password:
|
||||
length: 30
|
||||
special_chars: true
|
||||
min_special: 4
|
||||
min_upper: 4
|
||||
min_lower: 4
|
||||
min_digits: 4
|
||||
|
||||
# Настройки sudo
|
||||
devops_sudo:
|
||||
nopasswd: true
|
||||
commands: "ALL"
|
||||
|
||||
# SSH настройки
|
||||
devops_ssh:
|
||||
authorized_keys_file: "/home/devops/.ssh/authorized_keys"
|
||||
ssh_dir: "/home/devops/.ssh"
|
||||
ssh_dir_mode: "0700"
|
||||
authorized_keys_mode: "0600"
|
||||
64
roles/devops/examples.yml
Normal file
64
roles/devops/examples.yml
Normal file
@@ -0,0 +1,64 @@
|
||||
---
|
||||
# Примеры использования роли devops
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
# Пример 1: Базовое использование
|
||||
- name: "Базовое создание пользователя devops"
|
||||
hosts: all
|
||||
become: true
|
||||
roles:
|
||||
- devops
|
||||
|
||||
# Пример 2: С передачей SSH ключа из vault
|
||||
- name: "Создание пользователя devops с SSH ключом"
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
devops_ssh_public_key: "{{ devops_ssh_keys.public_key }}"
|
||||
roles:
|
||||
- devops
|
||||
|
||||
# Пример 3: С кастомными настройками
|
||||
- name: "Создание пользователя с кастомными настройками"
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
devops_user:
|
||||
name: "mydevops"
|
||||
home: "/home/mydevops"
|
||||
groups: ["sudo", "docker", "wheel"]
|
||||
devops_password:
|
||||
length: 40
|
||||
min_special: 6
|
||||
min_upper: 6
|
||||
min_lower: 6
|
||||
min_digits: 6
|
||||
devops_ssh:
|
||||
ssh_dir: "/home/mydevops/.ssh"
|
||||
authorized_keys_file: "/home/mydevops/.ssh/authorized_keys"
|
||||
roles:
|
||||
- devops
|
||||
|
||||
# Пример 4: С дополнительными группами
|
||||
- name: "Создание пользователя с дополнительными группами"
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
devops_user:
|
||||
groups: ["sudo", "docker", "wheel", "adm", "systemd-journal"]
|
||||
roles:
|
||||
- devops
|
||||
|
||||
# Пример 5: Только для определенных хостов
|
||||
- name: "Создание пользователя на серверах разработки"
|
||||
hosts: dev_servers
|
||||
become: true
|
||||
vars:
|
||||
devops_user:
|
||||
name: "developer"
|
||||
home: "/home/developer"
|
||||
devops_sudo:
|
||||
commands: "ALL, !/usr/bin/passwd root"
|
||||
roles:
|
||||
- devops
|
||||
25
roles/devops/handlers/main.yml
Normal file
25
roles/devops/handlers/main.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
# Обработчики для роли devops
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
# Обработчик для перезапуска SSH сервиса после изменения authorized_keys
|
||||
- name: "Перезапуск SSH сервиса"
|
||||
service:
|
||||
name: ssh
|
||||
state: restarted
|
||||
become: true
|
||||
when: ansible_os_family != "RedHat"
|
||||
|
||||
- name: "Перезапуск SSH сервиса (RedHat/CentOS)"
|
||||
service:
|
||||
name: sshd
|
||||
state: restarted
|
||||
become: true
|
||||
when: ansible_os_family == "RedHat"
|
||||
|
||||
# Обработчик для проверки sudo конфигурации
|
||||
- name: "Проверка sudo конфигурации"
|
||||
command: visudo -c
|
||||
become: true
|
||||
changed_when: false
|
||||
28
roles/devops/meta/main.yml
Normal file
28
roles/devops/meta/main.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
galaxy_info:
|
||||
author: Сергей Антропов
|
||||
description: Роль для создания пользователя devops с безопасным паролем и SSH доступом
|
||||
company: https://devops.org.ru
|
||||
license: MIT
|
||||
min_ansible_version: "2.9"
|
||||
platforms:
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- focal
|
||||
- jammy
|
||||
- name: Debian
|
||||
versions:
|
||||
- bullseye
|
||||
- bookworm
|
||||
- name: EL
|
||||
versions:
|
||||
- "8"
|
||||
- "9"
|
||||
galaxy_tags:
|
||||
- devops
|
||||
- usermanagement
|
||||
- security
|
||||
- ssh
|
||||
- sudo
|
||||
|
||||
dependencies: []
|
||||
50
roles/devops/playbook.yml
Normal file
50
roles/devops/playbook.yml
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
# Пример playbook для роли devops
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
- name: "Создание пользователя devops с безопасным паролем и SSH доступом"
|
||||
hosts: all
|
||||
become: true
|
||||
gather_facts: true
|
||||
|
||||
vars:
|
||||
# Переменная для SSH ключа (должна быть передана из vault)
|
||||
devops_ssh_public_key: "{{ devops_ssh_keys.public_key }}"
|
||||
|
||||
roles:
|
||||
- devops
|
||||
|
||||
post_tasks:
|
||||
- name: "Проверка создания пользователя devops"
|
||||
command: "id {{ devops_user.name }}"
|
||||
register: user_check
|
||||
failed_when: user_check.rc != 0
|
||||
changed_when: false
|
||||
|
||||
- name: "Проверка SSH директории"
|
||||
stat:
|
||||
path: "{{ devops_ssh.ssh_dir }}"
|
||||
register: ssh_dir_check
|
||||
|
||||
- name: "Проверка authorized_keys"
|
||||
stat:
|
||||
path: "{{ devops_ssh.authorized_keys_file }}"
|
||||
register: auth_keys_check
|
||||
when: devops_ssh_public_key is defined
|
||||
|
||||
- name: "Проверка sudo прав"
|
||||
command: "sudo -l -U {{ devops_user.name }}"
|
||||
register: sudo_check
|
||||
become: true
|
||||
changed_when: false
|
||||
|
||||
- name: "Вывод результатов проверки"
|
||||
debug:
|
||||
msg: |
|
||||
Пользователь {{ devops_user.name }} создан: {{ user_check.rc == 0 }}
|
||||
SSH директория создана: {{ ssh_dir_check.stat.exists }}
|
||||
{% if devops_ssh_public_key is defined %}
|
||||
authorized_keys создан: {{ auth_keys_check.stat.exists }}
|
||||
{% endif %}
|
||||
Sudo права настроены: {{ sudo_check.rc == 0 }}
|
||||
57
roles/devops/tasks/main.yml
Normal file
57
roles/devops/tasks/main.yml
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
# Задачи для роли devops
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
# Генерация безопасного пароля для пользователя devops
|
||||
- name: "Генерация безопасного пароля для пользователя devops"
|
||||
set_fact:
|
||||
devops_user_password: "{{ lookup('password', '/tmp/devops_password length=' + devops_password.length | string + ' chars=ascii_letters,digits,punctuation') }}"
|
||||
no_log: true
|
||||
|
||||
# Создание пользователя devops
|
||||
- name: "Создание пользователя devops"
|
||||
user:
|
||||
name: "{{ devops_user.name }}"
|
||||
home: "{{ devops_user.home }}"
|
||||
shell: "{{ devops_user.shell }}"
|
||||
groups: "{{ devops_user.groups }}"
|
||||
create_home: "{{ devops_user.create_home }}"
|
||||
state: "{{ devops_user.state }}"
|
||||
password: "{{ devops_user_password | password_hash('sha512') }}"
|
||||
become: true
|
||||
|
||||
# Создание SSH директории для пользователя devops
|
||||
- name: "Создание SSH директории для пользователя devops"
|
||||
file:
|
||||
path: "{{ devops_ssh.ssh_dir }}"
|
||||
state: directory
|
||||
owner: "{{ devops_user.name }}"
|
||||
group: "{{ devops_user.name }}"
|
||||
mode: "{{ devops_ssh.ssh_dir_mode }}"
|
||||
become: true
|
||||
|
||||
# Добавление SSH ключа в authorized_keys
|
||||
- name: "Добавление SSH ключа в authorized_keys"
|
||||
authorized_key:
|
||||
user: "{{ devops_user.name }}"
|
||||
key: "{{ devops_ssh_public_key }}"
|
||||
state: present
|
||||
manage_dir: false
|
||||
become: true
|
||||
when: devops_ssh_public_key is defined
|
||||
|
||||
# Настройка sudo для пользователя devops (без пароля)
|
||||
- name: "Настройка sudo для пользователя devops без пароля"
|
||||
lineinfile:
|
||||
path: /etc/sudoers.d/devops
|
||||
line: "{{ devops_user.name }} ALL=(ALL) NOPASSWD: {{ devops_sudo.commands }}"
|
||||
create: true
|
||||
mode: '0440'
|
||||
validate: 'visudo -cf %s'
|
||||
become: true
|
||||
|
||||
# Логирование успешного создания пользователя
|
||||
- name: "Логирование создания пользователя devops"
|
||||
debug:
|
||||
msg: "Пользователь {{ devops_user.name }} успешно создан с безопасным паролем и SSH доступом"
|
||||
88
roles/devops/tests/test.yml
Normal file
88
roles/devops/tests/test.yml
Normal file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
# Тесты для роли devops
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
- name: "Тестирование роли devops"
|
||||
hosts: all
|
||||
become: true
|
||||
gather_facts: true
|
||||
|
||||
vars:
|
||||
devops_ssh_public_key: "{{ devops_ssh_keys.public_key }}"
|
||||
|
||||
roles:
|
||||
- devops
|
||||
|
||||
post_tasks:
|
||||
# Тест 1: Проверка существования пользователя
|
||||
- name: "Проверка существования пользователя devops"
|
||||
command: "id {{ devops_user.name }}"
|
||||
register: user_exists
|
||||
failed_when: user_exists.rc != 0
|
||||
changed_when: false
|
||||
|
||||
# Тест 2: Проверка домашней директории
|
||||
- name: "Проверка домашней директории"
|
||||
stat:
|
||||
path: "{{ devops_user.home }}"
|
||||
register: home_dir
|
||||
failed_when: not home_dir.stat.exists
|
||||
|
||||
# Тест 3: Проверка SSH директории
|
||||
- name: "Проверка SSH директории"
|
||||
stat:
|
||||
path: "{{ devops_ssh.ssh_dir }}"
|
||||
register: ssh_dir
|
||||
failed_when: not ssh_dir.stat.exists
|
||||
|
||||
# Тест 4: Проверка authorized_keys (если SSH ключ передан)
|
||||
- name: "Проверка authorized_keys"
|
||||
stat:
|
||||
path: "{{ devops_ssh.authorized_keys_file }}"
|
||||
register: auth_keys
|
||||
failed_when: devops_ssh_public_key is defined and not auth_keys.stat.exists
|
||||
when: devops_ssh_public_key is defined
|
||||
|
||||
# Тест 5: Проверка sudo прав
|
||||
- name: "Проверка sudo прав"
|
||||
command: "sudo -l -U {{ devops_user.name }}"
|
||||
register: sudo_rights
|
||||
become: true
|
||||
failed_when: sudo_rights.rc != 0
|
||||
changed_when: false
|
||||
|
||||
# Тест 6: Проверка групп пользователя
|
||||
- name: "Проверка групп пользователя"
|
||||
command: "groups {{ devops_user.name }}"
|
||||
register: user_groups
|
||||
failed_when: user_groups.rc != 0
|
||||
changed_when: false
|
||||
|
||||
# Тест 7: Проверка прав на SSH директорию
|
||||
- name: "Проверка прав на SSH директорию"
|
||||
stat:
|
||||
path: "{{ devops_ssh.ssh_dir }}"
|
||||
register: ssh_dir_perms
|
||||
failed_when: ssh_dir_perms.stat.mode != "0" + devops_ssh.ssh_dir_mode
|
||||
|
||||
# Тест 8: Проверка shell пользователя
|
||||
- name: "Проверка shell пользователя"
|
||||
command: "getent passwd {{ devops_user.name }}"
|
||||
register: user_shell
|
||||
failed_when: user_shell.rc != 0
|
||||
changed_when: false
|
||||
|
||||
# Вывод результатов тестов
|
||||
- name: "Результаты тестов"
|
||||
debug:
|
||||
msg: |
|
||||
✅ Пользователь {{ devops_user.name }} создан
|
||||
✅ Домашняя директория {{ devops_user.home }} создана
|
||||
✅ SSH директория {{ devops_ssh.ssh_dir }} создана
|
||||
{% if devops_ssh_public_key is defined %}
|
||||
✅ authorized_keys настроен
|
||||
{% endif %}
|
||||
✅ Sudo права настроены
|
||||
✅ Группы пользователя: {{ user_groups.stdout }}
|
||||
✅ Shell пользователя: {{ user_shell.stdout.split(':')[-1] }}
|
||||
25
roles/devops/vars/main.yml
Normal file
25
roles/devops/vars/main.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
# Переменные для роли devops
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
# Список пакетов, необходимых для роли
|
||||
devops_required_packages:
|
||||
- openssh-server
|
||||
- sudo
|
||||
- passwd
|
||||
|
||||
# Настройки безопасности для SSH
|
||||
devops_ssh_security:
|
||||
permit_root_login: "no"
|
||||
password_authentication: "yes"
|
||||
pubkey_authentication: "yes"
|
||||
authorized_keys_file: ".ssh/authorized_keys"
|
||||
|
||||
# Настройки sudo для безопасности
|
||||
devops_sudo_security:
|
||||
requiretty: false
|
||||
visiblepw: false
|
||||
always_set_home: true
|
||||
env_reset: true
|
||||
env_keep: "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
|
||||
@@ -1,33 +1,80 @@
|
||||
---
|
||||
# Основные секреты для тестирования
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
# Пароли для баз данных
|
||||
database_passwords:
|
||||
root_password: "database-root-password"
|
||||
app_user_password: "database-app-password"
|
||||
monitoring_user_password: "monitoring-user-password"
|
||||
|
||||
# SSL сертификаты
|
||||
ssl_certificates:
|
||||
server_cert: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
# Server certificate content
|
||||
-----END CERTIFICATE-----
|
||||
server_key: |
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
# Server private key content
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
# API ключи
|
||||
api_keys:
|
||||
github_token: "ghp_example_token"
|
||||
dockerhub_token: "dckr_example_token"
|
||||
monitoring_api_key: "monitoring_api_key_example"
|
||||
|
||||
# Строки подключения
|
||||
database_connections:
|
||||
primary: "mysql://user:password@db1:3306/app"
|
||||
replica: "mysql://user:password@db2:3306/app"
|
||||
cache: "redis://cache1:6379/0"
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
35343565303431363831646439663864653034633332396533656362393138666235353365613631
|
||||
6633313964346463653166333131316161643064626539300a366366383264653236643366343861
|
||||
36643265643338346263663332663961613132613662303033386563356235666334613763303232
|
||||
3332636435353130380a643031343335306330643964363230333363653761376333306232663263
|
||||
37613937376662386563366237666630623935653663316235363037613962616663373534633066
|
||||
36356639656662653339613534373630326164303536633466613238306530326661343065376632
|
||||
63646330376662643836636539333837313366656237626264336130636139376665346162303834
|
||||
39366235333833303839646530663963346234316661306663356261316537663333326363326333
|
||||
34386536343137333736356139636461653737353062613730326665383761356337663264356539
|
||||
64623962363631356131373735643639333065663861336262346366313163303739306663616635
|
||||
63386534333936356636623532653339366464346531326562623062353839333563346562383832
|
||||
38656166626366653930343436633338363530313138323862353563323033306333353130383732
|
||||
63323931336338663663383532313635373166616631333832666330393933646165336164353634
|
||||
30666137626131636162333335373961343763383434386166346363626162663538653239633563
|
||||
64316539626632346133346339616164646336306331393466306333623638366137613866663263
|
||||
37623663316462376330643866303464366236613965663561383561643162393032663266383661
|
||||
63643466396433366530613830636666393862383134313165313162663262623536306164313633
|
||||
65383031646562356535626363326135656366323462383364306138626163363236333036316534
|
||||
36353364626130633965353036636430393035316434393063373062363362663430633462313631
|
||||
65373330646531333334623738653537623963663237663137306430656438316665623534313362
|
||||
36303934306331393365363866393265646263653830666234333234623266353634393239633337
|
||||
32663938613831656138376266333835613561643534663463373238323532313237336132613239
|
||||
31383665373964623362623561313161363831316361626432636665343938633437336561363161
|
||||
30366136383766356261396533356134326532353938326439303334396333363036363563653030
|
||||
33353538316363353637313835636535653136346234316636626533663331653163643466633164
|
||||
35633630316162396665626632363036373331343230306665313037336666663066653763653835
|
||||
34643532386138363665663238393336356431353464613031336334623761613732646565363730
|
||||
34353866616339616164663934626632663130393563646265343461303533653139653137303661
|
||||
30663539616162333739313366363861336562346132373861393734323366663863333063396232
|
||||
34373435306161383462306136333734303339353231386432313637343236356439626537663530
|
||||
33633331376439643732306365366530636134366431396566376330663162336334353031353834
|
||||
32636435656131616133643636363965316634626231356630323237613261663665393061616432
|
||||
35333031306562626234363061316562373964386236636464633939343437396234313036383561
|
||||
31646463313037323133616561633562323765303361346430313134316337626139663665326436
|
||||
31616334356663346234663833396635373162346136663062363138373034356638636537353737
|
||||
62336563333338343731626665323336386632303162383166346338373864613463326466386361
|
||||
37356135376430363038656439376366646238383736636461613034666163623838393236346464
|
||||
34356563366234306465366438326265366133663934323663313934313037313663633833343533
|
||||
38326163323438376336313065313338303239303766326636326433366566643935626530643537
|
||||
61313738313361353835373430386430343738356461633335396165323337623832663330383834
|
||||
61666363663939353238623861653962636638303138626435373366336130653565333532616664
|
||||
61643734393733646364623937356264306262366266396536656338343366306364663339656236
|
||||
63316635623037616266613739326335353066373463643132393331626232303134346233303833
|
||||
61303738383961636235616634356435313165613734336438333730353463313366653332626263
|
||||
61353731323133393735333664366134633434346130646164336665386264376265316266386665
|
||||
65613431303733376637643536646561636163633065393966333161313930356636353936663239
|
||||
36326561653132373335616237303764333661303961373139646663653431346338356331373765
|
||||
37333865333563333338666338633665316238396438333630306663383164383234636237393562
|
||||
32356130653538383632633462303665333733333365343237626262636563346361363764313663
|
||||
34306337636665633431353438373661306336396533613936313866623337343538613036353233
|
||||
66623936343762383033323830333266643463376138643133643434353135656261393733313433
|
||||
38303264303332643361376162303330343666636162396163366365353465623132663831323530
|
||||
33346565353262376131623431343538616533326564383637396538343336626336646633353934
|
||||
61376462656263663965383137376131643536336539613532373536376231626364643866646535
|
||||
38646430326138643339396464366438393263313665636562356631326133313734343562363065
|
||||
61663766616633333262623633396363336536373666316536363931333939383838663131613439
|
||||
66616663383334363330646638393139313330363533306639623437663763623333343038373838
|
||||
63303932663436636361663338346665386531333533633730323735333734376662383835343163
|
||||
38623435333662333634376361303734653130663833376264376336663363623966363939623336
|
||||
66656532663431333132663734386538663066323230356166356238333564336230633030353233
|
||||
61333933333763666564313233333432366231383666333832393035656234326161323332653135
|
||||
34323032613535336666633830373866383832393166636565646132633763616230326530346462
|
||||
63653638383263323532653261353365313433346534323865616336383864363530643237613061
|
||||
32613737353431626366643066663864663866323363396230333335346362373262393332333939
|
||||
34393539363836656539623766346336383834323831346261343635346466383164376135353136
|
||||
33366333323765616330333735383163663736646466653265326335306366663832643162363035
|
||||
39326661313732303830333236653134346534656433366366663539626364663362626135666438
|
||||
32356635386262336635396162666334616139353134323366633165626363336338393165663933
|
||||
62643431616632653838376239326531643733303636323236613561626534343535383130623766
|
||||
66343734396561386661306235393865336236323261356461356264326535316437653131326435
|
||||
38663866383332393033356165663032656433383763656431323836353961633437623662303135
|
||||
61373836626564373331303362313062313235373731646234393532343430363235326630373831
|
||||
35313635643936663438316132623265306531383838633266336563613662386233663937616230
|
||||
33333933353831396534356461653537616536633365323364326666323833346432636536643737
|
||||
31663065303933316438653864313734366464616137333838643839313437623532333766373763
|
||||
35346237383433643032613630396364386464316133343764666431636330333463333037306431
|
||||
35353232633463363732346462663230376631363832363239396262643531393831306633663966
|
||||
64333136343662343564653935306438663233623332626337613931353861396562663334346537
|
||||
353330613139383830303838353838356233
|
||||
|
||||
Reference in New Issue
Block a user