Впервые в Ansible и у вас есть несколько машин, которые используют pam_access
модуль, который настроен в /etc/security/access.conf
. Несколько строк, указывающих РАЗРЕШЕНИЕ / ЗАПРЕТ (+/-), а затем либо пользователей, либо группы вместе с IP-адресами src для сопоставления.
Какой более чистый способ управлять этим файлом в Ansible?
Файл /etc/security/access.conf
выглядит примерно так:
+ : root : cron crond :0 ttyS0 tty1 tty2 tty3 tty4 tty5 tty6
+ : root : 10.137.198.176
+ : inventory: 10.137.198.25
+ : sysadmin : 10.137.198.202
- : ALL : ALL
Большинство машин будут использовать этот базовый ACL, а затем при необходимости могут быть добавлены другие группы или пользователи. Веб-разработчики входят в систему через SFTP на двух веб-серверах, поэтому ACL будет вставлен для этой группы (перед - : ALL : ALL
строка) вот так:
+ : webdev : 10.137.198.0/24
- : ALL : ALL
Некоторые веб-серверы также запускают passenger
. Разработчики этих систем выдвигают код как passenger
user, поэтому этому пользователю разрешено использовать локальную сеть разработчика, но не на всех веб-серверах.
+ : passenger: 10.137.197.0/24
- : ALL : ALL
Правила становятся довольно специфичными для каждой машины, и я не вижу простого способа управления этим файлом. Я начал с playbook и group_vars ниже, которые работают, но для того, чтобы иметь несколько определений для одной и той же машины, нужна помощь. Возможно определение массива для line:
в playbook необходимо и разбираться в этом.
Кроме того, эта модель потребовала бы перезаписи файла каждый раз после удаления хоста из group_vars
не удаляет запись из access.conf
. Единственные состояния для lineinfile
являются absent
или present
. Мне нужно состояние под названием add_line_if_missing_remove_if_absent_from_vars
. Есть ли способ лучше?
- hosts: all
vars_files:
- ../group_vars/test-etc-security-access-conf.yml
gather_facts: false
tasks:
- name: "Set up /etc/security/access.conf for {{ inventory_hostname }}"
when: inventory_hostname is match (item.name)
lineinfile:
dest : /tmp/access.conf
regexp: '{{ item.regexp }}'
line: '{{ item.line }}'
with_items: "{{ access_rules }}"
group_vars - должно быть лучше:
access_rules:
- name: 10.137.1.66
regexp: '.*passenger.*'
line: '+ : passenger : 10.137.10.0/24'
- name: 10.137.1.66
regexp: '.*webdev.*'
line: '+ : webdev : 10.137.198.0/24'
Это то, что я в итоге использовал. Может быть кому нибудь будет полезно. Плейбук применит базовый ACL к каждому хосту, а затем будет искать дополнительный ACL в каталоге. {{ acl_dir }}
с именем текущего подготавливаемого хоста. Если он существует, он применяется. Наконец, правило запрета по умолчанию добавляется последним.
Я подумал, что было бы неплохо иметь комментарий в начале файла, когда он последний раз обновлялся. gather_facts
добавляет много времени выполнения, поэтому выбрал shell:
команда, чтобы вместо этого получить дату.
---
- hosts: all
vars:
dest_file: /etc/security/access.conf
base_acl : base
acl_dir : ../group_vars/pam_access
gather_facts: false
tasks:
- name: "Empty existing ACL and replace with base ACL"
copy:
content: ""
dest : "{{ dest_file }}"
owner : root
group : root
mode : 0644
- name: "Get current date from shell rather than wait for gather_facts"
shell: date '+%Y-%m-%d'
register: date_now
- name: "Add ansible header with modified date to beginning of file"
copy:
content: "# updated via ansible on {{ date_now.stdout }} by {{ lookup ('env', 'LOGNAME') }}"
dest: "{{ dest_file }}"
owner : root
group : root
mode : 0644
- name: "Add base ACL {{ acl_dir }}/base to {{ inventory_hostname }}"
lineinfile:
dest: "{{ dest_file }}"
line: "{{ lookup ('file', '{{ acl_dir }}/{{ base_acl }}') }}"
- name: "Check for additional ACL {{ acl_dir }}/{{ inventory_hostname }}..."
stat:
path : "{{ acl_dir }}/{{ inventory_hostname }}"
register: host_acl
- name: "Add host specific ACL from {{ acl_dir }}/{{ inventory_hostname }}"
when: host_acl.stat.exists
lineinfile:
dest: "{{ dest_file }}"
line: "{{ lookup ('file', '{{ acl_dir }}/{{ inventory_hostname }}') }}"
- name: "Add default DENY as last ACL as a security precaution"
lineinfile:
dest: "{{ dest_file }}"
line: "- : ALL : ALL"
базовый ACL:
+ : root : cron crond :0 ttyS0 tty1 tty2 tty3 tty4 tty5 tty6
+ : root : 10.137.198.176
+ : inventory: 10.137.198.25
+ : sysadmin : 10.137.198.202
дополнительный ACL хоста с именем websrv01.mydom.com
:
+ : webdev : 10.137.198.0/24
+ : passenger: 10.137.197.0/24