devsecops
@ -0,0 +1,260 @@
|
|||||||
|
# Ansible Vault SSH Key Management Guide
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
This document explains how to securely manage SSH private keys using Ansible Vault and the copy module with decryption capabilities, including proper playbook configuration to handle decryption before fact gathering.
|
||||||
|
|
||||||
|
## Important: Playbook Configuration
|
||||||
|
|
||||||
|
### Critical Setup Requirements
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Deploy with encrypted SSH key
|
||||||
|
hosts: all
|
||||||
|
gather_facts: false # ⚠️ ESSENTIAL - prevents early SSH connection attempts
|
||||||
|
vars:
|
||||||
|
ssh_private_key_file: key/deploy # Path to your encrypted key file
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
# Your decryption and deployment tasks here
|
||||||
|
```
|
||||||
|
|
||||||
|
### Why `gather_facts: false` is Mandatory
|
||||||
|
|
||||||
|
**Without `gather_facts: false`:**
|
||||||
|
- Ansible attempts to connect to target hosts immediately
|
||||||
|
- It tries to use SSH with the default SSH agent configuration
|
||||||
|
- Fails because the encrypted key isn't decrypted yet
|
||||||
|
- Playbook stops before reaching your decryption task
|
||||||
|
|
||||||
|
**With `gather_facts: false`:**
|
||||||
|
- Ansible skips the initial fact gathering phase
|
||||||
|
- Allows your decryption task to run first
|
||||||
|
- You control when and how the SSH key is used
|
||||||
|
|
||||||
|
## Step 1: Encrypt SSH Private Key with Ansible Vault
|
||||||
|
|
||||||
|
### Encrypt an existing SSH key:
|
||||||
|
```bash
|
||||||
|
# Method 1: Interactive password prompt
|
||||||
|
ansible-vault encrypt key/deploy --ask-vault-pass
|
||||||
|
|
||||||
|
# Method 2: Using a password file
|
||||||
|
ansible-vault encrypt key/deploy --vault-password-file vault_pass.txt
|
||||||
|
|
||||||
|
# Method 3: Using vault ID
|
||||||
|
ansible-vault encrypt key/deploy --vault-id deploy@vault_pass.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create a new encrypted SSH key:
|
||||||
|
```bash
|
||||||
|
ansible-vault create key/deploy --vault-password-file vault_pass.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verify encrypted content:
|
||||||
|
```bash
|
||||||
|
ansible-vault view key/deploy --vault-password-file vault_pass.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 2: Complete Ansible Playbook Example
|
||||||
|
|
||||||
|
### Full playbook structure:
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Deploy using encrypted SSH key
|
||||||
|
hosts: all
|
||||||
|
gather_facts: false # CRITICAL: Must be disabled
|
||||||
|
vars:
|
||||||
|
ssh_private_key_file: key/deploy
|
||||||
|
decrypted_key_path: /tmp/ansible_deploy_key
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Decrypt SSH private key
|
||||||
|
copy:
|
||||||
|
src: "{{ ssh_private_key_file }}"
|
||||||
|
dest: "{{ decrypted_key_path }}"
|
||||||
|
decrypt: yes
|
||||||
|
mode: '0600'
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
run_once: true
|
||||||
|
|
||||||
|
- name: Enable fact gathering with decrypted key
|
||||||
|
setup:
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
|
||||||
|
- name: Use the decrypted key for deployment
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
ssh -i "{{ decrypted_key_path }}" \
|
||||||
|
-o StrictHostKeyChecking=no \
|
||||||
|
-o UserKnownHostsFile=/dev/null \
|
||||||
|
deploy@{{ inventory_hostname }} 'deployment_command'
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
|
||||||
|
- name: Remove decrypted SSH key (cleanup)
|
||||||
|
file:
|
||||||
|
path: "{{ decrypted_key_path }}"
|
||||||
|
state: absent
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
always: yes
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 3: Running the Playbook
|
||||||
|
|
||||||
|
### Execution methods:
|
||||||
|
```bash
|
||||||
|
# With password file
|
||||||
|
ansible-playbook playbook.yml --vault-password-file vault_pass.txt
|
||||||
|
|
||||||
|
# Interactive password prompt
|
||||||
|
ansible-playbook playbook.yml --ask-vault-pass
|
||||||
|
|
||||||
|
# With vault ID
|
||||||
|
ansible-playbook playbook.yml --vault-id deploy@vault_pass.txt
|
||||||
|
|
||||||
|
# With inventory file
|
||||||
|
ansible-playbook -i hosts.ini playbook.yml --vault-password-file vault_pass.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 4: Advanced Error Handling & Security
|
||||||
|
|
||||||
|
### Robust playbook with proper error handling:
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Secure deployment with encrypted SSH key
|
||||||
|
hosts: all
|
||||||
|
gather_facts: false
|
||||||
|
vars:
|
||||||
|
ssh_private_key_file: key/deploy
|
||||||
|
decrypted_key_path: "/tmp/ansible_deploy_key_{{ ansible_date_time.epoch }}"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Ensure encrypted key file exists
|
||||||
|
stat:
|
||||||
|
path: "{{ ssh_private_key_file }}"
|
||||||
|
register: key_file
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
|
||||||
|
- name: Fail if encrypted key is missing
|
||||||
|
fail:
|
||||||
|
msg: "Encrypted SSH key file {{ ssh_private_key_file }} not found"
|
||||||
|
when: not key_file.stat.exists
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
|
||||||
|
- name: Decrypt SSH private key
|
||||||
|
copy:
|
||||||
|
src: "{{ ssh_private_key_file }}"
|
||||||
|
dest: "{{ decrypted_key_path }}"
|
||||||
|
decrypt: yes
|
||||||
|
mode: '0600'
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
run_once: true
|
||||||
|
|
||||||
|
- name: Verify decrypted key permissions
|
||||||
|
file:
|
||||||
|
path: "{{ decrypted_key_path }}"
|
||||||
|
mode: '0600'
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
|
||||||
|
- name: Gather facts using decrypted key (if needed)
|
||||||
|
setup:
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
|
||||||
|
- name: Perform deployment tasks
|
||||||
|
block:
|
||||||
|
- name: Execute remote deployment
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
ssh -i "{{ decrypted_key_path }}" \
|
||||||
|
-o ConnectTimeout=30 \
|
||||||
|
-o StrictHostKeyChecking=no \
|
||||||
|
deploy@{{ inventory_hostname }} 'your_deployment_script'
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
register: deployment_result
|
||||||
|
|
||||||
|
- name: Display deployment output
|
||||||
|
debug:
|
||||||
|
var: deployment_result.stdout
|
||||||
|
|
||||||
|
rescue:
|
||||||
|
- name: Handle deployment failure
|
||||||
|
debug:
|
||||||
|
msg: "Deployment failed - check SSH connectivity and permissions"
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Always remove decrypted key
|
||||||
|
file:
|
||||||
|
path: "{{ decrypted_key_path }}"
|
||||||
|
state: absent
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Best Practices
|
||||||
|
|
||||||
|
### 1. File Security:
|
||||||
|
```bash
|
||||||
|
# Secure permissions for password files
|
||||||
|
chmod 600 vault_pass.txt
|
||||||
|
|
||||||
|
# Secure permissions for encrypted key
|
||||||
|
chmod 600 key/deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Temporary File Safety:
|
||||||
|
- Use unique temporary filenames with timestamps
|
||||||
|
- Set strict permissions (0600)
|
||||||
|
- Always clean up, even on failure
|
||||||
|
|
||||||
|
### 3. Key Management:
|
||||||
|
- Never store unencrypted keys in version control
|
||||||
|
- Rotate deployment keys regularly
|
||||||
|
- Use different keys for different environments
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues & Solutions:
|
||||||
|
|
||||||
|
1. **"Permission denied" errors:**
|
||||||
|
- Verify vault password is correct
|
||||||
|
- Check encrypted file permissions
|
||||||
|
- Ensure cleanup tasks run successfully
|
||||||
|
|
||||||
|
2. **SSH connection failures:**
|
||||||
|
- Verify the decrypted key is authorized on target hosts
|
||||||
|
- Check network connectivity
|
||||||
|
- Validate target host accessibility
|
||||||
|
|
||||||
|
3. **Fact gathering issues:**
|
||||||
|
- Use `gather_facts: false` in main playbook
|
||||||
|
- Manually call `setup` module after decryption if needed
|
||||||
|
|
||||||
|
### Debug Commands:
|
||||||
|
```bash
|
||||||
|
# Test vault decryption
|
||||||
|
ansible-vault view key/deploy --vault-password-file vault_pass.txt
|
||||||
|
|
||||||
|
# Verify playbook syntax
|
||||||
|
ansible-playbook playbook.yml --syntax-check
|
||||||
|
|
||||||
|
# Dry run to see what would happen
|
||||||
|
ansible-playbook playbook.yml --vault-password-file vault_pass.txt --check
|
||||||
|
```
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
The key points for successful encrypted SSH key management:
|
||||||
|
|
||||||
|
1. **Always use `gather_facts: false`** in the main playbook
|
||||||
|
2. **Decrypt the key early** in your tasks
|
||||||
|
3. **Use unique temporary paths** for decrypted keys
|
||||||
|
4. **Always clean up** decrypted keys, even on failures
|
||||||
|
5. **Secure your vault passwords** with proper file permissions
|
||||||
|
|
||||||
|
This approach ensures your SSH keys remain encrypted at rest and are only temporarily decrypted during execution, maintaining security throughout your deployment process.
|
||||||
|
After Width: | Height: | Size: 149 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 215 KiB |
|
After Width: | Height: | Size: 199 KiB |
|
After Width: | Height: | Size: 142 KiB |
|
After Width: | Height: | Size: 168 KiB |
|
After Width: | Height: | Size: 140 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 192 KiB |
@ -0,0 +1,26 @@
|
|||||||
|
affectation d'un nom de domaine sur un projet gitlab
|
||||||
|
==========================================================
|
||||||
|
|
||||||
|
https://docs.framasoft.org/fr/gitlab/gitlab-pages.html#configuration-dns
|
||||||
|
|
||||||
|
settings > Pages
|
||||||
|
|
||||||
|
- ajouter un domaine (celui qu'on veut) exemple : test.pedrolalune.fr
|
||||||
|
|
||||||
|
sur le gitlab de framagit, mon projet est titi
|
||||||
|
https://gwen71.frama.io/titi/
|
||||||
|
|
||||||
|
configuration dns chez ovh :
|
||||||
|
|
||||||
|
- faire la redirection (CNAME)
|
||||||
|
|
||||||
|
exemple test.pedrolalune.fr -> gwen71.frama.io.
|
||||||
|
- TXT :
|
||||||
|
_gitlab-pages-verification-code.test ->
|
||||||
|
"_gitlab-pages-verification-code.test.pedrolalune.fr TXT
|
||||||
|
gitlab-pages-verification-code=2613sdfsdfsfdsdfsdf"
|
||||||
|
|
||||||
|
puis retourner dans les Pages gitlab,
|
||||||
|
et appuyer sur le bouton de vérification du nom de domaine.
|
||||||
|
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 122 KiB |