Puppet یک پلتفرم کانفیگ اتوماسیون میباشد که تسک های گوناگون یک ادمین سیستم را آسان میسازد. پاپت یک مدل client/server را برای مدیریت سرورها استفاده میکند، که agent های puppet نامیده میشوند و از طریق پروفایل های configuration با puppet master صحبت میکند.
Puppet به زبان custom خودش نوشته شده به طوریکه برای ادمین های سیستمی قابل دسترس است. ماژول هایی که روی puppet master موجود هستند در حقیقت برای تعریف سیستم مورد نظر استفاده می شوند. سپس نرم افزار puppet ماژول را به کد تبدیل میکند و همچنین (از آنجایی که نیاز است) وقتی دستور puppet agent روی یک سیستم agent اجرا شود و یا حتی در فواصل معین ، به صورت اتوماتیک به سرورهای agent هشدار میدهد.
Puppet میتواند برای مدیریت چندین سرور متفاوت با زیر ساخت های گوناگون مورد استفاده قرار گیرد. از گروهی از سرورهای شخصی گرفته تا یک عملیات در سطح enterprise. این ابزار را میتوان روی لینوکس و دیگر سیستم عامل های شبه یونیکس اجرا کرد، اگر چه روی ویندوز هم میتوان آنرا استفاده کرد. به هر حال در این مقاله ما روی Ubuntu 16.04 LTS به عنوان master server و دو سیستم agent یکی Ubuntu 16.04 و دیگری CentOS 7 کار خواهیم کرد.
نکته : دستورات این مقاله را با یوزر root اجرا کنید. یک یوزر محدود با دسترسی های ادمین در مرحله های بعدی کانفیگ خواهد شد.
نکات اولیه
1 - شما باید 3 سرور در دسترس داشته باشید، یکی از آنها حداقل 4 هسته CPU و 8 گیگ بایت RAM برای سرور master داشته باشد. دو سرور دیگر را میتوان با هر سایزی از ریسورس ها انتخاب کرد که به نوع استفاده شما بعد از اینکه puppet نصب و کانفیگ شد بستگی دارد.
2 - مطمئن شوید که timezone سرورها به درستی کانفیگ شده باشند.
نکته : برای راحتی کار hostname سرور puppet master را برابر با puppet-master تعریف کنید، و یک دامین valid داشته باشید. برای بررسی کردن hostname تان دستور hostname را اجرا کنید و FQDN (مخفف Fully Qualified Domain Name) خود را با دستور زیر چک کنید.
همچنین توصیه میشود مطالعه کنید :
دستور DSH برای اجرا کرد دستورات لینوکسی در چندین ماشین
دستور pssh برای اجرا کردن دستورات روی چندین سرور ریموت لینوکسی با استفاده تنها از یک ترمینال
نحوه نصب و راه اندازی Ansible در لینوکس - بخش اول
نحوه تنظیم/تغییر Hostname در لینوکس
نحوه تنظیم Timezone در لینوکس
نحوه نصب Puppet Master
1 - ریپازیتوری puppetlabs-release درون اوبونتو 16.04 نصب کنید و سیستم را آپدیت کنید. با این عمل یک فایل .deb دانلود میشود که ریپازیتوری ها را برای شما کانفیگ خواهد کرد.
نکته : اگر شما بخواهید توزیع لینوکسی دیگری را به عنوان سرور master تان داشته باشید فایل .deb اولیه با یک فایل دیگر و با یکی از فرمت های زیر جایگزین خواهد شد. لیست کلیه ورژن ها را میتوانید از صفحه ریپازیتوری puppetlabs مشاهده کنید.
برای سیستم های برپایه Red Hat
برای سیستم های برپایه Debian
دستورات مختص اوبونتو را نیز به جای دستور مورد نظر در توزیع های بالا جایگزین کنید. اطلاعات بیشتر را میتوان در Puppet Installation Documentation پیدا کنید.
2 - نصب پکیج puppetmaster-passenger
3 - نصب پیش فرض puppet ممکن است سرویس آپاچی را start کند و آنرا به نحوی کانفیگ کند که روی پورت یکسانی با خودش (puppet) لیسن (listen) کند (هر دو روی یک پورت لیسن کنند). سرویس apache را برای جلوگیری از این conflict باید stop کنید. (اگر از CentOS 7 استفاده میکنید در مثال زیر به جای apaceh2 از httpd استفاده کنید.
4 - با اجرای یکی از دستورات زیر مطمئن شوید که آخرین ورژن puppet را روی سیستم تان دارید.
تنظیمات Puppet Master
1 - ابتدا وارد مسیر etc/puppet/ شوید، سپس با استفاده از یک ادیتور متن فایل puppet.conf را ویرایش و آپدیت کنید.
خط dns_alt_names را به قسمت [main] اضافه کنید، puppet.example.com را با FQDN خودتان جایگزین کنید.
2 - با استفاده از دستور زیر Puppet master را start کنید.
به صورت پیش فرض پروسه puppet master به ارتباطات client روی پورت 8140 گوش میدهد. اگربعد از دستور بالا سرویس puppetmaster استارت نشد، چک کنید که پورت 8140 از قبل توسط سرویس دیگه ای مورد استفاده قرار نگرفته باشد.
نصب Puppet Agent
روی سیستم های agent که سیستم عامل شان Ubuntu 16.04 یا سایر توزیع های دبیان میباشد از دستور زیر برای نصب puppet استفاده کنید.
روی سیستم های agent که سیستم عامل شان CentOS 7 یا سایر توزیع های Red Hat باشد مراحل زیر را دنبال کنید.
1 - برای CentOS 7 ریپازیتوری Puppet Labs را اضافه کنید.
نکته : اگر روی هر توزیع دیگری غیر از CentOS 7 بودید مرحله بالا را نادیده بگیرید.
2 - نصب Puppet Agent
تنظیمات Puppet Agent
1 - فایل host مربوط به سیستم puppet agent را از مسیر /etc/hosts به منظور resolve کردن ip آدرس puppet master با عنوان puppet تغییر دهید.
2 - مقدار server را در قسمت [main] در فایل /etc/puppet/puppet.conf اضافه کنید، puppet.example.com را با FQDN سرور puppet-master جایگزین کنید.
3 - سرویس puppet را restart کنید.
ایجاد Certificate ها و Sign ها
1 - روی هر agent یک certificate برای puppet master ایجاد و sign کنید.
این دستور یک ارور ("Exiting; no certificate found and waitforcert is disabled") در خروجی می دهد که مشخص می کند certificate وجود ندارد. این error به این دلیل ایجاد میشود که certificate ایجاد شده نیاز دارد که توسط puppet master تایید شود.
2 - به Puppet master لاگین کنید و certificate هایی که نیاز به تایید دارند را لیست کنید.
خروجی آن باید لیستی از host name های سرور های agent شما باشد.
3 - certificate ها را تایید کنید. hostname.example.com را با hostname مربوط به هر سرور agent جایگزین کنید. (hostname موجود در هر سرور را جایگزین hostname.example.com کنید)
4 - به سرور puppet agent برگردید و مجدد دستور puppet agent را اجرا کنید.
نکته : در صورتی که هنگام اجرای دستور puppet agent با خطای "Error: Could not request certificate" مواجه شدید، مربوط به فعال بودن SELINUX در CentOS میباشد که میتوان با غیرفعال کردن SELINUX مشکل را برطرف کرد.
اضافه کردن ماژول ها برای کانفیگ سرورهای Agent
سرویس puppet master و همچنین سرورهای agent (که در بالا کانفیگ شدند) بسیار کاربردی هستند اما امنیتی ندارند. بر اساس راهنمای امن کردن سرور باید یک کاربر محدود و یک فایروال به درستی روی سیستم تان کانفیگ شود. این مورد را میتوانید روی همه سرورها از طریق ایجاد یک ماژول اولیه puppet همانند زیر ایجاد کنید.
اضافه کردن یک کاربر محدود
1 - از سرور puppet master به دایرکتوری modules وارد شوید و ماژول جدید خود را برای اضافه کردن اکانت های کاربر ایجاد کنید، سپس به دایرکتوری accounts وارد شوید.
2 - دایرکتوری های زیر را که برای داشتن یک ماژول کاربردی نیاز هستند ایجاد کنید.
دایرکتوری examples به شما این امکان را میدهد که ماژول را به صورت Local تست کنید. دایرکتوری files شامل هر فایل static است که ممکن است نیاز به ویرایش یا اضافه کردن داشته باشد. دایرکتوری manifests شامل puppet code واقعی برای ماژول میباشد و دایرکتوری templates شامل هر فایل غیر static میباشد که ممکن است مورد نیاز باشد.
3 - به دایرکتوری manifests بروید و clase اولیه خود را ایجاد کنید که init.pp نامیده میشود. همه ماژول ها به یک فایل init.pp که به عنوان فایل توصیفی اصلی یک ماژول مورد استفاده قرار میگیرد، نیاز دارد.
4 - ابتدا با استفاده از یک ادیتور متن فایل init.pp را ایجاد کنید.
درون فایل init.pp یک کاربر محدود برای استفاده به جای root تعریف کنید، همه عبارات username در زیر را با نام کاربر مورد نظرتان جایگزین کنید.
فایل init.pp کلاس accounts را تعریف میکند سپس ریسورس user را فرا میخواند که در آن یک username تعریف شده است مقدار ensure برای مطمئن شدن از اینکه کاربر وجود دارد (موجود است) تعریف میشود مقدار home باید برابر با مسیر دایرکتوری home کاربر تعریف شده باشد. shell نوع شل مورد استفاده را تعریف میکند که در اینجا ما bash را استفاده میکنیم. مقدار managehome دقت میکند که دایرکتوری home حتما ایجاد شده باشد. در نهایت مقدار gid باید برابر با primary group کاربر تعریف شده باشد.
5 - اگر چه primary group برای به اشتراک گذاشتن username تعریف میشوداما هنوز خود group ایجاد نشده است. فایل init.pp را ذخیره و از آن خارج شوید سپس یک فایل جدید به نام groups.pp ایجاد کنید.
محتوای زیر را به آن اضافه کنید. این فایل برای ایجاد گروه کاربر مورد استفاده قرار میگیرد. مجددا username را با نام کاربر مورد نظر خود جایگزین کنید.
این فایل را باید در فایل init.pp اضافه کنید. با استفاده از کلاس accounts و به واسطه اضافه کردن include groups در فایل init.pp باید فایل بالا را include کنید.
6 - این یوزر باید دسترسی هایی داشته باشد تا تسک های مدیریتی را بتوان با آن اجرا کرد. به دلیل اینکه ما سیستم های agent مان هم روی Debian و هم RedHat هستند، یوزر جدید باید در گروه sudo روی سیستم های دبیان و روی سیستم های ردهت در گروه wheel باشد. این مقدار را میتوان به صورت داینامیک و از طریق استفاده از یک selector و facter(برنامه ای که در puppet موجود است و اطلاعات یا واقعیت های درباره هر سرور را پیگیری میکند) تعریف کرد. یک عبارت selector به بالای فایل init.pp درون براکت کلاس account اضافه کنید و سپس دو آپشن زیر را در آن تعریف کنید.
این گروه از دستورات به puppet میگوید که متغییر $rootgroup درون ماژول accounts و با استفاده از facter مقدار operating system family (یا $osfamily) باید مشخص شود و اگر مقدار برگشتی برابر با Debian بود مقدار متغییر $rootgroup را برابر با sudo تعریف کنید. اگر مقدار برگشتی برابر با RedHat بود مقدار متغییر $rootgroup را برابر با wheel تعریف کنید، در غیر اینصورت مقدار defualt خطایی برخواهد گرداند مبنی بر اینکه توزیع انتخاب شده توسط این ماژول پشتیبانی نمیشود.
نکته : قسمت تعریف user شامل $rootgroup میباشد و زبان کانفیگی puppet کدها را از بالا تا پایین اجرا میکند. شما باید قبل از قسمت user متغیر $rootgroup را تعریف کنید تا قابل دسترسی باشد.
7 - مقدار groups را به resource مورد نظر اضافه کنید، که در حقیقت متغیر $rootgroup را که در مرحله قبل در فایل init.pp تعریف کردیم فراخوانی میکند.
نکته : مقدار $rootgroup را به دلیل اینکه یک متغیر است، به جای اینکه در single quotes (‘) قرار دهید باید در double quotes (“) بگذارید. هر مقدار دیگری که در single quotes قرار گیرد در حقیقت دقیقا عین همان عبارت در ماژول تان اضافه میشود و هر چیزی که در double quotes قرار گیرد به عنوان متغییر تلقی میشود.
8 - مقدار نهایی که باید اضافه شود password است. از آنجایی که نمیخواهیم plain text استفاده کنیم باید آنرا برای puppet با یک SHA1 digest رمز گذاری (encrypte) میکنیم که به صورت پیش فرض نیز پشتیبانی میشود. از طریق ترمینال یک پسورد تعریف کنید.
از شما خواسته میشود که پسورد خود را وارد کنید در نتیجه یک پسورد hash شده خروجی خواهد داد که باید آنرا کپی کرد و به قسمت user در فایل init.pp اضافه کرد.
هشدار : پسورد hash شده باید در single quote قرار گیرد.
9 - بعد از ذخیره کردن تغییرات تان از puppet parser برای اطمینان حاصل کردن از درستی کد استفاده کنید.
در صورت وجود هر گونه error ی، آن مورد در standard output لاگ خواهد شد. اگر هیچ خطایی برنگردد کد شما درست است.
10 - قبل از اینکه ماژول را بیشتر تست کنیم به پوشه example رفته و این بار برای فراخوانی ماژول accounts، فایل init.pp دیگری ایجاد کنید.
بعد از اضافه کردن فایل init.pp این خط فایل را کرده سپس تغییرات را ذخیره و از آن خارج شوید.
11 - در حالیکه همچنان در پوشه example هستید بدون اعمال تغییرات ماژول را تست کنید.
نکته : پارامتر --noop از اینکه puppet به صورت واقعی ماژول را اجرا کند جلوگیری میکند.
دستور بالا باید خروجی زیر را برگرداند.
12 - مجدد از دایرکتوری example دستور puppet apply را برای اعمال این تغییرات در سرور puppet master اجرا کنید.
13 - یوزر root را logout کنید و با یوزر جدید خود در puppet master لاگین کنید. در ادامه این مقاله دستورات با این کاربر اجرا خواهند شد.
ویرایش تنظیمات SSH
اگر چه یک کاربر جدید با موفقیت به puppet master اضافه شد، اما account همچنان امن نیست. دسترسی root باید قبل از ادامه در سرور غیر فعال شود.
1 - به پوشه files درون دایرکتوری ماژول account وارد شوید.
2 - فایل sshd_config را به این دایرکتوری copy کنید.
3 - فایل sshd_config با دسترسی sudo باز کنید و مقدار PermitRootLogin را برابر با no تعریف کنید.
4 - به دایرکتوری manifests برگردید سپس با استفاده از sudo فایلی به نام ssh.pp ایجاد کنید.
از قسمت file برای جایگزین کردن فایل کانفیگ پیش فرض با فایلی که توسط puppet مدیریت میشود استفاده میکنیم.
نکته : پوشه files از خط source حذف شده است، زیرا پوشه files مسیر پیش فرض فایل ها میباشد. برای کسب اطلاعات بیشتر در مورد فرمت مورد استفاده برای دسترسی به ریسورس های در یک ماژول به داکیومنت رسمی puppet module مراجعه کنید.
5 - فایل ssh.pp را با استفاده از یک ادیتور متن باز کنید.
ریسورس دومی به منظور restart کردن سرور SSH ایجاد کنید و تعریف کنید که هر زمان sshd_config تغییر کرد اجرا شود. این مورد همچنین نیاز به یک عبارت selector دارد زیرا سرویس SSH روی دبیان ssh و روی ردهت sshd نام دارد.
6 - فایل init.pp را با استفاده از یک ادیتور متن باز کنید.
درون فایل init.pp کلاس ssh را include کنید.
فایل کامل init.pp شما باید شبیه به زیر باشد.
7 - puppet parser را اجرا کنید سپس به دایرکتوری examples وارد شوید تا puppet apply را تست و اجرا کنید.
نکته : شما ممکن است خط زیر را در خروجی خود مشاهده کنید.
این به فایل کانفیگ puppet برمیگردد و از resource ماژولی که شما میخواهید کپی کنید نیست. اگر تنها error موجود در خروجی شما این باشد همچنان عملیات را میتوان پیش برد.
8 - برای اینکه مطمئن شوید کلاس ssh به درستی کار میکند، log out کنید و مجددا تلاش کنید با یوزر root لاگین شوید. در اینجا شما نباید قادر به لاگین باشید.
اضافه و تنظیمات IPtables
در این بخش ما رول های فایروال را با استفاده از iptables تعریف میکنیم. به هر حال این roule ها بعد از reboot دیگر وجود نخواهند داشت، برای جلوگیری از این مورد پکیج مربوطه و مناسب به هر سرور (هم master و هم agent) را قبل از ادامه نصب میکنیم.
در Ubuntu/Debian
در CentOS 7
CentOS 7 به صورت پیش فرض از firewalld به عنوان کنترل کننده ای برای iptables استفاده میکند. مطمئن شوید که سرویس firewalld متوقف (stop) شده باشد. قبل از اینکه کار با iptables را آغاز کنید از غیر فعال بودن firewalld مطمئن شوید.
1 - روی سرور puppet master خود ماژول Puppet Lab's firewall را از ریپازیتوری puppet forge نصب کنید.
ماژول در دایرکتوری /etc/puppet/modules نصب خواهد شد.
2 - به دایرکتوری manifests تحت ماژول جدید فایروال وارد شوید.
3 - با استفاده از یک ادیتور متن، فایلی با عنوان pre.pp ایجاد کنید.
خطوط زیر را به آن اضافه کنید. این فایل شامل همه رول های اولیه شبکه که در ابتدا باید اجرا شوند میباشد.
هر rule از طریق متن های کامنت شده توضیح داده شده. اطلاعات بیشتر را میتوان در صفحه Puppet Forge Firewall بررسی کنید.
4 - سپس در همان دایرکتوری فایل post.pp را ایجاد کنید.
خطوط زیر را به آن اضافه کنید. این فایل هر رول فایروالی که باید در آخرین مرحله اعمال شوند را اجرا خواهد کرد.
این رول ها سیستم را به drop کردن همه ترافیک ورودی که از قبل در فایروال مجاز نباشند را هدایت میکند.
5 - Puppet parser را روی هر دو فایل اجرا کنید تا مطمئن شوید که کد هیچ گونه خطایی برنخواهد گرداند.
6 - یک دایرکتوری به عقب برگردید، دایرکتوری جدید examples را ایجاد کنید و به آن وارد شوید.
7 - درون دایرکتوری examples یک فایل init.pp به منظور تست کردن فایروال روی puppet master ایجاد کنید.
سپس خطوط زیر را به آن اضافه و تغییرات را ذخیره کنید.
این قسمت کد بابت این است که از عملکرد درست pre.pp و post.pp مطمئن شویم و همچنین یک رول فایروال به puppet master به منظور مجاز کردن دسترسی سرورها به master اضافه میکند.
8 - فایل init.pp را با استفاده از puppet parser را اجرا میکنیم و سپس بررسی میکنیم که در حال اجرا باشد.
اگر با موفقیت تمام شد دستور puppet aply را بدون آپشن --noop اجرا میکنیم.
9 - به محض اینکه عملیات puppet انجام شد، رول های iptables را چک میکنیم.
خروجی شبیه به زیر باید نمایش داده شود.
اضافه کردن ماژول ها به سرورهای Agent
اکنون که ماژول های account و firewall روی puppet master ایجاد، تست و اجرا شده اند زمان آن رسیده که این ماژول ها را به سرورهای puppet agent که از قبل ایجاد کردیم اضافه کنیم.
1 - در سرور Puppet master به دایرکتوری manifests وارد شوید.
2 - تمام سرورهای موجود را لیست کنید.
3 - فایل site.pp را به منظور تعریف اینکه چه سرورهای این ماژول ها را دریافت کنند ایجاد کنید.
مقدارهای ubuntuagent.example.com و centosagent.example.com را با FQDN سرور agent خود جایگزین کنید.
این فایل شامل ماژول accounts میباشد و تنظیمات فایروال یکسانی را همانند بالا استفاده میکند تا مطمئن شود که رول های فایروال به درستی اعمال شده اند.
4 - روی هر سرور puppet agent دستور puppet agent را فعال کنید.
5 - دستور puppet agent را همانند زیر اجرا کنید.
6 - برای اطمینان از کار کردن puppet agent با یوزری که با دسترسی محدود در سرور puppet master ایجاد کردیم login کنید و iptables را چک کنید.
همچنین توصیه میشود مطالعه کنید :
دستورات cron job و crontab در لینوکس به همراه 11 مثال برای زمان بندی کارها
اکنون شما با موفقیت puppet را روی یک master و دو سرور agent نصب و راه اندازی کردید. اکنون که شما صحت عملکرد همه بخش ها را تایید میکنید میتوانید ماژول های اضافه برای اتوماتیک کردن مدیریت کانفیگ ها روی سرورهای agent تان، ایجاد کنید. برای کسب اطلاعات بیشتر Puppet module fundamentals را مشاهده و بررسی کنید. همچین شما میتوانید ماژول هایی را که دیگران روی Puppet Forge ایجاد کرده اند را نصب و استفاده کنید.
Puppet به زبان custom خودش نوشته شده به طوریکه برای ادمین های سیستمی قابل دسترس است. ماژول هایی که روی puppet master موجود هستند در حقیقت برای تعریف سیستم مورد نظر استفاده می شوند. سپس نرم افزار puppet ماژول را به کد تبدیل میکند و همچنین (از آنجایی که نیاز است) وقتی دستور puppet agent روی یک سیستم agent اجرا شود و یا حتی در فواصل معین ، به صورت اتوماتیک به سرورهای agent هشدار میدهد.
Puppet میتواند برای مدیریت چندین سرور متفاوت با زیر ساخت های گوناگون مورد استفاده قرار گیرد. از گروهی از سرورهای شخصی گرفته تا یک عملیات در سطح enterprise. این ابزار را میتوان روی لینوکس و دیگر سیستم عامل های شبه یونیکس اجرا کرد، اگر چه روی ویندوز هم میتوان آنرا استفاده کرد. به هر حال در این مقاله ما روی Ubuntu 16.04 LTS به عنوان master server و دو سیستم agent یکی Ubuntu 16.04 و دیگری CentOS 7 کار خواهیم کرد.
نکته : دستورات این مقاله را با یوزر root اجرا کنید. یک یوزر محدود با دسترسی های ادمین در مرحله های بعدی کانفیگ خواهد شد.
نکات اولیه
1 - شما باید 3 سرور در دسترس داشته باشید، یکی از آنها حداقل 4 هسته CPU و 8 گیگ بایت RAM برای سرور master داشته باشد. دو سرور دیگر را میتوان با هر سایزی از ریسورس ها انتخاب کرد که به نوع استفاده شما بعد از اینکه puppet نصب و کانفیگ شد بستگی دارد.
2 - مطمئن شوید که timezone سرورها به درستی کانفیگ شده باشند.
نکته : برای راحتی کار hostname سرور puppet master را برابر با puppet-master تعریف کنید، و یک دامین valid داشته باشید. برای بررسی کردن hostname تان دستور hostname را اجرا کنید و FQDN (مخفف Fully Qualified Domain Name) خود را با دستور زیر چک کنید.
کد PHP:
# echo “Master_IP puppet-master ” >> /etc/hosts
# hostname -f
همچنین توصیه میشود مطالعه کنید :
دستور DSH برای اجرا کرد دستورات لینوکسی در چندین ماشین
دستور pssh برای اجرا کردن دستورات روی چندین سرور ریموت لینوکسی با استفاده تنها از یک ترمینال
نحوه نصب و راه اندازی Ansible در لینوکس - بخش اول
نحوه تنظیم/تغییر Hostname در لینوکس
نحوه تنظیم Timezone در لینوکس
نحوه نصب Puppet Master
1 - ریپازیتوری puppetlabs-release درون اوبونتو 16.04 نصب کنید و سیستم را آپدیت کنید. با این عمل یک فایل .deb دانلود میشود که ریپازیتوری ها را برای شما کانفیگ خواهد کرد.
کد PHP:
# wget https://apt.puppetlabs.com/puppetlabs-release-pc1-xenial.deb
# dpkg -i puppetlabs-release-pc1-xenial.deb
# apt update
برای سیستم های برپایه Red Hat
کد PHP:
# wget https://yum.puppetlabs.com/puppetlabs-release-pc1-OS-VERSION.noarch.rpm
کد PHP:
# wget https://apt.puppetlabs.com/puppetlabs-release-pc1-VERSION.deb
2 - نصب پکیج puppetmaster-passenger
کد PHP:
# apt install puppetmaster-passenger
3 - نصب پیش فرض puppet ممکن است سرویس آپاچی را start کند و آنرا به نحوی کانفیگ کند که روی پورت یکسانی با خودش (puppet) لیسن (listen) کند (هر دو روی یک پورت لیسن کنند). سرویس apache را برای جلوگیری از این conflict باید stop کنید. (اگر از CentOS 7 استفاده میکنید در مثال زیر به جای apaceh2 از httpd استفاده کنید.
کد PHP:
# systemctl stop apache2
4 - با اجرای یکی از دستورات زیر مطمئن شوید که آخرین ورژن puppet را روی سیستم تان دارید.
کد PHP:
# puppet resource package puppetmaster ensure=latest
OR
# puppet --version
تنظیمات Puppet Master
1 - ابتدا وارد مسیر etc/puppet/ شوید، سپس با استفاده از یک ادیتور متن فایل puppet.conf را ویرایش و آپدیت کنید.
کد PHP:
# cd /etc/puppet/
# vim puppet.conf
کد PHP:
[main]
dns_alt_names=puppet,puppet.example.com
2 - با استفاده از دستور زیر Puppet master را start کنید.
کد PHP:
# systemctl start puppetmaster
کد PHP:
# netstat -anpl | grep 8140
نصب Puppet Agent
روی سیستم های agent که سیستم عامل شان Ubuntu 16.04 یا سایر توزیع های دبیان میباشد از دستور زیر برای نصب puppet استفاده کنید.
کد PHP:
# apt install puppet
1 - برای CentOS 7 ریپازیتوری Puppet Labs را اضافه کنید.
کد PHP:
# rpm -ivh https://yum.puppetlabs.com/el/7/products/x86_64/puppetlabs-release-22.0-2.noarch.rpm
2 - نصب Puppet Agent
کد PHP:
# yum install puppet
تنظیمات Puppet Agent
1 - فایل host مربوط به سیستم puppet agent را از مسیر /etc/hosts به منظور resolve کردن ip آدرس puppet master با عنوان puppet تغییر دهید.
کد PHP:
# echo “Master_IP puppet-master ” >> /etc/hosts
2 - مقدار server را در قسمت [main] در فایل /etc/puppet/puppet.conf اضافه کنید، puppet.example.com را با FQDN سرور puppet-master جایگزین کنید.
کد PHP:
[main]
server=puppet.example.com
3 - سرویس puppet را restart کنید.
کد PHP:
systemctl restart puppet
ایجاد Certificate ها و Sign ها
1 - روی هر agent یک certificate برای puppet master ایجاد و sign کنید.
کد PHP:
puppet agent -t
2 - به Puppet master لاگین کنید و certificate هایی که نیاز به تایید دارند را لیست کنید.
کد PHP:
puppet cert list
3 - certificate ها را تایید کنید. hostname.example.com را با hostname مربوط به هر سرور agent جایگزین کنید. (hostname موجود در هر سرور را جایگزین hostname.example.com کنید)
کد PHP:
puppet cert sign hostname.example.com
4 - به سرور puppet agent برگردید و مجدد دستور puppet agent را اجرا کنید.
کد PHP:
# puppet agent -t
نکته : در صورتی که هنگام اجرای دستور puppet agent با خطای "Error: Could not request certificate" مواجه شدید، مربوط به فعال بودن SELINUX در CentOS میباشد که میتوان با غیرفعال کردن SELINUX مشکل را برطرف کرد.
اضافه کردن ماژول ها برای کانفیگ سرورهای Agent
سرویس puppet master و همچنین سرورهای agent (که در بالا کانفیگ شدند) بسیار کاربردی هستند اما امنیتی ندارند. بر اساس راهنمای امن کردن سرور باید یک کاربر محدود و یک فایروال به درستی روی سیستم تان کانفیگ شود. این مورد را میتوانید روی همه سرورها از طریق ایجاد یک ماژول اولیه puppet همانند زیر ایجاد کنید.
اضافه کردن یک کاربر محدود
1 - از سرور puppet master به دایرکتوری modules وارد شوید و ماژول جدید خود را برای اضافه کردن اکانت های کاربر ایجاد کنید، سپس به دایرکتوری accounts وارد شوید.
کد PHP:
# mkdir /etc/puppet/modules/accounts
# cd /etc/puppet/modules/accounts
2 - دایرکتوری های زیر را که برای داشتن یک ماژول کاربردی نیاز هستند ایجاد کنید.
کد PHP:
# mkdir {examples,files,manifests,templates}
3 - به دایرکتوری manifests بروید و clase اولیه خود را ایجاد کنید که init.pp نامیده میشود. همه ماژول ها به یک فایل init.pp که به عنوان فایل توصیفی اصلی یک ماژول مورد استفاده قرار میگیرد، نیاز دارد.
کد PHP:
# cd manifests
4 - ابتدا با استفاده از یک ادیتور متن فایل init.pp را ایجاد کنید.
کد PHP:
# vim init.pp
کد PHP:
class accounts {
user { 'username':
ensure => present,
home => '/home/username',
shell => '/bin/bash',
managehome => true,
gid => 'username',
}
}
5 - اگر چه primary group برای به اشتراک گذاشتن username تعریف میشوداما هنوز خود group ایجاد نشده است. فایل init.pp را ذخیره و از آن خارج شوید سپس یک فایل جدید به نام groups.pp ایجاد کنید.
کد PHP:
# vim /etc/puppet/modules/accounts/manifests/groups.pp
کد PHP:
class accounts::groups {
group { 'username':
ensure => present,
}
}
کد PHP:
class accounts {
include groups
...
}
6 - این یوزر باید دسترسی هایی داشته باشد تا تسک های مدیریتی را بتوان با آن اجرا کرد. به دلیل اینکه ما سیستم های agent مان هم روی Debian و هم RedHat هستند، یوزر جدید باید در گروه sudo روی سیستم های دبیان و روی سیستم های ردهت در گروه wheel باشد. این مقدار را میتوان به صورت داینامیک و از طریق استفاده از یک selector و facter(برنامه ای که در puppet موجود است و اطلاعات یا واقعیت های درباره هر سرور را پیگیری میکند) تعریف کرد. یک عبارت selector به بالای فایل init.pp درون براکت کلاس account اضافه کنید و سپس دو آپشن زیر را در آن تعریف کنید.
کد PHP:
class accounts {
$rootgroup = $osfamily ? {
'Debian' => 'sudo',
'RedHat' => 'wheel',
default => warning('This distribution is not supported by the Accounts module'),
}
user { 'username':
...
}
نکته : قسمت تعریف user شامل $rootgroup میباشد و زبان کانفیگی puppet کدها را از بالا تا پایین اجرا میکند. شما باید قبل از قسمت user متغیر $rootgroup را تعریف کنید تا قابل دسترسی باشد.
7 - مقدار groups را به resource مورد نظر اضافه کنید، که در حقیقت متغیر $rootgroup را که در مرحله قبل در فایل init.pp تعریف کردیم فراخوانی میکند.
کد PHP:
user { 'username':
ensure => present,
home => '/home/username',
shell => '/bin/bash',
managehome => true,
gid => 'username',
groups => "$rootgroup",
}
نکته : مقدار $rootgroup را به دلیل اینکه یک متغیر است، به جای اینکه در single quotes (‘) قرار دهید باید در double quotes (“) بگذارید. هر مقدار دیگری که در single quotes قرار گیرد در حقیقت دقیقا عین همان عبارت در ماژول تان اضافه میشود و هر چیزی که در double quotes قرار گیرد به عنوان متغییر تلقی میشود.
8 - مقدار نهایی که باید اضافه شود password است. از آنجایی که نمیخواهیم plain text استفاده کنیم باید آنرا برای puppet با یک SHA1 digest رمز گذاری (encrypte) میکنیم که به صورت پیش فرض نیز پشتیبانی میشود. از طریق ترمینال یک پسورد تعریف کنید.
کد PHP:
# openssl passwd -1
از شما خواسته میشود که پسورد خود را وارد کنید در نتیجه یک پسورد hash شده خروجی خواهد داد که باید آنرا کپی کرد و به قسمت user در فایل init.pp اضافه کرد.
کد PHP:
class accounts {
user { 'username':
ensure => present,
home => '/home/username',
shell => '/bin/bash',
managehome => true,
gid => 'username',
groups => "$rootgroup",
password => '$1$07JUIM1HJKDSWm8.NJOqsP.blweQ..3L0',
}
}
9 - بعد از ذخیره کردن تغییرات تان از puppet parser برای اطمینان حاصل کردن از درستی کد استفاده کنید.
کد PHP:
# puppet parser validate init.pp
10 - قبل از اینکه ماژول را بیشتر تست کنیم به پوشه example رفته و این بار برای فراخوانی ماژول accounts، فایل init.pp دیگری ایجاد کنید.
کد PHP:
# cd ../examples
# vim init.pp
کد PHP:
include accounts
11 - در حالیکه همچنان در پوشه example هستید بدون اعمال تغییرات ماژول را تست کنید.
کد PHP:
# puppet apply --noop init.pp
دستور بالا باید خروجی زیر را برگرداند.
کد PHP:
Notice: Compiled catalog for puppet.example.com in environment production in 0.26 seconds
Notice: /Stage[main]/Accounts::Groups/Group[username]/ensure: current_value absent, should be present (noop)
Notice: Class[Accounts::Groups]: Would have triggered 'refresh' from 1 events
Notice: /Stage[main]/Accounts/User[username]/ensure: current_value absent, should be present (noop)
Notice: Class[Accounts]: Would have triggered 'refresh' from 1 events
Notice: Stage[main]: Would have triggered 'refresh' from 2 events
Notice: Finished catalog run in 0.02 seconds
12 - مجدد از دایرکتوری example دستور puppet apply را برای اعمال این تغییرات در سرور puppet master اجرا کنید.
کد PHP:
# puppet apply init.pp
13 - یوزر root را logout کنید و با یوزر جدید خود در puppet master لاگین کنید. در ادامه این مقاله دستورات با این کاربر اجرا خواهند شد.
ویرایش تنظیمات SSH
اگر چه یک کاربر جدید با موفقیت به puppet master اضافه شد، اما account همچنان امن نیست. دسترسی root باید قبل از ادامه در سرور غیر فعال شود.
1 - به پوشه files درون دایرکتوری ماژول account وارد شوید.
کد PHP:
# cd /etc/puppet/modules/accounts/files
2 - فایل sshd_config را به این دایرکتوری copy کنید.
کد PHP:
# sudo cp /etc/ssh/sshd_config .
3 - فایل sshd_config با دسترسی sudo باز کنید و مقدار PermitRootLogin را برابر با no تعریف کنید.
کد PHP:
PermitRootLogin no
4 - به دایرکتوری manifests برگردید سپس با استفاده از sudo فایلی به نام ssh.pp ایجاد کنید.
کد PHP:
# cd ../manifests
# sudo vim ssh.pp
کد PHP:
class accounts::ssh {
file { '/etc/ssh/sshd_config':
ensure => present,
source => 'puppet:///modules/accounts/sshd_config',
}
}
5 - فایل ssh.pp را با استفاده از یک ادیتور متن باز کنید.
کد PHP:
# sudo vim /etc/puppet/modules/accounts/manifests/ssh.pp
کد PHP:
class accounts::ssh {
$sshname = $osfamily ? {
'Debian' => 'ssh',
'RedHat' => 'sshd',
default => warning('This distribution is not supported by the Accounts module'),
}
file { '/etc/ssh/sshd_config':
ensure => present,
source => 'puppet:///modules/accounts/sshd_config',
notify => Service["$sshname"],
}
service { "$sshname":
hasrestart => true,
}
}
6 - فایل init.pp را با استفاده از یک ادیتور متن باز کنید.
کد PHP:
# sudo vim init.pp
کد PHP:
class accounts {
include groups
include ssh
...
کد PHP:
class accounts {
include groups
include ssh
$rootgroup = $osfamily ? {
'Debian' => 'sudo',
'RedHat' => 'wheel',
default => warning('This distro not supported by Accounts module'),
}
user { 'example':
ensure => present,
home => '/home/username',
shell => '/bin/bash',
managehome => true,
gid => 'username',
groups => "$rootgroup",
password => '$1$07JUIM1HJKDSWm8.NJOqsP.blweQ..3L0'
}
}
7 - puppet parser را اجرا کنید سپس به دایرکتوری examples وارد شوید تا puppet apply را تست و اجرا کنید.
کد PHP:
# sudo puppet parser validate ssh.pp
# cd ../examples
# sudo puppet apply --noop init.pp
# sudo puppet apply init.pp
کد PHP:
Error: Removing mount "files": /etc/puppet/files does not exist or is not a directory
این به فایل کانفیگ puppet برمیگردد و از resource ماژولی که شما میخواهید کپی کنید نیست. اگر تنها error موجود در خروجی شما این باشد همچنان عملیات را میتوان پیش برد.
8 - برای اینکه مطمئن شوید کلاس ssh به درستی کار میکند، log out کنید و مجددا تلاش کنید با یوزر root لاگین شوید. در اینجا شما نباید قادر به لاگین باشید.
اضافه و تنظیمات IPtables
در این بخش ما رول های فایروال را با استفاده از iptables تعریف میکنیم. به هر حال این roule ها بعد از reboot دیگر وجود نخواهند داشت، برای جلوگیری از این مورد پکیج مربوطه و مناسب به هر سرور (هم master و هم agent) را قبل از ادامه نصب میکنیم.
در Ubuntu/Debian
کد PHP:
# sudo apt install iptables-persistent
در CentOS 7
CentOS 7 به صورت پیش فرض از firewalld به عنوان کنترل کننده ای برای iptables استفاده میکند. مطمئن شوید که سرویس firewalld متوقف (stop) شده باشد. قبل از اینکه کار با iptables را آغاز کنید از غیر فعال بودن firewalld مطمئن شوید.
کد PHP:
# sudo systemctl stop firewalld && sudo systemctl disable firewalld
# sudo yum install iptables-services
1 - روی سرور puppet master خود ماژول Puppet Lab's firewall را از ریپازیتوری puppet forge نصب کنید.
کد PHP:
sudo puppet module install puppetlabs-firewall
ماژول در دایرکتوری /etc/puppet/modules نصب خواهد شد.
2 - به دایرکتوری manifests تحت ماژول جدید فایروال وارد شوید.
کد PHP:
# cd /etc/puppet/modules/firewall/manifests/
3 - با استفاده از یک ادیتور متن، فایلی با عنوان pre.pp ایجاد کنید.
کد PHP:
# sudo vim pre.pp
کد PHP:
class firewall::pre {
Firewall {
require => undef,
}
# Accept all loopback traffic
firewall { '000 lo traffic':
proto => 'all',
iniface => 'lo',
action => 'accept',
}->
#Drop non-loopback traffic
firewall { '001 reject non-lo':
proto => 'all',
iniface => '! lo',
destination => '127.0.0.0/8',
action => 'reject',
}->
#Accept established inbound connections
firewall { '002 accept established':
proto => 'all',
state => ['RELATED', 'ESTABLISHED'],
action => 'accept',
}->
#Allow all outbound traffic
firewall { '003 allow outbound':
chain => 'OUTPUT',
action => 'accept',
}->
#Allow ICMP/ping
firewall { '004 allow icmp':
proto => 'icmp',
action => 'accept',
}
#Allow SSH connections
firewall { '005 Allow SSH':
dport => '22',
proto => 'tcp',
action => 'accept',
}->
#Allow HTTP/HTTPS connections
firewall { '006 HTTP/HTTPS connections':
dport => ['80', '443'],
proto => 'tcp',
action => 'accept',
}
}
4 - سپس در همان دایرکتوری فایل post.pp را ایجاد کنید.
کد PHP:
# sudo vim post.pp
کد PHP:
class firewall::post {
firewall { '999 drop all':
proto => 'all',
action => 'drop',
before => undef,
}
}
5 - Puppet parser را روی هر دو فایل اجرا کنید تا مطمئن شوید که کد هیچ گونه خطایی برنخواهد گرداند.
کد PHP:
# sudo puppet parser validate pre.pp
# sudo puppet parser validate post.pp
6 - یک دایرکتوری به عقب برگردید، دایرکتوری جدید examples را ایجاد کنید و به آن وارد شوید.
کد PHP:
# cd ..
# sudo mkdir examples
# cd examples
7 - درون دایرکتوری examples یک فایل init.pp به منظور تست کردن فایروال روی puppet master ایجاد کنید.
کد PHP:
# sudo vim init.pp
کد PHP:
resources { 'firewall':
purge => true,
}
Firewall {
before => Class['firewall::post'],
require => Class['firewall::pre'],
}
class { ['firewall::pre', 'firewall::post']: }
firewall { '200 Allow Puppet Master':
dport => '8140',
proto => 'tcp',
action => 'accept',
}
8 - فایل init.pp را با استفاده از puppet parser را اجرا میکنیم و سپس بررسی میکنیم که در حال اجرا باشد.
کد PHP:
# sudo puppet parser validate init.pp
# sudo puppet apply --noop init.pp
کد PHP:
# sudo puppet apply init.pp
9 - به محض اینکه عملیات puppet انجام شد، رول های iptables را چک میکنیم.
کد PHP:
# sudo iptables -L
کد PHP:
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere /* 000 lo traffic */
REJECT all -- anywhere 127.0.0.0/8 /* 001 reject non-lo */ reject-with icmp-port-unreachable
ACCEPT all -- anywhere anywhere /* 002 accept established */ state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere /* 004 allow icmp */
ACCEPT tcp -- anywhere anywhere multiport ports ssh /* 005 Allow SSH */
ACCEPT tcp -- anywhere anywhere multiport ports http,https /* 006 HTTP/HTTPS connections */
ACCEPT tcp -- anywhere anywhere multiport ports 8140 /* 200 Allow Puppet Master */
DROP all -- anywhere anywhere /* 999 drop all */
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere /* 003 allow outbound */
اضافه کردن ماژول ها به سرورهای Agent
اکنون که ماژول های account و firewall روی puppet master ایجاد، تست و اجرا شده اند زمان آن رسیده که این ماژول ها را به سرورهای puppet agent که از قبل ایجاد کردیم اضافه کنیم.
1 - در سرور Puppet master به دایرکتوری manifests وارد شوید.
کد PHP:
# cd /etc/puppet/manifests
2 - تمام سرورهای موجود را لیست کنید.
کد PHP:
# sudo puppet cert list -all
3 - فایل site.pp را به منظور تعریف اینکه چه سرورهای این ماژول ها را دریافت کنند ایجاد کنید.
کد PHP:
# sudo vim /etc/puppet/manifests/site.pp
کد PHP:
node 'ubuntuagent.example.com' {
include accounts
resources { 'firewall':
purge => true,
}
Firewall {
before => Class['firewall::post'],
require => Class['firewall::pre'],
}
class { ['firewall::pre', 'firewall::post']: }
}
node 'centosagent.example.com' {
include accounts
resources { 'firewall':
purge => true,
}
Firewall {
before => Class['firewall::post'],
require => Class['firewall::pre'],
}
class { ['firewall::pre', 'firewall::post']: }
}
4 - روی هر سرور puppet agent دستور puppet agent را فعال کنید.
کد PHP:
# puppet agent --enable
5 - دستور puppet agent را همانند زیر اجرا کنید.
کد PHP:
# puppet agent -t
6 - برای اطمینان از کار کردن puppet agent با یوزری که با دسترسی محدود در سرور puppet master ایجاد کردیم login کنید و iptables را چک کنید.
کد PHP:
# sudo iptables -L
همچنین توصیه میشود مطالعه کنید :
دستورات cron job و crontab در لینوکس به همراه 11 مثال برای زمان بندی کارها
اکنون شما با موفقیت puppet را روی یک master و دو سرور agent نصب و راه اندازی کردید. اکنون که شما صحت عملکرد همه بخش ها را تایید میکنید میتوانید ماژول های اضافه برای اتوماتیک کردن مدیریت کانفیگ ها روی سرورهای agent تان، ایجاد کنید. برای کسب اطلاعات بیشتر Puppet module fundamentals را مشاهده و بررسی کنید. همچین شما میتوانید ماژول هایی را که دیگران روی Puppet Forge ایجاد کرده اند را نصب و استفاده کنید.