لنفترض أن أحد العملاء طلب منك المساعدة في ترحيل البرنامج النصي لنشر ملف sudoers مركزي على خوادم RHEL و AIX.

حسنًا ، هذا سيناريو شائع جدًا ، ويمكنك من خلال مثاله توضيح استخدام الميزات المتقدمة لـ Ansible ، وكذلك كيفية تغيير النهج - من برنامج نصي يؤدي مهمة معينة ، إلى وصف عاطفي (دون إجراء تغييرات) ومراقبة الامتثال لحالة المثيل.
خذ السيناريو:
هناك 212 سطرًا من التعليمات البرمجية ، مع عدم وجود تحكم في الإصدار في ملف sudoers. لدى العميل بالفعل عملية يتم تشغيلها مرة واحدة في الأسبوع ويتحقق من المجموع الاختباري للملف لضمان الأمان. على الرغم من أن البرنامج النصي يحتوي على إشارة إلى Solaris ، لهذا العميل لم يكن علينا نقل هذا المطلب.
لنبدأ بإنشاء دور ووضع ملف sudoers في Git للتحكم في الإصدار. من بين أشياء أخرى ، سيسمح لنا ذلك بالتخلص من الحاجة إلى تركيب وحدات تخزين NFS.
باستخدام معلمات التحقق والنسخ الاحتياطي لوحدات
النسخ والقالب ، يمكننا التخلص من الحاجة إلى كتابة التعليمات البرمجية لإجراء نسخ احتياطي واستعادة الملف. في هذه الحالة ، يتم إجراء التحقق من الصحة قبل وضع الملف في نقطة الوجهة ، وإذا فشلت عملية التحقق من الصحة ، فإن الوحدة النمطية تلقي خطأ.
لكل دور ، نحتاج إلى تحديد المهام والقوالب والمتغيرات. هنا هو هيكل الملف المقابل:

يحتوي ملف نصي الدور (playbook) ،
sudoers.yml ، على بنية بسيطة:
---
##
# Role playbook
##
- hosts: all
roles:
- sudoers
...
توجد متغيرات الدور في
ملف vars / main.yml . يحتوي هذا الملف على ملف المجموع الاختباري ويتضمن / يستثني التوجيهات التي سيتم استخدامها لإنشاء منطق خاص لتخطي مضيفي Lawson وتضمين ملف sudoers.d فقط في مضيفي hd.
فيما يلي محتويات
ملف vars / main.yml :
---
MD5FILE: /root/.sudoer.md5
EXCLUDE: la
INCLUDE: hd
...
إذا
استخدمنا وحدات النسخ و
lineinfile ، فلن يكون الدور ملائماً. ستقوم وحدة النسخ بتثبيت الملف الأساسي ، وسيشمل ملف lineinfile كل مرة يبدأ تشغيله. نظرًا لأن هذا الدور سيتم إطلاقه في
برج أنسبل ، فإن الشغور أمر لا بد منه. سنقوم بتحويل الملف إلى قالب jinja2.
في السطر الأول ، نضيف الأمر التالي
للتحكم في المسافات والمسافات البادئة :
#jinja2: lstrip_blocks: True, trim_blocks: True
لاحظ أن الإصدارات الأحدث من الوحدة النمطية
للقالب تتضمن معلمات
لكتل trim_blocks (أضيفت في Ansible 2.4).
إليك الرمز الذي يُدرج سطر
التضمين في نهاية الملف:
{% if ansible_hostname[0:2] == INCLUDE %}
#includedir /etc/sudoers.d
{% endif %}
نستخدم البنية الشرطية ({٪ if٪} ، {٪ endif٪}) لأمر shell الذي يقوم بإدراج سطر للمضيفين الذين تبدأ أسماؤهم بالحرف "hd". نستخدم حقائق Ansible وفلتر [0: 2] لتحليل اسم المضيف.
الآن دعنا ننتقل إلى المهام. أولاً ، تحتاج إلى إنشاء حقيقة لتحليل اسم المضيف. سوف نستخدم حقيقة "parhost" في البناء الشرطي.
---
##
# Parse hostnames to grab 1st 2 characters
##
- name: "Parse hostname's 1st 2 characters"
set_fact: parhost={{ ansible_hostname[0:2] }}
لا توجد معلمة
csum على خادم مخزون RHEL. إذا لزم الأمر ، يمكننا استخدام حقيقة أخرى للإشارة المشروطة إلى اسم الملف الثنائي مع المجموع الاختباري. يرجى ملاحظة أنه قد تكون هناك حاجة إلى رمز إضافي إذا كانت هذه الميزات مختلفة على AIX و Solaris و Linux.
بالإضافة إلى ذلك ، يتعين علينا حل المشكلة مع الاختلافات في مجموعات الجذر على AIX و RHEL.
##
# Conditionally set name of checksum binary
##
- name: "set checksum binary"
set_fact:
csbin: "{{ 'cksum' if (ansible_distribution == 'RedHat') else 'csum' }}"
##
# Conditionally set name of root group
##
- name: "set system group"
set_fact:
sysgroup: "{{ 'root' if (ansible_distribution == 'RedHat') else 'sys' }}"
باستخدام الكتل يسمح لنا بتعيين الشرط للمهمة بأكملها. سنستخدم الشرط في نهاية الكتلة لاستبعاد مضيفي "la".
##
# Enclose in block so we can use parhost to exclude hosts
##
- block:
وحدة القالب بالتحقق من صحة وتثبيت الملف. نصلح النتيجة حتى نتمكن من تحديد ما إذا كانت المهمة قد تغيرت. يتيح لك استخدام معلمة التحقق من الصحة في هذه الوحدة التحقق من صحة ملف sudoer الجديد قبل وضعه على المضيف.
##
# Validate will prevent bad files, no need to revert
# Jinja2 template will add include line
##
- name: Ensure sudoers file
template:
src: sudoers.j2
dest: /etc/sudoers
owner: root
group: "{{ sysgroup }}"
mode: 0440
backup: yes
validate: /usr/sbin/visudo -cf %s
register: sudochg
إذا تم تثبيت قالب جديد ، قم بتشغيل البرنامج النصي shell لإنشاء ملف المجموع الاختباري. يقوم التحديث الشرطي بتحديث ملف المجموع الاختباري عند تثبيت قالب sudoers ، أو في حالة عدم وجود ملف المجموع الاختباري. نظرًا لأن عملية التشغيل تراقب أيضًا الملفات الأخرى ، فإننا نستخدم كود shell الموضح في البرنامج النصي المصدر:
- name: sudoers checksum
shell: "grep -v '/etc/sudoers' {{ MD5FILE }} > {{ MD5FILE }}.tmp ; {{ csbin }} /etc/sudoers >> {{ MD5FILE }} ; mv {{ MD5FILE }}.tmp {{ MD5FILE }}"
when: sudochg.changed or MD5STAT.exists == false
تتحقق وحدة الملفات من تثبيت الأذونات اللازمة:
- name: Ensure MD5FILE permissions
file:
path: "{{ MD5FILE }}"
owner: root
group: "{{ sysgroup }}"
mode: 0600
state: file
نظرًا لأن المعلمة الاحتياطية لا توفر أي خيارات لمعالجة النسخ الاحتياطية السابقة ، فسوف يتعين علينا الاهتمام بإنشاء الشفرة المناسبة بأنفسنا. في المثال أدناه ، نستخدم المعلمة "تسجيل" وحقل "stdout_lines" لهذا الغرض.
##
# List and clean up backup files. Retain 3 copies.
##
- name: List /etc/sudoers.*~ files
shell: "ls -t /etc/sudoers*~ |tail -n +4"
register: LIST_SUDOERS
changed_when: false
- name: Cleanup /etc/sudoers.*~ files
file:
path: "{{ item }}"
state: absent
loop: "{{ LIST_SUDOERS.stdout_lines }}"
when: LIST_SUDOERS.stdout_lines != ""
إتمام الحظر:
##
# This conditional restricts what hosts this block runs on
##
when: parhost != EXCLUDE
...
حالة الاستخدام المقصود هي لعب هذا الدور على برج أنسبل. يمكن تكوين تنبيهات برج Ansible بحيث في حالة حدوث فشل في تنفيذ المهمة ، سيتم إرسال التنبيهات إلى البريد الإلكتروني أو Slack أو بطريقة أخرى. يعمل هذا الدور في Ansible أو Ansible Engine أو Ansible Tower.
نتيجةً لذلك ، أزلنا كل شيء غير ضروري من البرنامج النصي ، وقمنا بإنشاء دور متعطش تمامًا يمكن أن يوفر الحالة المطلوبة لملف sudoers. يتيح استخدام SCM التحكم في الإصدار ، ويوفر إدارة أكثر فعالية للتغيير والشفافية. تتيح لك CI / CD مع Jenkins أو أدوات أخرى إعداد اختبار تلقائي لرمز Ansible للتغييرات المستقبلية. يسمح لك دور Auditor في Ansible Tower بمراقبة وتطبيق المتطلبات التنظيمية.
يمكن إزالة رمز العمل مع المجموع الاختباري من البرنامج النصي ، ولكن لهذا العميل سيحتاج أولاً إلى استشارة خدمة الأمان الخاصة به. إذا لزم الأمر ، يمكن حماية نمط sudoers مع Ansible Vault. أخيرًا ، استخدام المجموعات يتجنب كتابة المنطق باستخدام ويشمل ويستبعد.
→ يمكنك تنزيل الدور من GitHub على هذا
الرابط